Skip to main content
1 of 2
ramon
  • 121
  • 5

Buffer overflow stops executing shellcode in the middle of it

I am trying to execute a simple shellcode by using a buffer overflow. The shell code starts executing but stops in the middle (even though it is fully copied to memory).

This is the vulnerabile C code:

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

void foo(char *c) {
    char buf[80];
    strcpy(buf, c);
}

int main(int argc, char *argv[]){
    foo(argv[1]);
    return 0;
}

Code compiled with: gcc -m32 -fno-stack-protector -z execstack s.c

And I've disabled ASLR: echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

This is the shell code in ASM (it just prints a "Hello_World!" string):

global _start
section .text

_start:
    ; write(1, "Hello World!\0", 13);
    xor eax, eax
    xor ebx, ebx
    xor ecx, ecx
    xor edx, edx
    mov al,  0x4
    mov bl,  0x1
    
    ; '\0'
    push ecx
    ;"!dlr"
    push 0x21646C72
    ;"oW_o"
    push 0x6f575f6f
    ;"lleH"    
    push 0x6C6C6548
    mov ecx, esp
    
    mov dl, 0xD
    int 0x80
    
    ; _exit(0)
    xor eax, eax
    xor ebx, ebx
    mov al, 0x1
    xor bl, bl
    int 0x80
../shellcode-hello/hello:     file format elf32-i386

Disassembly of section .text:

08049000 <_start>:
 8049000:       31 c0                   xor    %eax,%eax
 8049002:       31 db                   xor    %ebx,%ebx
 8049004:       31 c9                   xor    %ecx,%ecx
 8049006:       31 d2                   xor    %edx,%edx
 8049008:       b0 04                   mov    $0x4,%al
 804900a:       b3 01                   mov    $0x1,%bl
 804900c:       51                      push   %ecx
 804900d:       68 72 6c 64 21          push   $0x21646c72
 8049012:       68 6f 5f 57 6f          push   $0x6f575f6f
 8049017:       68 48 65 6c 6c          push   $0x6c6c6548
 804901c:       89 e1                   mov    %esp,%ecx
 804901e:       b2 0d                   mov    $0xd,%dl
 8049020:       cd 80                   int    $0x80
 8049022:       31 c0                   xor    %eax,%eax
 8049024:       31 db                   xor    %ebx,%ebx
 8049026:       b0 01                   mov    $0x1,%al
 8049028:       b3 00                   mov    $0x0,%bl
 804902a:       cd 80                   int    $0x80

I've then loaded the program to gdb and executed: run $(perl -e 'print "\x90" x 48 . "\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x04\xb3\x01\x51\x68\x72\x6c\x64\x21\x68\x6f\x5f\x57\x6f\x68\x48\x65\x6c\x6c\x89\xe1\xb2\x0d\xcd\x80\x31\xc0\x31\xdb\xb0\x01\x30\xdb\xcd\x80" . "\x30\xce\xff\xff"')

I've set up a breakpoint after strcpy() to ensure that the NOP sleds + shell code + return address are all overridden. x/120xb $esp confirms that.

By using si I am able to confirm that the NOPs started executing -- and it also started executing part of y shell code. But for some strange reason, the shell code stops executing after mov dl, 0xd and it doesn't even execute the first 0x80 (for the write() system call). This is code being executed from gdb:

   0xffffce62                  push   0x6f575f6f
   0xffffce67                  push   0x6c6c6548
   0xffffce6c                  mov    ecx, esp
 → 0xffffce6e                  mov    dl, 0xd
   0xffffce70                  dec    eax
   0xffffce71                  gs     ins BYTE PTR es:[edi], dx
   0xffffce73                  ins    BYTE PTR es:[edi], dx
   0xffffce74                  outs   dx, DWORD PTR ds:[esi]
   0xffffce75                  pop    edi

Note that after the arrow (→), gdb stops executing my shell code in the middle of it (thus the last line of the shell code that was execute was mov dl, 0xd) -- GDB then starts executing some garbage code.

Why is this so? Is there a fix?

ramon
  • 121
  • 5