
مدونة تحليلية لغرفة Source على منصة TryHackMe وسكربت بايثون لاستغلال الثغرة
مقالة حول غرفة Source على TryHackMe وسكربت بايثون لاستغلال الثغرة
لا أنسب لنفسي أي فضل في اكتشاف هذه الثغرة. أشكر الأشخاص التاليين على توفير الموارد التي تتيح لأشخاص مثلي التعلّم!
اكتشاف الثغرة:
Özkan Mustafa Akkuş
وحدة MSF:
https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/linux/http/webmin_backdoor.rb
https://www.rapid7.com/db/modules/exploit/linux/http/webmin_backdoor/
مؤلف وحدة MSF:
wvu
غرفة TryHackMe:
https://tryhackme.com/room/source
مؤلف THM:
https://tryhackme.com/p/DarkStar7471
الموارد:
https://www.webmin.com/exploit.html
https://github.com/webmin/webmin/issues/947
https://www.perlmonks.org/?node_id=301355
أنا لستُ بأي حالٍ من الأحوال خبيرًا أمنيًا متمرسًا. هذا يعني أنني قد أقدّم بعض المعلومات غير الصحيحة. إذا كنت محترفًا متمرسًا/باحثًا ذا خبرة ورأيت شيئًا غير صحيح، فيُرجى إبلاغي حتى أعود وأدرس ما أخطأت فيه وأقدّم المعلومات الصحيحة. هذا مفيد لي وللباحثين المبتدئين الآخرين الذين قد يصادفون هذه المقالة. إذا وجدت معلومات خاطئة كتبتها، فيُرجى التواصل معي على حتى أتمكن من تصحيحها. شكرًا لك!
1. التاريخ
Webmin أداة تعتمد على الويب لإدارة الأنظمة الشبيهة بيونكس. في مرحلة ما خلال الربع الأول من عام 2018، تعرّض Webmin لهجوم سلسلة توريد تمكن فيه مهاجم مجهول من إدخال كود خبيث في ملف password_change.cgi، مما أنشأ ثغرة تسمح بفتح باب خلفي على أي نظام يستضيف هذا الإصدار من Webmin (1.890) بالإعدادات الافتراضية. أسمّي هذا هجوم سلسلة توريد لأن الكود المصدري لمنتجات مطوّري/موزّعي البرنامج تعرّض للاختراق. عندما أصدر المورّد المنتج المخترق، أصبح كل من حدّث برنامجه يشغّل الكود الهش، مما أعطى المهاجم القدرة على اختراق أي نظام يشغّل هذا الكود الهش. في نفس العام، انتبه مطوّرو Webmin إلى ما حدث وأعادوا الملف إلى حالته الأصلية، لكن المهاجم تمكن من إعادة إدراج الكود مرة أخرى. هذه المرة، كان الكود هشًا فقط إذا تم تفعيل خيار تغيير كلمات المرور منتهية الصلاحية. لم تُكتشف هذه الثغرة حتى أغسطس 2019. تم إصلاح الثغرة في الإصدار 1.930 من Webmin.
2. الكود
بعد بعض البحث، تمكنت من العثور على سطر الكود الذي جعل إصدار Webmin 1.890 عرضة لحقن الأوامر. كنت أواجه صعوبة في العثور على المعلومات الصحيحة لأن هناك في الواقع ثغرتين CVE مختلفتين مرتبطتين بهذه المشكلة (CVE-2019-15231/CVE-2019-15107). ترتبط CVE-2019-15231 بثغرة الإعدادات الافتراضية في الإصدار 1.890، بينما ترتبط CVE-2019-15107 بالثغرة التي تتطلب تفعيل خيار تغيير كلمات المرور منتهية الصلاحية في الإصدارات حتى 1.920. دعونا نلقي نظرة على كود الإصدار 1.890. في السطر 12 في password_change.cgi، لدينا سطر الكود التالي:
$in{'expired'} eq '' || die $text{'password_expired'},qx/$in{'expired'}/;
حتى وقت كتابة هذا الشرح، لم أكتب أي شيء بلغة perl. سنقوم بتفكيك سطر الكود هذا باستخدام محركات البحث لفهم ما يفعله الكود ولماذا هو عرضة للاستغلال بشكل أفضل. يبدو أن الجزء الأول من الكود إلى يسار عامل || هو متغير ($in) يأخذ معاملًا (expired) ويتحقق مما إذا كان يساوي (eq) سلسلة فارغة ''. في المنتصف، لدينا عامل ||. إن || هو طريقة أخرى لاستخدام العامل المنطقي or في perl. عند استخدام || في perl، إذا كان الجانب الأيسر من العامل صحيحًا، فلن يتم تقييم النصف الأيمن. إذا كان النصف الأيسر خاطئًا، فسيتم تقييم النصف الأيمن. في النصف الأول من الكود إلى يمين عامل ||، يمكننا رؤية die $text{'password_expired'}. في perl، die هي دالة تعمل على إنهاء عملية السكربت وعرض رسالة خطأ. على الأرجح ستكون الرسالة هي متغير $text الذي يعني أن كلمة المرور منتهية الصلاحية. الجزء الأخير من الكود هو حيث يصبح الأمر مثيرًا للاهتمام. نرى أن لدينا فاصلة , تليها qx/$in{'expired'}/ وفاصلة منقوطة ; تنهي سطر الكود. تعمل الفاصلة كفاصل للكود، حيث يتم تقييم النصف الأيسر أولاً ثم يتم تقييم النصف الثاني. في perl، qx هي دالة تسمح بتنفيذ أوامر النظام على المضيف. إن // هي محددات تُستخدم لتحديد المعامل. في هذه الحالة، لدينا qx/$in{'expired'}/ والتي ستنفذ معامل $in{'expired'} كأمر نظام. أعتقد أن متغير $in قد يكون شيئًا مشابهًا لـ $_GET في php للسبب التالي. في سكربت الاستغلال الذي كتبته، لدينا معامل يسمى expired يخزن الحمولة (payload) قبل إرسالها إلى الخادم عبر طلب POST. هذا ما يبدو عليه الكود: data = {'expired':payload,}. يجب أن يقوم متغير $in بشيء ما لاسترجاع القيمة التي عيّنّاها لـ expired حتى يمكن تنفيذ الحمولة بواسطة دالة qx. لاختتام هذا القسم، يجد سطر الكود الهش أن معامل expired في طلب POST لا يساوي سلسلة فارغة، لذلك سيقوم عامل || الآن بتقييم النصف الأيمن من الكود وتنفيذ حمولتنا المخزنة في معامل expired. دعنا ننتقل إلى الشرح الخاص بغرفة Source من TryHackMe.com
لنبدأ بفحص المنافذ. سنستخدم rustscan للحصول على نظرة عامة واسعة لأن nmap قد يكون بطيئًا بشكل مؤلم.

