[Written on January 3rd 2004 - Updated January 24th 2004]

Breaking a steganography software (without even downloading it) :

Steganography 1.50 and 1.60


Steganography strength (is it easy to see there is hidden data?): Low
Cryptography strength (is it easy to recover the hidden data?): Low


A company called Pipisoft (which is a very funny name from a french-speaking perspective, because it means "peesoft") sells a steganography software called Steganography for 25 US$. This software seems to be part of a suite of security sharewares called SecureKit.

I didn't have to download, install or execute this software to crack its steganography scheme.

One week after I sent them an email to tell them about the page I wrote about the version 1.50 of their software, they suddenly updated to a new version 1.60. Great. These are reactive programmers. And that's one of the reasons I present these results: so people can increase the security level of their products. Unfortunately, the new version is as weak as the precedent one. The concept is exactly the same. I've written a new paragraph about it, see below. If you want to understand how this program works, you still have to read the first paragraph.



1. Steganography version 1.50

     1.1. How does it work?

They actually offer an online demo with an example of a JPG image carrier ("result.jpg") hiding another JPG image inside. So I just downloaded this demo image, and opened it with an hexadecimal editor.

Than I searched for the EOI (End Of Image) marker of the JPEG format, which is supposed to be at the end of the image data stream: two bytes "FF D9". It was not at the end, a clear sign that something was fused after the normal end of the image. Around the EOI, I saw this:

00004A80 34 BA 2C BC F0 4C 42 78 40 3E 5C 55 5B DF F1 37 4,+_LBx@>\U[_7 00004A90 F3 AB 6F FF 00 6E 7E B5 45 38 87 FF D9 50 4B 03 _o_.n~E8_+PK. 00004AA0 04 14 00 02 00 08 00 6A 4C 78 2F C1 66 CC 56 FE ......jLx/-fV_ 00004AB0 5D 00 00 81 63 00 00 0C 00 11 00 6A 65 6E 6E 69 ]..c......jenni 00004AC0 66 65 72 2E 6A 70 67 55 54 0D 00 07 58 60 C1 3F fer.jpgUT...X`-? 00004AD0 00 AF C5 3F 7D 3E C6 3F ED BB 65 54 5C 4D B7 2E .+?}>?_+eT\M+.

In white, the end of the JPG carrier image, with the EOI marker underlined. In yellow, "hidden" bytes.

No need to check further. The "PK" marker said everything. We understand how it works. The "hidden" JPG file (called "jennifer.jpg") is actually compressed in a ZIP file, and concatenated at the end of the image carrier. That's probably why they say in their website that this software uses "advanced compression" (which is indeed true).

Same strategy than the precedent software I analyzed, SQFileHide. And same level of security: the hidden data is *very* visible.

     1.2. More fun

I finally downloaded and installed an evaluation copy of the software, because I wanted to check this claim on the website "It uses 256 bits encryption". I was curious about which algorithm they were using. Blowfish? AES? TwoFish? TripleDES?

They actually don't use any encryption. They probably think they do, but the fact is that the hidden data is not encrypted and can be extracted without any particular tool, even when you set a password.

Here are three examples of a text file called "hiddenmessage.txt" added after a small JPG of mine. We now know that it will be included in a compressed ZIP file and concatenated at the end of the carrier.

Here is first the file added without password, as seen on a typical hexadecimal editor. The offset is on the extreme left (this is the position of the bytes in the file), the hexadecimal bytes are in the middle (the value of each byte, shown in hexadecimal form), and the ASCII translation of these bytes are on the right (how these bytes would look when seen with a text editor).

The end of the JPG file is in white, with the End Of Image marker underlined. The "hidden" text, in a perfectly valid ZIP container, is in yellow. You can see the "PK" markers and the name of the file inside the ZIP. Then there are a few bytes added by the steganography program, starting with a "HIZ" marker, in red. I've underlined a funny looking string of 16 bytes in this red section.

00000090 00 00 00 FF DA 00 08 01 01 00 00 3F 00 AA 60 3F ..._+......?.`? 000000A0 FF D9 50 4B 03 04 14 00 02 00 08 00 9C 41 23 30 _+PK.......A#0 000000B0 05 0B 24 E1 0A 00 00 00 0B 00 00 00 11 00 11 00 ..$............ 000000C0 68 69 64 64 65 6E 6D 65 73 73 61 67 65 2E 74 78 hiddenmessage.tx 000000D0 74 55 54 0D 00 07 D8 BF F6 3F A0 92 F6 3F D6 BF tUT...++??++ 000000E0 F6 3F 2B C8 CF C9 CF 55 28 00 91 00 50 4B 01 02 ?++-+-U(..PK.. 000000F0 17 0B 14 00 02 00 08 00 9C 41 23 30 05 0B 24 E1 .......A#0..$ 00000100 0A 00 00 00 0B 00 00 00 11 00 09 00 00 00 00 00 ................ 00000110 00 00 20 00 80 81 00 00 00 00 68 69 64 64 65 6E .. .....hidden 00000120 6D 65 73 73 61 67 65 2E 74 78 74 55 54 05 00 07 message.txtUT... 00000130 D8 BF F6 3F 50 4B 05 06 00 00 00 00 01 00 01 00 ++?PK.......... 00000140 48 00 00 00 4A 00 00 00 00 00 48 49 5A 00 A8 00 H...J.....HIZ.. 00000150 00 00 64 34 31 64 38 63 64 39 38 66 30 30 62 32 ..d41d8cd98f00b2 00000160 30 34 00 00 03 00 04....

