Rootkit (od ang. root – nazwy konta administratora w systemach uniksowych oraz kit – zestaw) – oprogramowanie pozwalające atakującemu na ukrycie obecności innych komponentów malware w systemie[1]. Według definicji NIST jest to zestaw narzędzi używanych przez atakującego po uzyskaniu uprawnień administratora (root), który służy do ukrycia jego działań i utrzymania dostępu do systemu[2].
Rootkit ukrywa niebezpieczne pliki i procesy, które umożliwiają utrzymanie kontroli nad systemem.
Historycznie rootkity były zestawami narzędzi, które włamywacz instalował w systemie uniksowym po uzyskaniu uprawnień konta root, aby utrzymać kontrolę nad systemem i ograniczyć ryzyko wykrycia[3]. Zawierały one zmodyfikowane wersje kluczowych programów systemowych, np. inetd, sshd i ps, które zastępowały oryginalne tuż po dokonaniu włamania[4]. Dzięki modyfikacjom w oryginalnym kodzie programy z rootkita np. nie pokazywały wybranych procesów lub umożliwiały logowanie na roota za podaniem specjalnego hasła. Od takich zestawów (ang. kits) pochodzi nazwa, którą przejęto także dla systemu Windows, choć nie ma w nim konta root[3].
Rootkity działające w trybie jądra infekują jądro tak, by ukrywane procesy i pliki nie pojawiały się na listach zwracanych innym programom. Rootkit może zostać załadowany jako moduł jądra, a następnie usunięty z dysku, przez co po ponownym uruchomieniu systemu praktycznie nie pozostawia śladów[5]. Rootkit może np. ukryć siebie i konia trojańskiego przed administratorem oraz oprogramowaniem antywirusowym. Ukrywanie odbywa się najczęściej przez przejęcie wybranych funkcji systemu operacyjnego, służących np. do wyświetlania listy procesów lub plików w katalogu, a następnie „cenzurowanie” zwracanych przez te funkcje wyników tak, by ukrywane przez rootkit nazwy nie znajdowały się na liście wynikowej.
Istnieją rootkity dla różnych systemów operacyjnych, m.in. Microsoft Windows, Solaris, Mac OS X i FreeBSD. Rootkity mogą działać w trybie użytkownika (ang. user mode) lub w trybie jądra (ang. kernel mode).
Rootkit może się dostać do komputera użytkownika wraz z aplikacją będącą w rzeczywistości trojanem.
Skuteczność programów antywirusowych wykrywających złośliwe oprogramowanie na podstawie sygnatur ograniczają rootkity, które ukrywają pliki na dysku, a nawet ślady swojej obecności w pamięci. Narzędzia wykrywające działają zwykle w tym samym systemie co złośliwy program, dlatego rootkit może je całkowicie oszukać, np. podając im fałszywe informacje[6]. Takie techniki stosowała m.in. komercyjna wersja rootkita Hacker Defender, przygotowana do atakowania poszczególnych narzędzi wykrywających dostępnych na rynku[7].
Do wykrywania rootkitów stosuje się technikę porównania krzyżowego (ang. cross-view), w której zestawia się dwa obrazy systemu: wynik zwrócony przez API systemu operacyjnego oraz stan odczytany bezpośrednio z jądra lub sprzętu. Pozwala to wykryć ukryte pliki, procesy i wpisy rejestru. Z tej techniki korzystają m.in. narzędzia Blacklight, RootkitRevealer i Strider GhostBuster[6]. W zdrowym systemie oba wyniki powinny być identyczne. Rekordy, które występują w drugim z nich, ale nie zwraca ich API, są prawdopodobnie ukrywane przez rootkit. W ten sam sposób porównanie listy plików odczytanej z obrazu dysku w innym systemie z listą zwracaną przez badany system pozwala wskazać pliki ukrywane przez rootkit działający w jądrze[5].
Inna metoda wykorzystuje to, że sekcje kodu są w nowoczesnych systemach operacyjnych tylko do odczytu, a programy nie powinny modyfikować własnego kodu. Narzędzie System Virginity Verifier, zaprezentowane w 2005 roku przez Joannę Rutkowską[6], sprawdza, czy sekcje kodu ważnych bibliotek dynamicznych (DLL) i sterowników jądra są takie same w pamięci operacyjnej i w odpowiadających im plikach na dysku[7]. Modyfikacja kodu wykonywalnego w pamięci może więc świadczyć o działaniu rootkita. Haków (ang. hooks) typowych dla rootkitów szukają w systemie m.in. narzędzia VICE i System Virginity Verifier[6].
W systemach uniksowych do automatycznego wyszukiwania rootkitów służą m.in. programy rkhunter i chkrootkit. Wykrywają one jednak tylko niektóre, powszechnie znane rootkity na podstawie sygnatur zapisanych jawnym tekstem, a niewielka zmiana w kodzie rootkita wystarcza, by uniknąć wykrycia[4]. Same narzędzia są zwykłymi skryptami powłoki, które w zaatakowanym systemie łatwo podmienić, dlatego przed ich użyciem należy sprawdzić ich integralność[5].
Rootkity wykrywa się także przez analizę zrzutu pamięci operacyjnej, np. programem Volatility, którego moduły sprawdzają m.in. tablicę wywołań systemowych i ukryte moduły jądra[5][8]. Rootkit może jednak wykryć wykonywanie obrazu dysku lub zrzutu pamięci działającego systemu i ukryć swoją obecność, np. przenosząc się w inne miejsce lub tymczasowo się dezaktywując[5].
Ponieważ w zarażonym systemie rootkit może kontrolować praktycznie wszystkie kroki narzędzia, które próbuje go wykryć, istniejące metody niewiele pozwalają zrobić w zakresie usunięcia rootkitów jądra poza uruchomieniem komputera z czystego obrazu systemu operacyjnego, np. z nośnika LiveCD[9]. Z tego samego powodu informacje uzyskane z działającego, potencjalnie skompromitowanego systemu mogą zostać sfałszowane przez rootkit na poziomie jądra. Analizę powłamaniową prowadzi się dlatego na kopii binarnej dysku albo z systemu uruchomionego z zewnętrznego nośnika, np. LiveCD, z badanym dyskiem zamontowanym w trybie tylko do odczytu. Po wykryciu włamania jedynym bezpiecznym rozwiązaniem jest w praktyce pełna reinstalacja systemu[5].
Nawet reinstalacja nie usuwa jednak rootkitów zapisanych w oprogramowaniu układowym UEFI, które przetrwają reinstalację systemu operacyjnego, a nawet wymianę dysku. Pierwszy taki rootkit wykryty w rzeczywistych atakach, LoJax, opisała w 2018 roku firma ESET. Wykorzystała go grupa Sednit (APT28) przeciwko organizacjom rządowym. Jego usunięcie wymaga ponownego zapisania pamięci flash czystym obrazem oprogramowania układowego właściwym dla danej płyty głównej, a jedyną alternatywą jest wymiana płyty głównej. Według ESET takie rzadkie zagrożenia są wymierzone przede wszystkim w cele o wysokiej wartości[10].