Red Hat 6.x / CentOS 6.x
Tworzenie własnych reguł audytowych daje nam bardzo szerokie możliwości monitorowania szerokiej gamy zdarzeń systemowych i późniejsze ich raportowanie.Wprowadzanie reguł można zrealizować na dwa sposoby - edytując plik reguł lub przy użyciu polecenia auditctl, przy czym reguły wprowadzone przy pomocy komendy nie są persystentne i nie przetrwają restartu maszyny.
Plikiem reguł, z którego korzysta system audytowy jest /etc/audit/audit.rules.
Do weryfikacji załadowanych w systemie reguł używać będziemy polecenia:
[root@server ~]# auditctl -l
No rules
No rules
Jak widać póki co nie mamy zdefiniowanych żadnych reguł audytowych.
Na początku muszę wspomnieć o jednej bardzo istotnej opcji auditctl, a mianowicie -e, czyli możliwości ustawienia flagi dostępności audytu. Flaga może przyjmować trzy wartości:
* 0 - czasowo blokuje audytowanie systemu
* 1 - oznacza normalną pracę systemu audytowego
* 2 - blokuje możliwość edycji reguł audytowych oraz możliwość wyłączenia samego audytowania, i działa do momentu restartu systemu.
Wspominam o niej z prostego powodu - choćby nie wiem jak dobre i szczegółowe reguły stworzymy, potencjaly intruz po zalogowaniu się na system może wykonać polecenie auditctl -e 0 wyłączając system audytowy i na tym skończy się nasza obserwacja jego poczynań.
Ta sama opcja posłuży nam do zapobiegania takim zachowaniom. W momencie, kiedy uznamy, że nasz zestaw reguł jest kompletny, możemy zablokować możliwość zarówno ingerencji w same reguły, jak i wyłączenia audytowania. Zrealizujemy to poprzez auditctl -e 2. Od tego momentu każda zmiana audit-a przez auditctl będzie możliwa dopiero po restarcie serwera (oczywiście jeśli nie dodany opcji -e 2 w pliku reguł).
Aktualny status usługi sprawdzimy przez:
[root@server ~]# auditctl -s
AUDIT_STATUS: enabled=1 flag=1 pid=1481 rate_limit=0 backlog_limit=320 lost=0 backlog=0
AUDIT_STATUS: enabled=1 flag=1 pid=1481 rate_limit=0 backlog_limit=320 lost=0 backlog=0
Same reguły możemy podzielić na trzy typy:
* control rule - będące swego rodzaju modyfikatorami działania samego systemu audytowania (jak np. wspomniana już -e)
* file system rule nazywane również watches przy użyciu których możemy audytować dostępy do plików
* system call rule monitorujące syscalle
Control rules
Przy ich pomocy mamy możliwość ustawienia zachowań i parametrów systemu audytującego:* -b określa wielkość buforu audit-a w kernelu - należy zwiększać go wraz z przyrostem ilości reguł
* -f określa akcję jaka zostanie podjęta w przypadku wykrycia krytycznego błędu, i może przyjmować trzy wartości: 0 - silent, 1 - printk, 2 - panic.
* -e flaga dostępności o możliwych wartościach opisanych już wcześniej
* -r ilość wiadomości generowanych per sekunda - -r 0 określa brak limitu
File system rules
Posłużą nam do audytowania dostępów do plików w systemie dla czterech poziomów:* r - audyt odczytu pliku
* w - audytowanie zapisu do pliku
* x - wykonanie pliku
* a - zmiana atrybutów pliku
Reguły audytowe tego typu mają prostą składnię:
-w sciezka-do-pliku -p poziom -k klucz-reguły
Dla pokazania praktycznego przykładu utwórzmy regułę, która będzie monitorować nam zapis do pliku /etc/passwd:
-w /etc/passwd -p w -k zapis_passwd
Po dodaniu reguły konieczne będzie ich załadowanie poprzez restart systemu audytowego:
[root@server ~]# service auditd restart
Stopping auditd: [ OK ]
Starting auditd: [ OK ]
Stopping auditd: [ OK ]
Starting auditd: [ OK ]
Po dodaniu reguły możemy zweryfikować jej obecność przez:
[root@server ~]# auditctl -l
-w /etc/passwd -p w -k zapis_passwd
-w /etc/passwd -p w -k zapis_passwd
Możemy również zweryfikować, czy nasza reguła działa. Jako, że ma informować o zapisach w pliku /etc/passwd, dokonajmy modyfikacji w pliku i zapiszmy go, np podmieńmy shella dla jednego z użytkowników podmieniając /bin/bash na /bin/sh. Operacja powinna zostać odnotowana a autit.logu:
[root@server ~]# aureport -k --summary
Key Summary Report
===========================
total key
===========================
5 zapis_passwd
Key Summary Report
===========================
total key
===========================
5 zapis_passwd
Jak widać, aureport pokazuje, że zaszły zdarzenia opatrzone naszym kluczem zapis_passwd. Możemy je wyszukać przy pomocy ausearch:
[root@server ~]# ausearch -i -k zapis_passwd
----
type=CONFIG_CHANGE msg=audit(10/08/2015 20:04:54.120:4639) : auid=root ses=517 subj=unconfined_u:system_r:auditctl_t:s0 op="add rule" key=zapis_passwd list=exit res=yes
----
type=PATH msg=audit(10/08/2015 20:09:27.843:4645) : item=3 name=/etc/passwd~ inode=191541 dev=fd:00 mode=file,644 ouid=root ogid=root rdev=00:00 obj=unconfined_u:object_r:etc_t:s0 nametype=CREATE
type=PATH msg=audit(10/08/2015 20:09:27.843:4645) : item=2 name=/etc/passwd inode=191541 dev=fd:00 mode=file,644 ouid=root ogid=root rdev=00:00 obj=unconfined_u:object_r:etc_t:s0 nametype=DELETE
type=PATH msg=audit(10/08/2015 20:09:27.843:4645) : item=1 name=/etc/ inode=130561 dev=fd:00 mode=dir,755 ouid=root ogid=root rdev=00:00 obj=system_u:object_r:etc_t:s0 nametype=PARENT
type=PATH msg=audit(10/08/2015 20:09:27.843:4645) : item=0 name=/etc/ inode=130561 dev=fd:00 mode=dir,755 ouid=root ogid=root rdev=00:00 obj=system_u:object_r:etc_t:s0 nametype=PARENT
type=CWD msg=audit(10/08/2015 20:09:27.843:4645) : cwd=/root
type=SYSCALL msg=audit(10/08/2015 20:09:27.843:4645) : arch=x86_64 syscall=rename success=yes exit=0 a0=0x221a780 a1=0x2246300 a2=0x2 a3=0xf items=4 ppid=12557 pid=12925 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts0 ses=517 comm=vi exe=/bin/vi subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=zapis_passwd
----
type=CONFIG_CHANGE msg=audit(10/08/2015 20:09:27.843:4644) : auid=root ses=517 op="updated rules" path=/etc/passwd key=zapis_passwd list=exit res=yes
----
type=CONFIG_CHANGE msg=audit(10/08/2015 20:09:27.843:4646) : auid=root ses=517 op="updated rules" path=/etc/passwd key=zapis_passwd list=exit res=yes
----
type=PATH msg=audit(10/08/2015 20:09:27.843:4647) : item=1 name=/etc/passwd inode=191544 dev=fd:00 mode=file,644 ouid=root ogid=root rdev=00:00 obj=unconfined_u:object_r:etc_t:s0 nametype=CREATE
type=PATH msg=audit(10/08/2015 20:09:27.843:4647) : item=0 name=/etc/ inode=130561 dev=fd:00 mode=dir,755 ouid=root ogid=root rdev=00:00 obj=system_u:object_r:etc_t:s0 nametype=PARENT
type=CWD msg=audit(10/08/2015 20:09:27.843:4647) : cwd=/root
type=SYSCALL msg=audit(10/08/2015 20:09:27.843:4647) : arch=x86_64 syscall=open success=yes exit=3 a0=0x221a780 a1=O_WRONLY|O_CREAT|O_TRUNC a2=0644 a3=0xf items=2 ppid=12557 pid=12925 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts0 ses=517 comm=vi exe=/bin/vi subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=zapis_passwd
----
type=CONFIG_CHANGE msg=audit(10/08/2015 20:04:54.120:4639) : auid=root ses=517 subj=unconfined_u:system_r:auditctl_t:s0 op="add rule" key=zapis_passwd list=exit res=yes
----
type=PATH msg=audit(10/08/2015 20:09:27.843:4645) : item=3 name=/etc/passwd~ inode=191541 dev=fd:00 mode=file,644 ouid=root ogid=root rdev=00:00 obj=unconfined_u:object_r:etc_t:s0 nametype=CREATE
type=PATH msg=audit(10/08/2015 20:09:27.843:4645) : item=2 name=/etc/passwd inode=191541 dev=fd:00 mode=file,644 ouid=root ogid=root rdev=00:00 obj=unconfined_u:object_r:etc_t:s0 nametype=DELETE
type=PATH msg=audit(10/08/2015 20:09:27.843:4645) : item=1 name=/etc/ inode=130561 dev=fd:00 mode=dir,755 ouid=root ogid=root rdev=00:00 obj=system_u:object_r:etc_t:s0 nametype=PARENT
type=PATH msg=audit(10/08/2015 20:09:27.843:4645) : item=0 name=/etc/ inode=130561 dev=fd:00 mode=dir,755 ouid=root ogid=root rdev=00:00 obj=system_u:object_r:etc_t:s0 nametype=PARENT
type=CWD msg=audit(10/08/2015 20:09:27.843:4645) : cwd=/root
type=SYSCALL msg=audit(10/08/2015 20:09:27.843:4645) : arch=x86_64 syscall=rename success=yes exit=0 a0=0x221a780 a1=0x2246300 a2=0x2 a3=0xf items=4 ppid=12557 pid=12925 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts0 ses=517 comm=vi exe=/bin/vi subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=zapis_passwd
----
type=CONFIG_CHANGE msg=audit(10/08/2015 20:09:27.843:4644) : auid=root ses=517 op="updated rules" path=/etc/passwd key=zapis_passwd list=exit res=yes
----
type=CONFIG_CHANGE msg=audit(10/08/2015 20:09:27.843:4646) : auid=root ses=517 op="updated rules" path=/etc/passwd key=zapis_passwd list=exit res=yes
----
type=PATH msg=audit(10/08/2015 20:09:27.843:4647) : item=1 name=/etc/passwd inode=191544 dev=fd:00 mode=file,644 ouid=root ogid=root rdev=00:00 obj=unconfined_u:object_r:etc_t:s0 nametype=CREATE
type=PATH msg=audit(10/08/2015 20:09:27.843:4647) : item=0 name=/etc/ inode=130561 dev=fd:00 mode=dir,755 ouid=root ogid=root rdev=00:00 obj=system_u:object_r:etc_t:s0 nametype=PARENT
type=CWD msg=audit(10/08/2015 20:09:27.843:4647) : cwd=/root
type=SYSCALL msg=audit(10/08/2015 20:09:27.843:4647) : arch=x86_64 syscall=open success=yes exit=3 a0=0x221a780 a1=O_WRONLY|O_CREAT|O_TRUNC a2=0644 a3=0xf items=2 ppid=12557 pid=12925 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts0 ses=517 comm=vi exe=/bin/vi subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=zapis_passwd
Na tej podstawie możemy generować raporty dla naszego klucza poprzez przekierowanie tego typu zdarzeń do aureport jak to czyniliśmy przy okazji śledzenia programów, np:
[root@server ~]# ausearch --raw -k zapis_passwd | aureport
Summary Report
======================
Range of time in logs: 10/08/2015 20:04:54.120 - 10/08/2015 20:09:27.843
Selected time for report: 10/08/2015 20:04:54 - 10/08/2015 20:09:27.843
Number of changes in configuration: 3
Number of changes to accounts, groups, or roles: 0
Number of logins: 0
Number of failed logins: 0
Number of authentications: 0
Number of failed authentications: 0
Number of users: 1
Number of terminals: 1
Number of host names: 0
Number of executables: 1
Number of files: 3
Number of AVC's: 0
Number of MAC events: 0
Number of failed syscalls: 0
Number of anomaly events: 0
Number of responses to anomaly events: 0
Number of crypto events: 0
Number of keys: 1
Number of process IDs: 1
Number of events: 5
Summary Report
======================
Range of time in logs: 10/08/2015 20:04:54.120 - 10/08/2015 20:09:27.843
Selected time for report: 10/08/2015 20:04:54 - 10/08/2015 20:09:27.843
Number of changes in configuration: 3
Number of changes to accounts, groups, or roles: 0
Number of logins: 0
Number of failed logins: 0
Number of authentications: 0
Number of failed authentications: 0
Number of users: 1
Number of terminals: 1
Number of host names: 0
Number of executables: 1
Number of files: 3
Number of AVC's: 0
Number of MAC events: 0
Number of failed syscalls: 0
Number of anomaly events: 0
Number of responses to anomaly events: 0
Number of crypto events: 0
Number of keys: 1
Number of process IDs: 1
Number of events: 5
Trzeba wspomnieć o jeszcze jednej właściwości watch-y. Jeśli wskazany przez nas do audytu plik będzie katalogiem, audytem objęte zostaną rekurencyjnie wszystkie pliki znajdujące się w nim, z pominięciem katalogów, które są oddzielnymi punktami mountowania.
System Call rules
Reguły te oparte są o wychwytywanie konkretnych calli systemowych, które każdy z działających w systemie programów wykonuje. Lista syscalli jest dość długa i dostępna w skarbnicy wiedzy o systemie, czyli manualu (man syscalls).Podstawowa składania reguł opartych o syscall wygląda następująco:
-a action,list -S syscall -F field=value -k keyname
Pierwsze z pól określa rodzaj akcji oraz filtra, który chcemy zaaplikować. Dostępne są 2 możliwe akcje: always, który zawsze tworzy event w audit.log, oraz never, który nie tworzy go nigdy.
Co do filtrów, możliwości mamy cztery:
* task - sprawdzany jedynie przy tworzeniu zdarzeń potomnych lub klonowaniu syscalla - w praktyce w zasdzie nie używany
* exit - tego filtra używa się najczęściej, gdyż wszystkie calle systemowe oraz plikowe kończą się exit codem, który przez filtr jest "wyłapywany"
* user jest używany do odfiltrowywania (usuwania) niechcianych zdarzeń z przestrzeni użytkownika
* exclude wyłącza pewne typy wiadomości określane przez msgtype
Drugim polem jest syscall, o którym wspominałem już wcześniej. Jest to nie mniej ni więcej typ zdarzenia jakie w systemie miało miejsce, np. chmod, chdir, mount.
Trzecie pole to to jedna lub wiele par typu klucz=wartość dzięki którym doprecyzujemy warunki filtrowania. Pełna lista kluczy, a także możliwych do zastosowania operatorów znajduje się w manualu do auditctl
Ostatnie pole to znany nam już klucz, z jakim nasz event zostanie zalogowany.
Pola -S oraz -F mogą występować w jednej regule wielokrotnie, a warukni w nich zawarte będą "and-owane", czyli wszystkie z nich muszą zostać spełnione, aby reguła zadziałała.
W tym miejscu należy wspomnieć o jeszcze jednej, ważnej a często pomijanej przypadłości reguł audytowych. Reguły powinny być tworzone dla określonej architektury systemowej i wdrażane powinny być z jej deklaracją. Przypadek ten jest szczególnie istotny w systemach bi-architekturowych, gdyż ten sam syscall ma różne identyfikatory w systemach 32 i 64 bitowych.
Dobrą praktyką jest rozbijanie stworzonej przez nas reguły na dwie, przy jednoczesnej deklaracji platformy w jakiej ma działać. Deklarację taką realizujemy korzystając z filtrów -F arch=b32 dla systemu 32 bitowego, oraz -F arch=b64 dla systemów 64 bitowych. Pozostałą treść reguły jest taka sama dla obu architektur, np regułę:
-always,exit -S open -k access
powinniśmy zastąpić dwiema:
-always,exit -F arch=b32 -S open -k access
-always,exit -F arch=b64 -S open -k access
-always,exit -F arch=b64 -S open -k access
Skonstruujmy zatem przykładowy filtr, żeby zademonstrować praktyczne użycie powyższej teorii.
Przykład z punktu widzenia audytu będzie abstrakcyjny, ale prosty do weryfikacji skuteczności reguły. Załóżmy, że chcielibyśmy monitorować tworzenie oraz usuwanie katalogów w naszym systemie.
W pierwszej kolejności poszukajmy syscalla, który może zostać wywołany w takiej sytuacji - ja przeszukałem manual do syscalls na wystąpienie dir. Znalazłem tam kilka calli: chdir, fchdir, mkdir, mkdirat, readdir, rmdir. Sama nazwa calla często jest wystarczająca do określenia czego dotyczy, ale warto zauważyć, że wszystkie posziadają dokumentację w rozdziale 2 manuala, do której zawsze można zajrzeć.
W naszym przypadku oczywistym wyborem wydaje się mkdir dla tworzenia katalogu oraz rmdir dla jego usunięcia. Mniej oczywisty, a konieczny będzie rónież mkdirat, który to odpowiada za tworzenie katalogu w ścieżce relatywnej do katalogu, z którego polecenie zostało wydane.
Znamy syscall-e, stworzenie reguły wydaje się zatem banalne:
[root@server ~]# vi /etc/audit/audit.rules
-a always,exit -F arch=b32 -S mkdir -S mkdirat -k dir_create
-a always,exit -F arch=b64 -S mkdir -S mkdirat -k dir_create
-a always,exit -F arch=b32 -S rmdir -k dir_remove
-a always,exit -F arch=b64 -S rmdir -k dir_remove
Tworzenie oraz usuwanie katalogu będzie logowane z innym kluczem audytowym, dla prostszego rozróżnienia zdarzeń. Po restarcie usługi poprzez service auditd restart możemy sprawdzić klucze zdefiniowane w naszym systemie audytowym:
[root@server ~]# aureport -k
Key Report
===============================================
# date time key success exe auid event
===============================================
1. 10/08/2015 23:21:18 dir_create yes ? 0 4856
2. 10/08/2015 23:21:18 dir_create yes ? 0 4857
3. 10/08/2015 23:21:18 dir_remove yes ? 0 4858
4. 10/08/2015 23:21:18 dir_remove yes ? 0 4859
Key Report
===============================================
# date time key success exe auid event
===============================================
1. 10/08/2015 23:21:18 dir_create yes ? 0 4856
2. 10/08/2015 23:21:18 dir_create yes ? 0 4857
3. 10/08/2015 23:21:18 dir_remove yes ? 0 4858
4. 10/08/2015 23:21:18 dir_remove yes ? 0 4859
Reguły w teorii zostały załadowane, więc czas sprawdzić, czy teoria przekłada się na praktykę, i czy zobaczymy informacje o tworzeniu lub usuwaniu katalogów w naszym audit logu. Test przeprowadzimy tworząc dwa katalogi, a następnie usuwając jeden z nich:
[root@server ~]# mkdir audit_test
[root@server ~]# mkdir audit_test_2
[root@server ~]# rmdir audit_test
[root@server ~]# mkdir audit_test_2
[root@server ~]# rmdir audit_test
Skutek w aureport będzie następujący:
[root@server ~]# aureport -k -i
Key Report
===============================================
# date time key success exe auid event
===============================================
...
15. 10/08/2015 23:26:58 dir_create yes /bin/mkdir root 4888
16. 10/08/2015 23:27:01 dir_create yes /bin/mkdir root 4891
17. 10/08/2015 23:27:24 dir_remove yes /bin/rmdir root 4894
Key Report
===============================================
# date time key success exe auid event
===============================================
...
15. 10/08/2015 23:26:58 dir_create yes /bin/mkdir root 4888
16. 10/08/2015 23:27:01 dir_create yes /bin/mkdir root 4891
17. 10/08/2015 23:27:24 dir_remove yes /bin/rmdir root 4894
Mamy trzy zdarzenia - opisane, jak się zdaje właściwymi kluczami... sprawdźmy więc detale jednego ze zdarzeń:
[root@server ~]# ausearch -a 4891 -i
----
type=PATH msg=audit(10/08/2015 23:27:01.057:4891) : item=1 name=audit_test_2 inode=195941 dev=fd:00 mode=dir,755 ouid=root ogid=root rdev=00:00 obj=unconfined_u:object_r:admin_home_t:s0 nametype=CREATE
type=PATH msg=audit(10/08/2015 23:27:01.057:4891) : item=0 name=/root inode=130653 dev=fd:00 mode=dir,550 ouid=root ogid=root rdev=00:00 obj=system_u:object_r:admin_home_t:s0 nametype=PARENT
type=CWD msg=audit(10/08/2015 23:27:01.057:4891) : cwd=/root
type=SYSCALL msg=audit(10/08/2015 23:27:01.057:4891) : arch=x86_64 syscall=mkdir success=yes exit=0 a0=0x7ffd88992810 a1=0777 a2=0x7ffd88992810 a3=0xa items=2 ppid=12557 pid=13308 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts0 ses=517 comm=mkdir exe=/bin/mkdir subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=dir_create
----
type=PATH msg=audit(10/08/2015 23:27:01.057:4891) : item=1 name=audit_test_2 inode=195941 dev=fd:00 mode=dir,755 ouid=root ogid=root rdev=00:00 obj=unconfined_u:object_r:admin_home_t:s0 nametype=CREATE
type=PATH msg=audit(10/08/2015 23:27:01.057:4891) : item=0 name=/root inode=130653 dev=fd:00 mode=dir,550 ouid=root ogid=root rdev=00:00 obj=system_u:object_r:admin_home_t:s0 nametype=PARENT
type=CWD msg=audit(10/08/2015 23:27:01.057:4891) : cwd=/root
type=SYSCALL msg=audit(10/08/2015 23:27:01.057:4891) : arch=x86_64 syscall=mkdir success=yes exit=0 a0=0x7ffd88992810 a1=0777 a2=0x7ffd88992810 a3=0xa items=2 ppid=12557 pid=13308 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts0 ses=517 comm=mkdir exe=/bin/mkdir subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=dir_create
Widzimy, że katalog audit_test_2 został utworzony (CREATE) a katalogiem nadrzędnym dla niego (PARENT) jest katalog /root. Zdarzenie na wyjściu wygenerowało syscalla, któy został obsłużony przez filtr dir_create.
Tips & tricks
Dokumentacja audit zawiera kilka gotowych do wdrożenia zestawów audytowych opracowanych przez różne instytucje, np. Amerykański Departament Obrony (nispom.rules). Zestawy te można skopiować bezpośrednio z katalogu /usr/share/doc/audit-2.3.7/ zastępując nimi standardowy /etc/audit/audit.rules. Są one również nieocenionym źródłem gotowych reguł audytowych.Troubleshooting
* audit loguje błąd "32/64 bit syscall mismatch in line XX, you should specify an arch" - należy zdefiniować architekturę dla której reguła została stworzona - czyt. w System call rules* entry rules deprecated, changing to exit rule oznacza, że filtr którego próbujemy użyć został zdeprecjonowany w tej wersji audit i należy dostosować regułę do nowych definicji filtrów. Filtr taki zostanie przeniesiony do exit, więc reguła nie zginie, ale aby pozbyć się problemu należy poprawić wpis.
Brak komentarzy:
Prześlij komentarz