Now that elves have taken over Santa has lost so many letters from kids all over the world. However, there is one kid who managed to locate Santa and sent him a letter. It seems like the XMAS spirit is so strong within this kid. He was so smart that thought of encrypting the letter in case elves captured it. Unfortunately, Santa has no idea about cryptography. Can you help him read the letter?
-
We are given a
challenge.py
file that encrypts a file calledletter.pdf
and stores it toencrypted.bin
. We haveencrypted.bin
so it looks we like just need to write a function to decrypt this file by doing whatchallenge.py
but in reverse. -
The important encryption line is
enc = (a*byte + b) % mod
. The inverse of this isdec = (byte * modinv(a, mod) - b) % mod
, which can be found using modular arithmetic. I don't understand modular arithmetic that well so I'm not going to explain how I solved this. This solution also probably isn't the most efficient, but it does decrypt the file in a matter of seconds, so its fast enough. -
We use a function to compute the modular multiplicative inverse using the extended Euclidean algorithm. More info on this StackOverflow answer.
-
Also, the encryption script uses a
mod
value of 256, determinesa
by selecting an a such that1 <= a < mod
andgcd(a, mod) == 1
, andb
is a random integer such that1 <= b < mod
. We can simply try every combination of these values since there are not that many combinations. However, since decrypting the file takes several seconds, we need a way to determine if a combination is the correct one without decrypting the whole file. This is possible because every PDF starts with the same bytes. These are known as magic bytes. For PDFs, the bytes are25 50 44 46 2D
in hex or%PDF-
in ASCII. So, we will loop through every combination ofa
andb
and decrypt the first 5 bytes of theencrypted.bin
file. If they decrypt to%PDF-
, then we will decrypt the rest of the file and save to toletter.pdf
. -
The flag is found in plain text in the decrypted
letter.pdf
file, which I've included in this repo. Apparently, this is an affine cipher (according to the flag), so there is likely a more basic and straightforward solution than this.
HTB{4ff1n3_c1ph3r_15_51mpl3_m47h5}