Balda's place


Release of Stegpy

Published on 04 June 2013

After several steganography challenges during CTFs, I decided to write a simple steganalysis software to help me (and others of course) quickly analyze an image without having to spend lots of time with Gimp or others.

The code is available right away on my github account :

How it works

Stegpy offers a visual help to indicate if data has been hidden in an image by the use of various filters :

  • Pixel difference

    Changes the pixel to white if the next pixel is different

  • Pixel invert (XOR)

    Inverts the colors

  • Pixel reverse (lsb<->msb)

    Reverts each pixel color. The MSB becomes the LSB. This helps finding a possible color manipulation

  • Value filters for each color bit

    All channels in a pixel are masked witht the defined value. This will immediately show if a bit is used to hide data

  • Alpha layer visualisation

    If data has been hidden in the alpha layer, this filter will show it by assigning a different color to all possible alpha layer values.

  • Palette switch

    If the image is palette-indexed (like in a GIF image), this filter will assign a different color for each possible palette value.

It also offers the possibility to extract LSB encoded data. For this, you can use the -x switch along with the -m{r,g,b,a} parameters that represent the masks applied to the color channel. The -p parameter is used to set the path the application will follow to extract the data. The -o switch is used to select the color channel order used to extract data.


Visual mode

Let's take the following image, which was a challenge I made for Insomni'hack 2013 :

At first sight, it's just a black image, right ?

$./ challenge.png -C
File color mode : RGBA

Image colors :
Color          Times used
(0, 0, 0, 255) (53212 times)
(0, 0, 1, 255) (2876 times)

Color statistics :
Red distribution :     [0]
Green distribution :   [0]
Blue distribution :    [0, 1]
Alpha distribution :   [255]

All right, there are two colors used in this image, pure black and black with a little bit of blue. Now let's fire up the visual mode to change the colors and see the result :

$./ challenge.png -v

Voila ! By using the value filter, each time the LSB in a color channel is on, the corresponding pixel is colored in full blue, which mean we have two colors now :

Image colors :
Color            Times used
(0, 0,   0, 255) (53212 times)
(0, 0, 255, 255) (2876 times)

Note that you can right-click on the image to save it. Useful for showing people what you've discovered.

Data extraction

In this example, We'll take this image :

Again, let's take the color map :

$./ challenge.png -C
File color mode : RGB

Image colors :
Color     Times used
(0, 0, 0) (15913 times)
(0, 0, 1) (87 times)

Color statistics :
Red distribution :     [0]
Green distribution :   [0]
Blue distribution :    [0, 1]

Again, only the blue LSB is used to hide data. Let's view the image to see how it looks like. This time, we'll enlarge the image eight times with the help of the -sf switch :

$./ challenge.png -sf 8 -v

As we see, some data seems to be hidden in the image. We can actually guess the path the data has been hidden by looking at the image : From left to right, then up to down. Now, to extract data hidden in it, let's use the data extract function :

$./ /tmp/challenge2.png -x -bm 1 -p lrud -o b
This is a secret message

That's it ! Now, if we take each parameter, we've told Stegpy to extract data (-x) with a mask on the LSB of the blue channel (-bm 1), get the data from left to right, then up to down (-p lrtd) and only extract data from the blue channel (-o b)