Here is the file added with password "a". You can see that the hidden data, in yellow, is exactly the same. Which means that there is no encryption. The red underlined part is actually the only one that changes when you add a password.

00000090 00 00 00 FF DA 00 08 01 01 00 00 3F 00 AA 60 3F ..._+......?.`? 000000A0 FF D9 50 4B 03 04 14 00 02 00 08 00 9C 41 23 30 _+PK.......A#0 000000B0 05 0B 24 E1 0A 00 00 00 0B 00 00 00 11 00 11 00 ..$............ 000000C0 68 69 64 64 65 6E 6D 65 73 73 61 67 65 2E 74 78 hiddenmessage.tx 000000D0 74 55 54 0D 00 07 D8 BF F6 3F A0 92 F6 3F D6 BF tUT...++??++ 000000E0 F6 3F 2B C8 CF C9 CF 55 28 00 91 00 50 4B 01 02 ?++-+-U(..PK.. 000000F0 17 0B 14 00 02 00 08 00 9C 41 23 30 05 0B 24 E1 .......A#0..$ 00000100 0A 00 00 00 0B 00 00 00 11 00 09 00 00 00 00 00 ................ 00000110 00 00 20 00 80 81 00 00 00 00 68 69 64 64 65 6E .. .....hidden 00000120 6D 65 73 73 61 67 65 2E 74 78 74 55 54 05 00 07 message.txtUT... 00000130 D8 BF F6 3F 50 4B 05 06 00 00 00 00 01 00 01 00 ++?PK.......... 00000140 48 00 00 00 4A 00 00 00 00 00 48 49 5A 00 A8 00 H...J.....HIZ.. 00000150 00 00 30 63 63 31 37 35 62 39 63 30 66 31 62 36 ..0cc175b9c0f1b6 00000160 61 38 00 00 03 00 a8....

Here is the file added with password "b". Once again, nothing changes, except the red underlined part.

00000090 00 00 00 FF DA 00 08 01 01 00 00 3F 00 AA 60 3F ..._+......?.`? 000000A0 FF D9 50 4B 03 04 14 00 02 00 08 00 9C 41 23 30 _+PK.......A#0 000000B0 05 0B 24 E1 0A 00 00 00 0B 00 00 00 11 00 11 00 ..$............ 000000C0 68 69 64 64 65 6E 6D 65 73 73 61 67 65 2E 74 78 hiddenmessage.tx 000000D0 74 55 54 0D 00 07 D8 BF F6 3F A0 92 F6 3F D6 BF tUT...++??++ 000000E0 F6 3F 2B C8 CF C9 CF 55 28 00 91 00 50 4B 01 02 ?++-+-U(..PK.. 000000F0 17 0B 14 00 02 00 08 00 9C 41 23 30 05 0B 24 E1 .......A#0..$ 00000100 0A 00 00 00 0B 00 00 00 11 00 09 00 00 00 00 00 ................ 00000110 00 00 20 00 80 81 00 00 00 00 68 69 64 64 65 6E .. .....hidden 00000120 6D 65 73 73 61 67 65 2E 74 78 74 55 54 05 00 07 message.txtUT... 00000130 D8 BF F6 3F 50 4B 05 06 00 00 00 00 01 00 01 00 ++?PK.......... 00000140 48 00 00 00 4A 00 00 00 00 00 48 49 5A 00 A8 00 H...J.....HIZ.. 00000150 00 00 39 32 65 62 35 66 66 65 65 36 61 65 32 66 ..92eb5ffee6ae2f 00000160 65 63 00 00 03 00 ec....

