Stan zagrożeń w internecie znajduje się obecnie na poziomie standardowym. Nie występują duże epidemie a eksperci z Kaspersky Lab nie zanotowali żadnych poważnych incydentów związanych z bezpieczeństwem. Poziom zagrożenia: 1

Rootkity oraz metody ich zwalczania


Jedną z największych trudności napotykanych przez twórców wirusów jest ukrycie obecności złośliwego kodu przed użytkownikiem zainfekowanego komputera. Dla autora wirusów idealnie byłoby, gdyby złośliwy program nie został wykryty także przez rozwiązania antywirusowe. Teraz, gdy pisanie wirusów przestaje być jedynie hobby i coraz częściej staje się zajęciem przynoszącym korzyści finansowe, zacieranie śladów ma coraz większe znaczenie dla hakerów, którzy piszą złośliwe programy dla pieniędzy. Jak można więc ukryć program, który kradnie informacje dotyczące konta bankowego lub instaluje serwer proxy w celu rozsyłania spamu bez wiedzy właściciela komputera?

Współcześni cyber-przestępcy przyjmują podejście stosowane przez cybernetycznych wandali 10-15 lat temu. Jednym z pierwszych znanych wirusów dla komputerów PC był Virus.Boot.Brain.a. Ten wirus sektora startowego przechwytywał systemowe funkcje dostępu do dysku. Podczas odczytywania sektora startowego (np. przez rozwiązanie antywirusowe) wirus zamieniał zainfekowane dane oryginalnymi. Od tej pory takie mechanizmy ukrywania (przechwytywanie funkcji systemu i zamienianie danych) stosowane były w wirusach dla systemu Windows. (Virus.Win32.Cabanas.a).

Obecnie złośliwe programy dla systemu UNIX nie są tak rozpowszechnione jak te dla środowiska DOS i Windows. Termin "rootkit" został zapoczątkowany w świecie Uniksa. Obecnie jednak stosowany jest na określenie technologii ukrywania stosowanych przez autorów koni trojańskich dla systemów Windows. Początkowo "rootkit" oznaczał zestaw programów, które pozwalały hakerowi na uniknięcie wykrycia. W tym celu należy zastąpić wykonywalne pliki systemowe (takie jak ligin, ps, ls, netstat itd.) lub biblioteki systemowe (libproc.a) lub zainstalować moduł jądra. Obydwa sposoby służą temu samemu: uniemożliwiają użytkownikom otrzymanie dokładnych informacji o tym, co się dzieje w komputerze.

Jak pokazuje Wykres 1, coraz częściej stosuje się rootkity w celu zamaskowania obecności złośliwego kodu w zainfekowanych systemach.

Graph 1.
Wykres 1. Zwiększenie zastosowania rootkitów w złośliwych programach

Wzrost popularności rootkitów spowodowany jest częściowo dostępnością w Internecie ich kodu źródłowego. Twórcy wirusów bez trudu dokonają niewielkich modyfikacji takiego kodu. Innym czynnikiem wpływającym na rozpowszechnienie rootkitów jest to, że większość użytkowników systemu Windows używa konta administratora zamiast tworzenia oddzielnego konta użytkownika. Znacznie ułatwia to zainstalowanie rootkita na komputerze ofiary.

Twórcy wirusów i producenci pseudo-legalnego oprogramowania typu spyware widzą dla siebie unikatową reklamę w możliwości wykorzystania rootkitów do ukrycia obecności złośliwego kodu zarówno przed użytkownikami, jak i rozwiązaniami antywirusowymi.

Przyjrzyjmy się bliżej rootkitom dla systemów Windows i UNIX.

Rootkity dla systemów Windows

Metody maskowania

Obecnie rootkity stosują dwie metody w celu maskowania swojej obecności w systemie:

  1. modyfikowanie ścieżek
  2. modyfikowanie struktur systemu

