رايت في الظلال

هذه قصة عن إحدى المهام التي أعددناها لمرحلة التصفيات CTFZone ، التي عقدت في نهاية نوفمبر. يمكنك أن تقرأ عن عملية إعداد التأهيل هنا .

تبدأ بملفين: decrypt_flag.py و ntfs_volume.raw. دعونا نلقي نظرة على البرنامج النصي. يقوم بفتح ملف يسمى key.bin ، وبعد ذلك ، باستخدام حلقة ، يحاول أخذ سلسلة ثنائية 34 بايت من كل إزاحة داخل الملف ، والتي يتم استخدامها بعد ذلك كمدخل لوظيفة PBKDF2. يتم استخدام كل مفتاح تم إرجاعه كمفتاح XOR لفك تشفير السلسلة المشفرة مخيطًا في التعليمات البرمجية. إذا تطابق تجزئة MD5 التي تم فك تشفيرها مع القيمة المحددة مسبقًا في نموذج تم فك تشفيره ، يستخدم البرنامج النصي البيانات المستلمة لإنشاء العلامة وطبعها.

لذلك تحتاج إلى العثور على ملف key.bin. من المستحيل ببساطة فرز جميع الإزاحات داخل ملف الصورة (ntfs_volume.raw) ، حيث أن عملية العثور على المفتاح ستكون بطيئة جدًا. هذا لا تحظره القواعد ، ولكن بالتأكيد لن يكون لديك وقت قبل نهاية CTF.

يحتوي ملف الصورة على جدول قسم MBR أحادي القسم. الإزاحة 2048 512 بايت ، وتحتوي على نظام الملفات NTFS ، ولكن ملف key.bin غير موجود:

$ fls -o 2048 -r -p ntfs_volume.raw | grep -F key.bin | wc –l
0

يقوم NTFS بتخزين أسماء الملفات المشفرة باستخدام UTF-16LE. دعونا نحاول البحث فيه!


نتائج البحث عن سجلات الملفات

بعد دراسة نتائج البحث ، نركز على سجلات الملفات التي تبدأ بتوقيع FILE [1]. هنا هو الدخول الوحيد من هذا القبيل:


العثور على سجل

الهدف قريب بالفعل! لدينا سجل ملف ، لكننا بحاجة إلى البيانات. في NTFS ، يتم تخزينها في سمة $ DATA ، والتي يمكن أن تكون مقيمة أو غير مقيمة [2]. بالنسبة للسجل الذي تم العثور عليه ، تبدأ هذه السمة عند الإزاحة 0 × 3AADD00 وتشير إلى البيانات غير المقيمة (وهذا يعني أنه يتم تخزين المعلومات خارج سجل الملف).

فأين بالضبط بيانات الملف المطلوب؟ للإجابة على هذا السؤال ، من الضروري فك تشفير ما يسمى أزواج التعيين أو تشغيل البيانات (أزواج "طول الكتلة - إزاحة الكتلة") [3]. فيما يلي بيانات تشغيل الملف المطلوب (لاحظ الإزاحة 0 × 3AADD40): 22 53 01 A0 4E 21 05 31 C1 11 38 30 00. أو ، إذا أعدنا ترتيبها:

1.	22 53 01 A0 4E
2.	21 05 31 C1
3.	11 38 30 00

يتألف الملف من ثلاثة أجزاء ، يبلغ حجم أولها 339 عنقودًا ، ويبدأ بالمجموعة رقم 20128. بالنسبة إلى رمزنا باستخدام PBKDF2 ، فإن هذا المقتطف كبير. كما هو موضح في رأس نظام الملفات ، حجم الكتلة الواحدة هو 4096 بايت:

$ fsstat -o 2048 ntfs_volume.raw | grep 'Cluster Size'
Cluster Size: 4096

دعنا نلقي نظرة على بيانات هذا الإزاحة (بالبايت):
2048 * 512 + 20128 * 4096 = 83492864. سنقوم باستخراج أي قدر كبير من المعلومات (على سبيل المثال ، 128 بايت) من هنا ، وإدراجها في ملف جديد ، والذي سوف نسميه key.bin ، وتشغيل البرنامج النصي ... لم ينجح شيء.

