XML External Entity (XXE)

نبدأ بمثال خفيف من محمد لنفترض في مطعم وطلبت من العامل الأول برجر و عصير واعطاك الفاتورة مكتوبة بقلم ورحت أنت جبت قلم عدلت عليها وأضفت ماء و بطاطا وأعطيتها الى العامل الثاني, العامل الثاني يفترض ان العامل الأول هو الي كتب الفاتورة ورح يعطيك كل الي مكتوب بالفاتورة. أنت في هذه الحالة كتبت أشياء خارجية أو External Entities. أذا حبيت تتعمق في التعريف اكثر تقدر تقرأ تعريف OWASP أو PortSwigger

الي رح تتعلمه:

  • Code Review

  • Basic of XXE

  • PHP Wrapper

  • Exfiltration with remote DTD

  • XXE to NTLM Hashes

Code Review

قدامنا هذا ال xml parser :

<?php
    libxml_disable_entity_loader (false);
    $xmlfile = file_get_contents('php://input');
    $dom = new DOMDocument();
    $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
    $credentials = simplexml_import_dom($dom);
    $user = $credentials->user;
    $passwd = $credentials->passwd;
    echo "You have logged in as $username";
?>

اول شي نقدر نشوفه هو انه ال libxml_disable_entity_loader حاطينه false في السطر الخامس نقدر نشوف انه ال loadXML function قاعد يستخدم two flags الي هم LIBXML_NOENT و LIBXML_DTDLOAD.ال LIBXML_NOENT يسوي enable لل substitution لكل ال entities و الثانية الي هية LIBXML_DTDLOAD والي تسوي load لل dtd files. نقدر الأن نوصل الى هذا التحليل ان هذا ال xml parsar يسوي load لكل انواع ال entities وكل ال dtd بدون اي exceptions

Basic of XXE

طيب قدامنا هذا الموقع الي ياخذ منك رابط ويسوي render لمحتواه

لو اعطيناه ملف عادي رح يرجع لنا error

test.txt
error message

طيب سويت هذا ال xml file على امل الموقع يقبله

parsing xml files

الأن قدرنا نعرف انه الموقع يسوي render على ملفات ال xml. خلونا نجرب نسوي ملف جديد بس هذه المرة نضيف عليه XML Entities تخلينا نقرأ ملفات الجهاز

سويت external entity الي هية &xxe; القيمة بداخلها رح تكون ملف etc/passwd/ اذا نجح ال attack. خلونا نجرب نرسل الملف الجديد

حلو طبعا تقدر تفتح ال source page عشان يوضح اكثر

PHP Wrapper

لنفترض عندك ملف كبير واذا حاولت تقرأه عن طريق ال XXE ما يجيك كامل في هذه الحالة تستخم ال PHP Wrappers مثل //:php نقدر نستخدمة عشان نسوي encode لل data وبعدين احنا نسويلها decode. تقدر تقرأ أكثر عن ال php Wrappers هنا. طبعاً أكيد في wrappers ثانية مثل:

اسهل payload نقدر نستخدمه هذا:

php://filter/convert.base64-encode/resource=/etc/passwd

بكل بساطة رح يسوي base64 encode على ملف ال etc/passwd/ ونقدر بعدين احنا ناخذه ونسوي له Decode. تعالو نشوف هذا المثال الشبيه الى المثال الأول بس هذه المرة خلونا نستخدم //:php

example 2

رح نرسل نفس الملف الي بالمثال الأول بس مع تعديل خفيف

طيب اذا أرسلنا هذا الملف رح يرجع لنا encoded base64 string ل etc/passwd/ خلو ببالكم احياناً اذا اردت رفع خطورة لازم تقرأ ملفات ثانية قد تساعدك للوصول الى RCE.

Sending exploit2.xml
base64 string

نسوي decode لل string تقدرون تستخدمون ال base64 command او CyberChef

/etc/passwd

Exfiltration with remote DTD

مو دائماً ال XML parser رح يرجع النتائج directly بال respnse. ممكن عندك file upload ل xml files بس ما ترجع لك ال response. في هذه الحالة رح نضطر ندور على طريقة نسوي exfiltrate لل data. على حسب علمي في طريقتين الي هم عن طريق ال HTTP او ال DNS. أنا رح اطبق على HTTP تقدرون تقرأون أكثر عن DNS Exfiltration من مشعل هنا.

نفس الموقع من المثال الثاني صار له version جديد بس ما يدرون انه الثغرة بعدها موجودة.

They call it version 2 XD

اول شي رح نسويه ملف document type definition (DTD) ما عرفت كيف اشرح معناه بالعربي بس بحث سريع ب google رح تكونون فاهمين.

خلوني أشرح ايش الي قاعد يصير: - سويت entity اسمها file وبداخلها رح يكون base64 encoded data لملف ال etc/passwd/ - استخدمت entity جديدة أسمها eval وبداخلها entity ثانية أسمها exfiltrate وهي الي رح تسوي request مع ال data الي داخل ال file entity الى ال attacker server - وأخر شي بس استخدمنا ال entity الي سويناهم.

الأن رح نستخدم نفس ال xml file بالمثال الأول بس مع تعديل خفيف رح نخلي الموقع يروح يقرأ ال DTD file

نجرب نرسل الملف

الأن أذا رحت على ال python server logs رح تقدر تشوف request ال xml file و ال DTD file ومعهم بال logs ال base64 string

نقدر نسوي له decode عن طريق ال base64 command:

XXE to NTLM Hashes

نجي على النظام الي للأسف مكروه عند الكثيرين WINDOWS. تسألني لو فيه XXE بس النظام Windows وحاب ترفع من خطورة الثغرة الى RCE. دائماً تذكر ال NTLM hashes أهم شي بال Windows تسألني كيف نوصل لها. رح نستخدم ال Responder و هذه ال payload الي شفناها أول =php://filter/convert.base64-encode/resource

أول شي نجهز ملف ال xml ما رح يختلف كثير عن الأمثلة السابقة. ركزو على نهاية ال payload:

نشغل ال Responder ونرسل الملف الى الموقع:

Responder.py

الأن أذا رجعنا على ال Responder رح تلاقي ال NTLM Hash:

الأن انت عندك طرق كثيرة عشان تاخذ RCE مثل تسوي crack لل hash ثم تشبك على جهاز الضحية وأكثر. في النهاية حبيت أوضح انه ممكن تحتاج تدمج كل الطرق هذه عشان توصل الى هدف معين. أتمنا كان الشرح واضح وسهل الفهم.

https://twitter.com/electronicbots

Last updated

Was this helpful?