I participated in VolgaCTF under the team Shell Smash. We finished in 138th place with 600 points. Here are the write-ups for the problems that I did.
VC (50 points)
This was a pretty standard image analysis problem. We are given two images that are relatively similar, except for a couple of bytes. If we just xor the two images together, the flag appears in plain sight.
PyCrypto (100 points)
We are given a Python file with an encrypt
function. It’s using an encryption function from the pycryptography.so
library that was also given. By analyzing
the so, it looks like the encryption algorithm is simply an xor with the key, and if the key is shorter
than the message, then just repeat the key. This algorithm is known as a vigenère cipher, or repeating-key
xor cipher. Fortunately, I had some old code to crack this type of cipher exactly from cryptopals.
Angry Guessing Game (200 points)
The first step was to open this binary in IDA. It’s easy to get lost, because there are so many functions, so the first thing I did was hit Shift+F12 and look at the strings. The one I was looking for, in particular, was “You’ve entered the correct license key!” If I found where this was called during execution, I could trace it back to the actual place where it performs the check.
Here you can see I’ve found that sub_5F70 contains the code that checks whether you’ve already played 3 times, and tells the program to start asking for a license key. Should it ask for a license key, it will redirect the execution to sub_6660, where it actually prompts the user.
I’m going to start from the bottom of sub_6660, trying to follow what it’s returning, because ultimately the result of this function is either going to be true/false — whether it accepts your license key. Poking around, I found this call to an interesting function: sub_67D0. Seems like it’s literally just checking your license key character by character.
I wonder what happens if you just convert all of those values to ASCII?
Looks like our license key is the flag!
KeyPass (100 points)
I didn’t actually finish this one during the competition time, because I was being really stupid and not reading their hint. In this challenge, they handed out an encrypted flag and a program that “generates secure encryption keys.”
Picking apart the binary, it looks like what the program is doing is just generating a seed out of the passphrase that you give to it, by xor’ing every character of your passphrase together. This was then used in an LCG to get “random” bytes out of a dictionary of 82 bytes.
The problem with this method is, there a total of about 128 values for this “seed,” because ASCII values range from 0 to 128, and since higher bits are not involved, xor will never go out of that range either. So to solve the problem, you simply generate all of the keys for seeds from 0 to 128. I’ve reimplemented the key generation in Python here:
So why couldn’t I finish it?
Because when I was actually checking the key with openssl aes-128-cbc -d -in flag.zip.enc -out flag.zip -pass env:PASSWORD
,
I wasn’t using the version of OpenSSL that they specified, version 1.1.0e. Lesson learned, I guess.