Wright In The Shadows

Ini adalah kisah tentang salah satu tugas yang kami siapkan untuk tahap kualifikasi CTFZone , yang diadakan pada akhir November. Anda dapat membaca tentang proses persiapan kualifikasi di sini .

Anda mulai dengan dua file: decrypt_flag.py dan ntfs_volume.raw. Mari kita lihat skripnya. Dia membuka file bernama key.bin, dan kemudian, menggunakan loop, dia mencoba untuk mengambil string biner 34 byte dari setiap offset di dalam file, yang kemudian digunakan sebagai input untuk fungsi PBKDF2. Setiap kunci yang dikembalikan digunakan sebagai kunci XOR untuk mendekripsi string terenkripsi yang dijahit ke dalam kode. Jika hash MD5 yang didekripsi cocok dengan nilai yang telah ditentukan dalam bentuk yang didekripsi, skrip menggunakan data yang diterima untuk membuat dan mencetak bendera.

Jadi, Anda perlu menemukan file key.bin. Tidak mungkin menyortir semua offset di dalam file gambar (ntfs_volume.raw), karena proses menemukan kuncinya akan terlalu lambat. Ini tidak dilarang oleh aturan, tetapi Anda tentu tidak akan punya waktu sebelum akhir KKP.

File gambar berisi tabel partisi MBR satu-partisi. Offset-nya adalah 2.048 sektor 512-byte, dan berisi sistem file NTFS, tetapi file key.bin tidak ada:

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

NTFS menyimpan nama file yang disandikan UTF-16LE. Ayo coba cari di dalamnya!


Hasil pencarian untuk catatan file

Setelah mempelajari hasil pencarian, kami fokus pada catatan file yang dimulai dengan tanda tangan FILE [1]. Inilah satu-satunya entri seperti itu:


Rekor Ditemukan

Tujuan sudah dekat! Kami memiliki catatan file, tetapi kami membutuhkan data. Dalam NTFS, mereka disimpan dalam atribut $ DATA, yang bisa penduduk atau bukan penduduk [2]. Untuk catatan yang kami temukan, atribut ini dimulai pada offset 0 × 3AADD00 dan menunjukkan data yang bukan penduduk (ini berarti bahwa informasi disimpan di luar catatan file).

Jadi di mana tepatnya data dari file yang diinginkan? Untuk menjawab pertanyaan ini, perlu untuk men-decode apa yang disebut pasangan pemetaan, atau data berjalan (pasangan “panjang blok - blok offset”) [3]. Data berjalan dari file yang diinginkan adalah sebagai berikut (perhatikan offset 0 × 3AADD40): 22 53 01 A0 4E 21 05 31 C1 11 38 30 00. Atau, jika kita mengatur ulang mereka:

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

File ini terdiri dari tiga fragmen, ukuran yang pertama adalah 339 cluster, dan dimulai dengan cluster # 20128. Untuk kode kami menggunakan PBKDF2, potongan ini besar. Seperti yang ditunjukkan dalam header sistem file, ukuran satu cluster adalah 4096 byte:

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

Mari kita lihat data untuk offset ini (dalam byte):
2048 * 512 + 20128 * 4096 = 83492864. Kami akan mengekstraksi sejumlah informasi penting (misalnya, 128 byte) dari sini, masukkan ke dalam file baru, yang akan kami panggil key.bin, jalankan skrip ... Tidak ada yang berhasil.

Mungkin file itu tidak disimpan pada saat ini, tetapi dalam versi sebelumnya dari sistem file (format sebelumnya) - jangan lupa bahwa kami tidak melihat catatan tentang file yang dihapus dengan nama yang sama. Berapa ukuran cluster sebelumnya? Mari kita mencari header sistem file dengan tanda tangan NTFS [4]. Mungkin kami beruntung dan kami benar-benar menemukan tajuk dari format sebelumnya.


Hasil pencarian untuk header sistem file

Posisi pertama dan terakhir dalam hasil merujuk pada sistem file saat ini, tetapi header sistem file yang terletak di antara mereka tampaknya milik format sebelumnya. Dan mereka memiliki ukuran cluster yang berbeda!


Header sistem file dari versi sebelumnya.

Ukuran sektor tersebut ditulis pada offset 0 × 4554800B: 00 02, atau 512. Tetapi ukuran cluster tersebut dicatat pada offset 0 × 0x4554800D: F7, atau 247.

Jadi, kami memiliki ukuran cluster (dalam byte) bersama kami 512 * 247 = 126464. Semacam omong kosong! Jika Anda percaya parser NTFS [5], nilai seperti itu harus memiliki tanda dan diproses dengan cara khusus, sehingga ukuran cluster nyata (dalam sektor) adalah 1 << - (- 9) = 512. Atau, jika dalam byte, 512 * 512 = 262144 Sekarang terdengar lebih bisa dipercaya.

Data dimulai di sini pada offset ini (dalam byte):
2048 * 512 + 20128 * 262144 = 5277483008. Mari kita coba lagi untuk melakukan trik yang sama dengan informasi yang tersimpan di sana ... Sekali lagi, sebuah kegagalan! Apa yang salah? Kami memiliki CTF di sini, itu berarti "tidak begitu" apa pun bisa terjadi.

Tugas yang kita lawan disebut In the Shadows. Mungkin ada hubungannya dengan salinan bayangan volume. Jadi, kami memiliki file dari sistem file yang sebelumnya ada di volume ini. Sayangnya, kami tidak bisa mengambil dan me-mount salinan bayangannya, tetapi kami tahu offset yang tepat di mana data dimulai! Ini adalah 5277483008, atau, dalam bagian tersebut, 5277483008 - 2048 * 512 = 5276434432.

Menurut spesifikasi format VSS [6], blok data yang dialihkan dijelaskan dalam struktur deskriptor Blok yang berisi bidang 64-bit di mana offset asli (di dalam volume) disimpan, dan juga bidang 64-bit yang menguraikan offset blok target (di dalam volume). Mari kita mencari 5276434432 sebagai nomor endian 64-bit kecil.

Hanya ada dua hasil dalam hasil, dan hanya satu dari mereka yang terletak pada offset genap.


Deskriptor blok yang ditemukan

Target offset blok : 00 00 9B 03 00 00 00 00, atau hanya 60489728. Final offset: 60489728 + 2048 * 512 = 61538304. Dari sini, ekspor sejumlah data ke file baru bernama key.bin, dan ...

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

Selesai!

Referensi


  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-descriptortor

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


All Articles