Metody te służą zamaskowaniu aktywności sieciowej, kluczy w rejestrze, procesów, tj. wszystkiego, co mogłoby skłonić użytkownika do zwrócenia uwagi na złośliwy program w systemie.

Pierwszą metodę można zastosować w rootkitach zarówno w trybie użytkownika, jak i jądra. W przypadku rootkitów w trybie użytkownika implementacja jest stosunkowo prosta. W celu modyfikacji ścieżki najczęściej wykorzystywana jest metoda opierająca się na przechwytywaniu funkcji API.

Pic 2. Hooking API functions
Rys. 2. Przechwytywanie funkcji API.

Metoda ta wykorzystuje fakt, że aplikacje wywołują funkcje API przy użyciu specjalnych pól danych (tabela importowa/eksportowa) lub przez połączenie się z adresem uzyskanym za pomocą funkcji API "GetProcAddress". Kod programu zaimplementowany jest w modułach DDL, które są następnie integrowane z przestrzenią adresową istniejących procesów systemowych. Dzięki temu zdalny haker może kontrolować wszystkie aplikacje użytkownika. Modyfikacja ścieżek jest dobrze udokumentowaną i łatwą w implementacji metodą, którą można często zastosować w rootkitach.

Pomimo wielu zalet podejście to posiada również poważne wady: rootkit nie jest w stanie zamaskować aktywności ze stuprocentową skutecznością. Oznacza to, że rootkit w trybie użytkownika jest łatwy do wykrycia w systemie przy użyciu wyspecjalizowanych narzędzi, takich jak RootKit Revealer, SoftIce itd. Niewątpliwie jest to przyczyną rosnącej popularności rootkitów w trybie jądra pomimo faktu, że znacznie trudniej jest je stworzyć.

Rootkity w trybie jądra znacznie lepiej maskują informacje. Większość z nich wykorzystuje nieudokumentowane struktury systemu operacyjnego. Rootkity te często przechwytują na przykład usługi z tabeli KeServiceDescriptorTable. Liczba usług w tej tabeli różni się w zależności od wersji systemu operacyjnego. Oznacza to, że przy opracowywaniu rootkitów należy przeprowadzić dodatkową analizę kodu systemu operacyjnego, aby znaleźć w tabeli wykaz programów obsługi. Podejście to jest bardzo zbliżone do przechwytywania funkcji API.

Modyfikacja PsActiveProcessList jest jednym z przykładów drugiego podejścia, tj. zmiany struktur systemu. Podejście to wykorzystywane jest przez rootkit FU i umożliwia mu ukrycie każdego procesu przed większością narzędzi systemowych.

Pic. 3. Process list before the rootkit is launched
Rys. 3. Lista procesów przed uruchomieniem rootkita
Pic. 4. Process list after the rootkit is launched
Rys. 4. Lista procesów po uruchomieniu rootkita.

Ilustracja pokazuje, że program Notepad widnieje na liście aktywnych procesów jako notepad.exe (zaznaczony czerwoną obwódką). Zrzut ekranu na rysunku 4 został wykonany po uruchomieniu rootkita FU z poleceniem ukrycia procesu. Zrzut ekranu pokazuje, że nawet jeśli edytor jest aktywny, jego proces nie jest widoczny na liście aktywnych procesów.

Wykrywanie rootkitów

Pierwszym krokiem w zwalczaniu rootkitów jest ich wykrycie. Autorzy rootkitów zawsze mogą o krok wyprzedzać narzędzia do ich wykrywania, ponieważ nieustannie rozwijają nowe technologie, natomiast producenci oprogramowania antywirusowego potrzebują czasu do zanalizowania tych technologii i opracowania narzędzi wykrywających. Pomimo złożoności rootkitów produkty firmy Kaspersky Lab w wersji 6 posiadają zdolność skutecznego wykrywania rootkitów (Wersja 6.0 przechodzi obecnie wewnętrzne testy). W jaki sposób produkty firmy Kaspersky Lab reagują na opisane powyżej rootkity FU?

