Auditd - Wprowadzenie cz. 2 - Security Bez Tabu

Auditd – Wprowadzenie cz. 2

Kontynuacja poprzednich wątków

W ostatnim wpisie poznaliśmy podstawy linuxowego systemu audytującego – Audit, potocznie nazywany auditd (po nazwie daemona).

W tym artykule skupimy się na rulkach, które mają na celu monitorowania wywołań systemowych (syscalle) oraz sprawimy, że detekcje przetrwają reboot systemu.

Jeśli chcesz przypomnieć sobie podstawy Audit, sprawdź ostatni wpis pod tym linkiem: Auditd – Wprowadzenie cz. 1

Takie detekcje przydadzą się w wielu sytuacjach m.in jak chcemy monitorować akcje, które wykonuje użytkownik root. Możemy definiować wywołania systemowe, których obserwowaniem jesteśmy zainteresowani.

Kolejnym przykładem rulki, która opiera swoje działanie na wywołaniach systemowych, byłoby monitorowanie nieudanych prób tworzenia plików/folderów.

Jest to elastyczne rozwiązanie, dające spory zakres możliwości.

Detekcje wywołań systemowych

Do utworzenia takich detekcji wykorzystujemy poniższy syntax:

$ auditctl -a akcja,filtr -S syscall -F klucz=wartosc -k tag

Przeanalizujmy ten syntax:

-a akcja/filtr określają kiedy konkretne zdarzenie powinno zostać zarejestrowane. Akcja może przyjmować wartość always lub never. Filtr może przyjmować następujące wartości: task, exit, user, exclude.

always – zawsze rejestruj zdarzenie
never – nie rejestruj zdarzenia

task – sprawdzany tylko podczas fork lub clone syscalls. Rzadko używany.
exit – miejsce, w którym wszystkie requesty są sprawdzane.
user – używany do filtrowania zdarzeń, które pochodzą z user space.
exclude – używany do wykluczenia wybranych zdarzeń.

-S syscall – określa system call po nazwie. Listę nazw syscalli możemy znaleźć w /usr/include/asm/unistd_64.h. W jednej rulce możemy określić kilka syscalli: -S syscall1 -S syscall2 -S syscall3 …

-F klucz=wartość – określa dodatkowe opcje, dzięki którym możemy wyszukiwać tylko interesujące nas zdarzenia.

Pełną listę „fields” możemy znaleźć w

$ man auditctl 8

-k tag – mieliśmy już okazję spotkać się z tym argumentem, jest to „tag”, który możemy dać naszej rulce co ułatwi nam wyszukanie eventów, które nasza detekcja wyłapała.

Jeśli chcesz dowiedzieć się więcej o syntaxie, najlepszym miejscem będzie man page: ? https://man7.org/linux/man-pages/man7/audit.rules.7.html

Tworzymy detekcje

Znamy już syntax, załóżmy że mamy potrzebę biznesową monitorowania wszystkich programów/komend (nie shell-bultins) wykonywanych przez roota.

Do tego będzie nam potrzebny syscall, który odpowiada za uruchomienie binarek/skryptów. Po dość szybkim googlowaniu możemy znaleźć syscall execve().

https://www.badprog.com/unix-gnu-linux-system-calls-using-execve

Poniżej gotowa rulka:

$ auditctl -a always,exit -F arch=b64 -F euid=0 -S execve -k root_execve

Rulke możemy rozumieć jako: zawsze rejestruj wywołania systemowe execve() gdy euid=0 (Effective User ID użytkownika root) oraz arch=b64 (architektura CPU wywołania systemowego 64 bit – użyj komendy uname -m by sprawdzić swoją)

Ciekawy artykuł o euid: https://linuxhint.com/difference-between-real-effective-user-id-in-linux-os/

!!Uwaga, nie określając arch, dostaniemy błąd **arch mismatch** – zalecam ustawienie tego parametru. Musi zostać określony przed opcją **-S**.

Testujemy detekcje

Wykonajmy jakąś prostą akcje za pomocą konta root, na przykład wyświetlenie zawartości pliku shadow:

$ cat /etc/shadow

W logach  następnie znajdziemy:

Na screenie widzimy wszystkie recordy o unikalnym id 170. Uwagę na pewno przykuwa EXECVE, który przechowuje informacje o komendzie i argumentach.

type=EXECVE msg=audit(1645468200.970:170): argc=2 a0="cat" a1="/etc/shadow"

Na podstawie tego recordu, moglibyśmy już tworzyć jakieś detekcje w dowolnym SIEMie, lub skorelować go z innymi eventami, dzięki czemu otrzymamy dużo ciekawsze rulki.

Ta detekcja może być trochę “głośna” i generować dosyć dużo szumu, wymagałaby dodatkowych filtrów.

Mechanizm persistence

Aby nasze rulki mogły przeżyć reboot, musimy je umieścić w pliku /etc/audit/audit.rules lub utworzyć plik nazwa.rules i umieścić go w  /etc/audit/rules.d/. Ważne jest, żeby plik w rules.d miał nazwę *.rules – inne pliki są ignorowane.

Bonus

https://raw.githubusercontent.com/Neo23x0/auditd/master/audit.rules

W powyższym linku znajdziemy plik z best practice konfiguracją by Florian Roth (twórca Sigmy!) – jak widać całkiem aktualną. Moim zdaniem jest to idealny punkt startowy do nauki jak i do wdrożenia testowo w ramach nauki.

Podsumowanie

Dowiedzieliśmy się czym są i jak zbudować rulki wywołań systemowych w auditd. Udało się nam również sprawić, że nasze detekcje przetrwają reboot. ? Auditd zbiera dosyć dużo negatywnych opinii ze względu na to, że log jest rozbity na kilka recordów. Nie jest to problemem jeśli wiemy co możemy znaleźć w poszczególnym record typie i jak korelujemy je po unikalnym id. Przy okazji nie sposób nie poruszyć tematu SysmonForLinux – dosyć świeża sprawa, także zanim na dobre wyprze auditd, myślę że minie jeszcze trochę czasu. ?

Więcej możecie znaleźć na: https://github.com/Sysinternals/SysmonForLinux

O Autorze

Paweł Mazur

Inżynier bezpieczeństwa, fanatyk Linuxa i wszystkiego co z nim związane – głównie aspektów security. Posiada doświadczenie Blue Teamowe, jak i Red Teamowe. Entuzjasta rozwiązań open source – Sigma etc. Obecnie rozwija się w aspektach Detection Engineering. Lubi dzielić się wiedzą na kanale YouTube, podczas live streamów. Jego rulki możesz znaleźć TUTAJ lub TUTAJ.

Dziękujemy autorowi za to, że zechciał podzielić się swoją wiedzą i doświadczeniem na łamach SecurityBezTabu.pl