Narnia 6 - OverTheWire
That other type of BufferOverflow ;)
Narnia 6 - OverTheWire
Introduction
This level is all about overflowing into a local variable, specifically to a local function
pointer variable. When you run the program without any argument it will exit asking for
2 arguments. These two arguments are mapped or copied to the two local variables on the stack, namely b1
, and b2
.
They are copied using strcpy
which we know is not a safe way of copying from user inputs.
|
|
The first that may confuse you when you look at this code may be on line 18, the:
|
|
This is the line where the function pointer is being declared, and assigned the address of
the puts
function, and letter called with one of our input. The signature of the puts
:
|
|
And if you try to compare this with the int(*fp)(char *)
part of the previous code you will
see the resemblance. Take a note of this we will be using this in our exploit.
The next part that seems to peculiar is the following:
|
|
The __asm__
function is used to include native Assembly code directly into C source code.
The get_sp
function is anding what ever is on the stack with 0xff000000
, but I don’t
know why I will update this post when I figure it out. I’m really Sorry for the inconvenience.
Examining
Moving on, If you try to get control of the eip
register you can but that is no use because:
- The environment variables are all being zeroed out.
- The argument variables other than the first three are being zeroed out.
- The two buffers we have are only 8 bytes long, which can not hold the shellcode without overwriting other important memory.
If you look closely though, you can see that we can overwrite the function pointer, fp
,
that points to the puts
function. This is very convenient because the function is being called
later, it is being called with one of our inputs, and we can overwrite it with any function
we want. A good function that has the same signature with the puts
that can be used to
spawn a shell is the system
function.
|
|
If somehow we make the program execute this function with the "/bin/sh"
string we are done.
Let’s look at how we can do that. First lets look at some assembly code. This the disassembly of the main function.
The blue highlighted part is where the program loads the address of puts which is 0x8048430
to the fb
function pointer. You can check this by typing x/x 0x8048430
on the gdb
prompt
Now let’s examine the stack after our inputs have loaded. For visibility I will load
4 A
s in the first argument and 4 B
s in the second argument. But first I will set a break
point after the copy of both arguments is done.
The red highlighted part is the b1
variable, and the blue highlighted part is b2
variable.
Down bellow don’t forget that fp
is being called with b1
. And note that b1
is written
first.
Exploiting
Which means to exploit this we can first overwrite what’s on the fp
with the address of
the system
function using the b1
buffer, and then overwrite the b1
buffer to include
the /bin/sh
string using b2
buffer. To get the address of the system function you just
have to type print system
in gdb, you have to run the program first.
After acquiring the address of system
all you have to do is plug it in and you are done.
./narnia6 aaaaaaaa$(echo -en "\x50\xc8\xe4\xf7") 'bbbbbbbb/bin/sh'
Thank you for reading :)