# Image steganography/ hidden message inside image

I have the following image

I'm new to solving puzzles and figuring them out, and I have no idea how to approach decryption of this image or how to solve it. I've tried running it on some image decrypting software, but they didn't really find anything. All I have to go off is the fact it's a forensics problem and the hint: you'll know for certain when you've found the flag.

Any help would be very appreciated. Thank you very much!

Edit: for clarification, this picture is found on the Internet. However, this image is bigger than the original image on the Internet. There is something hidden within this or a message. I just can't figure out what it is. THIS particular image has something unique in it that is different from the ones on the Internet.

• This is a JPEG. Are you sure that the original image isn't a PNG file? Sometimes the steganography needs a special bit-layer which is in PNG flies. – Varon Mar 12 '16 at 23:04
• This picture is multiple times in internet. Why you think it has an encrypted message? – Varon Mar 13 '16 at 4:31

The solution wouldn't have been possible without 2012rcampion's contribution.

The most common form of steganography for digital images is embedding a binary message in the least significant bit (LSB) of the pixels. However, in order for the information to survive, you must save it to a lossless format The image in the question is png so that is a good starting point.

A good initial test is checking the LSB of each colour plane, but here I found the alpha channel was modified in a more boldly way. The alpha values for column 128 are locally and serially modified, which implies intend.

Python code:

import matplotlib.pyplot as plt
import numpy as np
from PIL import Image

img = Image.open('nBXonA7.png')
data = np.array(img)

plt.pcolor(data[...,3])
plt.colorbar()
plt.show()


And the result:

Converting the values to ASCII we see the string resembles a base64 encoded stream.

alpha = data[...,3]
secret = alpha[alpha != 255]
stream = ''.join(map(chr, secret))
print(stream)


Which prints

AAAARooqvsPACc+zK/EjP5YzNh0LN+ETNx8yAo3AAY1preECIs4H


Decoding the reverse of this string reveals a gzip compressed stream (header 1f 8b), which when decompressed reveals the flag. All the credits goes to 2012rcampion for this one.

import zlib
print(zlib.decompress(stream[::-1].decode('base64'), 16+zlib.MAX_WBITS))


And the result

image_peek_a_boo


Note that the flag's last character is a newline.

• This looks like something encoded in Base64. – Sleafar Mar 13 '16 at 13:40
• @Sleafar You are most likely right, but I couldn't get anything meaningful out of it. Sad times. – Reti43 Mar 13 '16 at 14:18
• The character set and the significant AAAA in the beginning... I've seen it in ssh-rsa public keys. stackoverflow.com/questions/12749858/rsa-public-key-format. But usually RSA has some more ( B3NzaC1yc2EAAAA ) I'm not sure, but maybe it's a 3DES encryption or something that we can bruteforce – Varon Mar 13 '16 at 21:34
• @Varon It doesn't look likely, but I learnt something new today. :) If it is base64 encoded, we have to decode it anyway, but the hex of that doesn't mean anything to me. It could be a file, but I couldn't identify any particular header. Likewise for the base64 string if I read it as raw bytes. Another thing, the string is 52 bytes long and the decoded result only 39. Neither of these have an appropriate size for a hash, or hash+salt or block size of some cipher that I know of. – Reti43 Mar 19 '16 at 16:46