Liczba bootkitów systematycznie rośnie. Pojawiają się wszystkie możliwe rodzaje nowych bootkitów: wyrafinowane, proste, służące różnym celom (np. rootkity lub trojany wymuszające okup). Twórcy szkodliwego oprogramowania nie zasypują gruszek w popiele i często analizują złośliwy kod tworzony przez swoich konkurentów.
W dzisiejszych czasach nie jest łatwo zaimponować nowym bootkitem ekspertowi ds. szkodliwego oprogramowania: infekcje sektora rozruchowego zostały dokładnie przestudiowane, a w internecie można znaleźć mnóstwo informacji na ten temat. Jednak, tym razem udało nam się trafić na osobliwy przypadek: szkodnika Xpaj - infekującego pliki, uzupełnionego funkcjonalnością bootkita i posiadającego możliwość działania na systemach operacyjnych Windows x86 i Windows x64. To, co wyróżnia szkodnika spośród innych zagrożeń, to operowanie na systemach Windows x64 z włączoną funkcją PatchGuard. Szkodnik robi to przy pomocy splicingu na poziomie jądra, w celu ochrony przed odczytem lub modyfikacją zainfekowanego sektora rozruchowego.
W niniejszym artykule przeanalizujemy działanie rootkita w systemie operacyjnym Windows 7 x64. Przypadek działania szkodnika w Windows x86 nie jest wart odrębnej analizy, ponieważ szkodnik w mniejszym lub większym stopniu wykorzystuje ten sam algorytm w obu wersjach systemu operacyjnego.
Z analizy tej samej modyfikacji wirusa Xpaj, przeprowadzonej przez specjalistów z firmy Symantec, można wyciągnąć następujące wnioski:
Na podstawie powyższych wniosków i statystyk infekcji (patrz poniżej), można przypuszczać, że ten wariant wirusa jest tylko wersją testową. Kolejna modyfikacja szkodnika może być już w pełni funkcjonalna i, kto wie, być może twórcy zaimplementują w niej mechanizm infekowania 64-bitowych plików wykonywalnych wraz ze sterownikami trybu jądra (co będzie oczywiście wymagało wyłączenia sprawdzania podpisu cyfrowego).
Jak zwykle, wszystko rozpoczyna się od zainfekowanego sektora MBR. Jak w prawie wszystkich poprzednich przypadkach, głównym celem zainfekowanego rekordu rozruchowego jest odczytanie dodatkowych sektorów i przekazanie im kontroli.
Dodatkowe sektory na końcu dysku zawierają moduły, które są ładowane przez bootkita, gdy jest to wymagane. Wszystkie moduły, za wyjątkiem pierwszego, są skompresowane z użyciem APLib.
Pierwszy moduł działa według następującego algorytmu:
Po przekazaniu kontroli do oryginalnego MBR, system operacyjny będzie kontynuował inicjację. Podczas inicjacji plik jądra i wszystkie niezbędne składniki doczytywane są z dysku. Realizując przechwycenie przerwania bootkit oczekuje na odczyt pliku jądra, obliczając sumę kontrolną od początku pliku i sprawdzając niektóre pola w nagłówku.
Aby kontynuować inicjację bootkitu, twórcy szkodliwego oprogramowania wybrali metodę podobną do użytej w TDL-4, z jedyną różnicą polegającą na tym, że tym razem to plik jądra, a nie plik KDCOM.DLL, jest wybierany jako cel. Kiedy wykryta zostanie próba odczytu pliku jądra, bootkit zapisuje pierwsze 0x120 bajtów (licząc od początku pliku) i nadpisuje nagłówek przy pomocy swojego własnego kodu.
Następnie bootkit znajduje wyeksportowaną funkcję o nazwie MmMapIoSpace i przechwytuje ją używając splicingu. Punkt zaczepienia prowadzi do kodu w nagłówku pliku jądra.
Oto jak wygląda prototyp funkcji:
Funkcja ta odwzorowuje adres fizyczny w pamięci wirtualnej. Pamiętajmy, że pierwszy moduł bootkita cały czas rezyduje w pamięci fizycznej gdy ta funkcja jest wywoływana po raz pierwszy.
Kontynuacja inicjacji bootkita następuje po wywołaniu przechwyconej funkcji.
Przy pierwszym wywołaniu kod w nagłówku pliku jądra przywraca skradzione bajty funkcji MmMapIoSpace i wywołuje oryginalną funkcję, która odwzorowuje adres fizyczny pierwszego modułu bootkita (zobacz Rysunek 1 i Rysunek 5) w pamięci wirtualnej. Następnie kontrola jest przekazywana do odwzorowanego kodu.
Kontynuacja inicjacji bootkita następuje po przekazaniu kontroli do mapowanej pamięci fizycznej.
Późniejsze działanie opiera się na następującym algorytmie:
Dalsza inicjacja bootkita jest obsługiwana przez przechwyt funkcji ZwLoadDriver, ponieważ w pierwszym etapie pracy bootkita punkty zaczepienia NtReadFile / NtWriteFile są szkieletami, które przekazują kontrolę oryginalnym funkcjom i nie podejmują żadnych innych działań.
Oczywiście jest to specjalna "furtka" przygotowana, aby wstawić przez nią później kod pracy punktów zaczepienia funkcji NtReadFile / NtWriteFile.
Bootkit kontynuuje inicjację po pierwszym wywołaniu funkcji ZwLoadDriver.
Przechwyt funkcji ZwLoadDriver zachodzi na podstawie poniższego algorytmu:
Trzeci moduł, do którego przekazywana jest kontrola, kończy inicjację bootkita w systemie.
Trzeci moduł wykonuje następujące działania:
Porównajmy punkt zaczepienia funkcji NtReadFile na Rysunku 11 z Rysunkiem 9.
Jest oczywiste, że punkty zaczepienia NtReadFile / NtWriteFile są niezbędne do ochrony przed odczytem i modyfikacją krytycznych obszarów bootkita.
Podczas inicjacji bootkita instalowane są dwie funkcje zwrotne.
Pierwsza funkcja "zabija" wszystkie procesy antywirusowe. Kiedy funkcja jest wywoływana podczas tworzenia dowolnego procesu w systemie, bootkit na podstawie nazwy procesu oblicza sumę kontrolną i porównuje ją z własną wewnętrzną listą sum kontrolnych.
Jeśli suma kontrolna nazwy procesu pasuje do sumy kontrolnej na liście bootkita, bootkit ładuje instrukcję RET w punkt wejściowy procesu i proces jest przerywany.
Druga funkcja zwrotna jest wywoływana przez bootkit, gdy moduł jest ładowany do pamięci. Wykorzystywana jest do wstrzykiwania kodu w różne procesy, łącznie z procesami popularnych przeglądarek internetowych. Podobnie, jak w przypadku funkcji przerywającej procesy, funkcja ta oblicza sumę kontrolną z nazwy procesu i porównuje ją z wewnętrzną listą sum kontrolnych.
Wspomnieliśmy wcześniej o mechanizmie ochronnym, zintegrowanym z jądrem 64-bitowego systemu operacyjnego Windows. Mechanizm PatchGuard został stworzony do przeciwdziałania modyfikacjom jądra systemu operacyjnego i jego krytycznych struktur, takich jak: różne tablice usług (SSDT, IDT, GDT), obiekty jądra itd. Mechanizm ochrony uaktywnia się na wczesnym etapie inicjacji jądra i co pewien czas skanuje powyższe struktury w poszukiwaniu wprowadzonych modyfikacji. Jeśli jakiekolwiek modyfikacje zostaną zidentyfikowane, wywoływana jest celowa awaria systemu. Mechanizm ten został zaprojektowany przede wszystkim do ochrony przed rootkitami trybu jądra. Niestety posiada poważną wadę: wiele aplikacji antywirusowych i produktów bezpieczeństwa wykorzystuje przechwyty na poziomie jądra do różnych legalnych celów, w tym do działania modułów ochrony proaktywnej.
Wciąż dochodzi do ostrej wymiany zdań w tej sprawie pomiędzy producentami rozwiązań antywirusowych i firmą Microsoft. Niektórzy twierdzą, że firmy antywirusowe nie powinny stosować nieudokumentowanych punków zaczepienia w jądrze systemu i do zatrzymania wniknięcia złośliwego kodu do jądra muszą być używane inne metody. Inni uważają, że Microsoftowi nie udaje się zapewnić wymaganego poziomu bezpieczeństwa i te punkty zaczepienia są niezbędne dla zwiększenia bezpieczeństwa systemu operacyjnego. Kolejna grupa twierdzi, że nie można zaufać systemowi, do którego jądra choć raz przeniknął złośliwy kod - i na nic zdaje się leczenie takich systemów. Wszystkie z tych opinii niosą sporo racji, lecz my nie będziemy dalej roztrząsać tego tematu.
Każde narzędzie ochrony można zhakować lub obejść, w ten czy inny sposób. PatchGuard nie jest tutaj żadnym wyjątkiem. Mechanizm ten został dokładnie zbadany zarówno przez niezależnych badaczy, jak i cyberprzestępców, i wynalezionych zostało kilka metod jego obejścia. Dla przykładu, TDL-4 używa metody koncepcyjnej, w której wykrycie punktu zaczepienia rootkita jest po prostu ignorowane przez mechanizm ochrony. Istnieją również inne metody, np. działające w oparciu o modyfikację programu ładującego i pliku jądra systemu operacyjnego, mające na celu wyłączenie inicjacji PatchGuarda. Jeszcze inna metoda opiera się na modyfikacji zainicjowanego jądra i blokuje uruchomienie mechanizmu skanującego. PatchGuard nie zostanie zainicjowany również wtedy, gdy debuger jądra jest włączony podczas uruchamiania systemu operacyjnego – funkcja ta została fabrycznie wbudowana w system, aby deweloperzy oprogramowania mogli swobodnie testować i debugować swoje sterowniki.
Wirus Xpaj jest interesujący, ponieważ używa jeszcze innego koncepcyjnego sposobu na ominięcie PatchGuarda. Problemem mechanizmu PatchGuard jest to, że inicjuje się w dość późnym etapie uruchamiania systemu operacyjnego. Ponieważ Xpaj to bootkit, może on kontrolować każdy etap uruchamiania systemu operacyjnego i modyfikować jądro, zanim uruchomiony zostanie mechanizm ochronny. W momencie, gdy jądro zostanie zainicjowane, zawiera już wszystkie modyfikacje i punkty zaczepienia Xpaja, więc PatchGuard raczej CHRONI te modyfikacje ZAMIAST je WYKRYWAĆ.
Aby potwierdzić, że PatchGuard rzeczywiście chroni przed przechwyceniem ZwLoadDriver / NtReadFile / NtWriteFile, przeprowadziliśmy mały eksperyment. Uruchomiliśmy zainfekowany system w trybie debugowania, zaczekaliśmy na inicjację, włączyliśmy debuger jądra i przywróciliśmy zmodyfikowane bajty w jednej z przechwyconych funkcji. Po chwili system się zawiesił – PatchGuard wykrył modyfikację jądra w pamięci i zgłosił BSOD.
Jakikolwiek dodatkowy komentarz jest zbędny.
Użyliśmy KSN, naszej usługi w chmurze, do zgromadzenia statystyk infekcji sektorów startowych bootkitem Xpaj i informacji o detekcji instalatora szkodnika. Najbardziej użyteczne dane, które mogą zostać wyodrębnione z tych statystyk, dotyczą rozkładu geograficznego występowania bootkita i wersji infekowanych systemów operacyjnych.
W roku 2008 zaobserwowaliśmy powrót na scenę starej techniki cyberprzestępczej - infekcji sektora MBR. Od tamtej chwili upłynęło sporo czasu. Dzisiejsze bootkity są owocem nowoczesnej idei "budowania rootkitów". Mechanizm ten na pewno pozostanie w arsenale cyberprzestępców w najbliższej przyszłości.
Zainfekowanie sektora rozruchowego jest bardzo wygodnym sposobem inicjowania złośliwego kodu tak wcześnie, jak to możliwe. Na domiar wszystkiego, oferuje ogromne możliwości w zakresie kontroli uruchamiania systemu operacyjnego.
Rodzina systemów operacyjnych Windows x64 została bardzo rozpowszechniona i twórcy szkodliwego oprogramowania robią wszystko, aby ich złośliwe programy były bardziej uniwersalne i utrzymywały niezmiennie wysoki wskaźnik infekcji.
Firma Microsoft wprowadziła pewne ograniczenia i nowe technologie dla systemów Windows x64, zaprojektowane specjalnie do zwalczania rootkitów. Jednakże w praktyce, ani wymóg, że sterowniki trybu jądra powinny być podpisane ważnymi podpisami cyfrowymi, ani mechanizm PatchGuard nie okazały się skuteczne w poprawie sytuacji. Były i będą rootkity przeznaczone dla 64-bitowych systemów operacyjnych, a ich liczba będzie nieubłaganie rosnąć.
Analizy
Blog