Abstract
Multiple vulnerabilities have been found in Cisco RV Series devices that allows an attacker to overwrite/create arbitrary files, execute arbitrary commands, and execute Cross-Site Request Forgery attacks.
Affected versions
These following Cisco RV Series devices are affected by these issues:
- Cisco RV120W Wireless-N VPN Firewall running firmware prior to 1.0.5.9
- Cisco RV180 VPN Router and Cisco RV180W Wireless-N Multifunction VPN Router running firmware versions prior to 1.0.4.14
- Cisco RV220W Wireless Network Security Firewall running any currently available release
See also
- CVE-2014-2177
- CVE-2014-2178
- CVE-2014-2179
- cisco-sa-20141105-rv: Multiple Vulnerabilities in Cisco Small Business RV Series Routers
Fix
Please consult Cisco advisory cisco-sa-20141105-rv for fix information.
Introduction
Multiple vulnerabilities have been found in Cisco RV Series devices that allows an attacker to overwrite/create arbitrary files, execute arbitrary commands, and execute CSRF attacks.
Insecure handling of file uploads
The admin pages of the affected devices are created using LUA scripts. It has been discovered that the affected devices use a cookie named TeamF1Login
in an insecure manner. The cookie value is used as a path name for storing the uploaded file. No input validation is done on the cookie value. Consequently, an attacker can set this to any value and thus create files in arbitrary locations.
It should be noted that:
- the web server (thttpd) runs as
root
; - existing files will be overwritten;
- this issue can be exploited by unauthenticated users.
/pfrm2.0/share/lua/5.1/cgilua/post.lua
local function fileupload (filename)
-- create a temporary file for uploading the file field
--local file, err = tmpfile()
-- Adarsh 7/16/07
local filename = mycookieget("TeamF1Login")
local file, err = myopen("/tmp/" .. filename, "wb")
if file == nil then
discardinput(bytesleft)
error("Cannot create a temporary file.\n"..err)
end
local bytesread = 0
local boundaryline = "\r\n"..boundary
local out = function (str)
local sl = strlen (str)
if bytesread + sl > maxfilesize then
discardinput (bytesleft)
error (format ("Maximum file size (%d kbytes) exceeded while uploading `%s'", maxfilesize / 1024, filename))
end
file:write (str)
bytesread = bytesread + sl
end
if readuntil (boundaryline, out) then
file:seek ("set", 0)
return file, bytesread
else
error (format ("Error processing multipart/form-data.\nUnexpected end of input while uploading %s", filename))
end
end
Command injection in diagnostics tools
The admin pages contain a couple of network diagnostic tools, such as the ability to perform an ICMP ping. Entering special characters in the different forms renders the following error message:
Invalid IP Address/Domain name:Domain/WAN (Internet) must contain only alphanumeric letters, '.' and '-'.
It appears that this check is not enforced server side. Sending the request directly can be used to submit & execute arbitrary commands, which will be executed with root privileges. A valid session is required to access the diagnostics tools.
/pfrm2.0/var/www/diagnostics.htm
if (ButtonType and ButtonType == "ping") then
local inputTable = web.cgiToLuaTable(cgi)
local throughVpn = false
local ipToPing = string.sub(inputTable["ping.ip"], string.find(inputTable["ping.ip"], '[%a%d\.:]+'))
local pingfile = db.getAttribute("environment", "name", "PING_FILE_NAME", "value")
local pingprog = ""
if (inputTable["ping.throughVpn"] ~= nil and inputTable["ping.throughVpn"] == "1") then
throughVpn = true
end
-- ping
[...]
else
pingprog = db.getAttribute("environment", "name", "PING_PROGRAM", "value")
options1 = " 2>&1 "
local cmd_ping = pingprog .. " " .. ipToPing
globalCmdOutput = util.runShellCmd(cmd_ping, pingfile, "/tmp/pingErr.txt", options1)
STATUS_CLASS = INFO_CLASS
statusMessage = (trStrings["11307"] or 'i18nHTMLMissing') .. " " .. ipToPing
end
end
web.goToPage(NextPage, true, true)
GET requests can be used to bypass Referer check
Whenever a POST
request is send to the application, a check is performed on the Referer
header. If the Referer
is empty or contains an external page, an error message is displayed (401 Unauthorized
). It appears that this check is not performed for GET
requests. GET
& POST
parameters are interchangeable and since the Referer check is the only measure against Cross-Site Request Forgery (CSRF) attacks, it is possible to execute CSRF attacks using specially crafted URLs. For example the following URL adds an admin account to the user database:
https://192.168.2.1/platform.cgi?thispage=diagnosticsAP.htm&button.ping.diagDisplayAP=Ping&ping.ip=-h+ 2%3e%2fdev%2fnull%3b%2fpfrm2.0%2fbin%2fsqlite3+%2ftmp%2fsystem.db+%22INSERT+INTO+%5c%22users%5c%22+VALUES%28%5c%22 admin%5c%22%2c%5c%22admin%5c%22%2c0%2c%5c%22admin%5c%22%2c10%29%3b%22