Golang executable for LSB Steganography
CoCa Code and Eng DK30 Fall 2019 0 1
Description
Build an executable in Golang that takes a source file (png, jpeg, gif, bmp) and embeds a secret message using Least Significant Bit(s) insertion, and can then extract the secret message. My work is putting on a Cyber “Capture The Flag” event at a hacker convention in late October and I’m going to contribute some flags to capture! I’m not building this during work hours so I figured I’d put it here for my first DK30 :D
Recent Updates
Tagged a release here with a compiled executable.
Yeah, so work stuff got busy and I sorta stopped around week 3.
Summary: The code I’ve written is able to hide a message in 3 of the 4 image formats I chose. GIF image format has been trouble from the start, but I am still able to hide a small-ish message (~200 chars) inside frame 1 of the animation.
My final goal before the official DK30 closes out is to clean up what I can, and tag a release just in case my project gets featured.
Finally remembered to do an update.
I finished the method that extracts the Secret back out of PNG, JPEG, and BMP files, but not GIF files. It’s frustrating because I don’t exactly know how to define what I’m struggling with.
I think it has something to do with a GIF frame’s Local Color Table. The LCT only supports up to 256 colors, and when reading back the pixels… they’re all the same exact “color”
Note: Literally as I’m typing out what the problem is I think of a possible solution, will update if the solution worked. Possible solution: pre-populate & set the LCT before actually setting pixel values.
Update: The solution idea above actually worked. Determining the colors I’m going to be setting pixels to beforehand and setting those colors as the LCT for that frame allows the pixels to keep their actual value.
Tonight I spent about 4 hours reworking the Embed process to include some metadata about the Secret being embedded. The first chunk of bits being embedded is a JSON key:value store of pre-encoding types, the Secret’s input type, and the Secret’s size. This metadata allows the Extraction process to know how to decode, format for output (.png, .txt, etc.), and when to stop extracting.
I started writing the Extraction process and tested it on a .png file but have not been able to get anything readable yet :(
I’ve updated the Github README with some installation & run instructions. Also after some research, MP4 encoding/decoding is a massive endeavor that simply cannot fit into this DK30. Bummer, maybe for another DK30 I can focus only on that.
Tonight I spent approximately 3 hours writing methods needed for embedding a message into a GIF frame by frame. Once the message to embed runs out I just copy the remaining frames from the source GIF.
It takes several minutes to process, mainly because this first version has 3 nested for loops.
For each frame in GIF For each row (y) in frame For each pixel (x) in row (y) \t // do work
In the future the frame processing should be handled by goroutines (threading)
One more problem, after embedding the message into the GIF in memory, it’s not writing to disk correctly. When I go to check if the output GIF stayed in tact I’m greeted by a 0 byte empty file :(
Edit: This morning before work I discovered some mistakes. I wasn’t handling if the writing to disk returned an error. Once that was in place the error showed that I was using a color Palette that was too large.
Estimated Timeframe
Sep 3rd - Oct 3rd
Week 1 Goal
I’ve already had a bit of a head start setting some things up, I’ve created a repository on Github and pushed up some initial code.
What I’ve got already:
- Pre-encoding the input message to throw people off (options for rot13, base16, base32, base64, or base85)
- Embedding the secret message into a PNG or JPEG file
By the end of the week:
Embedding secret message into a GIF file’s frame dataEmbedding secret message into a BMP file (but I’m fine without it)Clean up the README file and include install & run instructions- Too ambitious
Bonus points: Embedding secret message into an MP4 (oof…) Figure out how to preserve a GIF’s color palette, so after embedding it’s less noticeable that it’s been tampered with.
2019.09.05 - Embedding appears to be working for all 4 intended formats. I won’t know for sure until I start writing the methods that extract messages back out, since it’s pretty hard to tell by just looking at them.
Week 2 Goal
The secret message can now be embedded in PNG, JPEG, GIF, BMP
Next steps:
- Write methods to extract the secret message back out of the embedded image file
- Determine a way of storing which pre-encoding was used, if any, so that during extraction it can decode all the way
Week 3 Goal
- Write unit tests for the first time ever
- Test like crazy
- TBD
Week 4 Goal
Final steps:
- Cleanup and Refactor code where possible
- Compile an executable and tag a release on Github