Hacking Series Part 15
Category: reverse engineering and forensics
We are given a binary called “mystery” and an image named “encoded.bmp”. When I opened mystery in IDA, I saw that three files were being opened, two that are being read from (flag.txt and original.bmp) and one that is being appended to (encoded.bmp). I renamed the streams that were returned after each
fopen call with the name of the file it referenced.
The next few blocks of assembly dealt with error handling in case these files are not found. If this is the case, the program prints an output message telling you to run mystery on the server. This can be skipped over. The logic of mystery starts at
At this location, it reads a single character from original.bmp, then sets up a counter from 0 to 723 (2D3h). I renamed all the counter variables in this program so that it is easier to understand how everything functions. If the counter is less than 723, a character is read from original.bmp and appended to encoded.bmp.
If the counter goes over 723, 50 characters are read from flag.txt. If there are not 50 characters in the file flag.txt, error handling is preformed. After this, execution jumps to
Another counter is set up, this one goes from 0 to 99 (or repeats 100 times). If the counter is less than or equal to 99, execution jumps to
loc_1331. In this location, an
and operation is being preformed on the counter. If the result of the operation is 0 (all even numbers of the counter), then the character gets encoded with the function
codedChar, then appended to encoded.bmp. This repeats 8 times, since another counter is set up from 0 to 7.
If the result of the operation is 1 (all odd numbers of counter), then a single character from original.bmp is written to encoded.bmp without any encoding. If the counter goes over 99, then the rest of original.bmp is appended to encoded.bmp. That means that we only need to analyze 450 (50*8 + 50) bytes of encoded.bmp to get the flag. This section resides after 723 bytes, which we established previously.
In order to get the important part of encoded.bmp that contains the flag, we need to split the file after every 723 bytes, then only keep the second partition. For this, I used the command
split -b 723 encoded.bmp.
The only file we need is xab, which I renamed to analyze.txt so that we can delete all the other partitions easily. Now we have to figure out how the LSB encoding is applied which is mentioned in the challenge. I found that the first letter of the flag (“p”) was found by taking the LSB of the first 8 binary numbers in analyze.txt, then reversing them. I then found that the next binary number (the 9th one) was irrelevant towards finding any letter in the flag, so it could be discarded.
This pattern repeated itself until all the letters of the flag were encoded. You could follow this pattern manually and determine the flag, but I chose to use a Python script instead.
The script first reads the binary digits of analyze.txt and separates them into a list called
chars. Then, it gets the LSB of 8 binary digits in
chars, skipping over the 9th one. This repeats until the loop goes through every character in
chars. Finally, each digit formed from LSB is reversed and converted into ASCII, then appended onto
When I ran the script, I got the correct flag.