So why this red underlined part, the only one that changes when you set up a password, is funny looking? When your eyes are used to look at hexadecimal data, you can see that the ASCII translation of these bytes (on the right) looks like hexadecimal values (number from 0 to 9, and letters from A to F). In other words, it looks like these bytes are stored in a strange format, which actually takes twice the space, because one byte is stored as 2 bytes (for example, a byte value of 255, which is "FF" in hexadecimal, would be stored as the 2 bytes "102 102" or "66 66" in hexa, which is the ASCII representation of "FF"). Weird.

Anyway. My guess was these bytes would be some kind of hash of the password. I was right. You can check with some free utility like HashCalc that it's actually a MD5 hash:

128 bits (16 bytes) MD5 hash of string "" is "d41d8cd98f00b204e9800998ecf8427e"

128 bits (16 bytes) MD5 hash of string "a" is "0cc175b9c0f1b6a831c399e269772661"

128 bits (16 bytes) MD5 hash of string "b" is "92eb5ffee6ae2fec3ad71c777531578f"

You can compare with the red underlined values above. Another surprise is that the programmers of this steganography software take some freedom with the MD5 hash: they just store half of the MD5 bytes! That's probably the weirdest thing in this already strange software. La cerise sur le gateau, as we say in France.

And it's the demonstration number 783265832 (and counting) that if you use secure algorithms in a wrong way, you don't add any security. Here we have the typical demonstration: MD5 hash is a secure enough cryptographic algorithm, but the way it is implemented in this software is completely and totally and absolutely useless.

     1.3. So how do you extract "hidden" and "encrypted" data?

Two possibilities:

- calculate the MD5 hash of the password of your choice and overwrite the current password hash bytes (at the red underlined position in the exemple above). Then you can extract the data with Steganography 1.50 software.

- don't bother and just copy-paste the ZIP file bytes (the yellow ones in the exemple above), and open the file with Winzip.



2. Steganography version 1.60

     2.1. What's the difference with the precedent version?

Conceptually, there is no difference at all. They just added a quick obfuscation layer to hide the obvious use of a ZIP file format, and to outdate my precedent analysis. So the hexadecimal dumps in the precedent paragraph cannot be read literally anymore, and we cannot anymore copy/paste the "hidden" bytes and read them directly with Winzip. But strip out this small layer, and it's still the same. A quick obscurity trick does not enhance the security level. Let's have a look.

     2.2. Show me a new hexa dump!

Here is a new small text hidden at the end of another JPG, using the password "a". Color coding is the same than above. We can see that the ZIP file is now somehow encrypted. No structure is visible. But the final red data starting with "HIZ" is still here. And the 16 funny looking bytes are still here too, although a little bit different.

00000290 08 09 42 00 4A 52 30 00 D8 01 A0 3F FF D9 9E 97 ..B.JR0...?.. 000002A0 BA 2A 00 80 88 C9 A3 70 97 5B A2 E4 99 B8 C1 78 *...ɣp.[.x 000002B0 72 0F 88 DD DC 34 2B 4E 7D 31 7F B5 E8 70 39 A8 r..4+N}1.p9 000002C0 B8 42 75 68 71 91 03 5F A4 A4 E0 EA 43 9F AA 8E Buhq._C.. 000002D0 04 99 FA A5 EC 63 9F 23 79 7E 5D 91 33 43 3B C3 ..c.#y~]3C; 000002E0 C1 C4 21 5F 71 5F DF C5 D9 1C C5 DE 83 6C 4D EC !_q_..lM 000002F0 D5 DC 45 A9 D7 C7 09 EE 15 21 53 28 0E 56 4A A9 E..!S(.VJ 00000300 22 71 C1 03 3E D5 F0 EE 68 F5 4F DC 08 01 F3 61 "q.>hO..a 00000310 34 41 E7 10 89 75 89 30 C0 49 7A CF C6 CB 11 B4 4A..u.0Iz. 00000320 F1 10 19 93 83 27 E2 8B 49 26 33 F3 76 8E A4 11 ....'.I&3v.. 00000330 D2 7D A6 17 96 F9 11 58 02 E2 4C A3 B5 32 33 32 }...X.L232 00000340 21 B1 1A A6 D9 FD 23 45 1F 87 13 3F 45 34 E0 8C !.#E...?E4. 00000350 F1 E5 0D 35 A9 5C EB DD F3 EC 32 5F DE 38 93 86 .5\2_8.. 00000360 8A D7 F8 5D EB B9 FC 1C E0 68 D7 C2 91 68 B1 DC .].h‘h 00000370 44 6C E2 DC 27 E1 A3 5B 71 29 8B 78 E5 04 D5 6E Dl'[q).x.n 00000380 81 CF 34 BF 1F 5B E8 55 B1 C2 7F F3 62 F0 48 49 .4.[U.bHI 00000390 5A 00 F0 00 00 00 38 6B 6B 39 3F 3D 6A 31 6B 38 Z....8kk9?=j1k8 000003A0 6E 39 6A 3E 69 30 00 00 03 00 n9j>i0....

