Tuesday, October 28, 2014

(CVE-2014-2718) ASUS wireless router updates vulnerable to a Man in the Middle attack

Over the past few months I have come across a couple of significant issues with ASUS wireless routers (which to their credit the company has been quick to resolve).

In mid February, I wrote that a substantial portion of ASUS wireless routers would fail to update their firmware. In fact, the "check for update" function would inform the administrator that the router was fully up-to-date, even though it was not. The timing could not have been worse, coming right on the heels of an exploit for a bug in which USB hard drives connected to the router could be accessed from the public Internet, with no login required.

In April I wrote that the same line of routers exposed the administrator username and password in clear text. Anyone that could access a PC that had logged into the router could retrieve the admin credentials. Since the admin session would never time out, this could be exploited even without the administrator having a window open on the router.

Today I am disclosing one additional vulnerability, submitted as CVE-2014-2718. The ASUS RT- series of routers rely on an easily manipulated process to determine if an update is needed, and to retrieve the necessary update file. In short, the router downloads via clear-text a file from http://dlcdnet.asus.com, parses it to determine the latest firmware version, then downloads (again in the clear) a binary file matching that version number from the same web site.

This report is one in a series I have written on ASUS wireless router features and vulnerabilities. Others of interest:

This applies to the RT-AC68U, RT-AC68U, RT-AC66R, RT-AC66U, RT-AC56R, RT-AC56U, RT-N66R, RT-N66U, RT-N56R, RT-N56U. It may also apply to the RT-N53, RT-N14U, RT-N16, and RT-N16R since they use the same firmware base but a different sub-version.

When you browse a web site via HTTPS, the web site provides an SSL Certificate to vouch for its identity. This certificate is issued by a certificate authority that is trusted to prove identity, much like a government-issued ID is trusted to prove identity in the physical world (i.e. both cases can be abused, but both cases are foundational to validating identity). Since the router downloads via HTTP instead of HTTPS, there is no way to validate that the server at the other end is in fact the ASUS server and not an impostor, as I will show through a proof of concept.


The router has two shell scripts /usr/sbin/webs_update.sh and /usr/sbin/webs_upgrade.sh that handle the upgrade logic; these scripts are called by the web admin interface on the router, at https://<router_address>:8443/Advanced_FirmwareUpgrade_Content.asp (you did change the authentication method to HTTPS, right? If not, the default path is http://<router_address>/Advanced_FirmwareUpgrade_Content.asp - now change the authentication method right away!). They can also be run from a telnet session.



The shell scripts use the built-in function nvram to query and set various system values. Running nvram show will display considerable information about the system, but the values we are interested in are productid (the model number), webs_state_update (a boolean flag that is set to 1 if there is a newer firmware available), webs_state_url (the path to the new firmware to download), and webs_state_info (the new firmware version). For this proof of concept I will use an RT-AC66R running firmware 3.0.0.4.374_5517, knowing that the legitimate new version is 3.0.0.4.376_1123.

Webs_update.sh uses nvram to query a couple of system variables that denote variations of hardware - devices made for Swiss telco Swisscom, and devices containing an SQ audio chipset, use a different firmware branch and a different download path. In this case though we are using the "normal" model.

Webs_update.sh next uses wget (a simple non-GUI web browser) to download the lookup file, in this case from http://dlcdnet.asus.com/pub/ASUS/LiveUpdate/Release/Wireless/wlan_update_v2.zip. Note that even though the file has a .zip extension, it is actually a plain text file that looks something like this:


Webs_update.sh parses the downloaded file to get the new build number, version number, and extended number. It concatenates these values and sets the nvram variable webs_state_info (in our example, this value is set to 3004_376_1123-gfde0c1d).

Webs_upgrade.sh is called next. It first downloads the firmware file identified by the previous script; in our case, it would download http://dlcdnet.asus.com/pub/ASUS/wireless/ASUSWRT/RT-AC66U_3004_376_1123-gfde0c1d_un.zip. Again note that while the filename is .zip, it is actually a TRX file, a file format used for storing kernel images in flash memory.

