I recently researched a relatively new 5G-capable modem from Quectel: the RG500Q-EA. I identified a security issue with how the OTA download procedure operates which allows an attacker to execute commands on the modem as
I've previously posted about an issue affecting older Quectel modems present in the PinePhone. The issue, which was assigned the CVE ID CVE-2021-31698, is similar to the one described in this article. The article presents some background on how the modem and the mainboard (the "host" machine) communicate - usually, the mainboard sends AT commands over a serial line to the modem, which runs its own black-box operating system entirely independent of the mainboard. These AT commands are parsed by a daemon running on the modem, which then indicates whether the command executed successfully and optionally returns some data.
Analyzing the daemon
In the previously mentioned issue, I described that the AT commands were parsed by a daemon on the modem called
atfwd_daemon. While this is still technically somewhat true, a bulk of the core functionality is offloaded to other components or libraries. Some AT commands are executed by the modem's QDSP processor, which is at the time of writing still quite difficult to reverse engineer. The library we're interested in is
libql_atcop.so, which is an ARMv8 shared library present on the modem's host OS.
I identified the vulnerable command
AT+QFOTADL. In practice, this command is used to point to an OTA download link, for example:
The modem downloads the OTA, extracts it, verifies whether it's installable, and finally installs it on the modem device.
This command is handled in
libql_atcop.so by a procedure named
This procedure first matches the provided schema and checks to see which protocol is being used (plain HTTP, HTTPS, or FTP):
Code flow is then passed to another procedure, which formats the provided URL into a system command using
snprintf() and initiates the download:
Disassembling the binary further revealed that there is no user input sanitization in place and the provided user input is used in the command as-is, which is executed using
system() (provided by a wrapper function in another library).
From this, we can deduce that arbitrary command execution is possible. We can, for example, enter a valid schema and use backticks to execute our commands in a subshell. As an example, to reboot the modem:
Due to the fact that the daemon runs as root, the code is also being executed as the root user on the modem.
As an example, in this Asciinema recording, I use the
nc binary present to establish a reverse shell (over 5G!) to my server.
It's very possible that this vulnerability affects other Quectel products as well, as firmware is commonly reused, but I do not possess other hardware to test it on. Most probably, it affects all RG50xQ products, if not more. Vendor did not clarify which products this vulnerability affects.
- 22/02/2022 - Attempted to contact vendor
- 23/02/2022 - Vendor confirmed vulnerability
- 23/02/2022 - Vendor informs of fix in codebase
- 25/02/2022 - Assigned ID CVE-2022-26147
- 14/06/2022 - Notified vendor of imminent public disclosure of vulnerability, no response from vendor
- 21/06/2022 - Article published