We found this file. Recover the flag
Intro
File yang diberikan berupa
$ file mystery
mystery: data
TLDR
- Perbaiki file-header
- Perbaiki chunks
- Get the flag
Full Steps
Hint yang diberikan adalah
Try fixing the file header
Sehingga langkah pertama yang dilakukan adalah menganalisis hex-value-nya menggunakan hex editor atau hex viewer, disini saya menggunakan Bless
Delapan bytes pertama terlihat seperti membentuk file header PNG namun tidak sempurna, sehingga diubah ke file header PNG yang benar
Dari
89 65 4E 34 0D 0A B0 AA
Ke
89 50 4E 47 0D 0A 1A 0A
Pengecekan dengan command file
masih belum berubah, namun dengan pngcheck
terdapat informasi lain
$ pngcheck -v mystery
File: mystery (202940 bytes)
invalid chunk name "C"DR" (43 22 44 52)
ERRORS DETECTED in mystery
Berdasarkan referensi [1], diketahui bahwa:
The PNG datastream consists of a PNG signature (see 5.2: PNG signature) followed by a sequence of chunks. Each chunk has a chunk type which specifies its function. This clause defines the PNG chunk types standardized in this International Standard
Dengan Critical Chunks dari PNG adalah:
- IHDR: image header, which is the first chunk in a PNG datastream.
- PLTE: palette table associated with indexed PNG images.
- IDAT: image data chunks.
- IEND: image trailer, which is the last chunk in a PNG datastream.
Berdasarkan informasi tersebut, diasumsikan invalid chunk name C”DR” seharusnya IHDR, ubah kembali menggunakan Bless
Kini file mystery telah terbaca, meskipun belum dapat dilihat gambarnya karena masih terdapat error lain
$ file mystery
mystery: PNG image data, 1642 x 1095, 8-bit/color RGB, non-interlaced
$ pngcheck -v mystery
File: mystery (202940 bytes)
chunk IHDR at offset 0x0000c, length 13
1642 x 1095 image, 24-bit RGB, non-interlaced
chunk sRGB at offset 0x00025, length 1
rendering intent = perceptual
chunk gAMA at offset 0x00032, length 4: 0.45455
chunk pHYs at offset 0x00042, length 9: 2852132389x5669 pixels/meter
CRC error in chunk pHYs (computed 38d82c82, expected 495224f0)
ERRORS DETECTED in mystery
Masih berdasarkan referensi [1], diketahui bahwa layout sebuah chunk adalah:
- 4-bytes Length
- 4-bytes Chunk Type
- x-bytes Chunk Data (x tergantung Length yang didefinisikan sebelumnya)
- 4-bytes Cyclic Redundancy Cycle (CRC)
Berdasarkan error message terdapat kesalahan di CRC milik chunk pHYs, namun jika diteliti lebih lanjut terdapat angka yang terlalu besar di chunk pHYs tersebut, yaitu 2852132389, sehingga inisiatif yang dilakukan adalah mengubah ukuran tersebut menjadi 5669 daripada memperbaiki CRC-nya. Cari layout chunk data milik pHYs (offset 00000046), ubah dari
AA 00 16 25
karena 0xaa001625 = 2852132389 menjadi
00 00 16 25
0x00001625 = 5669
Simpan, kemudian cek kembali error message-nya
$ pngcheck -v mystery
File: mystery (202940 bytes)
chunk IHDR at offset 0x0000c, length 13
1642 x 1095 image, 24-bit RGB, non-interlaced
chunk sRGB at offset 0x00025, length 1
rendering intent = perceptual
chunk gAMA at offset 0x00032, length 4: 0.45455
chunk pHYs at offset 0x00042, length 9: 5669x5669 pixels/meter (144 dpi)
: invalid chunk length (too large)
ERRORS DETECTED in mystery
Terdapat error message invalid chunk length namun tidak disebutkan chunk yang error, analisis bytes setelah chunk pHYs berakhir melalui Bless didapatkan:
Bytes penanda chunk length
AA AA FF A5
dan Bytes penanda chunk type
AB 44 45 54
Chunk Type 0xab444554 = \xabDET tidak dikenali sebagai chunk type dari PNG, dan diasumsikan paling mendekati adalah Chunk IDAT, sehingga diubah menjadi 0x49444154
Untuk chunk length 0xaaaaffa5 = 2863333285 diasumsikan terlalu besar, sehingga perlu diubah. Berdasarkan referensi [1], tertera bahwa:
There can be multiple IDAT chunks; if so, they must appear consecutively with no other intervening chunks.
Sehingga, untuk memperbaiki chunk length perlu dicari chunk IDAT lainnya, kemudian dihitung selisihnya. Apabila tidak ada chunk IDAT lain, selisih yang dicari adalah dengan chunk IEND. Analisis dari Bless, terdapat total 4 chunk IDAT dimana IDAT pertama (yang sedang diperbaiki) berada pada offset 0x00057, sedangkan IDAT kedua berada pada offset 0x10008. Selisih keduanya adalah
0x10008 - 0x00057 = 0xFFB1
0xFFB1 masih harus dikurangi dengan bytes length dari IDAT 1 (4 bytes), CRC dari IDAT 1 (4 bytes) dan chunk type dari IDAT 2 (4 bytes), sehingga total 12 bytes
0xFFB1 - 0xC = 0xFFA5
0xFFA5 merupakan length dari IDAT pertama, sehingga edit kembali bytes penanda length IDAT pertama dari
AA AA FF A5
menjadi
00 00 FF A5
Hasil dari pngcheck
menandakan tidak ada error lagi
$ pngcheck -v mystery
File: mystery (202940 bytes)
chunk IHDR at offset 0x0000c, length 13
1642 x 1095 image, 24-bit RGB, non-interlaced
chunk sRGB at offset 0x00025, length 1
rendering intent = perceptual
chunk gAMA at offset 0x00032, length 4: 0.45455
chunk pHYs at offset 0x00042, length 9: 5669x5669 pixels/meter (144 dpi)
chunk IDAT at offset 0x00057, length 65445
zlib: deflated, 32K window, fast compression
chunk IDAT at offset 0x10008, length 65524
chunk IDAT at offset 0x20008, length 65524
chunk IDAT at offset 0x30008, length 6304
chunk IEND at offset 0x318b4, length 0
No errors detected in mystery (9 chunks, 96.3% compression).
Sehingga file mystery dapat dibuka
Flag
picoCTF{c0rrupt10n_1847995}