Auditd – Wprowadzenie cz. 1

Wsparcie w monitorowaniu bezpieczeństwa Linux

Linuxowy system audytujący pozwala na generowanie istotnych pod względem bezpieczeństwa eventów na systemie. Opiera swoje działanie na tzw. rulach, czyli detekcjach, które to konfigurujemy, gdy uznamy, że jakiś plik, komenda etc. jest warty „obserwowania”. Informacje, które Audit generuje, są niezbędne/kluczowe w tworzeniu detekcji dla SOCa w SIEMie, analizie po włamaniowej, różnych raportach, wykrywaniu błędnej konfiguracji.

WAŻNE: Istotne jest zrozumienie, że Audit nie zapewnia nam dodatkowej warstwy zabezpieczeń, ale pozwala raczej na wykrywanie akcji, które uznajemy za podejrzane.

Auditd działa na poziomie kernela. Mamy możliwość monitorowania dostępu do plików/katalogów, ruchu sieciowego, wywołań systemowych itp.

Auditd jest bardzo szczegółowy, jedna akcja – wywołanie komendy, wygeneruje nam wiele eventów. Każdy z tych eventów zawiera informacje, które razem tworzą pełny obraz. Eventy powiązane są ze sobą za pomocą współdzielonego unikalnego ID. Więcej o “unikalnym ID” zobaczymy podczas tworzenia naszej pierwszej rulki 😉

Sam w sobie jest logging systemem, co oznacza że nie korzysta z sysloga – wszystko odbywa się za pomocą narzędzi dostarczanych w pakiecie auditd.

Konfiguracja auditd może być zarówno łatwa lub skomplikowana, ale już z podstawowym zestawem rulek możemy osiągnąć całkiem fajny poziom monitoringu na naszym systemie.

Auditd jest dostarczany z defaultowymi rulkami, które znajdziemy w /usr/share/audit/sample-rules/ (RHEL-based distro):

Najtrudniejsza część konfiguracji to ustalenie jaki plik, binarka czy też system call powinien być monitorowany w naszym środowisku.

Konfiguracja Auditd

Do przykładów wykorzystuję Rocky Linux 8.5:

Auditd powinien być już zainstalowany w dystrybucjach RHEL-based. Dla Debiana etc. standardowo można zainstalować oprogramowanie za pomocą:

 $ apt install auditd audispd-plugins

W pakiecie znajdziemy dosyć spory zakres tooli, których będziemy używać. Na potrzeby tego wstępu do auditd skupimy się na dwóch: auditctl oraz ausearch.

auditctl – konfiguracja rulek

ausearch – wyszukiwanie eventów

Możemy wyróżnić 3 rodzaje rulek audytujących:

  1. Rulki kontrolujące – ogólne rulki kontrolujące system audit
  2. Rulki „obserwujące” – monitorują pliki i foldery
  3. Syscall – rulki monitorujące wywołania systemowe (syscalle)

Rulki audit są zaciągane do kernela w czasie bootowania systemu lub ręcznie za pomocą komendy auditctl. Możemy je zdefiniować w pliku /etc/audit/audit.rules. W ten sposób uzyskamy “persistence” pomiędzy bootami. Możemy je również tworzyć poprzez przekazywanie ich jako argumenty do komendy auditctl – nie jest to rozwiązanie idealne, jeśli chcemy zachować nasze detekcje po reboocie 😉

Tworzymy pierwszą detekcję

Nasza pierwsza detekcja będzie z kategorii rulek obserwujących. Załóżmy, że chcemy obserwować zmiany w pliku .bashrc – jest to plik często wykorzystywany przez atakujących do tworzenia backdorów, czy innych mechanizmów persistence. (Więcej info o metodologii – TUTAJ)

Żeby zacząć monitorować zmiany w pliku .bashrc wykorzystamy poniższą rulkę:

$ sudo auditctl -w /home/*/.bashrc -p wa -k bashrc_changes

W tym miejscu warto przypomnieć, że dodawanie rulek za pomocą komendy auditctl, nie jest “trwałe” i rulka nam zniknie po reboocie.

Rozbijmy syntax naszej rulki na czynniki pierwsze:

sudo auditctl – wywołanie komendy auditctl (niezbędne są uprawnienia roota)
-w /home/*/.bashrc – argument watch i po nim ścieżka do pliku/katalogu, który chcemy monitorować
-p wa – argument permission i po nim “typ dostępu”, który spowoduje wygenerowanie eventu (r=read,w=write, x=execute, a=attribute change)
-k bashrc_changes – argument key to swego rodzaju tag, który możemy dać naszej rulce – znacznie ułatwi to późniejsze wyszukiwanie eventów

Auditd monitoruje zmiany w swojej konfiguracji, i dodanie nowej rulki możemy zobaczyć w recordzie typu CONFIG_CHANGE:

Testujemy detekcje

Proces inżynierii detekcji jasno mówi nam, że nasze detekcje należy testować, więc wykonamy akcję (edytujemy plik .bashrc), która powinna wygenerować nam event.

Za pomocą komendy vim /home/pawel/.bashrc otworzymy plik, a następnie dodamy komentarz na końcu pliku:

Po zapisaniu pliku, użyjemy komendy:

$ sudo ausearch -i -k bashrc_changes

sudo ausearch –  wywołanie komendy ausearch, która służy do przeszukiwania logów audit (niezbędne są uprawnienia roota)
-i – argument interpret, który “dekoduje” wartości numeryczne na tekstowe. np. timestamp na date, uid na nazwę użytkownika/konta
-k bashrc_changes – argument key, klucz (tag) po którym przeszukujemy logi audit

Powyżej możemy zobaczyć screen z eventami, które zostały wygenerowane, gdy dokonaliśmy zmian w pliku .bashrc. Możemy tu zauważyć różne typy eventów. Każdy z nich przekazuje inne informacje. Wprawne oko od razu zauważy, że w większości eventy składają się z  par: klucz=wartość.

Informacje o dostępnych typach eventów tzw. recordów można znaleźć TUTAJ.

PROCTITLE – zawiera informacje o wywołanej komendzie
PATH – zawiera informacje o plikach, jakie “brały” udział w akcji
CWD – inaczej current working directory – z jakiego miejsca akcja została wykonana
SYSCALL – wywołanie systemowe, tu znajdziemy m.in użytkownika, komendę, binarkę, typ syscalla

Zwróćmy uwagę na wartość msg=audit(01/10/2022 19:17:35.490:222) – 222 to “unikalny ID”, który jest współdzielony dla wszystkich typów recordów dla naszej akcji. Swoją drogą timestamp (data), dla wszystkich eventów też będzie taka sama 😉 Często w swoich detekcjach bazujących na auditd korzystam z wartości “timestamp_id” – czyli w tym wypadku byłaby to wartość: 1641838655.490:222. Żeby zobaczyć timestamp z ausearch wyrzucimy switch -i:

Podsumowanie

W tym artykule dowiedzieliśmy się, czym jest auditd i dlaczego warto jest z niego korzystać. Utworzyliśmy naszą pierwszą detekcję, która niestety nie jest trwała (zniknie po reboocie) – tym zajmiemy się w następnym artykule poświęconym auditd. 😉