https://chacker.pl/
Program meet.c wgląda następująco:
Użyjemy Pythona, aby przepełnić bufor 400-bajtowy w meet.c. Python jest językiem interpretowanym, co oznacza, że nie trzeba go prekompilować, co czyni go bardzo wygodnym w użyciu w wierszu poleceń. Na razie musisz zrozumieć tylko jedno polecenie Pythona:
To polecenie po prostu wydrukuje 600 A na standardowym wyjściu (stdout) — spróbuj!
UWAGA Znaki odwrotnego apostrofu (`) są używane do opakowania polecenia i wykonania polecenia przez interpreter powłoki oraz zwrócenia wartości. Skompilujmy i wykonajmy meet.c:
Teraz przekażmy 600 A do programu meet.c jako drugi parametr w następujący sposób:
Zgodnie z oczekiwaniami, Twój 400-bajtowy bufor przepełnił się; miejmy nadzieję, że EIP również. Aby to sprawdzić, uruchom ponownie gdb:
UWAGA: Twoje wartości mogą być inne. Pamiętaj, że próbujemy tu przekazać koncepcję, a nie wartości pamięci.
Nie tylko nie kontrolowaliśmy EIP, ale przenieśliśmy się daleko do innej części pamięci. Jeśli spojrzysz na meet.c, zauważysz, że po funkcji strcpy() w funkcji powitania następuje wywołanie printf(), które z kolei wywołuje vfprintf() w bibliotece libc. Funkcja vfprintf() wywołuje następnie strlen. Ale co mogło pójść nie tak? Masz kilka zagnieżdżonych funkcji, a zatem kilka ramek stosu, z których każda została umieszczona na stosie. Kiedy spowodowałeś przepełnienie, musiałeś uszkodzić argumenty przekazane do funkcji printf(). Przypomnij sobie z poprzedniej sekcji, że wywołanie i prolog funkcji sprawiają, że stos wygląda jak na poniższej ilustracji:
Jeśli zapiszesz poza EIP, nadpiszesz argumenty funkcji, zaczynając od temp1. Ponieważ funkcja printf() używa temp1, będziesz miał problemy. Aby sprawdzić tę teorię, sprawdźmy ponownie w gdb. Kiedy uruchomimy gdb ponownie, możemy spróbować uzyskać listę źródłową:
W poprzednim pogrubionym wierszu widać, że argumenty funkcji temp1 i temp2 zostały uszkodzone. Wskaźniki wskazują teraz na 0x41414141, a wartości to „” (lub null). Problem polega na tym, że printf() nie przyjmuje wartości null jako jedynego wejścia i dlatego się dławi. Zacznijmy więc od mniejszej liczby A, takiej jak 405, a następnie powoli ją zwiększajmy, aż uzyskamy pożądany efekt:
Jak widać, gdy w gdb występuje błąd segmentacji, wyświetlana jest bieżąca wartość EIP. Ważne jest, aby zdać sobie sprawę, że liczby (400–412) nie są tak ważne jak koncepcja zaczynania od niskiego poziomu i powolnego zwiększania, aż do przepełnienia zapisanego EIP i niczego więcej. Dzieje się tak z powodu wywołania printf bezpośrednio po przepełnieniu. Czasami będziesz mieć więcej miejsca na oddech i nie będziesz musiał się tym zbytnio martwić. Na przykład, gdyby nic nie następowało po podatnym poleceniu strcpy, nie byłoby problemu z przepełnieniem powyżej 412 bajtów w tym przypadku.
UWAGA: Pamiętaj, że używamy tutaj bardzo prostego fragmentu wadliwego kodu; w prawdziwym życiu napotkasz wiele takich problemów. Ponownie, chcemy, abyś zrozumiał koncepcje, a nie liczby wymagane do przepełnienia konkretnego podatnego fragmentu kodu.