Sunday 26 March 2017

KeyPass - VolgaCTF 2017

This was a 100 points re challenge.
The challenge description was as follows:

For reasons unknown an amature cryptographer wrote an application to generate "strong encryption keys". One of these keys was used to encrypt a tar archive with the flag. They used openssl command line util with -aes-128-cbc. Could you please get the flag? It shouldn't take much time...



The file command gives the following output:
~/D/V/keypass 100 ❯❯❯ file flag.zip.enc keypass
flag.zip.enc: data
keypass:      ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=a2bcacc1e853c36e757ec1608a37f79b30315da4, stripped


Now,
What we have to do is decrypt flag.zip.enc using a particular key generated by the program keypass.

So, we have to find the right key.

When I tried running the program, it asked for a command line argument, so I supplied it with a random input, it gave out the following ouput:

~/D/V/keypass 100 ❯❯❯ ./keypass asdf
evMSVbNx7SmvxT#46

Then I loaded the file in IDA and then disassembled it. The main function looks like this.



First of all, it was checking if the number of command line arguments supplied was 2. If it is true then it goes inside the if condition else it exits the program.

If argc==2, the next thing the binary does is calculate the length of the input. After that we can see a while loop. The loop is actually, xor-ing the characters of the input one by one starting from the first character to the last character. The final value is stored in v5.

Then a buffer v24, of size 256 bytes is allocated. After that the value of v7 is calculated as 
v7= 16631*v5*511115. 

We can also see that there is an array arr[ ] . So I checked what is stored at that address using gdb and I got the following string.

gdb-peda$ x/s 0x0400A41
0x400a41: "2FuMlX%3kBJ:.N*epqA0Lh=En/diT1cwyaz$7SH,OoP;rUsWv4g\\Z<tx(8mf>-#I?bDYC+RQ!K5jV69&)G"

So it is character array of size 82.
From the ida disassembly we can see that, the array index is calculated by the mod of 0x7fffffff and 82.
As shown in the disassembly the same thing is repeated again and again. Total 17 times. Therefore the output of the program or our key is calculated in the above manner.

After the xor-ing of the input the value in v5 can vary between 0x0 to 0x7f. So we have a total 0x80 possibilities. One of them is the right key.

So what I did is bruteforce all the possible keys and then try to decrypt the flag.zip.enc using openssl. But make sure that the openssl version is 1.1.0e or higher. The reason for the same can be found in the comments section.

This is the script I wrote for bruteforcing and decrypting the flag.zip.enc file using openssl:


The output that I got after running that script is:
\M)R<.DDe/:;d>JZP

It is the right key to decrypt the flag.zip.enc file.
After running the script, you can see the decrypted flag.zip file in the parent folder.
Simply extract the .zip file. After extracting, you can find flag.txt inside which is the flag.

The flag is :


VolgaCTF{L0ve_a11_trust_@_few_d0_not_reinvent_the_wh33l}



If you have any doubts, feel free to ask in the comments section.

3 comments:

  1. Why would it need to be version 1.1.0e, what difference would it make?

    ReplyDelete
  2. OpenSSL changed default digest for key generation from MD5 to SHA256 in 1.1

    https://github.com/openssl/openssl/commit/f8547f62c212837dbf44fb7e2755e5774a59a57b

    ReplyDelete
  3. Yep....that's the reason...:)

    ReplyDelete