Steganography

  • Tabs&Spaces - 100

Tabs&Spaces

The challenge provides a ZIP containing a number of image files, and a Python script that compares hashes of the image files against a target value (not set in the script provided).

Given this, it’s likely that the file containing the flag has a hash that differs in some way from the rest of the files.

Listing the hash for each file in the directory reveals that they all share identical hashes, except for one file:

$ fd . --hidden -t f files/ -x sha256sum
 
e89bf7...f87e64  files/. 36.jpg
e89bf7...f87e64  files/. 95.jpg
...
e89bf7...f87e64  files/. 45.jpg
32a210...98b77d  files/. 87.jpg
e89bf7...f87e64  files/. 11.jpg
...

The file . 87.jpg does not match the others, though it appears visually identical. The tool StegoVeritas can be used to apply various transforms to the image. It successfully detects a file hidden with steghide:

$ stegoveritas "files/. 87.jpg"
 
Running Module: SVImage
+------------------+------+
|   Image Format   | Mode |
+------------------+------+
| JPEG (ISO 10918) | RGB  |
+------------------+------+
...
Found something with StegHide: /home/kali/ctf/acectf-1.0/tabsspaces/ctf/results/steghide_ae45f26c1c89b95c6cce233216918d21.bin

This can be verified with steghide:

$ steghide info "files/. 87.jpg"
 
". 87.jpg":
  format: jpeg
  capacity: 6.0 KB
Try to get information about embedded data ? (y/n) y
Enter passphrase: <Enter>
  embedded file "whitespace_flag.txt":
    size: 234.0 Byte
    encrypted: rijndael-128, cbc
    compressed: yes

The file consists entirely of three ASCII characters:

$ xxd results/steghide_ae45f26c1c89b95c6cce233216918d21.bin
 
00000000: 2009 2020 2020 2009 0a20 0920 2020 2009   .     .. .    .
00000010: 090a 2009 2020 2009 2009 0a20 0920 2020  .. .   . .. .   
00000020: 2009 090a 2009 2009 2009 2020 0a20 0920   ... . . .  . . 
00000030: 2020 0909 200a 2009 0909 0920 0909 0a20    .. . .... ... 
00000040: 0909 2009 0909 200a 2020 0909 2020 2020  .. ... .  ..    
00000050: 0a20 0920 0909 0909 090a 2020 0909 2020  . . ......  ..  
00000060: 0909 0a20 0909 0909 2020 200a 2009 0909  ... ....   . ...
00000070: 2020 2020 0a20 2009 0920 2020 090a 2020      .  ..   ..  
00000080: 0909 2020 2020 0a20 2009 0920 2020 090a  ..    .  ..   ..
00000090: 2020 0909 2009 0909 0a20 0920 0909 0909    .. .... . ....
000000a0: 090a 2009 0920 0909 0920 0a20 2009 0920  .. .. ... .  .. 
000000b0: 2020 200a 2009 2009 0909 0909 0a20 0909     . . ...... ..
000000c0: 2020 0909 090a 2020 0909 2009 2020 0a20    ....  .. .  . 
000000d0: 2009 0920 2020 090a 2009 0920 0909 0920   ..   .. .. ... 
000000e0: 0a20 0909 0909 0920 090a                 . ..... ..

These characters are (as the challenge name suggests): Space (0x20), Tab (0x09), and a Line Feed (0x0A) — a new line (ref).

Given the presence of two characters (spaces and tabs), and a delimiter (newline), this could be a representation of binary encoding. A recipe in CyberChef is able to convert this and decode the flag by replacing Tab with 1 and Space with 0:

This may be clearer with this image of the intermediate output, prior to binary decoding: