Zdobycie dostępu to połowa sprawy; druga połowa polega na tym, żeby go nie stracić. Dlatego niemal całe zautomatyzowane szkodliwe oprogramowanie w pierwszej kolejności zapewnia sobie ponowne uruchomienie: po restarcie, po usunięciu pliku, po zmianie hasła. Stąd typowa historia — „posprzątaliśmy, a dwa dni później wróciło”.
Miejsc, w których się to urządza, nie ma znowu tak wiele i wszystkie da się sprawdzić w kilka minut. Poniżej pełny obchód po kolei.
1. Klucze SSH
Najprostszy sposób na powrót: wiersz w authorized_keys przeżyje zmianę hasła, aktualizację systemu i restart.
sudo find /home /root -name authorized_keys -exec ls -l {} \; -exec cat {} \;
Każdy wiersz to czyjś stały dostęp. Jeśli nie da się powiedzieć czyj, uznajemy go za obcy. Warto też zwrócić uwagę na komentarz na końcu wiersza: to dowolny tekst i zgodność z naszym imieniem niczego nie dowodzi.
2. Zadania crona wszystkich użytkowników
Sprawdzać trzeba nie tylko własną crontab:
for u in $(cut -f1 -d: /etc/passwd); do echo "== $u"; sudo crontab -u "$u" -l 2>/dev/null; done
sudo ls -la /etc/cron.d/ /etc/cron.hourly/ /etc/cron.daily/
sudo cat /etc/crontab
Na co zwracać uwagę: wiersze @reboot, długie zakodowane polecenia, wywołania curl albo wget przekazywane do powłoki, wszystko, co uruchamia się z /tmp, /dev/shm albo /var/tmp. Z tych katalogów nie uruchamia się nic zwyczajnego.
3. Liczniki czasu i usługi systemd
Współczesny odpowiednik crona, sprawdzany zauważalnie rzadziej:
systemctl list-timers --all
systemctl list-units --type=service --state=running
sudo ls -la /etc/systemd/system/ /run/systemd/system/
Osobno usługi użytkownika, które działają bez uprawnień roota i nie trafiają na ogólną listę:
systemctl --user list-units --type=service
sudo ls -la /home/*/.config/systemd/user/
Jeszcze jeden szczegół: włączone dla użytkownika podtrzymanie sesji (loginctl enable-linger) pozwala jego usługom działać bez aktywnej sesji. Sprawdza się to poleceniem loginctl list-users.
4. Pliki startowe powłoki
Kod dopisany na końcu pliku startowego powłoki wykonuje się przy każdym logowaniu:
sudo tail -5 /root/.bashrc /root/.profile /home/*/.bashrc /home/*/.profile
sudo ls -la /etc/profile.d/
Patrzeć trzeba właśnie na koniec pliku — tam się dopisuje, żeby nie rzucało się w oczy przy pobieżnym przejrzeniu.
5. ld.so.preload
Plik zmuszający system do wczytania wskazanej biblioteki do każdego uruchamianego procesu. W normalnych warunkach nie powstaje nigdy:
ls -l /etc/ld.so.preload
Jego obecność to praktycznie jednoznaczna oznaka poważnej kompromitacji, a taka biblioteka zwykle ukrywa i pliki, i procesy, i połączenia sieciowe. Nic, co zobaczymy dalej na tej maszynie, nie zasługuje na zaufanie.
6. Zaczepy menedżera pakietów
Metoda, o której rzadko się pamięta: apt potrafi wykonywać polecenia przed każdą operacją na pakietach i po niej.
sudo ls -la /etc/apt/apt.conf.d/
sudo grep -r 'DPkg::Pre-Invoke\|DPkg::Post-Invoke\|APT::Update' /etc/apt/apt.conf.d/
Taki zaczep uruchamia się przy każdej instalacji aktualizacji — czyli regularnie i z uprawnieniami roota.
7. Wiadomość dnia w Ubuntu
Katalog /etc/update-motd.d/ zawiera skrypty wykonywalne uruchamiane przy każdym logowaniu po SSH, które składają tekst powitania. Miejsce jest wygodne właśnie tym, że wygląda na systemowe:
sudo ls -la /etc/update-motd.d/
8. Odroczone zadania at
sudo atq
sudo ls -la /var/spool/cron/atjobs/ 2>/dev/null
Mechanizm stary i rzadko używany, a przez to sprawdzany najrzadziej ze wszystkich.
Kolejność działań, jeśli coś się znajdzie
Pierwszy odruch to natychmiast usunąć znalezisko. To błąd: razem z nim zniknie informacja o tym, jak się tam znalazło, a bez odpowiedzi na to pytanie wszystko się powtórzy.
- Zachować kopię pliku albo zadania i jego czas modyfikacji.
- Po tym czasie sprawdzić w dziennikach serwera WWW i w
auth.log, co działo się w tej samej minucie. Zwykle właśnie tam jest punkt wejścia. - Sprawdzić wszystkie osiem miejsc z listy, a nie tylko to, w którym coś znaleziono. Furtki prawie nigdy nie zostawia się w jednym egzemplarzu.
- Dopiero potem sprzątać i zamykać samą podatność.
Wiedzieć, jak wygląda norma
Główna trudność tego sprawdzenia to nie polecenia, lecz to, że nieznany wiersz na liście zadań nie wygląda podejrzanie, jeśli nie pamiętamy, jak ta lista wyglądała wcześniej. Na serwerze konfigurowanym przez kogoś innego albo konfigurowanym rok temu odróżnienie swojego od obcego jest prawie niemożliwe.
Stąd praktyczny wniosek: migawkę stanu „jak jest” warto zrobić dzisiaj, dopóki serwer jest w porządku. Lista zadań crona, liczników czasu, kluczy i usług na zdrowej maszynie to wzorzec, z którym będziemy potem porównywać. Zebrana i zachowana wraz z historią zamienia poszukiwanie furtki z wielogodzinnego zajęcia w porównanie dwóch list. Jak to wygląda, pokazują strony demonstracyjne poniżej.