Post

Pass

This is a writeup of the reversing challenge Pass from the TFC CTF

Points: 50

Premise

Can you get the right password?

Challenge files:

pass

Observations

We can start by seeing if we can tell what language the program was written in.

Looking in the tool Detect it easy, we find that the program is written in C/C++

die

This means we can make progress in our investigation by opening the file in IDA.

The program gives us some interesting functions, but we’ll run the decompiler and start at main(), which gives us the following output:

ida main decompile

Observing the program flow, we see the while loop which seems to be an iterator making a check to see if the string we entered into the program matches an expected string from the flag variable and it seems to check character by character.

Additionally, we have the variable in this case labeled v3 which seems to be a counter, and it multiplies with 26 when selecting the character in the flag variable.

If we look at the program we see two functions that are of interest, set_flag() and encrypt(), so we investigate these further.

Looking at the set_flag() function, we see that it sets a very large string to the flag variable and returns '8e3NXAl2' ida set_flag decompile

Looking at the encrypt() function, we see that it performs the encryption seen here:

ida encrypt decompile

Solution

We have the flag string from the set_flag() function: PziP97vkc5sA6oJM0KwWEnQX2OFaH0nAFTuS42myr31GYbJIfBSdAFWsLpx8N0v4PzO7aIVQaHrVq6AW8c1K5ZyFXzMeRAOiJ2nWXYy2Pj7x96RzkcA3inNqlDOBLKZ4rNFYGTn0Cl5U9aX2WIH1cOyIbm2AZ0k31u7FrxBECKPpMhYVUyvA5LfgXcW9eDSMTBlsorR22laXN3e8<qSCmwK0Do9bJzYvd5YgG3dRBhwMvOp2qS08UWQKtLQbphJTXLd2~fktr45ES7OK3x0yNqu1XSC9nA`rGpBvQlbDktjIxLm2KlVYnXw0mpt5aOe8B4grGXFe06gaZv3PYdpS4CDquJnmkR1Mn6sKScF3vV7pdzYfTkBRbqGbzu2wtPHkXsx1pK14ojTfJYIe0PpU1TjDKaW85uZ2mlFHYMSEkBvKo6WIdTnVRewMPk|3pU1SjNErN7s0HYlp9tMqAmBh0dXD4VaK8NZWU1fnrsQaEc5Bht09eHwxDSpWj0ahd5rtIzyKETxUq9CkXC8DAP37Kc1UqOvdb2GT0Yvxuh1grzfdR4JiVpo83QOEWlL2<Bt9Xm7Q5RNkljfOZogB8ctIzyra9wF0RKycTJjvZfDlm6o75QsG`2laXN3e85qSCmwK0Do9bJzYvdZE6, and the encryption method used from the encrypt() function.

The encryption function takes a character, if its a curly brace ({ or }), it returns Z, otherwise it casts the character to its numerical decimal value, adds 7, and XORs it with 0xB.

The good thing is that the encryptor uses XOR, which is a reversible operation.

So, we have a long string, where we need to take every 26th character (and the “0th” character), cast it to its numerical decimal value, XOR it with 0xB (or 11 in decimal form), subtract 7, and recast it into a character.

We can achieve this with a python script that can look something along the lines of the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
encrypted_flag = "PziP97vkc5sA6oJM0KwWEnQX2OFaH0nAFTuS42myr31GYbJIfBSdAFWsLpx8N0v4PzO7aIVQaHrVq6AW8c1K5ZyFXzMeRAOiJ2nWXYy2Pj7x96RzkcA3inNqlDOBLKZ4rNFYGTn0Cl5U9aX2WIH1cOyIbm2AZ0k31u7FrxBECKPpMhYVUyvA5LfgXcW9eDSMTBlsorR22laXN3e8<qSCmwK0Do9bJzYvd5YgG3dRBhwMvOp2qS08UWQKtLQbphJTXLd2~fktr45ES7OK3x0yNqu1XSC9nA`rGpBvQlbDktjIxLm2KlVYnXw0mpt5aOe8B4grGXFe06gaZv3PYdpS4CDquJnmkR1Mn6sKScF3vV7pdzYfTkBRbqGbzu2wtPHkXsx1pK14ojTfJYIe0PpU1TjDKaW85uZ2mlFHYMSEkBvKo6WIdTnVRewMPk|3pU1SjNErN7s0HYlp9tMqAmBh0dXD4VaK8NZWU1fnrsQaEc5Bht09eHwxDSpWj0ahd5rtIzyKETxUq9CkXC8DAP37Kc1UqOvdb2GT0Yvxuh1grzfdR4JiVpo83QOEWlL2<Bt9Xm7Q5RNkljfOZogB8ctIzyra9wF0RKycTJjvZfDlm6o75QsG`2laXN3e85qSCmwK0Do9bJzYvdZE6"

flag_str = ""

for i in range(0, len(encrypted_flag)):
    if(i % 26 == 0):
        decoded = ord(encrypted_flag[i])
        if(decoded == 90):
            flag_str += '{'
        else:
            decoded ^= 11
            decoded -= 7
            flag_str += chr(decoded)
    
print(flag_str)

The output of this script is TFCCTF{f0und_th3_p44sv0rd{

Where we simply swap the direction of our closing brace to get the flag: TFCCTF{f0und_th3_p44sv0rd}

Tools and sources used:

  • IDA
  • python3
This post is licensed under CC BY 4.0 by the author.