CVE-2021-22909- Digging into a Ubiquiti Firmware Update bug
May 25, 2021 | Vincent LeeBack In February, Ubiquiti released a new firmware update for the Ubiquiti EdgeRouter, fixing CVE-2021-22909/ZDI-21-601. The vulnerability lies in the firmware update procedure and allows a man-in-the-middle (MiTM) attacker to execute code as root on the device by serving a malicious firmware image when the system performs an automatic firmware update. The vulnerability was discovered and reported to the ZDI program by the researcher known as awxylitol.
This vulnerability may sound contrived; a bad actor gives bad firmware to the device and bad things happen. However, insecure download vulnerabilities have been the backbone of multiple Pwn2Own winning entries in the router category since its inception. The impact of this vulnerability is quite nuanced and worthy of further discussion.
How exactly does the router perform a firmware update?
According to Ubiquiti documentation, the new templated operational command add system image
can be used to update the firmware of the router through the command line interface (CLI). A templated operational command allows the user to quickly modify the operational state of the router without fiddling with complex command-line parameters. This simplifies the process for day-to-day operations and minimizes user errors. I am sure we have all heard of horror stories of system administrators who accidentally deleted critical files, locked themselves out of equipment that is far away from civilization, and so forth. Templated commands attempt to mitigate these issues.
The templating system used by the Ubiquiti EdgeRouter is provided by the vyatta-op package. The command add system image
is defined in the /opt/vyatta/share/vyatta-op/templates/add/system/image/node.def
file.
By running this operational command, the user is effectively invoking the ubnt-fw-latest
script with the --upgrade
option. This option causes the ubnt-fw-latest
script to run the upgrade_firmware()
function, which will check with a Ubiquiti update server to get information about the latest firmware release, including the firmware download URLs.
The function proceeds to parse and compare the results from the server with the current firmware version. If an update is available, the script will invoke ubnt-upgrade
to fetch the firmware from the fw-download.ubnt.com
domain provided by the upgrade server. It will then perform the actual firmware upgrade.
The Bug - ZDI-21-601
The issue lies in the way the /usr/bin/ubnt-upgrade
bash script downloads the firmware. The get_tar_by_url()
function uses the curl
command to perform the fetch. However, the developers specified the -k option (also known as the –insecure
option), which disables certificate verification for TLS connections.
Since /usr/sbin/ubnt-upgrade
does not check for the validity of the certificate, an attacker can use a self-signed certificate to spoof the fw-download.ubnt.com
domain without triggering any warnings or complaints on the device to alert the user. This vulnerability significantly reduces the skill barrier needed to launch a successful attack.
To exploit this vulnerability, the attacker can modify an existing EdgeRouter firmware image and fix up the checksum contained in the file. In the submitted proof-of-concept, the researcher modified the rc.local
file to connect back to the attacker with a reverse shell. A reboot is part of the upgrade process, triggering the rc.local
script.
Conclusion
If an attacker inserts themselves as MiTM, they can then impersonate the `fw-download.ubnt.com` domain controlled by Ubiquiti. However, to successfully serve up malicious firmware from this domain, the attackers would normally need to obtain a valid certificate with private key for the domain. To proceed, the attackers would probably need to hack into Ubiquiti or convince a trusted certificate authority (CA) to issue the attackers a certificate for the Ubiquiti domain, which is no insignificant feat. However, due to this bug, there is no need to obtain the certificate.
The heart of the problem is the lack of authentication on the firmware binary. The function of a secure communications channel is to provide confidentiality, integrity, and authentication. In TLS, encryption provides confidentiality, a message digest (or AEAD in the case of TLS 1.3) provides integrity, and certificate verification provides authentication. Without the verification of certificates, clients are foregoing authentication in the communications channel. In this scenario, it is possible for the client to be speaking to a malicious actor “securely”, as it were.
It should also be noted how checksums are not replacements for cryptographic signatures. Checksums can help to detect random errors in transmission but do not provide hard proof of data authenticity.
One final consideration is the possibility that a vendor's website could become compromised. In that case, the firmware along with its associated hash could both be replaced with malicious versions. This situation can be mitigated only by applying a cryptographic signature to the firmware file itself. Perhaps Ubiquity will make the switch to signing their firmware binaries cryptographically, which would improve the overall security of its customers.
Ubiquity addressed this bug in their v2.0.9-hotfix.1 security update by removing the -k
(--insecure
) flag from the templated command.
This was the first submission to the program from awxylitol, and we hope to see more research from them in the future. Until then, you can find me on Twitter @TrendyTofu, and follow the team for the latest in exploit techniques and security patches.
Footnote
Cautious users of the EdgeRouter seeking advice on how to upgrade the device properly should avoid the use of automatic upgrade feature for this update. They may want to download the firmware file manually from a browser and verify the hashes of the firmware before performing a manual upgrade by uploading the firmware file to the device through the web interface.