2 minutes
Steganography - Recover data hidden with the “Least Significant Bit” algorithm
Taking the Pat1_.bmp file shown above and reading the file in as binary (“rb”). Seeking forward 84 bytes to skip the header information (should be 54 bytes). Using binascii.hexlify, I converted to hexadecimal and then to binary (filling in any missing or leading zeros). Looping through each binary string, I took the last bit of every byte and append that to the LSB_binary string.
import binascii
# from PIL import Image
filename = 'Part_1.bmp'
with open(filename, 'rb') as f:
# seek forward 84 bytes to skip the header
f.seek(84, 1)
content = f.read()
# convert to hex
hex_str = binascii.hexlify(content)
# convert to binary
bin_str = bin(int(hex_str, 16))[2:].zfill(8)
# add in missing leading 0
bin_str = '0000000' + bin_str
# Loop through and take the last bit of each byte and append it together
count = 7
LSB_binary = ""
while count <= len(bin_str):
bin_value = bin_str[count]
LSB_binary = LSB_binary + bin_value
count += 8
When I tried to convert from binary to hex, the length of the LSB_binary string was not a multiple of 8. So I removed the last few bits to allow for the conversion to hex to occur. Doing quick research, the start and end of JPEG I found that “ffd8ff” is the usual starting hex and “ffd9” is the ending hex. Limiting my converted hex string to the start and end index of JPEG, I unhexelify the hex string. Finally, I write a new JPEG file using write binary (wb) to create the final hidden image. As shown below.
print(len(LSB_binary))
# make it a multiple of 8 to convert to hex
LSB_hex_str = hex(int(LSB_binary[:494968], 2))
# find first occurrence of ffd8ff for jpeg file
start_JPEG_Index = LSB_hex_str.find("ffd8ff")
# reverse find to find the last occurrence of ffd9 (as there are other ffd9 that do not complete the image)
end_JPEG_Index = LSB_hex_str.rfind("ffd9")
# Narrow down to the start and the end of the JPEG
LSB_New_JPEG_str = LSB_hex_str[start_JPEG_Index:end_JPEG_Index]
filename_Output = 'part1_hiddenFile.jpeg'
# write file as binary and unhex back
with open(filename_Output, "wb") as f:
f.write(binascii.unhexlify(LSB_New_JPEG_str))