For some reason I'm not showing here, I suspect the obfuscation of the ZIP file is very weak. But it's not really worth spending the minutes to break it. Why? Because you don't need it to recover the "hidden" data.

Let's look more into the 16 red underlined bytes. We remember that in version 1.50 of this software, it was half of the MD5 of the password. For password "a", we had:

v1.50:  30 63 63 31 37 35 62 39 63 30 66 31 62 36 61 38     0cc175b9c0f1b6a8

And now, with the same password "a", we have:

v1.60:  38 6B 6B 39 3F 3D 6A 31 6B 38 6E 39 6A 3E 69 30     8kk9?=j1k8n9j>i0

When there was no password, the bytes were, with v1.50:

v1.50:  64 34 31 64 38 63 64 39 38 66 30 30 62 32 30 34     d41d8cd98f00b204

And now, with the version 1.60, we have:

v1.60:  6C 3C 39 6C 30 6B 6C 31 30 6E 38 38 6A 3A 38 3C     l<9l0kl10n88j:8<

So it looks like they obfuscate this data by just adding 8 to every byte. Wow. Powerful encryption method. Don't forget that this field is what the program uses to verify the password you enter is correct. The hidden data itself is not encrypted depending on the password. So now we can use whatever password we want to fool the program, or just remove it.

So the first method to extract the data is still valid. Calculate the MD5 of your favorite password, just get the first half, add 8 to each byte of the ASCII representation of the hexadecimal value, and overwrite them in the HIZ structure at the end of the camouflaged file.

Or, simpler, just write the bytes 6C3C396C306B6C31306E38386A3A383C into this field and you can extract any data you want without entering a password.

     2.2. Temporary files typical error

Just a note about another security hole in this program. Well, I'm not sure it can be called a hole, as the program has no security at all already.

A lot of programs use temporary files while they are working. They calculate something, and to avoid using memory, or for some reason it's more convenient, they create a new file on the hard drive and write some content in it. Then, after some time, they delete it and go ahead with their tasks.

Serious encryption programs generally avoid to do that, especially writing temporary files with passwords or data before encryption, because it can be a security hole. You know that deleted files are not really deleted. They disappear from the directory list, but their content is still here on the hard drive, and depending on the amount of free space you have, it may stay there for a while. So you think that your porn files are safely encrypted and hidden, but actually, because of this security hole, they are all around your hard drive, very easy to find with any kind of undelete program or hard disk sector viewer.

The good security programs, when they really have to write temporary files, after using them, wipe their temporary files by overwriting them several times with some kind of pattern, so the old data totally disappears from the magnetic support.

The bad security programs copy and spread your secret data all over the hard drive in temporary files, and attackers can read and enjoy them whenever they want. That's what is happening with Steganography.

You can check it easily by looking in the windows\temp folder while you are using this program. Here is what you have in this folder when you hide a file, just before you save the final file:

These are 1. a temporary file which is the obfuscated ZIP, 2. the ZIP file which contains your secret data before it's fused at the end of the image, and 3. the image carrier.

Here is what you have when you unhide a file:

In both case, unknown to you, your secret data is duplicated all over the place, in a zip or in plain form. When the program delete these files, their content is still here. Someone using the computer after you can get it easily by using some kind of undelete program.



3. The conclusion

The conclusion is simple. It's actually a a question I'm asking myself. I don't know anything about cooking, so I'm not going to publish recipe books. I don't know anything about astrophysics, so I'm not going to publish a scientific paper about black holes. So why people who obviously have no idea about computer security suddenly decide to write security software?

I thought that the only interesting thing in this software was its nice graphical interface. But after all, it's not that original:

Screenshot of their interface:

Screenshot of the website GUIStuff:





Have a nice day!




     Guillermito, January 24th 2004





[Back]