When dabbling in internet things for career and hobby, you’re destined to stumble upon some intriguing things. One such thing I came across was a Github project that hid secret messages in an emoji. You choose an emoji from a defined set, write a short message, encode the message, and then copy your emoji and paste to a friend.
The magic emoji
Almost like magic, it worked! I could copy and paste the emoji from the app to text messages, and vice-versa. But how could it be possible?
Well, as it turned out, the developer ingeniously used non-printing characters to encode the message. By adding these characters in a decodable pattern after the emoji character, the whole set of characters (emoji + invisible letters) can be copied and pasted from the clipboard, sent to friends, and decoded in just the same way. Of course, when I see something neat, I want to recreate it. I’ve made my own version that can check out here: Emoji Encoder.
I did some deeper diving into this neat feat, and began learning about steganography. Simple put, steganography is the act of hiding data within–or behind–other data, either in the open or out of sight. Security experts use it to protect intellectual property, and hackers use it to hide malware.
Steganography + encryption
Cryptographers often combine steganography with encryption to add an extra layer of diffusion between the goodies and prying eyes.
Cryptographer vs cryptologist
Cryptology is the broader field that includes both cryptography and cryptanalysis. Cryptography is the practice of creating secure communication systems, and cryptanalysis is the practice of breaking codes. In the field, typically a cryptographer designs and implements codes, while a cryptologist studies and analyzes them.
I had been recently working on another custom encryption algorithm, so I thought this could be a perfect opportunity to combine steganography to the cipher. After much tinkering, I’ve come up with Entρy. Pronounced “entropy” (the ρ is the Greek letter rho), my app first compresses your file to save space and add a layer of entropy. Then, it’s encrypted by the industry standard, quantum-resistant AES-256-GCM using your supplied password seeded with randomized data. Next it’s wrapped in my second custom encryption layer, topped with a tamper-proof HMAC seal. The encrypted filename and data is appended to a valid PNG image file. Finally, a 640-bit key file and your encrypted file-containing PNG are produced for you to download.
The highly encrypted outer custom algorithm will be uncrackable and undetectable by modern software (because it’s custom), requiring manual intervention, hours of work, and the likelihood it still can’t be cracked. Even if it is, the inner AES layer will remain an impenetrable vault. You can display your stego image on a public webpage, but without the key file and password, the hidden file will remain secret. You can read more about Entρy here: How It Works.
Barcode and pixel matrices
I couldn’t help but think about the beloved QR code when it came to steganography. What if we could hide data in plain sight, within one of the most popular encoding formats in the world? What I arrived at is QR Steganography. It does what the name implies, and allows you to hide a message within a (URL-containing) QR barcode. The QR code will still scan and work like normal, but the blue channel’s LSB has been changed to add some nearly-invisible extra data to the image.
What is LSB steganography?
LSB steganography is a technique for hiding secret data inside digital files (like images, or audio) by subtly altering the least significant bits of the file’s data, so the changes are invisible to the human eye (or ear).
In binary numbers, the LSB is the “smallest” bit: The one that changes the value the least.
Example:
Binary 10110010 = 178
Changing the last bit → 10110011 = 179
The difference is tiny and often imperceptible in media files.
Digital images are made of pixels, each pixel represented by numbers (like RGB values from 0–255).
By replacing the last bit of each pixel’s value with bits from a secret message, you can embed data without noticeably altering the image.
I’ll admit that I haven’t incorporated a camera function (yet) nor have I tested the secret message decoding via a smartphone camera.
Next up, I thought about storing binary data in images for sake of data compression. A QR code can only hold about 3KB of data, which isn’t much. What if we used pixel-sized blocks, taking advantage of several colors? As it turns out, some data can be compressed into smaller files via PNGs, mainly text (like JSON) files. Which makes sense, since PNGs are highly compressed themselves. However, generally speaking, other files will remain about the same size or slightly larger. For the purpose of compression, I found it impractical.
I couldn’t determine a really great purpose for this app. The pixel density is too high to be scanned like a QR, and would by threatened by printer smears or low DPI. It’s also not technically steganography. Nonetheless, you can find my file-to-PNG app here: PixelGrid Data Container (PDC).
Webpages
“What else can we hide data in?” I pondered. How about within HTML webpages, or their CSS? Well, of course! My unique web app Palimpsest does just that. Encode your secret within an inconspicuous webpage via HTML or CSS. You can choose between encoding your message within HTML attributes, CSS classes, text spacing, or HTML comments. Take note that neither PDC not Palimpsest are cryptographically secure (even with a password), so don’t use it to hide government secrets or anything.
Manipulation POCs
Adding an extra layer of safety to file sharing is a positive addendum. But, I was also curious about what ways a malicious actor could use steganography for malice. The most common way I was aware was malware, often hidden within WordPress-infected sites, and encoded as base64. But I wanted to dig a little deeper.
The most common way for malware to activate is by the user opening an executable file. Half of the battle for the perpetrator is to get the malicious file on to the victim’s computer. All modern web browsers employ several safety features to prevent just this thing. For example, a file download prompt requires user interaction. But this can easily be manipulated.
Fake cookie banners & no-click interactions
Cookie banners are super common on websites. By clicking Agree (or disagree) you could potentially be initiating an incoming file transfer. The first POC I created was a cookie banner as a download link. Speaking of user interaction, it doesn’t take much. In fact, it doesn’t require a click. A mouseover event can also trigger a download prompt, and is easy to hide on a page, leading to my second POC.
Base64 encoded images
Did you know that an image on a webpage doesn’t require an external image file? You can simply use a base64 encoded string as an image source. One HTML file to incorporate an image that contains an executable file payload, as seen in my third POC. Clicking the image will prompt a download for “image_file.png.exe” (it’s actually PuTTy).
Fake context
A web browser does not allow manipulation of the menu options in the right-click context menu on a webpage. For example, you can not customize the “Save image as…” function, because this could be malicious. However, there is a way around this: Web browsers allow disabling the right-click menu, and JavaScript allows a custom right-click menu. So, if you just mimic the web browser’s native context menu, you have something dangerous, as seen in my fourth POC.
Finally, the save dialog allows setting a predefined “Save as type”, for example a Text file (.txt). This may give confidence to the user that they are downloading the proper filetype. However, if the file extension is also specified, then the selected Save as type is completely ignored. Check out the fifth POC here.
I’ve created a POC site to house these gadgets, as well as future experiments, which you can explore here.
AI steganography
On the topic of steganography, we wouldn’t be complete without touching on AI. In the world of LLMs, there are still several “prompt injections” in the wild; Some are still working, many others are continuously getting patched. A unique stenographical approach is to use invisible characters to hide text within prompts., also known as ASCII smuggling The payload could be sent as a MMS, for example, or even a calendar invite. To showcase this approach, I have created PUA Smuggler. It works by offsetting characters into an old (not modernly used), invisible character array called the Private Use Area (PUA). Invisible to the screen, it can be read by LLMs such as Google’s Gemini, and X’s Grok.
Conclusion
Thank you for reading and following along! hope that you had as much fun as I did learning about and exploring steganography. If you’re interested to learn a whole lot more on the subject of steganography, here are some great free online resources:
- Stanford University Online Cryptography Course, with instructor Dan Boneh
- Network Steganography and Network Information Hiding, with instructor Prof. Dr. Steffen Wendzel
- Steganography – A list of useful tools and resources
- The EXO Guide to Steganography