Insecure Backdoor Allowing Attackers on the Local Network to Obtain a Root Shell
AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H (8.8/8.6)
A daemon called telnetd_startup was found to be listening on UDP port 21210 on the Phicomm firmware for router models K2, K3, K3C, K2 A7, and K2G A1.
The intended use of this service appears to be to allow a client in possession of a certain private RSA key to launch a telnetd service and obtain a root shell on the device without any further authentication. This service is nowhere advertised to the owner of the router, and the private key in question is not made available to the owner, or under the owner's control.
After analysing and testing eleven different firmware versions, for various Phicomm router models, I have identified three distinct variations in the protocol implemented by the telnetd_startup backdoor.
The oldest generation I’ve found of Phicomm’s telnetd_startup
protocol (shaded blue, in the tables above) is relatively simple: the server waits to receive an encrypted message, which it decrypts and hashes with two different salts. It then waits for another message, and if that message matches either of those hashes, it will either spawn the telnet service or write a flag to the flash drive to trigger the spawning of telnet on boot. This is the protocol we see in the K2 22.5.9.163, released in early 2017. That particular build made the blunder of hardcoding the private key in the binary, which defeats the purpose of asymmetric encryption. This error enabled the creation of RoutAckProV1B2.exe
, a router-hacking tool which has been circulating online for several years, which uses the pilfered private key to allow any interested party to gain root access to this iteration of the backdoor. Of course, as we just saw, use of the private key isn’t even necessary to open the door. What the design overlooks — and this oversight will never be truly corrected — is that it’s not only possible but easy to generate phony ciphertext that a public RSA key will “decrypt” into predictable, phony plaintext. Doing so will permit an attacker to subvert the locking mechanism on the backdoor, and gain unauthorized entry.
Phicomm responded to this situation in an entirely insufficient fashion in the next generation of the protocol (shaded yellow), which we find in the firmware versions released later in 2017, including the still-for-sale international release of the K3C (analysed above). They redacted the private key from the binary, but failed to change the public key. Their next design, moreover, appears to share the assumption that it’s only by encrypting data the private key that an attacker can predict or control the output of its public key decryption. Rather than addressing either of these errors, they just piled on further complexity: this is when they began to generate a 31-character random secret and XOR it with the public-key-decrypted data received from the client in order to generate their ephemeral passwords. This made the backdoor slightly harder to attack, if we continue to ignore the leaked private key, but it’s ultimately just a matter of discovering some phony ciphertext that decrypts to a plaintext that begins with a printable ASCII character. This gives us a 1 in 92 chance of colliding with the first byte of the random secret, which, due to the careless use of sprintf
‘s %s
specifier for bytearray concatenation, will result in the a completely predictable empheral password.
In the next iteration (mauve in the tables above) is the last we looked at, and likely the last released. Phicomm finally removed the compromised public key, and took the additonal precaution of deploying a distinct public key to each router model. They also added a device-identifying handshake phase to the protocol, which makes the backdoor considerably stealthier — there’s no real way to tell that it’s listening on UDP port 21210, unless you send it the magic token ABCDEF1234
. It responds to this magic token with a device-identifying hash, permitting the client to select the private key that matches the public key compiled into the service. The algorithm itself, however, shares the same security flaws as its precedessor, and is vulnerable to an essentially identical attack. This is the iteration we see in the Chinese market release of K3C 32.1.46.268, and the Chinese market K2G A1 22.6.3.20 — the firmware image that ended up on certain Wavlink-branded routers, that Wavlink neglected to flash with firmware of their own.
The fully reverse engineered third-generation protocol is illustrated in the agent interaction diagram below.
Phicomm's implementation of this protocol is faulty, however. By means of a carefully crafted exchange of packets, an attacker is able to cause a null byte to appear at the head of a buffer that telnetd_startup uses internally to construct the ephemeral passwords that the client can use to peristently or temporarily launch telnetd -l /bin/login.sh. Condensing things a little, the pseudo-code below shows how the temp_password is constructed (mutato mutandis for the permanent password, constructed using the "+PERM" salt):
sprintf(result, "%s+TEMP",
xor(SECRET_PLAINTEXT,
RSA_public_decrypt(HARDCODED_PUBLIC_KEY,
ENCRYPTED_XOR_MASK)));
temp_password = MD5(result);
Since the client controls the ENCRYPTED_XOR_MASK, all they need to do is find a buffer that the hardcoded public key will "decrypt" to a buffer that begins with a printable character, which gives it a 1-in-94 chance of colliding with the first character in the SECRET_PLAINTEXT. The xor() operation will then produce the desired null byte. When the resulting buffer is processed by sprintf(), using the %s format specifier, it will be treated as if it were empty, since %s designates a null-terminated string. This means that the result passed to the hasher will be nothing but the salt -- "+TEMP" for the password that will instantaneously launch telnetd and "+PERM" for the password that will do so persistently. This upshot of all this is that the attacker now has an extremely good chance of steering telnetd_startup towards a perfectly predictable ephemeral password. Since there is no rate-limiting mechanism in place, they should be able to obtain a root shell on the device within seconds.
I've illustrated this attack below, in another agent protocol interaction diagram.
I've designed and implemented a tool to exploit this very loophole, and obtain a root shell on devices affected by this vulnerability. Here is a screencast of the exploit in action:
Improper Access Control Allowing Unauthenticated Remote Attackers to Obtain Sensitive Information and Credentials
AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:L/A:H (7.7/7.5)
The Phicomm firmware’s administrative web server exposes a number of *.asp endpoints that can be used to get and set router configuration parameters without requiring any authentication whatsoever. This is especially hazardous when remote management has been enabled, since it effectively grants administrative control of several router settings to any passer-by on the internet, and discloses some highly sensitive information.
For example, if an attacker is curious what devices might be connected to an exposed router’s local area network, all they need to do is issue a request to http://10.3.3.12:8181/LocalClientList.asp?action=get
(assuming 10.3.3.12 is the router’s IP address and 8181 is its remote management port):
But suppose they'd like to connect to the LAN themselves. If the router’s nearby, they could try to connect to one of its WiFi networks. But how will they obtain the password? It turns out that all they need to do is ask and the router will gladly provide it:
If the owner of that router had taken Phicomm up on its suggestion that they use the same password for both the 2.4GHz wireless network and the administrative interface, then the attacker now has remote administrative access to the router as well.
These endpoints can also be used to ban hosts from the router's LAN without requiring authentication, and to rename LAN-side hosts. The latter technique can be used to push crafted HTML code into the Phicomm router's administrative panel.
The attacker is also able to crash the administrative interface by passing malformed data to the LocalMACConfig.asp?action=set endpoint, though it will reboot after a brief delay.
Unprotected UART Console on K3C Router, with Hardcoded Credentials
AV:P/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H (6.8/6.4)
The K3C routers suffer from a hardware vulnerability as well. They expose an unprotected UART port by means of which an attacker with physical access is able to access both a U-Boot BIOS shell and an operating system login prompt.
With the username root and password admin--a password that can't be changed through the router's official administrative interface--the attacker can obtain a root shell on the device.
These Routers Will Never Be Patched
The Phicomm corporation shut its doors in 2018, while under police investigation for fraud, and on February 4, 2021 the CEO, Gu Guoping, was arrested. On December 8, he was stripped of political rights for life, and sentenced to at least 10-15 years in prison. Further details can be found in the accompanying blog post.
A Warning Regarding the Presence of Phicomm Firmware on Wavlink Routers
My first encounter with Phicomm's router firmware was, in fact, when I booted up a Wavlink-branded product. The Wavlink AC 1200 home router. It appears as though the Win-star corporation bought off Phicomm's surplus stock, rebanded the devices as their own, and flashed most--but not all--of those devices with their own firmware. In several instances--and we have no way of knowing how many--the Wavlink-branded devices reached the market still carrying vulnerable Phicomm firmware.
Further Reading
For more details on these issues, please see "A Backdoor Lockpick: Reversing Phicomm's Backdoor Protocols".