The program is now also able to embed the payload file into random bytes of the image. New functionality:
lsb.py hideRandom <imgFile> <payloadFile> <password> <bitSelectionLimit>
lsb.py extractRandom <stegoFile> <outputFile> <password> <bitSelectionLimit>
Instead of saving the payload bits linearly into the image, a PRNG is initialized with the password passed as the seed, and it is used to select the image bytes that should be used to hide the payload. The specific bit of the byte that will be used to hide information is also randomly selected from the least significant bit (index 0) to bitSelectionLimit (included).
Usage example:
lsb.py hideRandom images/orig.png images/test.txt pass 2
This hides images/test.txt in images/orig.png using 'pass' as the encryption password to encrypt images/test.txt (and as the PRNG seed), and can use randomly the bit number 0, 1 o 2 of each byte of the image to store info.
How to use:
$ python lsb.py
LSB steganograhy. Hide files within least significant bits of images.
Usage:
lsb.py hide <img_file> <payload_file> <password>
lsb.py hideRandom <imgFile> <payloadFile> <password> <bitSelectionLimit>
lsb.py extract <stego_file> <out_file> <password>
lsb.py extractRandom <stegoFile> <outputFile> <password> <bitSelectionLimit>
lsb.py analyse <stego_file>
<bitSelectionLimit>: the program will randomly use one bit of each byte to store
the payload info, but only up to the <bitSelectionLimit> bit.
Possible values are: 0, 1, ... , 7.
Platform independent Python tool to implement LSB image steganography and a basic detection technique. Features:
- Encrypt data before insertion.
- Embed within LSBs.
- Extract hidden data.
- Basic analysis of images to detect LSB steganography.
How to use:
$ python lsb.py
LSB steganogprahy. Hide files within least significant bits of images.
Usage:
lsb.py hide <img_file> <payload_file> <password>
lsb.py extract <stego_file> <out_file> <password>
lsb.py analyse <stego_file>
All data is encrypted before being embedded into a picture. Encryption is not optional. Two consequences of this are that:
- The payload will be slightly larger.
- The encrypted payload will have a high entropy and will be similar to random data. This is why the frequency of 0s and 1s in the LSB position should be the same – 0.5. In many cases, real images don’t have this propriety and we’ll be able to distinguish unaltered images from the ones with embedded data. More below.
Encrypt and hide an archive:
$ python lsb.py hide samples/orig.jpg samples/secret.zip p@$5w0rD
[*] Input image size: 640x425 pixels.
[*] Usable payload size: 99.61 KB.
[+] Payload size: 74.636 KB
[+] Encrypted payload size: 74.676 KB
[+] samples/secret.zip embedded successfully!
Original image:
Image with 75k archive embedded:
$ python lsb.py extract samples/orig.jpg-stego.png out p@$5w0rD
[+] Image size: 640x425 pixels.
[+] Written extracted data to out.
$ file out
out: Zip archive data, at least v1.0 to extract
A simple way to detect tampering with least significant bits of images is based on the observation above – regions within tampered images will have the average of LSBs around 0.5, because the LSBs contain encrypted data, which is similar in structure with random data. So in order to analyse an image, we split it into blocks, and for each block calculate the average of LSBs. To analyse a file, we use the following syntax:
$ python lsb.py analyse <stego_file>
Example
Now let’s analyse the original:
$ python lsb.py analyse castle.jpg
… and now the one containing our payload:
$ python lsb.py analyse castle.jpg-stego.png
- It is entirely possible to have images with the mean of LSBs already very close to 0.5. In this case, this method will produce false positives.
- More elaborate theoretical methods also exist, mostly based on statistics. However, false positives and false negatives cannot be completely eliminated.