يبدو أن لدينا منفذين مفتوحين، 22 و10000. سنستخدم الآن nmap لمعرفة الخدمات التي تعمل على كل منفذ.

إذن لدينا SSH يعمل على منفذه القياسي وخدمة HTTP تعمل على المنفذ 10000. دعنا ننتقل إلى الصفحة التي تعمل على المنفذ 10000 ونرى ما يوجد هناك.

ستحتاج إلى استخدام HTTPS وتجاوز تحذير شهادة SSL للوصول إلى هذه الصفحة. يبدو أن لدينا صفحة تسجيل دخول لخدمة Webmin. عندما حللت هذا الصندوق في البداية، جربت عدة محاولات تخمين مجلدات (directory bruteforce) لكن لم يظهر شيء مثير للاهتمام. دعنا نرى ما إذا كانت هناك ثغرة للإصدار الذي حصلنا عليه من فحص nmap عبر searchsploit.

يبدو أن لدينا عدة خيارات مختلفة هنا، لكن لا شيء منها يطابق إصدارنا. دعنا نفتح MSF ونرى ما لدينا للعمل به.

لدينا عدة خيارات مختلفة للاختيار من بينها هنا. دعنا نبحث عن إصدار webmin الذي حصلنا عليه من nmap ونرى ما إذا كانت هناك أي CVE تظهر يمكن أن تساعدنا في تضييق نطاق البحث.

في ملخص الثغرة، نرى أنه يذكر شيئًا عن ملف password_change.cgi. دعنا نستخدم الخيار رقم 5 من بحث MSF لأنه يذكر أيضًا ملف password_change.cgi بالإضافة إلى نفس تاريخ الإفصاح.

لول، لن نستخدم MSF في الواقع. MSF جيد لكنه ليس ممتعًا مثل اكتشاف كيفية استغلال شيء ما بكودك الخاص! استخدمت الكود المصدري لـ ruby كمرجع لهذا الاستغلال لصياغة كود الاستغلال الخاص بي بلغة python. دعنا نستخدم ذلك بدلاً من ذلك!

وهكذا، وبكل سهولة، حصلنا على شل جذر في الغرفة! لن أكشف عن الـ flags. أنا متأكد من أنكم ستجدونها! شكرًا للقراءة وأتمنى لكم يومًا سعيدًا!