Pisanie exploitów systemu Windows

https://chacker.pl/

Następnie użyjesz domyślnej instalacji Pythona w systemie Kali Linux. Jeśli biblioteki paramiko i scp nie są jeszcze zainstalowane, musisz je zainstalować za pomocą pip. Docelowym systemem operacyjnym, na którym działa podatna aplikacja używana w przykładach, jest Windows 10 x64 20H2 Enterprise. W tej sekcji kontynuujemy korzystanie z Immunity Debugger, a także używamy wtyczki Mona od Petera Van Eeckhoutte i zespołu Corelan (https://www.corelan.be). Celem jest kontynuacja procesu opracowywania exploitów omówionego do tej pory. Następnie dowiesz się, jak przejść od porady dotyczącej podatności do podstawowego exploita proof-of-concept.

Awaria programu

https://chacker.pl/

Do tego laboratorium musisz pobrać i zainstalować Immunity Debugger w systemie Windows z powyższego łącza. Immunity Debugger nadal jest zależny od Pythona 2.7, który zostanie zainstalowany automatycznie, jeśli nie jest już zainstalowany w systemie. Będziesz debugować program meet.exe, który wcześniej skompilowałeś. Używając Python IDLE w systemie Windows, wpisz następujące polecenie:

W poprzednim kodzie przekazaliśmy drugi argument 408 A. Program powinien automatycznie uruchomić się pod kontrolą debugera. Być może będziesz musiał przekazać wszelkie wyjątki czasu wykonania, naciskając SHIFT-F9. 408 A przepełni bufor. Teraz jesteśmy gotowi, aby rozpocząć analizę programu. Interesuje nas wywołanie strcpy() z wnętrza funkcji Greeting(), ponieważ wiadomo, że jest podatne na ataki z powodu braku sprawdzania granic. Znajdźmy je, uruchamiając okno Executable Modules, które można otworzyć za pomocą ALT-E. Kliknij dwukrotnie moduł „meet”, a zostaniesz przeniesiony do wskaźników funkcji programu meet.exe. Zobaczysz wszystkie funkcje programu (w tym przypadku Greeting i Main). Przejdź strzałką w dół do wiersza JMP meet.greeting (możesz musieć go poszukać), a następnie naciśnij ENTER, aby przejść do tej instrukcji JMP w funkcji Greeting, jak pokazano tutaj:

UWAGA: Jeśli nie widzisz nazw symboli, takich jak Greeting, strcpy i printf, być może nie skompilowałeś pliku binarnego z symbolami debugowania. Możesz również zobaczyć mniejszą lub większą tabelę skoków, w zależności od używanej wersji systemu Windows. Nawet kompilacja w innej wersji systemu Windows może dać różne wyniki. Jeśli nadal nie widzisz symboli po prawej stronie, patrząc na ekran, po prostu postępuj zgodnie z instrukcjami w następnym akapicie, aby wyszukać ciąg ASCII „Hello %s %s” i przerwać na instrukcji CALL kilka wierszy nad nim. Jest to wywołanie strcpy, które można zweryfikować, klikając je i naciskając ENTER. Teraz, gdy patrzymy na funkcję Greeting() w oknie Deasemblera, ustawmy punkt przerwania przy wywołaniu podatnej funkcji (strcpy). Przesuwaj strzałkę w dół, aż dojdziesz do wiersza 0x011C6EF4. Ponownie, adresowanie i symbole w Twojej wersji systemu Windows mogą być inne. Jeśli tak, po prostu poszukaj instrukcji call kilka linijek nad disasemblacją pokazującą ASCII „Hello %s %s” po prawej stronie, aby zobaczyć, gdzie ustawić punkt przerwania. Możesz sprawdzić, czy jest to prawidłowe wywołanie, klikając instrukcję i naciskając ENTER. Powinno to pokazać, że wywołanie jest wykonywane do funkcji strcpy(). W tym wierszu naciśnij F2, aby ustawić punkt przerwania; adres powinien zmienić kolor na czerwony. Ten punkt przerwania pozwala na szybki powrót do tego punktu. Na przykład w tym momencie uruchom ponownie program za pomocą CTRL-F2, a następnie naciśnij F9, aby przejść do punktu przerwania. Powinieneś teraz zobaczyć, że Immunity Debugger zatrzymał się na wywołaniu funkcji, która nas interesuje (strcpy).

UWAGA: Adresy przedstawione tu prawdopodobnie będą się różnić w Twoim systemie ze względu na rebasing i ASLR. Dlatego powinieneś postępować zgodnie z technikami, a nie konkretnymi adresami. Ponadto, w zależności od wersji systemu operacyjnego, może być konieczne ręczne ustawienie punktu przerwania przy każdym uruchomieniu programu, ponieważ Immunity Debugger wydaje się mieć problemy z trwałością punktu przerwania w niektórych wersjach systemu Windows. WinDbg jest świetną alternatywą, ale nie jest tak intuicyjny. Teraz, gdy mamy ustawiony punkt przerwania w wywołaniu podatnej funkcji (strcpy), możemy kontynuować, przechodząc przez funkcję strcpy (naciskając klawisz F8). Gdy rejestry się zmienią, zobaczysz, że staną się czerwone. Ponieważ właśnie wykonaliśmy wywołanie funkcji strcpy, powinieneś zobaczyć, że wiele rejestrów zmieni kolor na czerwony. Kontynuuj przechodzenie przez program, aż dojdziesz do instrukcji RETN, która jest ostatnim wierszem kodu w funkcji powitalnej. Na przykład, ponieważ „wskaźnik powrotu” został nadpisany czterema A, debugger wskazuje, że funkcja zamierza powrócić do 0x41414141. Zwróć również uwagę, jak funkcja epilog skopiowała adres EBP (Extended Base Pointer) do ESP (Extended Stack Pointer), a następnie zdjęła wartość ze stosu (0x41414141) do EBP, jak pokazano poniżej.

UWAGA: Jeśli nie widzisz nazw symboli, takich jak Greeting, strcpy i printf, być może nie skompilowałeś pliku binarnego z symbolami debugowania. Możesz również zobaczyć mniejszą lub większą tabelę skoków, w zależności od używanej wersji systemu Windows. Nawet kompilacja w innej wersji systemu Windows może dać różne wyniki. Jeśli nadal nie widzisz symboli po prawej stronie, patrząc na ekran, po prostu postępuj zgodnie z instrukcjami w następnym akapicie, aby wyszukać ciąg ASCII „Hello %s %s” i przerwać na instrukcji CALL kilka wierszy nad nim. Jest to wywołanie strcpy, które można zweryfikować, klikając je i naciskając ENTER. Teraz, gdy patrzymy na funkcję Greeting() w oknie Deasemblera, ustawmy punkt przerwania przy wywołaniu podatnej funkcji (strcpy). Przesuwaj strzałkę w dół, aż dojdziesz do wiersza 0x011C6EF4. Ponownie, adresowanie i symbole w Twojej wersji systemu Windows mogą być inne. Jeśli tak, po prostu poszukaj instrukcji call kilka linijek nad disasemblacją pokazującą ASCII „Hello %s %s” po prawej stronie, aby zobaczyć, gdzie ustawić punkt przerwania. Możesz sprawdzić, czy jest to prawidłowe wywołanie, klikając instrukcję i naciskając ENTER. Powinno to pokazać, że wywołanie jest wykonywane do funkcji strcpy(). W tym wierszu naciśnij F2, aby ustawić punkt przerwania; adres powinien zmienić kolor na czerwony. Ten punkt przerwania pozwala na szybki powrót do tego punktu. Na przykład w tym momencie uruchom ponownie program za pomocą CTRL-F2, a następnie naciśnij F9, aby przejść do punktu przerwania. Powinieneś teraz zobaczyć, że Immunity Debugger zatrzymał się na wywołaniu funkcji, która nas interesuje (strcpy).

UWAGA: Adresy przedstawione w tym rozdziale prawdopodobnie będą się różnić w Twoim systemie ze względu na rebasing i ASLR. Dlatego powinieneś postępować zgodnie z technikami, a nie konkretnymi adresami. Ponadto, w zależności od wersji systemu operacyjnego, może być konieczne ręczne ustawienie punktu przerwania przy każdym uruchomieniu programu, ponieważ Immunity Debugger wydaje się mieć problemy z trwałością punktu przerwania w niektórych wersjach systemu Windows. WinDbg jest świetną alternatywą, ale nie jest tak intuicyjny. Teraz, gdy mamy ustawiony punkt przerwania w wywołaniu podatnej funkcji (strcpy), możemy kontynuować, przechodząc przez funkcję strcpy (naciskając klawisz F8). Gdy rejestry się zmienią, zobaczysz, że staną się czerwone. Ponieważ właśnie wykonaliśmy wywołanie funkcji strcpy, powinieneś zobaczyć, że wiele rejestrów zmieni kolor na czerwony. Kontynuuj przechodzenie przez program, aż dojdziesz do instrukcji RETN, która jest ostatnim wierszem kodu w funkcji powitalnej. Na przykład, ponieważ „wskaźnik powrotu” został nadpisany czterema A, debugger wskazuje, że funkcja zamierza powrócić do 0x41414141. Zwróć również uwagę, jak funkcja epilog skopiowała adres EBP (Extended Base Pointer) do ESP (Extended Stack Pointer), a następnie zdjęła wartość ze stosu (0x41414141) do EBP, jak pokazano poniżej.

Aby kontynuować sprawdzanie stanu uszkodzonej maszyny, w oknie stosu przewiń w dół do bieżącej ramki stosu (bieżąca ramka stosu zostanie podświetlona). Możesz również powrócić do bieżącej ramki stosu, wybierając wartość rejestru ESP, a następnie klikając prawym przyciskiem myszy tę wybraną wartość i wybierając Follow in Stack. Zauważysz, że kopię bufora można również znaleźć w lokalizacji ESP+4, jak pokazano poniżej. Informacje takie stają się cenne później, gdy wybieramy wektor ataku

Jak widać, Immunity Debugger jest łatwy w użyciu.

UWAGA : Immunity Debugger działa tylko w przestrzeni użytkownika i tylko dla aplikacji 32-bitowych w momencie pisania tego tekstu. Jeśli musisz zanurzyć się w przestrzeni jądra, będziesz musiał użyć debugera Ring0, takiego jak WinDbg firmy Microsoft.

W tym laboratorium pracowaliśmy z Immunity Debugger, aby śledzić przepływ wykonywania z naszymi złośliwymi danymi jako danymi wejściowymi. Zidentyfikowaliśmy podatne wywołanie strcpy() i ustawiliśmy punkt przerwania oprogramowania, aby przejść przez funkcję. Następnie pozwoliliśmy na kontynuowanie wykonywania i potwierdziliśmy, że możemy uzyskać kontrolę nad wskaźnikiem instrukcji. Stało się tak, ponieważ funkcja strcpy() pozwala nam nadpisać wskaźnik powrotu używany przez funkcję Greeting(), aby zwrócić kontrolę z powrotem do main().

Debugowanie w systemie Windows za pomocą Immunity Debugger

https://chacker.pl/

Popularnym debugerem w trybie użytkownika jest Immunity Debugger, który możesz pobrać ze strony https://www.immunityinc.com/products/debugger/. W momencie pisania tego tekstu stabilną wersją jest wersja 1.85, używana w tym rozdziale. Główny ekran Immunity Debugger jest podzielony na pięć sekcji. Sekcja „Code” lub „Disassembler” (w lewym górnym rogu) służy do przeglądania zdemontowanych modułów. Sekcja „Registers” (w prawym górnym rogu) służy do monitorowania stanu rejestrów w czasie rzeczywistym. Sekcja „Hex Dump” lub „Data” (w lewym dolnym rogu) służy do przeglądania surowego heksadecymalnego pliku binarnego. Sekcja „Stack” (w prawym dolnym rogu) służy do przeglądania stosu w czasie rzeczywistym. Możesz zobaczyć te sekcje na nadchodzącym obrazku. Sekcja „Information” (w lewym środkowym rogu) służy do wyświetlania informacji o instrukcji wyróżnionej w sekcji Code. Każda sekcja ma menu kontekstowe dostępne po kliknięciu prawym przyciskiem myszy w tej sekcji. Immunity Debugger ma również oparty na Pythonie interfejs powłoki na dole okna debugera, aby umożliwić automatyzację różnych zadań, a także wykonywanie skryptów, aby pomóc w rozwijaniu exploitów. Mimo że dostępne są inne aktywnie utrzymywane debugery, społeczność użytkowników stworzyła bogate w funkcje rozszerzenia, takie jak Mona.py od Corelanc0d3r. Przed kontynuowaniem pobierz i zainstaluj Immunity Debugger z podanego wyżej łącza. Możesz rozpocząć debugowanie programu za pomocą Immunity Debugger na kilka sposobów:

  • Otwórz Immunity Debugger i wybierz Plik | Otwórz.
  • Otwórz Immunity Debugger i wybierz Plik | Dołącz.

• Wywołaj Immunity Debugger z wiersza poleceń — na przykład z wiersza poleceń Windows IDLE Python, w następujący sposób:

  • Otwórz Immunity Debugger i wybierz Plik | Otwórz.
  • Otwórz Immunity Debugger i wybierz Plik | Dołącz.

• Wywołaj Immunity Debugger z wiersza poleceń — na przykład z wiersza poleceń Windows IDLE Python, w następujący sposób:

Poprzednia linia poleceń uruchomi meet.exe wewnątrz Immunity Debugger, jak pokazano tutaj:

Debuger może wychwycić wyjątek, a jeśli tak się stanie, musisz przekazać wyjątek, naciskając SHIFT-F9, aby przejść do domyślnego punktu przerwania w punkcie wejścia programu. Podczas nauki Immunity Debugger będziesz chciał znać typowe polecenia wymienione w Tabeli  (jeśli używasz hosta macOS do przekazywania tych poleceń do maszyny wirtualnej Windows, może być konieczne zamapowanie powiązań klawiszy).

Debuger może wychwycić wyjątek, a jeśli tak się stanie, musisz przekazać wyjątek, naciskając SHIFT-F9, aby przejść do domyślnego punktu przerwania w punkcie wejścia programu. Podczas nauki Immunity Debugger będziesz chciał znać typowe polecenia wymienione w Tabeli  (jeśli używasz hosta macOS do przekazywania tych poleceń do maszyny wirtualnej Windows, może być konieczne zamapowanie powiązań klawiszy).

W tym przypadku możemy zobaczyć główny moduł wykonywalny dla meet.exe wymieniony jako pierwszy, a następnie różne biblioteki DLL. Ta informacja jest przydatna, ponieważ, jak zobaczysz później, te moduły zawierają kody operacji, które są dostępne podczas eksploatacji. Należy pamiętać, że adresowanie będzie się różnić w każdym systemie ze względu na randomizację układu przestrzeni adresowej (ASLR) i inne czynniki.

Opcje kompilatora Windows

https://chacker.pl/

Jeśli wpiszesz cl.exe /?, otrzymasz ogromną listę opcji kompilatora. Jednak większość z nich nie jest dla nas interesująca w tym momencie. Tabela  zawiera listę i opis flag, których będziesz używać.

Ponieważ będziemy teraz używać debugera, skompilujmy meet.exe z pełnymi informacjami debugowania i wyłączmy funkcjonalność stack canary.

UWAGA: Przełącznik /GS włącza implementację ochrony stack canary firmy Microsoft, która jest dość skuteczna w zatrzymywaniu ataków przepełnienia bufora. Aby dowiedzieć się więcej o istniejących lukach w oprogramowaniu (zanim ta funkcja stała się dostępna), wyłączymy ją za pomocą flagi /GS–.

Wykonaj następujący krok, aby skompilować wersję programu meet.c, której będziesz używać w laboratorium

Świetnie, teraz, gdy masz plik wykonywalny zbudowany z informacjami debugowania, czas zainstalować debuger i sprawdzić, jak debugowanie w systemie Windows wypada w porównaniu z debugowaniem w systemie Unix. W tym laboratorium użyłeś programu Visual Studio 2019 Community Edition do skompilowania programów hello.c i meet.c. Skompilowaliśmy program meet.c z pełnymi informacjami debugowania, które pomogą nam w następnym laboratorium. Przyjrzeliśmy się również różnym flagom kompilatora, których można użyć do wykonywania działań, takich jak wyłączenie kontroli łagodzenia eksploitów /GS.

Kompilacja w systemie Windows

https://chacker.pl/

Microsoft C/C++ Optimizing Compiler and Linker są dostępne bezpłatnie na stronie https://visualstudio.microsoft.com/vs/community/. W tym laboratorium korzystamy z systemu Windows 10 w wersji 20H2. Pobierz i uruchom instalator z poprzedniego łącza. Gdy pojawi się monit, w kategorii Workloads wybierz opcję Desktop Development with C++ i odznacz wszystkie inne opcje z wyjątkiem następujących:

  • MSVC v142 – narzędzia do kompilacji VS 2019 C++ x64/x86
  • Windows 10 SDK (10.0.19041.0)

Możesz również zaakceptować wszystkie opcjonalne ustawienia domyślne; pamiętaj jednak, że każde z nich zajmuje dodatkowe miejsce na dysku twardym. Konkretny numer kompilacji zestawu SDK może się różnić w zależności od tego, kiedy wykonasz pobieranie. Po pobraniu i prostej instalacji powinieneś mieć łącze w menu Start do wersji Visual Studio 2019 Community. Kliknij przycisk Start systemu Windows i wpisz prompt. Spowoduje to wyświetlenie okna pokazującego różne skróty wiersza poleceń. Kliknij dwukrotnie ten zatytułowany Developer Command Prompt lub VS 2019. Jest to specjalny wiersz poleceń ze środowiskiem skonfigurowanym do kompilowania kodu. Jeśli nie możesz go znaleźć za pomocą menu Start, spróbuj wyszukać „Developer Command Prompt” w katalogu głównym dysku C:. Często znajduje się on w C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio 2019\Visual Studio Tools. Po otwarciu wiersza poleceń dla programistów przejdź do folderu C:\grayhat. Aby przetestować wiersz poleceń, zacznijmy od programów hello.c i meet.c. Używając edytora tekstu, takiego jak Notepad.exe, wpisz następujący przykładowy kod i zapisz go w pliku o nazwie hello.c znajdującym się w folderze C:\grayhat:

Kompilator Windows to cl.exe. Przekazanie nazwy pliku źródłowego do kompilatora generuje hello.exe, jak pokazano tutaj:

Przejdźmy do zbudowania kolejnego programu, meet.exe. Utwórz plik kodu źródłowego meet.c z następującym kodem i skompiluj go w systemie Windows za pomocą cl.exe:

Kompilowanie i debugowanie programów Windows

https://chacker.pl/

Narzędzia programistyczne nie są dołączone do systemu Windows, ale na szczęście Visual Studio Community Edition pozwala kompilować programy do celów edukacyjnych. (Jeśli masz już licencjonowaną kopię, świetnie — możesz jej swobodnie użyć w tym rozdziale). Możesz bezpłatnie pobrać ten sam kompilator, który Microsoft dołącza do Visual Studio 2019 Community Edition. W tej sekcji pokażemy, jak skonfigurować podstawową stację roboczą do wykrywania luk w zabezpieczeniach systemu Windows. Można również użyć programu Visual Studio 2022.

Podstawowe wykorzystanie systemu Windows

https://chacker.pl/

Microsoft Windows jest zdecydowanie najczęściej używanym systemem operacyjnym, zarówno do użytku profesjonalnego, jak i osobistego. Procenty pokazane na tym rysunku często się zmieniają; jednak daje on dobry pogląd na ogólny udział w rynku systemów operacyjnych.  Windows 10 zdominował z 67 procentami rynku, podczas gdy Windows 7 powoli spada, ale nadal ma prawie 20 procent rynku. Jeśli chodzi o ogólne wykorzystanie i polowanie na exploity 0-day, powinno być stosunkowo jasne, które systemy operacyjne Windows są potencjalnie lukratywnymi celami. Windows 7 często stanowi łatwiejszy cel w porównaniu do Windows 10, ponieważ niektóre funkcje zabezpieczeń i łagodzenia zagrożeń są niedostępne dla Windows 7, takie jak Control Flow Guard (CFG). Przykłady godnych uwagi funkcji i łagodzenia zagrożeń podano później. Często zdarza się, że luka w zabezpieczeniach odkryta w jednej wersji systemu Windows wpływa na wiele innych wersji, starszych i nowszych. Prawdopodobnie w nadchodzących latach udział systemu Windows 11 w rynku znacznie wzrośnie.