JCT Exam Solution
(Exam Score: 100)
Note: The reversed code could be refactored. But the task was to write the code like the original program was coded.
- Find what is missing which causes the error message and fix it.
- Find an input that will provide a success message.
- Write the program in C.
- CFF Explorer
- Static Analysis with IDA
- Dynamic Analysis with x32/x64 dbg (a.k.a x96dbg)
- C Coding
By opening the executable in CFF Explorer, it is noticeable that the executable has TLS.
Therefore, I suspect the message I am getting is originated from the TLS.
Let’s open IDA to statically analyze the executable and have a closer look at the TLS callback.
It is noticeable that the TLS callback checks if the file C:\temp\test.txt exists.
If it does, the program will not print the error message and halt like it did, but it will print the initial success message and start running the main function.
Therefore, in order to pass this check, I simply created a file named test.txt under C:\temp
Note: The loading of the string “abcd…0123…” to the memory as shown in the TLS callback is a prep for the main function.
By dynamically analyzing the main function of the program, first I understand that the length of the username must be bigger or equal 6.
Second, the password is constructed based on the username and the “abcd…0123…” that we saw in the TLS.
The program loops over the username and calculates the modulo of the division of the char’s ascii value with 0x24 (36 in decimal) which will be the index of where to grab a char from the “abcd…0123…” string.
Therefore, the password will be constructed in a way, that in each iteration, the loop will add to it a new char from the “abcd…0123…” string based on the calculated index (username[i] % 36).
This is the body of the loop that performs this action:
So, let’s give it a try.
I will use the username “Benjamin Mamistvalov”
This is the password that will be generated as explained above:
Username = Benjamin Mamistvalov
Password = 4xzxmnkmincdahpzoor1
In this part I will start by coding the main and after the main is done I will code the functions.
By statically analyzing the program, I understand that the main works as follows:
-
Assigns destIdx with the value 0 and then calls the function inputUsername() to allow the user to input his username.
asm:

C:

-
If the length of the username is less than 6, the program exits.
asm:

C:

-
Else, it loops over the username and generates the password as shown above in Section #2
asm:

C:

-
After the loop, the program assigns the length of the username into a new variable named bufferLength.
asm:

C:

-
Compiler-added check, therefore I will not add it to the code.
asm:

-
Calls the function inputPassword() to allow the user to input his password.
asm:

C:

-
Calls the function checkPassword() in order to check if the user’s password matches the generated password by the program. This function will print a message accordingly.
asm:

C:

No parameters.
No parameters.
- *password1*
- *password2*
- Compares between password1 and password2.
- If they are not equal, the program prints “Wrong\n”.
- Else, the program prints “Ace!\n”.
asm:

C:

- I defined BUFFER_SIZE to be 100
- Destination, Username, GeneratedPassword and UserPassword are global variables because as seen in the assembly, we could access them from everywhere in the code and because they are defined in the memory.
