ربما لم يتم تخزين الملف في الوقت الحالي ، ولكن في الإصدار السابق من نظام الملفات (التنسيق السابق) - لا تنس أننا لم نشاهد السجل حول الملف المحذوف بنفس الاسم. ماذا كان حجم الكتلة من قبل؟ دعونا نبحث عن رأس نظام الملفات بتوقيع NTFS [4]. ربما نكون محظوظين ونجد الرأس من التنسيق السابق.


نتائج البحث لرأس نظام الملفات

تشير المواضع الأولى والأخيرة في نتائج البحث إلى نظام الملفات الحالي ، ولكن يبدو أن رؤوس نظام الملفات الموجودة بينهما تنتمي إلى التنسيق السابق. ولديهم حجم كتلة مختلف!


عنوان نظام الملفات من الإصدار السابق. تتم كتابة

مثل هذا الحجم بالقطاع عند إزاحة 0 × 4554800B: 00 02 أو 512. ولكن يتم تسجيل حجم الكتلة هذا في إزاحة 0 × 0x4554800D: F7 أو 247.

لذا ، لدينا حجم الكتلة (بالبايت) 512 * 247 = 126464. نوع من الهراء! إذا كنت تعتقد أن محلل NTFS [5] ، يجب أن تحتوي هذه القيمة على علامة ومعالجتها بطريقة خاصة ، لذا فإن حجم الكتلة الحقيقي (في القطاعات) هو 1 << - (- 9) = 512. أو إذا كان بالبايت ، 512 * 512 = 262144 يبدو الآن أكثر تصديقًا.

تبدأ البيانات هنا عند هذا الإزاحة (بالبايت):
2048 * 512 + 20128 * 262144 = 5277483008. دعنا نحاول مرة أخرى القيام بنفس الحيلة مع المعلومات المخزنة هناك ... مرة أخرى ، فشل! ما المشكله؟ لدينا CTF هنا ، هذا يعني "ليس كذلك" أي شيء يمكن أن يكون.

المهمة التي نقاتلها تسمى في الظل. من الممكن أن يكون له علاقة بنسخ الظل من المجلد. لذا ، لدينا ملف من نظام الملفات كان موجودًا سابقًا في هذا المجلد. لسوء الحظ ، لا يمكننا ببساطة أخذ نسخة الظل الخاصة بها وتركيبها ، ولكننا نعرف الإزاحة الدقيقة التي تبدأ عندها البيانات! هذا هو 5277483008 ، أو ، داخل القسم ، 5277483008 - 2048 * 512 = 5276434432.

وفقًا لمواصفات تنسيق VSS [6] ، يتم وصف كتل البيانات المعاد توجيهها في هيكل واصف الكتلة الذي يحتوي على حقل 64 بت يتم فيه تخزين الإزاحة الأصلية (داخل وحدة التخزين) ، و أيضًا حقل 64 بت يصف إزاحة الكتلة الهدف (داخل وحدة التخزين). دعونا ننظر إلى 5276434432 كرقم إنداني صغير 64 بت.

هناك نتيجتان فقط في النتائج ، واحد منهم فقط موجود في إزاحة متساوية.


تم العثور على واصف الكتلة الموجودة

إزاحة الكتلة الهدف: 00 00 9B 03 00 00 00 00 ، أو 60489728 فقط. الإزاحة النهائية: 60489728 + 2048 * 512 = 61538304. من هنا ، قم بتصدير كمية معينة من البيانات إلى ملف جديد يسمى key.bin ، و ...

$ ./decrypt_flag.py
ctfzone{my_c0ngr4t5_t0_u,w311_d0n3_31337}

منجز!

المراجع


  1. https://flatcap.org/linux-ntfs/ntfs/concepts/file_record.html
  2. https://flatcap.org/linux-ntfs/ntfs/attributes/data.html
  3. https://flatcap.org/linux-ntfs/ntfs/concepts/data_runs.html
  4. https://flatcap.org/linux-ntfs/ntfs/files/boot.html
  5. https://github.com/msuhanov/dfir_ntfs/blob/94bb46d6600153071b0c3c507ef37c42ad62110d/dfir_ntfs/BootSector.py#L58
  6. https://github.com/libyal/libvshadow/blob/master/documentation/Volume٪20Shadow٪20Snapshot٪20(VSS)٪20format.asciidoc#431-block-descriptor

Source: https://habr.com/ru/post/undefined/


All Articles