This image refuses to open in anything, which is a bit odd. Open it for the flag!
Category: Forensics
I did a quick apt-cache search
to see what png tools are available and found these:
kali@kali:~/Downloads/ractf/cut_short$ pngcheck flag.png
flag.png first chunk must be IHDR
ERROR: flag.png
kali@kali:~/Downloads/ractf/cut_short$ pngmeta flag.png
libpng error: IEND: out of place
pngmeta: libpng read error for flag.png
Now let's take a look with hexdump
:
kali@kali:~/Downloads/ractf/cut_short$ hd flag.png | head
00000000 89 50 4e 47 0d 0a 1a 0a 00 00 00 00 49 45 4e 44 |.PNG........IEND|
00000010 ae 42 60 82 00 00 00 0d 49 48 44 52 00 00 01 5e |.B`.....IHDR...^|
00000020 00 00 00 96 08 06 00 00 00 96 e7 e0 77 00 00 20 |............w.. |
00000030 00 49 44 41 54 78 9c ed 9d 09 d4 b5 d5 f8 c6 77 |.IDATx.........w|
00000040 e6 79 9e 93 10 15 ca 50 49 86 a8 68 51 14 cb 90 |.y.....PI..hQ...|
00000050 8c 19 ca 94 b2 94 84 4a a1 90 08 25 63 ad 0a 21 |.......J...%c..!|
00000060 91 a8 64 2e 85 84 92 95 31 63 32 65 cc 3c a6 ff |..d.....1c2e.<..|
00000070 fa 1d e7 fe fe f7 b9 9f 7b ef 67 3f c3 79 ce 73 |........{.g?.y.s|
00000080 de 77 5f 6b 9d f5 7d ef 19 9f 61 ef 6b df fb ba |.w_k..}...a.k...|
00000090 a7 b5 ae bc f2 ca 2b 43 41 41 41 41 c1 60 b8 4a |......+CAAAA.`.J|
For comparison, here is what a healthy .png
image looks like:
kali@kali:~/Downloads/ractf/cut_short$ pngcheck defenit.png
OK: defenit.png (1500x944, 32-bit RGB+alpha, non-interlaced, 97.7%).
kali@kali:~/Downloads/ractf/cut_short$ pngmeta defenit.png
pngmeta: PNG metadata for defenit.png:
kali@kali:~/Downloads/ractf/cut_short$ hd defenit.png | head
00000000 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 |.PNG........IHDR|
00000010 00 00 05 dc 00 00 03 b0 08 06 00 00 00 24 d3 b6 |.............$..|
00000020 7f 00 00 20 00 49 44 41 54 78 9c ec dd 0b 70 55 |... .IDATx....pU|
00000030 f5 bd ff fd 5f 2e 24 d9 c9 de 04 13 a8 0f 27 a1 |...._.$.......'.|
00000040 39 0e 43 68 0f 8c 28 38 10 b4 c3 ed 0f 9d d1 40 |9.Ch..(8.......@|
00000050 1c 28 0c 81 b6 b6 a6 9d 78 a9 3c b5 04 91 d1 47 |.(......x.<....G|
00000060 44 3c 3a c8 4d f8 07 6f 99 f3 04 e5 54 84 91 e2 |D<:.M..o....T...|
00000070 1c 76 52 67 0c 7f 2e 8e d5 c0 23 28 0e 17 13 86 |.vRg......#(....|
00000080 c1 fc 25 87 3f 6a 22 c9 de 21 21 04 7c e6 bb c8 |..%.?j"..!!.|...|
00000090 b6 11 03 d9 49 d6 e5 b7 d6 7e bf 66 d2 76 2a ac |....I....~.f.v*.|
In flag.png, IEND comes before IHDR, which seems wrong. What does it say in the spec?
"A valid PNG image must contain an IHDR chunk, one or more IDAT chunks, and an IEND chunk."
The IHDR chunk must appear FIRST. It contains:
Width: 4 bytes
Height: 4 bytes
Bit depth: 1 byte
Color type: 1 byte
Compression method: 1 byte
Filter method: 1 byte
Interlace method: 1 byte
"The IEND chunk must appear LAST. It marks the end of the PNG datastream. The chunk's data field is empty."
Well, it already has an IEND chunk at the end:
kali@kali:~/Downloads/ractf/cut_short$ hd flag.png | tail
00003af0 f1 c5 61 fd f5 d7 9f a4 1a 97 ba b7 05 05 69 48 |..a...........iH|
00003b00 57 63 f4 54 88 ad 69 a7 8d d5 88 42 bc 05 05 05 |Wc.T..i....B....|
00003b10 05 03 a3 84 93 15 14 14 14 0c 8c 42 bc 05 05 05 |...........B....|
00003b20 05 03 a3 10 6f 41 41 41 c1 c0 28 c4 5b 50 50 50 |....oAAA..(.[PPP|
00003b30 30 30 0a f1 16 14 14 14 0c 8c 42 bc 05 05 05 05 |00........B.....|
00003b40 03 a3 10 6f 41 41 41 c1 c0 28 c4 5b 50 50 50 30 |...oAAA..(.[PPP0|
00003b50 30 0a f1 16 14 14 14 0c 89 10 c2 ff 01 bb 81 1f |0...............|
00003b60 41 19 f7 a0 ca 00 00 00 00 49 45 4e 44 ae 42 60 |A........IEND.B`|
00003b70 82 |.|
00003b71
So we just need to remove the IEND chunk from the beginning of the flag.
From the head of the file:
kali@kali:~/Downloads/ractf/cut_short$ hd flag.png | head -2
00000000 89 50 4e 47 0d 0a 1a 0a 00 00 00 00 49 45 4e 44 |.PNG........IEND|
00000010 ae 42 60 82 00 00 00 0d 49 48 44 52 00 00 01 5e |.B`.....IHDR...^|
We need to remove bytes 13 - 24:
49 45 4e 44 ae 42 60 82 00 00 00 0d
We can remove that with dd
.
kali@kali:~/Downloads/ractf/cut_short$ dd if=flag.png of=flag2.png bs=1 count=12
12+0 records in
12+0 records out
12 bytes copied, 0.000200297 s, 59.9 kB/s
kali@kali:~/Downloads/ractf/cut_short$ hd flag2.png
00000000 89 50 4e 47 0d 0a 1a 0a 00 00 00 00 |.PNG........|
0000000c
kali@kali:~/Downloads/ractf/cut_short$ dd if=flag.png bs=1 skip=24 >> flag2.png
15193+0 records in
15193+0 records out
15193 bytes (15 kB, 15 KiB) copied, 0.0220703 s, 688 kB/s
kali@kali:~/Downloads/ractf/cut_short$ hd flag2.png | head -2
00000000 89 50 4e 47 0d 0a 1a 0a 00 00 00 00 49 48 44 52 |.PNG........IHDR|
00000010 00 00 01 5e 00 00 00 96 08 06 00 00 00 96 e7 e0 |...^............|
Run pngcheck
on the new image... crap, there's another error.
kali@kali:~/Downloads/ractf/cut_short$ pngcheck flag2.png
flag2.png invalid IHDR length
ERROR: flag2.png
From comparing defenit.png
to flag2.png
, it looks like I got the IHDR chunk in the right place.
kali@kali:~/Downloads/ractf/cut_short$ hd defenit.png | head
00000000 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 |.PNG........IHDR|
00000010 00 00 05 dc 00 00 03 b0 08 06 00 00 00 24 d3 b6 |.............$..|
00000020 7f 00 00 20 00 49 44 41 54 78 9c ec dd 0b 70 55 |... .IDATx....pU|
00000030 f5 bd ff fd 5f 2e 24 d9 c9 de 04 13 a8 0f 27 a1 |...._.$.......'.|
00000040 39 0e 43 68 0f 8c 28 38 10 b4 c3 ed 0f 9d d1 40 |9.Ch..(8.......@|
00000050 1c 28 0c 81 b6 b6 a6 9d 78 a9 3c b5 04 91 d1 47 |.(......x.<....G|
00000060 44 3c 3a c8 4d f8 07 6f 99 f3 04 e5 54 84 91 e2 |D<:.M..o....T...|
00000070 1c 76 52 67 0c 7f 2e 8e d5 c0 23 28 0e 17 13 86 |.vRg......#(....|
00000080 c1 fc 25 87 3f 6a 22 c9 de 21 21 04 7c e6 bb c8 |..%.?j"..!!.|...|
00000090 b6 11 03 d9 49 d6 e5 b7 d6 7e bf 66 d2 76 2a ac |....I....~.f.v*.|
kali@kali:~/Downloads/ractf/cut_short$ hd flag2.png | head
00000000 89 50 4e 47 0d 0a 1a 0a 00 00 00 00 49 48 44 52 |.PNG........IHDR|
00000010 00 00 01 5e 00 00 00 96 08 06 00 00 00 96 e7 e0 |...^............|
00000020 77 00 00 20 00 49 44 41 54 78 9c ed 9d 09 d4 b5 |w.. .IDATx......|
00000030 d5 f8 c6 77 e6 79 9e 93 10 15 ca 50 49 86 a8 68 |...w.y.....PI..h|
00000040 51 14 cb 90 8c 19 ca 94 b2 94 84 4a a1 90 08 25 |Q..........J...%|
00000050 63 ad 0a 21 91 a8 64 2e 85 84 92 95 31 63 32 65 |c..!..d.....1c2e|
00000060 cc 3c a6 ff fa 1d e7 fe fe f7 b9 9f 7b ef 67 3f |.<..........{.g?|
00000070 c3 79 ce 73 de 77 5f 6b 9d f5 7d ef 19 9f 61 ef |.y.s.w_k..}...a.|
00000080 6b df fb ba a7 b5 ae bc f2 ca 2b 43 41 41 41 41 |k.........+CAAAA|
00000090 c1 60 b8 4a b9 d4 05 05 05 05 c3 a2 10 6f 41 41 |.`.J.........oAA|
What am I missing?
At this point, I searched for more tools to help, and found PCRT:
kali@kali:~/Downloads/ractf/cut_short$ git clone https://github.com/sherlly/PCRT.git
Cloning into 'PCRT'...
remote: Enumerating objects: 23, done.
remote: Total 23 (delta 0), reused 0 (delta 0), pack-reused 23
Unpacking objects: 100% (23/23), done.
kali@kali:~/Downloads/ractf/cut_short$ python PCRT/PCRT.py -i flag2.png -o flag3.png
____ ____ ____ _____
| _ \ / ___| _ \_ _|
| |_) | | | |_) || |
| __/| |___| _ < | |
|_| \____|_| \_\|_|
PNG Check & Repair Tool
Project address: https://github.com/sherlly/PCRT
Author: sherlly
Version: 1.1
[Finished] Correct PNG header
Traceback (most recent call last):
File "PCRT/PCRT.py", line 780, in <module>
my_png.CheckPNG()
File "PCRT/PCRT.py", line 424, in CheckPNG
res=self.CheckIHDR(data)
File "PCRT/PCRT.py", line 513, in CheckIHDR
width,height=struct.unpack('!II',chunk_ihdr[:8])
struct.error: unpack requires a string argument of length 8
Ugh, I must have screwed up the IHDR or something. What about the original image?
kali@kali:~/Downloads/ractf/cut_short$ python PCRT/PCRT.py -i flag.png -o flag3.png
____ ____ ____ _____
| _ \ / ___| _ \_ _|
| |_) | | | |_) || |
| __/| |___| _ < | |
|_| \____|_| \_\|_|
PNG Check & Repair Tool
Project address: https://github.com/sherlly/PCRT
Author: sherlly
Version: 1.1
[Finished] Correct PNG header
[Finished] Correct IHDR CRC (offset: 0x29): 96E7E077
[Finished] IHDR chunk check complete (offset: 0x14)
[Finished] Correct IDAT chunk data length (offset: 0x2D length: 2000)
[Finished] Correct IDAT CRC (offset: 0x2035): 3196B0B1
[Detected] Error IDAT chunk data length! (offset: 0x2039)
chunk length:1B20
actual length:1B2C
[Notice] Try fixing it? (y or n) [default:y] y
[Warning] Only fix because of DOS->Unix conversion
[Failed] Fixing failed, auto discard this operation...
[Finished] Correct IDAT chunk data length (offset: 0x3B71 length: 1B20)
[Finished] Correct IDAT CRC (offset: 0x5699): 19F7A0CA
[Finished] IDAT chunk check complete (offset: 0x2D)
[Finished] Correct IEND chunk
IHDR)cted] Some data (length: 15197) append in the end (
[Notice] Try extracting them in: <1>File <2>Terminal <3>Quit [default:3]
[Finished] IEND chunk check complete
[Finished] PNG check complete
[Notice] Show the repaired image? (y or n) [default:n] y
kali@kali:~/Downloads/ractf/cut_short$ pngcheck flag3.png
flag3.png additional data after IEND chunk
ERROR: flag3.png
Sweet! That's good enough to get the flag.
The flag is:
ractf{1m4ge_t4mp3r1ng_ftw}