NDH Writeups

From YobiWiki
Jump to navigation Jump to search

2014 Nuit du Hack CTF Quals by Hackerzvoice

It was a great moment of fun to participate to this year's CTF Quals organised by Hackerzvoice
Solving challenges involved all Pollypocket team members, here is only some polished results.

The greatest

The greatest was a steganography challenge:

We are sure that this e-mail contains hidden information, go get it !
Score 500
Link http://static.nuitduhack.com/mail.tar

Let's get this one:

wget http://static.nuitduhack.com/mail.tar
file mail.tar 
mail.tar: POSIX tar archive (GNU)

And a quick inspection through an hexadecimal editor didn't reveal anything suspicious or noticeable.
So let's open it:

tar tvf mail.tar 
-rw-r--r-- null/null    296008 2014-04-05 07:05 Mail
tar xvf mail.tar

And we get a file called Mail containing an email from BOOBA#rapfr.fr to theflag#nuitduhack.com

Hi dude!
Check out this pic. I used the cool tool I told you about last time, except that I played around with the code a bit.
Speaking of tools, Gregory Evans right?
Have fun trying to find the hidden data ;)
Peace out.

Together with an attachment (well, two attachments as the email was text+html)
The html version differed slightly ("this pic" => "this pick") but that didn't reveal to be of importance.
The other attachment:

Content-Type: image/gif; name=greg.gif
Content-Disposition: attachment; filename=greg.gif
Content-Transfer-Encoding: base64

Let's get it out of the mail using munpack from package mpack

munpack Mail
file greg.gif
greg.gif: GIF image data, version 89a, 500 x 645

greg.gif is... a GIF showing #1 world hacker :-)
Greg.gif

Here again, after inspection, nothing else than the GIF itself in the file.
Using gifsicle from the eponym package

gifsicle --xinfo greg.gif
* greg.gif 1 image
  logical screen 500x645
  global color table [256]
  background 65
  + image #0 500x645

There is no much possibilities for stegano in GIF as the image is made of refs to the colormap so it could be:

  • position of pixels of a given color
  • duplicates or alike in the colormap (e.g. #cccccc and #cccbcc) or other tricks

So let's dump the colormap:

gifsicle --color-info greg.gif
* greg.gif 1 image
  logical screen 500x645
  global color table [256]
  |   0: #FFFFFF      64: #A3835C     128: #1E3E71     192: #769DD1
  |   1: #FCF5F6      65: #A37F81     129: #030915     193: #0F314D
  |   2: #F5E9E8      66: #A27C58     130: #546473     194: #5982BB
[...]
  |  61: #A48A64     125: #675847     189: #4B3A47     253: #000000
  |  62: #A3BCE1     126: #101627     190: #7CA2CD     254: #000000
  |  63: #A38C6B     127: #4C6169     191: #594837     255: #000000
  background 65
  + image #0 500x645

243 colors were used (it's #000000 from 244 to 255)
They are globally sorted from #FFFFFF to #000000 but there are quirks in the sorting: e.g. #126, #129, #191 and #193 in the partial dump above are not sorted properly.
Clearly that can be a way to hide info but the problem as often in steganography challenges is that it's hard to guess how info was stored without the original tool.
And indeed the mail was talking about a modified tool, remember?
Googling for "gif stegano colormap" one of the hits mentioned gifshuffle: a tool used to conceal messages which are stored in GIF images by “shuffling” the color map.
That sounds promising!
And source code is available: http://www.darkside.com.au/gifshuffle/gifshuffle.tar.gz
It compiles smoothly.
Its man page explains very well how it embeds information by first sorting the colormap then changing the order of some of the colors.
Exactly what we observed!
There is also an encryption mode but that would be hard to crack and when used the colormap looks completely randomly sorted, which is not what we observed, luckily!
There is also a basic compression option
But when we try on the gif:

./gifshuffle greg.gif
<output is binary garbage>
./gifshuffle -C greg.gif
                                 uttEioe)udi
sgahat	aam wttf?ltkt tc(w a't weuos nllopcdyiccefohtr*c'npi na iarinrrrmgY rtolra"dbedna0tywUpea)ph   ic.i@t)w   i  Rdlnos 
igoi atyd	tns s t  hb bs0.iianiubiksiata gOobroiaw ..occsasniDtmdder tdpcatr. nI*ti	inmuaoitdfK  voesd ab leany0. l,nnetuCi .aabsas th e  g
Eo)bvrncitrid
sa	n.  Msdree

Hmmm.
Remember the mail, the tool was modified by the sender...
We can use gifshuffle ourselves on a gif to add some data into it.
We can use greg.gif as it will first sort the table, erasing the old data, then embed ours.

./gifshuffle -m fooooooooooooooooooooooooooooooooooooooooooooooooooooo greg.gif greg2.gif
Message used approximately 27.25% of available space.
gifsicle --color-info greg2.gif 
* greg2.gif 1 image
  logical screen 500x645
  global color table [256]
  |   0: #000000      64: #3B608F     128: #7C9CC5     192: #95675B
  |   1: #010001      65: #3C4230     129: #7CA2CD     193: #9C9499
  |   2: #030915      66: #44555D     130: #7CA3D2     194: #968C94
[...]
  |  61: #372819     125: #7B654B     189: #DFC69D     253: #000000
  |  62: #372925     126: #7B9ECB     190: #E6D9D8     254: #000000
  |  63: #394A58     127: #7C7456     191: #CFD8E9     255: #000000
  background 214
  + image #0 500x645

See, sorted colormap except for #191, #194
But global sorting is from #000000 to #FFFFFF (then some #000000 for the unused colors)
That's the thing we need to modify too in the tool
gifshuffle/encode.c colourmap_encode() starts by sorting the colormap:

if (encrypting_colourmap ()) {
    ...
    qsort (ci_array, ncols, sizeof (CMAP_INFO), cmap_encrypt_cmp);
} else
    qsort (ci_array, ncols, sizeof (CMAP_INFO), cmap_cmp);

Sorting is based on the comparison function cmap_cmp() defined in the same file:

static int cmap_cmp ( const void *p1, const void *p2) {
    return (rgb_cmp (&((CMAP_INFO *) p1)->rgb, &((CMAP_INFO *) p2)->rgb));
}

Let's just swap its arguments to inverse its effect:

static int cmap_cmp ( const void *p1, const void *p2) {
    return (rgb_cmp (&((CMAP_INFO *) p2)->rgb, &((CMAP_INFO *) p1)->rgb));
}

Let's try it:

gifshuffle_inverted greg.gif
The flag for this wonderful Gregory D. Evans picture is : L0n9L1v3TheW0rldN00n3Hack3rGr3g0ryD.3van