كتابة CTFZone Quals 2019: Chicken

على الرغم من تأجيل مؤتمر OFFZONE 2020 ، سيكون هناك نهائي CTFZone ! سيقام هذا العام لأول مرة عبر الإنترنت وسيتم بثه بنشاط على الشبكات الاجتماعية.

سنعلن التفاصيل لاحقًا ، ولكن في الوقت الحالي ، نقترح استكشاف بدء تشغيل مهام الويب من مرحلة التأهل. تم إرسال تحليل الحل إلينا من قبل Devand MacLean من كندا. خاصة بالنسبة لحبر ، قمنا بترجمة نص الغارة المحلية وندعوك لمعرفة سلسلة الثغرات التي واجهها المشاركون وما علاقة الدجاجة بها.



معلومات عامة


مؤلف المهمة: Pavel Sorokin
النقاط: 470
عدد الفرق التي قامت بحل المهمة: 2

روابط مفيدة:




, - :


  • (/Home/Index);
  • (/Home/Hens);
  • (/Home/Contact);
  • (/Auth/Login).

,   , :


  • ;
  •  API ,   .


تحتوي الصفحة / الرئيسية / الدجاج على روابط لتنزيل "جوازات سفر" الدجاج.


بعد فك ترميز Base64 ، نجد اسم المعلمة: 1.txt. باستخدام CyberChef ، نقوم بتشفير / etc / passwd في Base64 واتباع الرابط:

http://web-chicken.ctfz.one/File/Download؟filename=L2V0Yy9wYXNzd2Q= يتم

فتح محتويات الملف / etc / passwd على الخادم في المتصفح ، مما يعني نحصل على حق قراءة الملفات العشوائية في النظام.

عند محاولة العثور على ملفات أخرى في النظام ، قد تلاحظ خطأ يظهر في كل مرة تطلب فيها ملفًا غير موجود (أو ملف لا يمكن قراءته بحقوق المستخدم الخاصة بالتطبيق):


بعد أن رأينا أن الخطأ يشير إلى متغير بيئة ASPNETCORE_ENVIRONMENT ، نبدأ في دراسة تخطيطات تطبيق الويب ASP.NET Core. ونرى ما يلي:


لتحويل المسارات وأسماء الملفات اللازمة واستخراجها إلى Base64 ، نكتب نصًا صغيرًا لبرامج Python ( fetch.py ):


باستخدام هذه المعرفة حول بنية تطبيق الويب MVC الذي تم إنشاؤه في ASP.NET Core ، باستخدام fetch.py ​​نحصل على شفرة المصدر للملفات التالية:


  • ../Views/Shared/_Layout.cshtml
  • ../Views/Home/Index.cshtml
  • ../Views/Home/Contact.cshtml
  • ../ المشاهدات / الصفحة الرئيسية / Hens.cshtml
  • ../Views/Auth/Login.cshtml

بعد القيام بذلك ودراسة شفرة المصدر لكل صفحة ، نجد تفاصيل مثيرة للاهتمام في Hens.cshtml


يحتوي السطر 1 على بيان التضمين @ باستخدام StackHenneryMVCAppProject ، والذي يعني في ASP.NET ارتباطًا بملف DLL.

نفتح ../StackHenneryMVCAppProject.dll - ولكن ليس من خلال أداة Python في Kali Linux ، ولكن في المتصفح على Windows ، لأننا سنقوم بفك ضغط هذا الملف في Windows. من خلال استخدام عنوان URL

التالي : http://web-chicken.ctfz.one/File/Download؟filename=Li4vU3RhY2tIZW5uZXJ5TVZDQXBwUHJvamVjdC5kbGw=

فتح ملف DLL في dnSpy (أداة فك ترميز .NET) ، انظر على الفور إلى تهيئة (تهيئة) الفئة . التهيئة ، التي يتم تشغيلها عند بدء تشغيل تطبيق الويب ، تقرأ محتويات ملف chicken_domains_internal.txt . باستخدام نص Python النصي ، نستخرج محتويات هذا الملف:

web-chicken-flag
web-chicken-auth تتصل 

طريقة Initialize () بعلامة web-chicken-flag عبر المنفذ 4321 وتتلقى عدة معلمات: secret_token و RSA_key و  flag .

للأسف ، لا يمكن بدء الاتصال بعلم الدجاج على الويب. ولكن ، عندما نضع سجل مضيف DNS المحلي لترجمة web-chicken-auth إلى عنوان IP الخارجي للخادم ( 34.89.232.240 ) ، نتمكن من فتح http: // web-chicken-auth / مع واجهة Swagger UI المستخدمة لوصف وتنفيذ الأوامر من خلال REST API.


أثناء الحفر في ملف DLL المتحلل ، يمكنك ملاحظة أن وحدة تحكم AuthController لم يكن لديها أسلوب Login () فقط ، ولكن أيضًا طريقة Change_Password_Test () :


عندما نذهب إلى  / Auth / Change_Password_Test نرى هذا النموذج:


عند دراسة طريقة Change_Password_Test () ، نتفهم أنها تعالج أربع معلمات من النوع String من خلال طلب HTTP POST:


  • اسم المستخدم؛
  • كلمة السر الجديدة؛
  • كلمة سر قديمة؛
  • base_url.


أقل قليلاً في طريقة Change_Password_Test () التي نراها: بدون تلقي قيمة لـ base_url ، تأخذ الطريقة القيمة conf.auth_server ، وهي web-chicken-auth ، ثم تضيف / auth / login إلى نهاية قيمة base_url ، وتعيين السلسلة الناتجة إلى متغير requestUri :


في جزء مهم المقبل للرمز، وقيم السلسلة من اسم المستخدم و  المعلمات old_password من طلب HTTP POST، ومعها  secret_token من التكوين، يتم إدراجها في سلسلة JSON. بعد ذلك ، يتم إنشاء كائن JSON StringContent من هذه البيانات ، والتي يتم إرسالها كبيانات HTTP POST إلى متغير requestURI الذي تم إنشاؤه في الخطوة السابقة.


ينتظر الخادم الآن طلب HTTP POST للطلب  request لإرجاع كائن JSON بمعلمة الرمز تساوي 0. إذا لم يحدث ذلك ، نصل إلى فرع الرمز الذي يبدأ من السطر 6 ويعيد العرض / المشاهدات / المصادقة / تسجيل الدخول مع الخطأ تسجيل الدخول غير صالح / كلمة المرور .

إذا استمر طلب HTTP POST في إرجاع كائن JSON بمعلمة الرمز تساوي 0 ، ننتقل إلى فرع الرمز من السطر 11. ثم يحصل متغير requestUri2 على القيمة http: // web-chicken-auth ، يتم إنشاء كائن JSON StringContent آخرمع المعلمات من طلب HTTP POST الأصلي ، كما هو الحال في الجزء السابق ، ويتم إرسال هذه البيانات إلى عنوان requestUri2  في طلب HTTP PUT. وأخيرًا ، يتم إرجاع رسالة تغيير كلمة المرور إلى العميل .


باختصار: تبدأ العملية بأكملها بطلب HTTP POST إلى  / Auth / Change_Password_Test ، والذي يتوقع عددًا معينًا من المعلمات. يستغرق الأمر هذه القيم وينشئ كائن JSON لإرساله إلى  <base_url> / auth / login عبر HTTP POST. إذا استجابت استجابة JSON بمعامل الرمز يساوي 0 ، فإنها تنشئ كائن JSON آخر وترسل طلب HTTP PUT إلى  http: // web-chicken-auth / auth / change_password .

عند تعلم واجهة برمجة التطبيقات REST في Swagger UI ، نرى أنه في ملف DLL  المتحلل لم يكن هناك فقط المسارات / auth / login و / auth / change_password ، ولكن أيضًا مسار / auth / password_recovery .


توقع مسار واجهة برمجة التطبيقات هذا كائن JSON مع معلمتين: البريد الإلكتروني و  secret_token . إذا حصل ذلك، ثم عاد كائن JSON مع قانون الملكية من 0 و رسالة و  رمزية السلاسل .


اتضح أنه إذا فرضنا بطريقة أو بأخرى طريقة Check_Password_Test () لطلب المسار / auth / password_recovery على الفور بدلاً من / auth / login ، فسيكون إدخال فرع تغيير كلمة المرور كافيًا لإدخال عنوان بريد إلكتروني صالح.

ندرس مرة أخرى جزء من الشفرة حيث تقوم طريقة Check_Password_Test () بتعيين قيمة requestUri في طلب HTTP POST الأصلي ، ونحن نتفهم أننا بحاجة إلى إرسال القيمة http: // web-chicken-auth / auth / password_recovery # كمعلمة base_url ، و requestUri في النهائي ستكون النتيجة http: // web-chicken-auth / auth / password_recovery # / auth / login .

يشير الحرف # في عنوان URL الخاص بـ HTTP إلى انتهاء جزء من عنوان الطلب. لذلك ، سيتجاهل الخادم الذي يتلقى الطلب ببساطة الجزء / auth / login .


هذا بالطبع جيد ، ولكن علينا فقط معرفة كيف ستتلقى نقطة نهاية REST ، حيث نعيد توجيه الطلب الآن ، قيمة البريد الإلكتروني . بدون هذه القيمة ، سيفشل الطلب ، ولن نذهب إلى أبعد من ذلك.

نحن ننظر بعناية في كيفية إنشاء طريقة Check_Password_Test () لبيانات JSON ، ونرى أنه لم يتم مسح بيانات الإدخال على الإطلاق ، مما يعني أنه يمكنك بسهولة تنفيذ المعلمات الخاصة بك. يكفي إرسال المعلمات التالية في طلب HTTP POST:

username = admin
old_password = pwned "،" email ":" admin@chicken.ctf.zone "،" lol ":"
new_password = p0tat0
base_url = http: // web-chicken-auth / auth / password_recovery #

يتم إرسال كائن JSON الناتج إلى  / auth / password_recovery :


باستخدام بيانات JSON هذه ، استوفينا المتطلبات التي يجب أن تعرضها / auth / password_recovery استجابة ، وبعدها سيدخل الخادم إلى فرع تغيير كلمة المرور (يحتوي كائن JSON على خاصية البريد الإلكتروني ). الآن لم نعد بحاجة إلى قيمة كلمة المرور القديمة . في فرع الرمز هذا ، قدمنا ​​جميع القيم اللازمة لتغيير كلمة المرور (خاصية اسم المستخدم هي admin وخاصية كلمة المرور هي p0tat0 ). اكتمل الطلب ، وتم تغيير كلمة المرور استجابة لذلك.


يبقى فقط لإدخال اسم مستخدم وكلمة مرور جديدة في صفحة تسجيل الدخول!


وهنا علمنا:


All Articles