Format Strings
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
W C printf
to funkcja, która może być używana do drukowania pewnego ciągu znaków. Pierwszym parametrem, którego oczekuje ta funkcja, jest surowy tekst z formatami. Kolejnymi parametrami są oczekiwane wartości, które mają zastąpić formaty w surowym tekście.
Inne podatne funkcje to sprintf()
i fprintf()
.
Vulnerabilność pojawia się, gdy tekst atakującego jest używany jako pierwszy argument tej funkcji. Atakujący będzie w stanie stworzyć specjalne dane wejściowe, które wykorzystują możliwości formatu printf do odczytu i zapisu dowolnych danych w dowolnym adresie (czytliwym/zapisywalnym). Dzięki temu będzie mógł wykonać dowolny kod.
Przykłady:
Wrażliwy przykład:
Normalne użycie:
Z brakującymi argumentami:
fprintf podatny:
Format %<n>$x
, gdzie n
to liczba, pozwala wskazać printf, aby wybrał n parametr (ze stosu). Więc jeśli chcesz odczytać 4. parametr ze stosu używając printf, możesz to zrobić:
i możesz czytać od pierwszego do czwartego parametru.
Lub możesz zrobić:
i odczytać bezpośrednio czwarty.
Zauważ, że atakujący kontroluje parametr printf
, co zasadniczo oznacza, że jego dane wejściowe będą znajdować się na stosie, gdy printf
zostanie wywołane, co oznacza, że mógłby zapisać konkretne adresy pamięci na stosie.
Atakujący kontrolujący te dane wejściowe będzie w stanie dodać dowolny adres na stosie i sprawić, że printf
uzyska do nich dostęp. W następnej sekcji zostanie wyjaśnione, jak wykorzystać to zachowanie.
Możliwe jest użycie formatera %n$s
, aby sprawić, że printf
uzyska adres znajdujący się na n pozycji, podążając za nim i wydrukować go tak, jakby był ciągiem (drukować aż do znalezienia 0x00). Więc jeśli adres bazowy binarnego pliku to 0x8048000
, a wiemy, że dane wejściowe użytkownika zaczynają się na 4. pozycji na stosie, możliwe jest wydrukowanie początku binarnego pliku za pomocą:
Zauważ, że nie możesz umieścić adresu 0x8048000 na początku wejścia, ponieważ ciąg zostanie obcięty na 0x00 na końcu tego adresu.
Aby znaleźć offset do swojego wejścia, możesz wysłać 4 lub 8 bajtów (0x41414141
), a następnie %1$x
i zwiększać wartość, aż uzyskasz A's
.
Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)