XML External Entity Injection (XXE)
الثغرات المتعلّقة بالـ XML Parser : XXE
قبل البدء في مناقشة مختلف أنواع الثغرات المتعلّقة بلغة الترميز XML ، لنُلقي نظرة شمولية ( انظر للصورة الآتية) على هذه الأنواع ونعرف كل نوع منها ما الهدف الذي يُحدث به الضّرر:
* لعرض الصور بحجمها الأصلي اضغط عليها
· الثغرات المتعلّقة بالـ XML Parser
تطبيقات الويب التي تعتمد على لغة الترميز XML في بعض أجزائها وعملياتها يقوم مطوريها بإستخدام XML Parser خاص باللغة المستخدمة في تطبيق الويب ، الـ XML Parser يساعد في قراءة (Parsing) أكواد الـ XML وجعلها مفهومه لتطبيق الويب حتى يستطيع التعامل معها، أي أن الـ Parser أشبه بـ API بين كود الـ XML والكود الخاص بتطبيق الويب. فعوضًا عن أن يتعامل مطوّر الويب مع كود الـ XML بشكل مباشر ويحاول تفسير كل سطر بنفسه، يقوم بإستخدام XML Parser يؤدي هذه الوظيفة، وبالمناسبة هذه الميزة هي أحد الأسباب التي جعلت لغة الـترميز XML واسعة الإنتشار، فالعديد من لغات البرمجة لديها مكتبات خاصة بالـ XML Parser ، بالتالي عملية التخاطب بين تطبيقين من لغتين مختلفتين بغرض تبادل أو قراءة البيانات ستكون مهمّة سهلة إلى حدٍ ما إذا أوجدنا لغة مشتركة بين هذين التطبيقين ، وفي هذه الحالة نقصد لغة الترميز XML .
يوجد العديد من الأنواع المختلفة للـ XML Parser ولسنا بصدد مناقشتها هنا، لكن هذه قائمة ببعض الـ XML Parser المفتوحة المصدر لبعض اللغات وأُطر العمل:
بعد هذه المقدمة حول الـ XML Parser ، لننتقل الآن للثغرات التي تحدث بسبب بعض نقاط الضعف في الـ XML Parser أو بسبب جهل مطوّر تطبيق الويب بطبيعة الخصائص التي يقدمها هذا الـ Parser وحدود إمكانياته.
XML External Entity Injection (XXE) :
قبل أن نتعرّف على هذا النوع من الثّغرات لنعرف بدايةً ما هو الـ XML Entity ؟
الـ XML Entity نستطيع إعتباره متغير يحمل بيانات وهذه البيانات قد تكون في نفس (Internal) ملف الـ XML أو في خارجه (External) .
هذا مثال على تعريف ENTITY ضمن ملف الـ XML :
في المثال أعلاه عرّفنا نوعين مختلفين من الـ XML ENTITY وهما :
- External ENTITY
- Internal ENTITY
ما يهمنا هنا هو النوع الأول External ENTITY وهذا هو الـ Syntax الخاص بتعريفه :
- EntityName : يرمز لأسم هذا المتغيّر
- SystemLiteral : ترمز إلى المسار المتواجد به الملف، وهنا بإمكاننا إستخدام أنواع مختلفة من الـ URI Scheme مثل الـ HTTP , File
الآن بعد أن تعرّفنا على الـ XML External Entity ،
لنعرف ماهي ثغرة الـ XML External Entity Injection؟
بما أنها ثغرة من نوع Injection فلا بد أن يتواجد "مكان" تأتي منه البيانات من المستخدم ( أو من تطبيق آخر ) ومن ثم يتم خَلط هذه البيانات مع الكود وتُرسل إلى الـ Parser
(إطلع على سلسلة مقالات الـ Injection Attacks لمزيد من التفاصيل حول هذه النقطة)
وفي حالتنا هنا تطبيق الويب يستقبل قيم من المستخدمين وهذه القيم قد يتم خلطها مع Code XML ، ولا يقوم تطبيق الويب بعمل فَلترة كافية للمدخلات ممّا يتيح للمخترق حقن كود XML وتحديدًا نقصد هنا حقن XML External Entity
لنتوقف قليلًا عن الشرح ونبدأ بالجانب العملي حتى تتضح الصورة أكثر:
سنقوم بالتطبيق وحل تحدّي بسيط على هذه الـ Machine
إعدادات المعمل ستكون كالآتي:
- تطبيق الويب المصاب بالثغرة: http://172.16.220.134
- الـ Machine التي نقوم بالإختبار من خلالها: Kali machine
بعد الدخول على الصفحة الخاصة بالتطبيق ( http://172.16.220.134/xxe/ ) نجد واجهة تسجيل الدخول هذه:
نحاول تسجيل الدخول وإعتراض الطلب عن طريق أداة Burp Suite قبل أن يتم إرساله إلى تطبيق الويب حتى نفهم ما الآلية التي يعمل بها التطبيق
بعد إعتراض الطلب، نلاحظ أن البيانات الخاصة بالمستخدم يتم تمريرها عبر الـ XML ، نُلقي نظرة على الـ Source Code ونجد الدالة XMLFunction() والتي تقوم ببناء الـ xml document وتمريره إلى تطبيق الويب :
الجزء الذي يهمُّنا تحديدًا في الكود هو أن المدخلات القادمة من المستخدم (اسم المستخدم وكلمة المرور) يتم خلطها مع كود الـ XML ولا يوجد أي عملية فلترة مُسبقة لهذه المدخلات، ومن هنا نستطيع الحقن ، كِلا المتغيرين name و password مُصابين ونستطيع الحقن من خلالهما :
بعد تحليل الكود ، لنعود الآن إلى الـ Repeater في الـ Burp Suite
نبدأ الإختبار عن طريق تمرير أحد قيم الـ Meta-character في الـ XML مثل :
في حالة كان تطبيق الويب لا يقوم بعمل الفلترة للمدخلات فحقن أحد هذه القيم في المدخلات سيعمل على إحداث خطأ في البنية السليمة لملف الـ XML ، مما يجعل الـ Parser يُظهر لنا رسالة خطأ في الـ Response ، في الخطوة الآتية مرّرنا القيمة & ضمن اسم المستخدم أولًا حتى نتأكد أنه مصاب ، ومن ثم أعدنا المحاولة على المتغير الخاص بكلمة المرور .
نلاحظ أن رسالة الخطأ التي توقعناها من الـ Parser لم تظهر ضمن الـ Response ، لنبدأ الآن بحقن شيء آخر ، على سبيل المثال لنحاول الحقن بـ XML External Entity كالآتي:
<!DOCTYPE Doc [
<!ENTITY ex SYSTEM "file:///etc/passwd">
]>
ومن ثم نستدعي هذا الـ Entity ضمن أحد قيم المدخلات
<name>&ex;</name>
ونرسل الـ Request :
جميل!! ما الذي حصل هنا ؟
إستطعنا قراءة ملف الـ passwd عن طريق تعريف External Entity يحمل المسار الخاص بهذا الملف ، ومن ثم حقنا هذا الـ External Entity في أحد قيم المدخلات
لننتقل لمستوى آخر من الحقن،
بعد قراءة محتوى ملف الـ robots.txt وجدنا صفحة تسجيل فرعية خاصة بالـ admin
بعد محاولات عدّة لإختبار صفحة الدخول لنفس الثغرة وتحليل الكود لم نتوصّل لشيء،
لكن ماذا عن قراءة محتوى ملف الـ admin.php عن طريق الثغرة في صفحة تسجيل الدخول الأولى؟
لنُلقي نظرة!
إستطعنا قراءة محتوى الملف أيضًا!
لاحظ أننا قمنا بعمل Encoding لمحتوى الملف كالآتي (لمعرفة السبب وراء هذه الخطوة إطلع على هذا الشرح):
<!ENTITY ex SYSTEM “php://filter/read=convert.base64-encode/resource=admin.php”>
بعد عمل Decoding لمحتوى الملف ، وجدنا هذه البيانات ضمن الصفحة
نقوم بتسجيل الدخول بإستخدام هذه البيانات :
ومن ثم نحصل على العَلَم :[
المراجع:
كتب:
- WEB TECHNOLOGIES A Computer Science Perspective , Chapter 7 (XML) & Chapter 9 ( Web Services )
- The Web Application Hackers Handbook , Chapter 10 (Injecting into XML Interpreters)
أوراق علمية:
- Automated and Effective Security Testing for XML-based Vulnerabilities, By : Sadeeq Jan
- XXE Explanation and Exploitation, By : Haboob Team
يوتيوب:
- SOAP Web Services 01 - Introduction To Web Services