I'm trying to replicate a simple buffer overflow for which I have the following code (strcpy_ex.c):

#include <string.h>

int main( int argc, char** argv ) {
        char buffer[500];
        strcpy(buffer, argv[1]);
        return 0; 

which I compile by using:

gcc -m32 -z execstack strcpy_ex.c -fno-stack-protector -o strcpy

The goal is to achieve a shell by exploiting the buffer overflow flaw when filling the buffer with more than 500 characters.

From the literature I've read, I expected to overwrite the EIP in order to change the execution flow and make it point to a memory address where my shellcode resides. In order to achieve this, I attempted to fill the buffer with "A's" followed by "B's" to locate where the overwriting takes place:

(gdb) r $(python -c "print 'A'*500+'B'*500")
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /root/Examples/Buffer Overflow/strcpy $(python -c "print 'A'*500+'B'*500")

Program received signal SIGSEGV, Segmentation fault.
0x565555ec in main ()

Unfortunately, it seems I have not managed to overwrite EIP. I expected to find a value 0x42424242 in EIP, but I did not.

(gdb) i r eip esp
eip            0x565555ec   0x565555ec <main+76>
esp            0x4242423e   0x4242423e

Additional information about the ASM instructions:

(gdb) disas main
Dump of assembler code for function main:
   0x565555a0 <+0>: lea    0x4(%esp),%ecx
   0x565555a4 <+4>: and    $0xfffffff0,%esp
   0x565555a7 <+7>: pushl  -0x4(%ecx)
   0x565555aa <+10>:    push   %ebp
   0x565555ab <+11>:    mov    %esp,%ebp
   0x565555ad <+13>:    push   %ebx
   0x565555ae <+14>:    push   %ecx
   0x565555af <+15>:    sub    $0x200,%esp
   0x565555b5 <+21>:    call   0x565555ed <__x86.get_pc_thunk.ax>
   0x565555ba <+26>:    add    $0x1a46,%eax
   0x565555bf <+31>:    mov    %ecx,%edx
   0x565555c1 <+33>:    mov    0x4(%edx),%edx
   0x565555c4 <+36>:    add    $0x4,%edx
   0x565555c7 <+39>:    mov    (%edx),%edx
   0x565555c9 <+41>:    sub    $0x8,%esp
   0x565555cc <+44>:    push   %edx
   0x565555cd <+45>:    lea    -0x1fc(%ebp),%edx
   0x565555d3 <+51>:    push   %edx
   0x565555d4 <+52>:    mov    %eax,%ebx
   0x565555d6 <+54>:    call   0x56555400 <strcpy@plt>
   0x565555db <+59>:    add    $0x10,%esp
   0x565555de <+62>:    mov    $0x0,%eax
   0x565555e3 <+67>:    lea    -0x8(%ebp),%esp
   0x565555e6 <+70>:    pop    %ecx
   0x565555e7 <+71>:    pop    %ebx
   0x565555e8 <+72>:    pop    %ebp
   0x565555e9 <+73>:    lea    -0x4(%ecx),%esp
=> 0x565555ec <+76>:    ret    

Due to the simplicity of the code, shouldn't EIP be overwritten immediatly after the buffer is filled?

Even if in this situation it should not make any difference, I would like to clarify that ASLR is off.

What am I missing?

Regarding platform:

# uname -a
Linux kali 4.9.0-kali4-amd64 #1 SMP Debian 4.9.30-2kali1 (2017-06-22) x86_64 GNU/Linux

I may be missing something really here, but the easiest way for exploiting this, is that the strcpy() call is in another function. This way, you overwrite the stored return address, essentially giving you control to EIP.

Your main function doesn't really return into a space that you control.

Make the code something like:

#include <string.h>

void vuln(char *arg) {
    char buffer[500];
    strcpy(buffer, arg);

int main( int argc, char** argv ) {
    return 0; 

The overflow will happen when vuln( ) is finishes and fetches the stored (but overwritten) return address to drop you back in main( ).

That should get you started.

  • Thank you very much, I'm going to try this. Just have 1 more question: I had assumed that calling strcpy implies that arguments and the return address for the next instruction in main() are stored in the stack, as strcpy is an external function. Is my understanding wrong? Shouldn't it work in the same way as your example? – Jausk Jul 28 '17 at 19:57
  • It's too much to type here, I'll update the answer. – ndrix Jul 28 '17 at 20:39
  • Just to clarify for OP on what ndrix has stated, you can see the references clarified at the following two urls: phearless.org/istorija/razno/buffer-overflow-example.txt AND why main return0 is something you aren't controlling: stackoverflow.com/questions/35471878/… – SCIS Security Jul 29 '17 at 5:51

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.