Steganalysis is the science or art of detecting the presence of messages hidden using Steganography.
Steganography tries to hide a message to avoid detection of the fact that there is a hidden message.
Steganalysis attempts to detect the presence of a message using statistical analysis, basically looking for noise in data. The more noisey data is at base the less chance that a message will be detected, though of course a more noisey image may very well indicate the presence of Steganography. The more evenly spread the noise of the encoded data the less chance of detection.
The main way that Steganalysis works is by having a copy of the original and a copy of the StegData. This is what I will concentrate on here, though the more advanced techniques of Steganalysis is what drives a good pattern creation technique in Steganography.
To derive the pattern of the Steganography, comparing the difference between the coverData and the StegData is all that is required.
We could compare the difference by looking at the numerical values of each pixel, but there do exist more graphical ways, which can be a little more fun.
Fire up the GIMP (GNU Image Manipulation Program), it may be possible to do this with PhotoShop, but the GIMP can do this quite easily.
I will use the images that were used in the source code walkthrough, as well as some screen shots of the GIMP toolset.
The coverData used was this image:
I applied a canvas on the image but varied the canvas size between the circle and the background. The drop shadow has no canvas applied, only derives it from the background. The background was a gradient from white to black, the image is not a bad one for Steganography, but there are some weaknesses, namely in the gradients.
The message encoded was this great work of post millenium poetry:
Through sheer abandum fly the messages through the knowing into the zip a deep well Obscured objects, onomatophobia an aged amphidiscophoran dove dove down Does buck does I i i the import subject to re reproduce
That is 211 characters long including newlines. Gzipped it is 157 characters, plus 4 characters to 161 characters long taking into account how the plainInfo length is encoded.
msgLen = 161 msgLenInBits = 161 * 8 = 1228 bitsPerPixel = 3 pixelsAffected = 1228 / 3 = 430 imgCols = 64 rows = (430 / 64) = 6.71875
The resulting stegData was this image:
You may wish to download these images and then open them both up in the GIMP.
Selecting the coverTest.png image, duplicate the image (Ctrl-D).
Then select the stegTest.png image and copy it all (Ctrl-C).
Go to the new image created (probably called Untitled-X.0) and select Layer -> New Layer...
A dialog box should open and select new transparent layer.
Select the new image again, and the Layers panel should look like this with the new layer selected.
Now with the stegData image in the clipboard paste the contents into the new layer.
A Floating Selection should have appeared in the Layers panel, right click that and anchor it.
I have labeled the two layers to make things a little clearer, to do that just click on the layer name and type a more descriptive name.
Select the StegData layer in the Layers Panel. Look above in the Layers Panel and you will see a Mode: drop down list, move it from Normal to Difference.
Flatten the image; Image -> Flatten Image. The resulting image should look like this:
Pretty black, but the message pattern is hidden in there.
We need a way to undercover and the gamma correction tool is just the thing, in GIMP it is called Adjust Color Levels. To bring this tool up select the difference image, and Layer -> Colors -> Levels...
The histogram is black, but one can just make out a bit of information to the right of the big black line.
There are three pointers on the Input Levels, slide the middle (grey) one closer to the left (the black side). Then slide the right (white) one close as well. Something should start to appear. OK it when the image becomes clearer.
The pointers should be roughly in these positions.
The image should now look like the below:
Here it is magnified 8 times.
And here is the plainInfo that was encoded magnified 8 times. I adjusted the color levels (gamma) again to make the example even clearer.
Looking back at the calculations before we expect about 6.7 rows of data and it looks like we have that.
Working from the colours is not too hard to do by eye. The table below shows the translation.
| Colour | Name | Hex | Binary |
|---|---|---|---|
| Copyright Poised Solutions Ltd | |||
| Black | #000000 | 000 | |
| Blue | #0000ff | 001 | |
| Lime | #00ff00 | 010 | |
| Cyan | #00ffff | 011 | |
| Red | #ff0000 | 100 | |
| Fuchsia | #ff00ff | 101 | |
| Yellow | #ff00ff | 110 | |
| White | #ffffff | 111 | |
And that is Steganalysis at a basic level.
It is important to realise that keeping the coverData secure, preferably by eradication, is the best way to ensure StegData is not detected. But, even without the coverData analysis can be done to determine the possibility of something being StegData, it is just harder to do.
The minor encryption and obfuscation techniques I used help to keep the data secure a little longer, but it would not take too long for cryptanalysis to break it, so combining strong encryption and Steganography is a wise move.
| Previous page - Source Code | Steganography Home | Next page - Download |