Want a byte?
Description
Scrolling through my projects, I found some old project code. I remember this code had some "backdoors". But since I mistakenly deleted utils.py, now I cannot understand my own code! Can you help me make sense out of it? You will be rewarded with a flag for your help.
TL;DR
Decompile utils.pyc
Find out that master_key is always 'a'*20
Notice its just encrypting the flag by xoring each character of the flag with 'a's
Xor the encrypted flag with 'a's
Win flag
Solution
Analysis
We have to first decompile utils.pyc to understand the functions that reside in it.
Using decompyle3
, it indicates that the file is coded in Python2.7. This guy really needs to upgrade his Python.
For Python2.7, we can use uncompyle6
. We see that it decompiles it nicely.
Note, some of you might have trouble installing uncompyle6 or decompyle3. I faced similar issues and managed to get it to work. If you need help, just give me a dm on discord :)
utils.py
In main.py I noticed that the code in the derive_key
and generate_random_key
functions are pretty much static.
So printing out derive_key(generate_random_key(40))
would give us the same output everytime, which is 'a'*20.
We can see that it grabs the characters within the brackets of the flag STANDCON22{}
and performs a check against it, where the output would have to be ">\x13R\x17>\x11\x18V\tQ\x0f>\x03\x18\x15R\x02Q\x05R"
What the utils.generate_mask
function does is pretty simple after you try to run it with your own input. You don't really have to reverse engineer the code in the function.
It just returns whatever you feed it before a space.
Though, if you did try to reverse it, you would see that it seems like the function is returning an md5 hash value. So how can it return the string itself? If you look carefully at the naming of the variable assigned to the hash, it is different from the one that the function returns.
mod_inp_
andmod_inp
I fell for this sly trickery as well.
The mask_master_key
function in short, basically just converts each character of the master_key
('a'*20) and the flag (within the brackets) into bits, and performs an xor operation between the two, returning the result.
This is just a simple xor operation, you don't have to split them into bits to perform an xor like that.
Because xor can be reversed if you know what the result is and what the original value got xored with, we can just use the expected output and xor each character with 'a' to retrieve the original value, the flag.
Solve.py
Flag: STANDCON22{_r3v_py7h0n_byt3c0d3}
Last updated