This was the easy reverse challenges for the purpose to give little knowledge of the reverse engineering in C programming. You should have a little bit knowledge about assembly language.
The challenges give us a exe file. We can use Command Prompt to launch the file. If we use double click, something will missing because we cannot make sure there is getch() in the exe. We just type reverse1 to launch the program. In the figure, I just try with "123" and the wrong message is come out.
There are a lot of reverse engineering tools, but this time I choose IDA. We can direct go to main() because the main function is the first function run on C program. First time to see this things will be shock or weird, but the reverse will basically in the assembly code.
In main(), I just divide it into 5 section which is A, B, C, D and E.
A:main() function, we can see there is strcmp() in the function. So, we can have our mind set that the program will make the string compare.
B:If the password is correct, we will run this side due to the jnz short loc_40160 (or jne, jump not equal), if the password is equal to the correct password, we will run on it. Then, another user prompt will come out, scanf will run.
E:If the password is not equal to the that strcmp() that the program expected (simply called wrong password), the program will printf "Password Wrong" and etc. This is what we see when we just type "123".
C:If we get the password correct in B and correct one more time, we can see jnz short loc_4015F in B. If the password correct, we will enter here and call the flag() function (call flag).
D:If we get the password wrong, the program will be here and the messages by printf "Your secret password is wrong" will come out.
Summary:The program start with main() which is A, if the user prompt the first password, the program will run strcmp function. If the password is same with expected characters, B will run with another user prompt, if not E will run which is the error messages. D will run if the user input the wrong password. If the password is correct one more time, C will run and call the flag function.
After we have little understanding about main(). We look at the flag() function.
So how we going to do? Think first! The hint will be strcmp(). Think before move to the next step.
Tadaaa. The answer is strcmp() need two argument which is argument1 and argument2, so the program should has the correct password in memory of the program. The program cannot compare without the value.
We look back to the main()
We just look into B.
We run the program one more time and input two password.
And we got the flag. Here the lesson we learn, if we reverse one program with strcmp, we can look into the variable or memory that it load.
This is a pwning challenge which means we have to completely understand and make some exploitation. But the exploitation is helping us to understand and prevent to use it. Still remember, when I in first year of degree, when I code in C, Dr Malik told us don't use gets() because it is vulnerability. I wonder that time, but now I understand what going on. Let get started:
Firstly, we will get two file, one is binary and source.c which is the source code. Many people would experience cannot open the file as this is the binary file in linux. You may open it in Ubuntu or any others linux operating system.
I open my virtual machine in kali linux. Then, open the terminal and can type "file binary" to check the details of this binary file.
To run the binary, we should give the privelege of execution to the binary file. So, we type "chmod +x binary" to give execution priveleges to the binary. Then, type "./binary" to execute the binary. The terminal is waiting for the input and I just type "123" but it just return nothing here.
From the source.c, we can simply know that the coding is told me about:
But, wait. So, what should we do? We can use the vulnerability in this program, do you remember gets()? Actually, gets have the vulnerability of buffer overflow, the program will have anormally process if there is longer string than the desire input.
So, we may tried input more than 10 characters and see what will happen. Try with 10A and 1B. Let see what will happen?
Tadaaa. We make it, from the source.c, we know that we have overwrite the value of omg. Let look at the theory part:
|input (10)||AAAAAAAAAAA||gets() will put the input it get from here.|
|omg(4)||B||Overflow character will come out here.|
somebody may ask, why omg is 4 character. Because in C 1 character in 1 byte and up to 2^8=256 character (refer ASCII table) and integer in C is 4 byte which is -2^31 to 2^31. So, omg is equivalent with 4 byte.
So how can we input 1000 in omg. We can use python to help us. We can use p32() to convert 1000 to hex in little endian which is what the program store in the memory.
We just use python command to input the value. Here the flag we will got
But how could it happen? Let look at the memory map of program in GDB.
To observe the condition of memory, we can set a break point in cmpl after the gets() and compare the memory mapping.
|input (10)||AAAAAAAAAAA(which is 41414141 in memory map)||fill the input with anything|
|omg(4)||\xd0\x07\x00\x00(which is 2000 in integer)||We change here to overwrite value of omg|
The value of highlight which is the 1000 before overwrite.
The value of highlight which is the 1000 have been set to 2000.
We also can write exploit in python. Here, the source code:
The lesson learn from this exploitation, it is aware to use gets() in C because it has vulnerability of buffer overflow, use scanf(), fscanf() which is more secure.
Hope you guys enjoy this write up and learn something along the challenges. Credit to reminthink.com to host this challenges. I will try my best to cover more write up. Stay tuned.