Tracing command injection across router interfaces.
Research notes on CVE-2022-28571, CVE-2022-28572, and CVE-2022-28573.
Security Research / 6 min read
On this page
Research notes · CVE-2022-28571–28573 research notes
Introduction
These notes document several command injection vulnerabilities I found during the same period.
CVE-2022-28571 && CVE-2022-28572
CVE-2022-28571 stems from incomplete filtering of Telnet CLI parameters. It requires a known password, so its impact is constrained by authentication. The discovery process was interesting, and this article focuses on that vulnerability.
CVE-2022-28572 is a command injection vulnerability in the Tenda AX18 series. I identified two other potential triggers, but submitted the one that was easiest to reproduce.
CVE-2022-28573 is a straightforward command injection vulnerability in the D-Link 823 Pro.
Analyzing CVE-2022-28571
I started by reproducing vulnerabilities in the D-Link DIR-882, including CVE-2021-45998. Packet captures suggested strict request validation: each AUTH value appeared to work only once. The vulnerability reproduced, but my usual command for starting a shell did not work:
SHELL
telnetd -l /bin/sh -p 2333
The shell did not connect. I wondered whether the DIR-882 used an unusual Telnet implementation, so I searched the firmware for Telnet-related code.
Telnet-related strings appeared in lighttpd, suggesting that an HTTP request could start Telnetd. I followed the string references in lighttpd.
This revealed the /start_telnet route and what appeared to be its launch command, telnetd -b 0.0.0.0.
On the physical device I had bought for about CNY 200, a GET request started the service without authentication. The response was a 404, but the authenticated system-debug page returned a file containing system information. It confirmed that the command had run, and port 23 was now open.
At this point I shifted from reproducing an existing issue to investigating the Telnet service. My initial hypothesis was that its password might be hardcoded. That hypothesis later proved incorrect.
The next step was to locate the password. Connecting to Telnet produced the following prompt:
The prompt included dlinkrouter login. Based on earlier Tenda research, I searched for references to that string, but found none.
That suggested dlinkrouter was generated from system information. Telnetd was linked into BusyBox, so I moved the analysis there.
Cross-references to the login string led to the following code:
sub_465960 retrieves uname, suggesting that dlinkrouter comes from the system name. Following the remaining references exposed the Telnet login call path.
Analysis of the key functions established the DIR-882 Telnet login flow:
Enter a username.
Look up the corresponding password record in /etc/passwd.
Compare the salted password hash.
I then investigated how that password record was generated. Reversing the main program, prog.cgi, showed the following:
The password used for the /etc/passwd entry is the web login password with @twsz2018 appended.
Appending that suffix to the login password allowed access to Telnet. However, the session opened a CLI rather than a normal shell.
Further analysis of BusyBox showed why:
The input reaches popen directly. Appending a shell command therefore provides a command injection path.
I later found that the D-Link Telnetd command needed the following arguments to start a shell listener:
SHELL
telnetd -l /bin/sh -p 2333 -b 0.0.0.0
Disclosure timeline
March 8, 2022: Submitted the vulnerability for CVE assignment.
April 1, 2022: The submission was returned because version information was missing.
April 1, 2022: Resubmitted with the required information.