Alright let's move to the second challenge of the pwn CTF
Try to run it first so we know what we up against
hmmm, ok I try to enter something and nothing happen I assume we need to find the correct string to trigger something in the program.
load it to peda and look at the disassembly code. As we can see there is function name "one" and "two" that will print if function one called "This is function one \n" and if function two called "This is function two \n"
the first two mentioned function is not interesting, let just quickly analyze main and move to select_func.
in main function, it clearly indicates that we can overflow the binary since it's using gets function after that our input is passed to the select_func
dump the select_func assembly code and try to type "checksec" to see what kinda protection used in the binary. One that is caught my eyes is the PIE (Position Independent Executable)
ok so take a look at the highlighted function which is "<__x86.get_pc_thunk.bx>" this function is used in PIE that supports ASLR (memory randomization) used to prevent memory corruption
whereas for NX it's explaining that the memory segment used by the application is not executable
as you can see there are two functions from libc that called in this function (strncpy and strcmp) one is to copy a value from variable to variable and the other one is to compare two string.
to get more about this assembly code I load the executable at the Ghidra
notice that if we enter string "one" it will call one function but if we don't put the expected string and the program called the local_10 variable to execute function two.
let's try to input a random string to find out what will happen if we overflow the stack.
notice in the above pic the EAX is changed to 0x80000641 and you may notice that 41 is "A"
and we know that print_func located at
cool! so the EAX and the location of print_flag is almost the same and all we have to do is to change last two bytes into "d8"
but the problem is how we can find in what offset that we need to put the value "d8"
you have two choices to calculate how many offsets you need to have to overwrite the EAX to control the flow of the function
1st choice: using math
take a look at this assembly code:
this equivalent to:
code *local_10;
local_10 = two;
this two line of code tells us to point the address of function two to the [ebp-0xc]
and take a look at another at this assembly code:
this equivalent to:
strncpy(ebp-0x2a,ebp+0x8,0x1f)
ebp+0x8 is our input, ebp-0x2a is the destination with the size of limit to copy is 0x1f(31)
realize that the function two destinations that were moved are (ebp-0xc) is near the destination of copy (ebp-0x2a) of our input since we can overflow the copy (ebp-0x2a) we can control the function two destination
| ebp-0xc| aaaaaaaaaaaaaaaaaaaa
................ aaaaaaaaaaaaaaaaaaaa
.................aaaaaaaaaaaaaaaaaaaa
|ebp-0x2a|aaaaaaaaaaaaaaaaaaaa
to calculate the offset all we have to do is to subtract
0x2a(42) - 0xc(12) = 30
2nd choice: using fuzzing
as you know when we try to figure out how many offsets need to control the EIP is pretty difficult when using pattern exploits. What we need now is to have pattern exploit that every char is distinguished to each other
we can do it using python:
~# import string
~# print string.ascii_letters + string.digits
cool so we got how many offset that we need to overwrite the EAX to control the program execution.
yess we are able to control execution in the program
have a nice day
resources:(Kudos to the one who made the write up)
https://github.com/zst123/tamuctf-2019-writeups/tree/master/Solved/Pwn2
Comments
Post a Comment