As requested here is the program used to produce the image for the Basic Stego challenge we published yesterday.
If you are still trying to solve it, you may want to wait to read this.
The image was generated with a very simple C program using
libgd. `libgd' (http://libgd.github.io/) is a classical library to produce images. The name stands for _GIF Draw. It was (I think still is) very popular to generate images on websites and, despite of its name, it supports many different images formats nowadays.
To easily understand the code, I will just explain how the message has been encoded into the image. As you probably already know the message was stored in the blue component of the image. The blue component was chose as this is the light wave length the eye is less sensitive to. Green is the colour with the light wave length firing the highest excitation in the cell in the back of our retina. That's one of the reason the old monochrome displays used green phosphor. The image looked brighter with less energy
Anyway, the program, just stores an ASCII string in this component. ASCII text is actually 7 bits long, so the program keeps the higher bit to do not fully destroy the blue component. For the selected image, with a lot of black, it does not really make a difference, but this is something you may consider when writing your own encoders.
Then, instead of stopping once the original message has been stored in the image, the rest of the image is filled with random data, just to make the whole image look a bit more uniform and making a bit more difficult to figure out where the hidden message is actually stored.
Finally, note that you have to use an image format that supports lossless compression or no compression at all. GIF, PNG, BMP should be fine, but JPEG will destroy your encoding... it can be tweaked but in general it will just destroy your data. We have to do encode the information in a different way in that case.
The code is not very optimal, but, as you had already checked it works
char *s = "0x00sec.org is an awesome community!\n"
"Open the image with GIMP and separate the channels in layers (Colors > Components > Decompose)\n"
"Then remove the green and red layers and export the file as .pgm... Choose RAW encoding\n"
"Then you can just cat the pgm file to see this message\n"
main(int argc, char *argv)
int i, l, x, y, w, h;
int rgb, color, r, g, b, c;
if (argc != 2)
fprintf (stderr, "usage:%s input_image.png\n", argv);
f = fopen (argv, "rb");
image = gdImageCreateFromPng (f);
w = image->sx;
h = image->sy;
fprintf (stderr, "Image size: %dx%d\n", image->sx, image->sy);
i = 0;
l = strlen (s) + 1;
for (y = 0; y < h; y++)
for (x = 0; x < w; x++)
if (i >= l)
c = rand () % 127;
c = s[i];
/* Get pixel value */
rgb = gdImageGetPixel (image, x, y);
r = (gdImageRed(image, rgb));
g = (gdImageGreen(image, rgb));
b = (gdImageBlue(image, rgb) & 0x80) + c;
color = gdTrueColor (r, g, b);
gdImageSetPixel (image, x, y, color);
gdImagePng (image, stdout);
Well, there is not much to say about the program. Just loads the image and then, for each pixel, either adds the ASCII value of the message into the lower bits of the blue component or it adds some random value.
To compile the code just link the library. Remember to install the
dev package for
libgd in your system.
gcc -o stego_enc stego_enc.c -lgd
Supossing you have named stegoenc.c to your source code file_
Why it can be decoded without a program?
This is just by chance. What happen is that the whole message fits into an image area that is black. That means that the eighth bit of each blue component is just 0 and then the blue component is effectively containing the ASCII value of the message. Try to use a image with something different to black in the first image row and you will get some strange results... OK supposing some pixels has a blue component higher than 127.
The PGM format mentioned in the hints is a raw grey scale format. When saving the blue component in this format, the values of the text are actually popping up from the file when you just
Actually this can be done in just one command, if you have the tool
pngtopnm c.png | head -10
However, I though that using GIMP to manually go through the process was more didactic.
It is very easy to modify this program to produce stego messages without artifacts as strong as the ones in the "Basic Stego CryptoChallenger".