Knowing how it is supposed to work, we can begin our fun. The first step is to download the legitimate version table file
from http://dlcdnet.asus.com/pub/ASUS/LiveUpdate/Release/Wireless/wlan_update_v2.zip. Knowing the actual latest revision for one or more target router models, we can increment the extended version (EXT####) and place the file in a matching path (pub/ASUS/LiveUpdate/Release/Wireless/wlan_update_v2.zip) on a server that we control.

The next step is to create a binary kernel image with a filename that matches the target model plus version that we chose. Using the RT-AC66R as an example and assuming we incremented the extended version from 5517 to 5518, we would create a file with the name RT-AC66U_3.0.0.4_374_5518-g5f5c8d8_un.zip. 3.0.0.4_374 matches the FW version 3004374, and 5518-g5f5c8d8 matches the extended version EXT5518-g5f5c8d8 in the lookup file. _un.zip is the naming convention used by ASUS - despite the .zip extension it is in fact a TRX file, a file format used for storing kernel images in flash memory. This file should be placed on our server, in the folder /pub/ASUS/wireless/ASUSWRT.


A couple of side notes are in order. First, I am using an RT-AC66R, while the file shows RT-AC66U - the difference is only in where the router was purchased. ASUS uses "R" for models delivered to a brick-and-mortar retail store, and "U" for models delivered to an online supplier such as Amazon. Beneath the model number, they are identical. Second, I know the router for my test is running 3.0.0.4_374_5517, so I set the value in my file to 5518; the newest official firmware is actually 3.0.0.4_376_1123, which can no longer be exploited in this manner. Third, the 8-character checksum that follows the version number needs to match the checksum of the firmware file we are providing - NOT the checksum of the legitimate firmware.

With these two file in place, we are ready to begin our fun.

Upon logging into the router's web interface, the router will check dlcdnet.asus.com to see if a newer firmware is available, and if so will show an indicator on the screen. We can also use the firmware upgrade function on the administration tab to check for and apply updates. In either case, the router is downloading files from http://dlcdnet.asus.com. Since there is no SSL connection (no HTTPS), there is no SSL certificate to prove the identity at the other end, meaning we can conduct a man-in-the-middle attack. There are lots of ways to do this, but the easiest is to simply tell the router that dlcdnet.asus.com goes to your server instead of to the actual ASUS server. You can do this by poisoning the DNS configuration on the router, but I went the easy route of adding a static host to /etc/hosts.


With that done, clicking the "Check" button on the firmware upgrade screen queries our server instead of ASUS, finds that a "new" firmware is available, and downloads it. ASUS does some file integrity checking that I have not found a way around (though I believe it would be possible to use Firmware Mod Kit to modify a legitimate binary in a way that the upgrader would accept). I was successful though in taking an older genuine firmware (one with specific known vulnerabilities) and renaming it as a newer version. The router happily accepted that and "upgraded" to the older version.





ASUS quietly included an undocumented fix in firmware 3.0.0.4.376.1123 to resolve this vulnerability. The new design incorporates a signed checksum downloaded from the ASUS web site, which is verified using the public key on the router. Without the private key, an attacker cannot sign a checksum in such a way that the router would accept it. A MiTM attack could still show a new firmware as available, or prevent the router from seeing a legitimate new firmware, but an attacker can no longer induce the router to install a fake firmware. I strongly suggest installing this update as soon as possible.

I would recommend downloading directly from asus.com and not trusting the update feature of the router web GUI, but alas the support website does not use HTTPS either.

As a side note, the new flagship RT-AC87 models were launched with the new 3.0.0.4.376.x firmware codebase, and thus not susceptible to this form of attack.

Update 31-October - For those wondering why the latest firmware at asus.com does not have a date of this week, the issue was first fixed beginning in mid-July in the RT-AC68 and RT-AC66 models, and the new RT-AC87 was released with the fixed firmware. The fix then rolled out across the model line.

In the versioning scheme (ex: 3.0.0.4.376.1123), the 376 denotes the new code branch with the redesigned auto-update process. As long as your router's current firmware version is in the 376 branch, it has the fix.

Do you have something to add? A question you'd like answered? Think I'm out of my mind? Join the conversation below, reach out by email at david (at) securityforrealpeople.com, or hit me up on Twitter at @dnlongen