Dla przypomnienia: instalacja rootkita spowodowała ukrycie procesów systemowych. Podsystem przeznaczony do zwalczania rootkitów wykrywa to i ostrzega użytkownika (rysunek 5).

Pic.5 Detecting unknown, hidden processes
Rys. 5. Wykrywanie nieznanych, ukrytych procesów

Podsystem pozwala na wykrycie nie tylko rootkitów, które zostały już dodane do antywirusowych baz danych, ale również tych nieznanych, jak pokazuje rysunek 6.

Podobny podsystem wykorzystywany jest do wykrywania rootkitów w trybie użytkownika (omówionym w pierwszej części artykułu), który wprowadza DLL do innych procesów.

W takich wypadkach podsystem reaguje powiadamiając użytkownika, że określony proces próbuje wprowadzić kod do innego procesu (rysunek 6).

Pic.6. Detecting code injection into another process
Rys. 6. Wykrywanie wprowadzania kodu do innego procesu

Rootkity dla systemu UNIX

Maskowanie obecności w systemie

W systemach Unix rootkity wykorzystywane są w taki sam sposób jak w systemach Windows. Haker instaluje rootkita na komputerze ofiary, jak tylko zdoła uzyskać przywileje administratora. Przywileje te są niezbędne do zainstalowania większości rootkitów i można je uzyskać wykorzystując znane luki w zabezpieczeniach pod warunkiem, że haker posiada standardowe przywileje użytkownika w systemie ofiary. Zdalny użytkownik może wykorzystać lokalny exploit lub narzędzie do złamania bazy danych haseł. Jeśli haker nie posiada odpowiednich uprawnień, w celu przechwycenia haseł może użyć zdalnego eksploita lub aplikacji podsłuchującej (sniffera). Hasła można przechwytywać w szeregu różnych usług (ftp, telnet itd.), ponieważ wszystkie te usługi przesyłają hasła poprzez sieć w formie czystego tekstu.

Rootkity mogą zawierać wiele różnych złośliwych programów (Trojan-DDos, backdoor itd.), które po zainstalowaniu na zainfekowanym komputerze będą czekały na polecenia od zdalnego hakera. Dodatkowo, rootkity mogą również zawierać łaty na luki w systemie mające na celu uniemożliwienie przeniknięcia do systemu innego hakera.

Podobnie jak w przypadku systemu Windows, rootkity dla Uniksa mogą wykorzystywać zarówno tryb użytkownika, jak i tryb jądra.

Rootkity w trybie użytkownika posiadają zazwyczaj trojańskie wersje standardowych programów, które maskują obecność ich komponentów w systemie oraz backdoora, który umożliwia ukryty dostęp do systemu. Przykłady rootkitów w trybie użytkownika obejmują lkr, trOn, ark. Przyjrzyjmy się rootkitowi w trybie użytkownika na przykładzie trOn. W celu zamaskowania swojej obecności w systemie rootkity te wykonują szereg czynności. Po zainstalowaniu rootkit zatrzymuje demona syslogd, a następnie zastępuje swoją własną trojańską wersją następujące narzędzia systemowe: du, find, ifconfig, login, ls, netstat, ps, top, sz. Poza tym, do systemu dodawana jest trojańska wersja demona sshd. Na koniec w tle zostaje uruchomiony sniffer. Do pliku inetd.conf zostaje dodane polecenie uruchamiające demony telnetd, rsh oraz finger; inetd zostaje powtórnie uruchomiony, a syslogd zrestartowany.

TrOn zazwyczaj zlokalizowany jest w /usr/src/.puta. Katalog ten jest jednak niewidoczny z powodu komponentu ls, który został już zainstalowany.

Przyjrzyjmy się teraz rootkitom w trybie jądra. Rootkity tego typu posiadają wszystkie funkcje rootkitów w trybie użytkownika, ale na niższym poziomie. Rootkity w trybie użytkownika przeznaczone są do modyfikacji poszczególnych plików binarnych, podczas gdy rootkity w trybie jądra mogą modyfikować tylko jądro. Rootkity te są znacznie efektywniejsze w maskowaniu aktywności.

