Stack Buffer Overflow-02 (tamu19_pwn1)
Last updated
Was this helpful?
Last updated
Was this helpful?
I will be following up on the last writeup and in this one, we will be doing some more stack buffer overflow challenges. In this challenge, we first reverse engineer the binary to realize there are 3 checks that binary does. The 2 checks are just simple string comparisions but for the last one, we have to overflow a variable and make the check pass.
Before proceeding let's run the file
command on the binary, this is done to know more details, (like for what architecture the binary is compiled, etc) about the binary we will be going to exploit
We see it's a 32-bit ELF binary and it is dynamically linked.
Now lets fire off Ghidra and take a look at the decompiled code:
We select the main function from Symbol Tree
pane inside ghidra
You can see the main function is doing a couple of string comparisions on line 21 and 29 and we now know the two strings it is comparing to areSir Lancelot of Camelot
and To seek the Holy Grail.
This will pass the first two checks and after that, there is another check, which is checking local_18 with a hex value.
Now let's do some dynamic analysis using radare2
I have added the two lines Sir Lancelot of Camelot \n
and To seek the Holy Grail.\n
to the stdin.txt
file and after that, I have added a bunch of 'A's at the end of the file to fill the rest of the buffer. Now let's start radare2 with
and we should be inside radare2 CLI
Let's start by looking at all the functions inside the binary with
We see there is a main
function.
and lets disassemble main
function with
Let's put the breakpoint right towards the end of the code, where there is a cmp
instruction (the third comparision). This is the assembly equivalent of the If statement we looked in the Ghidra output. We can put the breakpoint in radare2 with:
Now if we print the disassembly again, we can see a b
right next to the memory address we placed the breakpoint at.
Now we can execute the binary with dc
(debugger continue) and we are presented with the output in r2 window saying hit breakpoint at: 0x566268b2
Let's run the binary with dc and switch to Visual Mode with the command vv
and you should be presented with the following beautiful screen
In the stack you can see our input (a bunch of A's) and looking at the current instruction pointer we can see that var_10h
is being compared with the hex 0xdea110c8
.
Note: In radare2 local variables are referenced with there relative location to the base pointer, i.e., If we have a variable
var_10h
that means its located10h
or (0x10
or decimal16
) away from the base pointer (ebp/rbp)
Now we know that the value ebp - 0x10
is being compared with 0xdea110c8
.
In the stack we can see ebp
being referenced in the comments in the stack view and we can simply look at the exact address that ebp
holds down in the registers pane
We see ebp
holds 0xff99f4e8
, now we want to look at the memory whose address is ebp - 0x10
or 0xff99f4d8
, so we can go to the address 0xffd249d0
in the stack view and look at the 8th column (0xff99f4d8
). This is what the register ebp-0x10
points to.
Currently, that memory just holds a bunch of zeros. So the jne
statement will result in the exit of the program and we will not get the flag.
To make the comparison statement true we just have to fill in the memory address that ebp
points to, with the hex value 0xdea110c8
. And for that, we need to find the offset from the start of our input to the start of ebp
.
We can either do this manually or automate this by creating a cyclic pattern. Obviously, as hackers we choose to automate, right?
We will be using msfvenom's pattern_create module to create the cyclic pattern. Run the following command in another terminal pane
We have the cyclic pattern with us. Let's stick it to the end of our stdin.txt
(replacing A's):
Now let's rerun the binary by first going into the command mode from Visual mode with :
and then we can enter :
Now to go back into visual mode by pressing an enter (with no command) in the command mode and you should be presented with the following view
We can see the stack address has changed (but that's no problem for us right now)
We can see ebp - 0x10
or 0xfff38198
has the hex value 62 34 41 62
or b4Ab
in ASCII. We can confirm that by
Go to command mode with :
Type px @ ebp
and we can see the first four bytes are exactly what we found by just looking at the stack earlier
Now we can calculate the offset with metasploit's pattern_offset
module.
Before we can launch our first exploit we just need to encode the hex value 0xdea110c8
to little endian which is '\xc8\x10\xa1\xde'
Now with the offset known, we can create our final exploit as follows
Offset: 43
Overflow value: \xc8\x10\xa1\xde
This is how our final exploit looks like:
And Boom! we got our flag!
I will not be going through how to set up the stdin and stdout environment that I will be using with radare2, you can follow the steps mentioned and finally, you should be having something similar to this: