Skip to content

Instantly share code, notes, and snippets.

@Drakota
Last active April 14, 2024 15:52
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Drakota/e17f4e8a1b6f30292acd442dda9d3565 to your computer and use it in GitHub Desktop.
Save Drakota/e17f4e8a1b6f30292acd442dda9d3565 to your computer and use it in GitHub Desktop.
(0xL4ugh CTF) Imagination Writeup

Upon unzipping the Imagine.zip, we can do file to see what type of file we are working with.

$ file Challenge 
Challenge: data

Nothing interesting, so I then opened it up with a hex editor (ghex)

corrupted

The header seemed familiar, but somehow corrupted so I've checked a list of file signatures to check if I could match it with one of those. I've then assumed it was a corrupted PNG and saw that the first bytes where wrong instead of . P O G it should have been . P N G and instead of . I H C R it should be . I H D R.

Now file recognizes successfully that the file is a PNG

$ file Challenge 
Challenge: PNG image data, 1920 x 1289, 8-bit/color RGB, interlaced

I still wasn't able to read it. I then used the pngcheck tool which allows to check for issues in the different chunks in the PNG format.

$ pngcheck -vctfp7 Challenge
File: Challenge (5560700 bytes)
  chunk IHDR at offset 0x0000c, length 13
    1920 x 1289 image, 24-bit RGB, interlaced
  chunk tEXt at offset 0x00025, length 25, keyword: Software
    Adobe ImageReady
  chunk iTXt at offset 0x0004a, length 784, keyword: XML:com.adobe.xmp
    uncompressed, no language tag
    no translated keyword, 763 bytes of UTF-8 text
  chunk IDAT at offset 0x00366, length 5526247
    zlib: deflated, 32K window, maximum compression
    rows per pass: 162, 162, 161, 323, 322, 645, 644
  CRC error in chunk IDAT (computed b9d7708b, expected 6f623c3e)
  invalid chunk name "C>D2" (43 3e 44 32)
  chunk C>D2 at offset 0x545659, length 842155847:  illegal critical, safe-to-copy chunk
:  invalid chunk length (too large)
ERRORS DETECTED in Challenge

I tried for a while to fix it manually, but couldn't find what could be the end of the IDAT chunk. I then found the writeup of a RADARCTF challenge which introduce a tool called PCRT to automatically repair errors with a PNG. I used it on the Challenge file.

python PCRT/PCRT.py -i Challenge  -o Fixed.png

Which resulted in the following image: fixed

In the bottom right corner there was a message telling us that there's nothing here and we have to search more. Our job is not done yet.

Even though the image was displaying correctly, when I was running pngcheck on the Fixed image I still had the same error has earlier:

$ pngcheck -vctfp7 Fixed.png
File: Fixed.png (5594275 bytes)
  chunk IHDR at offset 0x0000c, length 13
    1920 x 1289 image, 24-bit RGB, interlaced
  chunk tEXt at offset 0x00025, length 25, keyword: Software
    Adobe ImageReady
  chunk iTXt at offset 0x0004a, length 784, keyword: XML:com.adobe.xmp
    uncompressed, no language tag
    no translated keyword, 763 bytes of UTF-8 text
  chunk IDAT at offset 0x00366, length 5526247
    zlib: deflated, 32K window, maximum compression
    rows per pass: 162, 162, 161, 323, 322, 645, 644
  invalid chunk name "C>D2" (43 3e 44 32)
  chunk C>D2 at offset 0x545659, length 842155847:  illegal critical, safe-to-copy chunk
:  invalid chunk length (too large)
ERRORS DETECTED in Fixed.png

That prompted me to check further down in my hex editor to see if there was any obvious problems (I also had doubt that there might be other files here). I then found what seemed like a START section: start

I wasn't sure if this was a format that some file extensions were using, so I spent a lot of time looking for it online. I then found lower that there was an END section. I was pretty sure I this point that it had nothing to do with the signature of any file types and was probably for the CTF. I then wanted to carve this out of the file using dd.

$ dd if=Challenge of=Carved bs=1 skip=5526542 count=33530

When rechecking the description of the challenge the hacker that corrupted the file was called (x^6) which made me think that maybe this file was XORed with a key value of 6. I pulled up CyberChef and then got the flag: flag

@Drakota
Copy link
Author

Drakota commented Jan 16, 2021

Images

corrupted
fixed
start
flag

@Kartibok
Copy link

Great writeup thanks. I don't have the file to run through your process, but it reminded me of a binwalk use for another CTF. Not sure if my notes will help at all.
Extract:

$ binwalk -e hell.jpg 

$ binwalk -M --dd=.* steg06.jpg 

Also use dd if binwalk cannot extract files but reports different images

$ binwalk -e steg06.jpg 

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             JPEG image data, EXIF standard
12            0xC             TIFF image data, little-endian offset of first image directory: 8
117819        0x1CC3B         JPEG image data, EXIF standard
117831        0x1CC47         TIFF image data, big-endian, offset of first image directory: 8
118003        0x1CCF3         JPEG image data, EXIF standard
118015        0x1CCFF         TIFF image data, big-endian, offset of first image directory: 8

We can use the decimal settings to actually specify the next image.

$ dd if=steg06.jpg of=out2.jpg skip=117819 bs=1

The if=inputfile the of=outputfile skip=startpoint and finally the bs=setsblocksize

@Drakota
Copy link
Author

Drakota commented Jan 17, 2021

@Kartibok In this case, binwalk wasn't able to show anything except the initial image, because START doesn't match any existing file signatures and the second image was XORed, so it couldn't see the proper magic bytes. I didn't know about the --dd flag for binwalk looks interesting!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment