Skip to content

ben18mk/JCT_RE_Final_2023A

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

JCT Reverse Engineering Final Exam 2023A Solution

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.

Write-Up

Objective

  1. Find what is missing which causes the error message and fix it.
  2. Find an input that will provide a success message.
  3. Write the program in C.

Topics Covered

  • CFF Explorer
  • Static Analysis with IDA
  • Dynamic Analysis with x32/x64 dbg (a.k.a x96dbg)
  • C Coding

1

image

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.

image

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

image

Note: The loading of the string “abcd…0123…” to the memory as shown in the TLS callback is a prep for the main function.

2

By dynamically analyzing the main function of the program, first I understand that the length of the username must be bigger or equal 6.

image

Second, the password is constructed based on the username and the “abcd…0123…” that we saw in the TLS.

How is it done?

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:

image

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:

image

Username = Benjamin Mamistvalov
Password = 4xzxmnkmincdahpzoor1

image

3

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:

Main

  1. Assigns destIdx with the value 0 and then calls the function inputUsername() to allow the user to input his username.
    asm:
    image
    C:
    image

  2. If the length of the username is less than 6, the program exits.
    asm:
    image
    C:
    image

  3. Else, it loops over the username and generates the password as shown above in Section #2
    asm:
    image
    C:
    image

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

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

  6. Add null char to the generated password.
    asm:
    image
    C:
    image

  7. Calls the function inputPassword() to allow the user to input his password.
    asm:
    image
    C:
    image

  8. 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:
    image
    C:
    image

inputUsername()

No parameters.

  1. Prints the string “Enter username\n”.
    asm:
    image
    C:
    image

  2. Inputs the username to Username.
    asm:
    image
    C:
    image

  3. Gets the length of the username without ‘\n’.
    asm:
    image
    C:
    image

  4. Replaces ‘\n’ with null char.
    asm:
    image
    C:
    image

inputPassword()

No parameters.

  1. Prints the string “Enter password\n”.
    asm:
    image
    C:
    image

  2. Inputs the password to UserPassword.
    asm:
    image
    C:
    image

  3. Gets the length of the password without ‘\n’.
    asm:
    image
    C:
    image

  4. Replaces ‘\n’ with null char.
    asm:
    image
    C:
    image

checkPassword()

2 parameters

  • *password1*
  • *password2*
  1. Compares between password1 and password2.
  2. If they are not equal, the program prints “Wrong\n”.
  3. Else, the program prints “Ace!\n”.
    asm:
    image
    C:
    image

Notes

  1. I defined BUFFER_SIZE to be 100
  2. 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.

About

JCT Reverse Engineering Final Exam 2023A

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages