Classic Buffer overflow exploits on Linux x64


If you are learning buffer overflow exploit development on Linux x64 machine, then there are something which you need to take care of.

This is because architecture and execution of programs in x64 machine model is completely different from x32 machine model.

For a reference to stack frame in x64, refer to this link

Consider this C program and I will demonstrate the effect of compiling this program for x32 and x64.

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

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

If you are on x64, simply executing this command will compile it for x64

gcc -ggdb -m64 -o buffer1 -fno-stack-protector -mpreferred-stack-boundary=4 buffer1.c

And this one for x32

gcc -ggdb -m32 -o buffer1 -fno-stack-protector -mpreferred-stack-boundary=4 buffer1.c

Let's try to exploit this buffer overflow vulnerability using gdb on both the versions. Here are the outputs

x64

[email protected]:~/buffer$ gdb buffer1
GNU gdb (GDB) 7.1-ubuntu
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/madhur/buffer/buffer1...done.
(gdb) run $(python -c 'print "\x41" * 1500')
Starting program: /home/madhur/buffer/buffer1 $(python -c 'print "\x41" * 1500')

Program received signal SIGSEGV, Segmentation fault.
0x0000000000400565 in main (argc=Cannot access memory at address 0x4141414141413f3d
) at buffer1.c:10
10  }
(gdb) info registers
rax            0x0  0
rbx            0x0  0
rcx            0x41414141414141 18367622009667905
rdx            0x1000   4096
rsi            0x7fffffffe769   140737488349033
rdi            0x7fffffffe1f0   140737488347632
rbp            0x4141414141414141   0x4141414141414141
rsp            0x7fffffffde28   0x7fffffffde28
r8             0x7ffff7dd8300   140737351877376
r9             0x5c0    1472
r10            0x7  7
r11            0x7ffff7ba92a0   140737349587616
r12            0x400440 4195392
r13            0x7fffffffdf00   140737488346880
r14            0x0  0
r15            0x0  0
rip            0x400565 0x400565 <main+65>
eflags         0x10206  [ PF IF RF ]
cs             0x33 51
ss             0x2b 43
ds             0x0  0
es             0x0  0
fs             0x0  0

x32

[email protected]:~/buffer$ gdb buffer1
GNU gdb (GDB) 7.1-ubuntu
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/madhur/buffer/buffer1...done.
(gdb) run $(python -c 'print "\x41" * 1500')
Starting program: /home/madhur/buffer/buffer1 $(python -c 'print "\x41" * 1500')
warning: the debug information found in "/lib/ld-2.11.1.so" does not match "/lib/ld-linux.so.2" (CRC mismatch).


Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb) info registers
eax            0x0  0
ecx            0x0  0
edx            0x5dd    1501
ebx            0xf7fbdff4   -134488076
esp            0xffffcf80   0xffffcf80
ebp            0x41414141   0x41414141
esi            0x0  0
edi            0x0  0
eip            0x41414141   0x41414141
eflags         0x10246  [ PF ZF IF RF ]
cs             0x23 35
ss             0x2b 43
ds             0x2b 43
es             0x2b 43
fs             0x0  0
gs             0x63 99
(gdb) 

As you can see in the outputs above, there is no EIP register in x64 version of program. And in the x32 version, the EIP value is correctly corrupted with our overflowed value of x41.