Istnieje kilka metod wprowadzenia rootkitów do jądra systemu:

  1. wykorzystanie LKM: jądro Linuksa (podobnie jak w wielu innych systemach operacyjnych) umożliwia podładowanie modułów (lub sterowników urządzeń) w locie, co pozwala zdalnemu hakerowi na modyfikację odwołań systemu do jądra i prowadzi do zwrócenia nieprawidłowych informacji (np. zmodyfikowana lista plików). Atakom takim można zapobiec kompilując jądro monolityczne bez obsługi LKM. Jednak wadą tego rozwiązania jest to, że jądro musi posiadać wszystkie sterowniki.
  2. zapisanie (rootkita) w /dev/kmem, co pozwala na uzyskanie dostępu do obszaru pamięci zajmowanej przez jądro. Powoduje to przepisanie jądra bez powiadamiania użytkownika. Jądro można zmodyfikować poprzez zlokalizowanie odpowiedniego obszaru pamięci. Można jednak dokonać modyfikacji, kóre uniemożliwią zapisanie bezpośrednio do /dev/kmem. Zapisanie do /dev/kmem możne również zostać wykonane przy użyciu odwołań mmap.
  3. infekcja istniejących modułów; metoda ta różni się od pierwszego sposobu tym, że sam rootkit nie zawiera oddzielnego modułu i wprowadza się do istniejących modułów. Oznacza to, że rootkit "opiera się" ponownemu uruchomieniu systemu, ponieważ infekuje moduły, które są zawsze ładowane (np. sterowniki systemu plików).

Wykrywanie rootkitów

Niestety podanie uniwersalnych metod wykrywania rootkitów jest niemożliwe. Następujące czynności można jednak zastosować w przypadku większości rootkitów:

  1. śledzenie nietypowych zachowań plików, zużycia zasobów sieciowych, uruchamiania zadań według terminarza oraz po ponownym uruchomieniu komputera, monitorowanie kont użytkownika.
  2. zastosowanie następujących narzędzi, które mogą być pomocne w wykryciu obecności rootkita w systemie: Saint Jude, Chrootkit, RkScan, Carbonite, Kstat, Rootkithunter, Tripware, Samhain i inne.

Wnioski

Wszystkie metody wykrywania aktywnych rootkitów wykorzystują fakt, ze rootkity w ten czy inny sposób zakłócają funkcjonowanie systemu. Tę właściwość rootkitów wykorzystują produkty firmy Kaspersky Lab. Dzięki temu potrafią również wykrywać nieznane rootkity. Znacznie trudniej będzie napisać rootkity dla przyszłych wersji systemu Windows, które nie będą pozwalały na modyfikację kodu i architektury systemowej. Przedsięwzięcie to powinno zmniejszyć, przynajmniej na jakiś czas, liczbę nowych rootkitów dla nowych wersji systemów Windows.

Obecnie złośliwe programy dla systemu Windows są bardziej rozpowszechnione niż dla systemu UNIX, ponieważ Windows jest najpopularniejszym systemem operacyjnym. Sytuacja zmieni się jednak wraz ze wzrostem popularności Uniksa; tworzone będą nowe rootkity dla Uniksa oraz nowe metody ich zwalczania.

Należy pamiętać, że najlepszą ochroną przed rootkitami jest podjęcie działań zapobiegawczych poprzez zapewnienie systemom właściwej ochrony.

Bibliografia

  1. [Encyklopedia Wirusów] Kaspersky Lab, Viruslist.pl, 2005
  2. [iDEF2003] Anton Chuvakin, An Overview of Unix Rootkits, 2003
  3. Linux Kernel Rootkit. Rainer Wichmann
  4. Rootkit: Attacker undecover tools. Saliman Manap
  5. www.phrack.org
  6. www.securityfocus.org