/******************************
* LIDS - Opis + Konfiguracja *
******************************/
1. Wstęp
LIDS (Linux Intrusion Detection System) to łatka na jądro Linuxa
wprowadzająca dodatkowy obowiązkowy tryb kontroli dostępu MAC (Mandory Access
Control) oparty o reguły kontroli dostępu ACL (Access Control List). Ponadto
zawiera wbudowany wykrywacz skanowań portów oraz dwa bardzo proste narzędzia do zarządzania systemem. LIDS nie wychwytuje błędów typu Buffer Overflow czy implementuje niewykonywalny stos tak jak robią to łaty grsec oraz owl. Dobrze skonfigurowany LIDS dopuści co prawda do wykorzystania błędu lecz tak okroi prawa intruzowi, że w niczym nie będzie on w stanie zaszkodzić. Jak wiadomo systemy z rodziny *nix posiadają konto "wszechwładnego" administratora (root'a), który ma nieograniczoną władzę. Jeśli intruz w wyniku pozytywnie przeprowadzonego ataku uzyska jego prawa, może tak "edytować" sobie system, że to on będzie prawdziwym jego "władcą". Zdarzają się sytuacje w których prawdziwy niedouczony administrator niezauważa takich zmian przez długie miesiące :).
Tutaj właśnie idealnie sprawuje się LIDS. Jedna linijka potrafi zabezpieczyć
cały katalog /sbin przed modyfikacją plików oraz do instalowywaniem w nim czego kolwiek bez znajomości hasła (do LIDSA) nawet administratorowi.Łatka dostępna jest na kernele z serii 2.2, 2.4 i 2.6 z czego najbardziej funkcjonalna jest łata na wersję 2.4 i ją właśnie tutaj opiszę.
2. Instalacja
Oczywiście potrzebujemy źródeł kernela, muszą być to źródła bez żadnych dodatkowych łatek inaczej LIDS sie niespaczuje, więc ściągamy najlepiej najnowsze jajko z kernel.org. W artykul użyję 2.4.30 czyli najnowszego w tym momencie. No to robim sobie tak:
roott@devils shark # cd /usr/src
root@devils src # wget http://www.kernel.org/pub/linux/kernel/v2.4/linux-2.4.30.tar.bz2
w czasie ściągania źródeł możemy udać się na stronę lids.org oraz ściągnąć
łatkę pod wersję naszego kernela.
root@devils src # wget http://www.lids.org/download/v2.4/2.4.30/lids-1.2.2-2.4.30.tar.gz
Jeśli ściągną się źródła kernela to je wypakowujemy (chyba każdy umie ?)
rozpakowujemy również lidsa i łatamy:
root@devils src # cd linux-2.4.30
root@devils linux-2.4.30 # patch -p1 <../lids-1.2.2-2.4.30/lids-1.2.2-2.4.30.patch
Jeśli wszystko przeszło bez problemów piszemy
root@devils linux-2.4.30 # make mrproper menuconfig
Pojawiła się nam nowa zakładka w konfiguracji kernela
Linux Intrusion Detection System --->
Wchodzimy do niej i zaznaczamy wsparcie a następnie opcje według uznania
(zalecam eksperymentowanie), osobiście zaznaczyłem wszystkie oprócz tych:
- Hang up console when raising security alert (jeśli źle skonfigurujemy LIDSa odetnie nas od systemu)
- Allow any program to switch LIDS protections
- Send security alerts through network
Jeśli skończyliśmy wybór opcji kompilujemy i instalujemy kernel. Jeśli
wszystko się zakończy sukcesem wchodzimy do katalogu lidstools-x.x/ w katalogu w którym wypakował się lids (jeśli robiliście tak jak ja to jest to katalog /usr/src/lids-1.2.2-2.4.30/lidstools-0.5.7) i piszemy
root@devils lidstools-0.5.7 # ./configure KERNEL_DIR=/usr/src/linux-2.4.30
zmienna KERNEL_DIR to ścieżka do spaczowanego kernela, następnie wydajemy polecenia make && make install. Po wydaniu tego ostatniego poproszeni zostajemy o podanie hasła którym będziemy się posługiwać. Ważne aby hasło było INNE niż hasło roota, wtedy intruz nawet znając hasło i wiedząc o zainstalowanym lidsie nie będzie wstanie go wyłączyć.
3. Konfiguracja
Domyślne ustawienia są tak rygorystyczne i ogólne, że niektóre dystrybucje w ogóle się nie zabootują nie mówiąc już o działaniu jakiejkolwiek usługi. Do zarządzania lidsem służą nam dwa programy: lidsconf i lidsadm. Za pomocą lidsconf możemy dodać nowe reguły dostępu (ACL-e) lub sprawdzić
aktualnie używane. Lidsadm służy natomiast do zmiany stanu LIDSa, włączania lub wyłączania zabezpieczenia.
Dobrze ale co to są te stany?
LIDS działa w trzech stanach (dokładnie w 4 ale ten czwarty opisze później ze względu na jego odmienne przeznaczenie):
- BOOT - używany podczas bootowania kernela oraz odpalania wszystkich startujących z systemem usług.
- POSTBOOT - używany podczas normalnej pracy systemu. Przejście ze stanu BOOT
do POSTBOOT wykonuje się wydając polecenie "lidsadm -I"
- SHUTDOWN - stan używany podczas rebootowania lub wyłączania komputera. W stanie tym powinny znajdować się regułki pozwalające bezproblemowo zakończyć działanie systemu.
Skąd wiadomo jakie regułki są już dodane?
Globalne regułki wyświetlamy poleceniem "lidsconf -L".
Globalne czyli takie, które odnoszą się do każdego stanu i jeśli nie
zadeklaruje się wyrażenie, że w jakimś stanie reguła nie obowiązuje, uznaje
się, że jest ona aktywna.
Przed konfiguracją najlepiej jest wyzerować wszystkie regułki i zaczynać od
zera dostosowując je do własnych potrzeb. Wykonujemy to poleceniem "lidsconf -Z". Dla pewności sprawdźmy liste, powinna być pusta.
Jak w ogóle tworzy się regułki?
Lidsconf używa składni tematu i obiektu (subject,object). Tematem może być tylko i wyłącznie program. Obiektem natomiast plik, folder, gniazdo, prawo dostępu.
przykład:
lidsconf -A -o /etc -j READONLY, dodajemy regułkę (-A) dla obiektu (katalog
/etc) z prawem tylko do odczytu (-j READONLY).
lidsconf -A -s /bin/progi -o /etc -j WRITE, dodajemy regułkę z prawem zapisu w katalog /etc przez program /bin/progi.
Widzimy składnia jest banalna. Przy czym możemy dodawać reguły z następującymi prawami (chodzi o prawa wpisywane po parametrze -j):
- DENY - odmowa dostępu. Obiekty tak oznaczone są niedostępne dla
jakiegokolwiek użytkownika lub programu, dopóki nie zostanie to wyraźnie
umożliwione.
- READONLY - Obiekty tylko do odczytu nie mogą być modyfikowane przez nikogo,
włączając w to użytkownika root.
- APPEND - Do tak oznaczonych obiektów możliwe jest dołączanie danych, lecz nie możliwe jest usuwanie ani modyfikacja danych już w pliku istniejących. Najlepiej pasuje do plików logów, które mogą być dopisywane, lecz nie można ich usunąć.
- WRITE - Zezwala na zmianę, usuwanie oraz dowolne modyfikowanie obiektu.
- GRANT - Przyznaje prawo do obiektu.
- IGNORE - Ignoruje wszystkie prawa obiektu określone w danym stanie.
- ENABLE - włącza prawo LIDS_EXEC lub LIDS_SANDBOX.
- DISABLE - wyłącza powyższe prawa.
No dobra, pokażmy teraz kilka podstawowych reguł, które zabezpieczą nam
podstawową instalację systemu. Podstawowa czyli bez żadnej działającej usługi typu ssh ani X-servera.
Na początku zmieńmy w pliku /etc/lids/lids.postboot.cap linijke
"+7:CAP_SETUID" na "-7:CAP_SETUID" oraz w pliku lids.boot.cap włącz prawo 17:CAP_SYS_RAWIO (- oznacza wyłączone, + włączone). W każdym pliku *.cap wyłączyć należy jeszcze dla bezpieczeństwa prawo 10 i 13. Co te prawa dają?
CAP_SETUID pozwala na zmianę ID procesów, wyłączenie go Ściągnie z procesów prawo do zmiany własnego ID na inne. Obiekty, które powinny zmieniać swoje ID (np login i su) przyznamy te prawo własnoręcznie. CAP_SYS_RAWIO zezwoli na dostęp do plików urządzeń (musi być
włączone podczas montowania partycji inaczej system sie nie uruchomi).
CAP_NET_BIND_SERVICE pozwala otwierać porty poniżej numeru 1024. CAP_NET_RAW pozwala na tworzenie i czytanie RAW socketów. Wyłączamy to prawo tak, by żaden sniffer w systemie nie mógł działać. Na końcu artykułu znajduje się link do mojej konfiguracji, jeśli nie chce się komuś bawić może po prostu wgrać ją zamiast domyślnych (tak jest łatwiej).
Z wyzerowanymi regułami i edytowanymi plikami możemy zacząć zabezpieczać system. Ja używam dystrybucji Gentoo więc niektóre programy odnoszą się tylko i wyłącznie do niej. Przed przystąpieniem do konfiguracji zapoznaj się z zasadą działania twojej dystrybucji (pliki startowe rc,położenia programów itd). PAMIĘTAJ, ŻE ŹLE SKONFIGUROWANY SYSTEM MOŻE WOGÓLE SIĘ NIE ODPALIĆ!!! Zawsze zostawiaj jeden działający dziewiczy kernel, żeby w razie czego prze edytować konfigurację.
Wstępna konfiguracja mojego systemu.(wklejmy to do pliku sec.sh i odpalmy (:)
#!/bin/bash
lidsconf -Z
lidsconf -Z BOOT
lidsconf -Z POSTBOOT
lidsconf -A -o /etc/lids -j DENY #chronimy katalog konfiguracyjny lidsa !
lidsconf -A -o /bin -j READONLY #chronimy binarne pliki systemu przed ich
modyfikacją
lidsconf -A -o /sbin -j READONLY
lidsconf -A -o /usr/bin -j READONLY
lidsconf -A -o /usr/sbin -j READONLY
lidsconf -A -o /etc -j READONLY #chronimy konfiguracje systemu
lidsconf -A -o /lib -j READONLY #zabezpieczamy biblioteki
lidsconf -A -o /usr -j READONLY
lidsconf -A -o /etc/lilo.conf -j DENY
lidsconf -A -s /sbin/lilo -o /etc/lilo.conf -j READONLY
lidsconf -A -s /etc/init.d/modules -o /etc/modules.conf -j WRITE
lidsconf -A -o /var/log -j DENY #logi to podstawa, nikt nie ma potrzeby do
nich zaglądać
lidsconf -A -o /etc/shadow -j DENY #hasła pod kontrolą
lidsconf -A -s /bin/login -o /etc/shadow -j READONLY #dajemy prawo do
odczytu,żebyśmy się mogli zalogować (:
lidsconf -A -s /bin/login -o CAP_SETUID -j GRANT #pozwalamy na zmiane ID
lidsconf -A -s /bin/su -o /etc/shadow -j READONLY
lidsconf -A -s /bin/su -o CAP_SETUID -j GRANT
lidsconf -A -s /bin/login -o /var/log -j WRITE
lidsconf -A -o /var/run/utmp -j READONLY
lidsconf -A -s /bin/login -o /var/run/utmp -j WRITE
lidsconf -A -s /bin/login -o /var/log/lastlog -j WRITE
lidsconf -A -s /bin/su -o /var/log -j APPEND
lidsconf -A -s /bin/su -o CAP_PROTECTED -j GRANT
lidsconf -A -s /usr/sbin/syslog-ng -o /var/log -j APPEND #pozwalamy syslogowi na dopis logów
lidsconf -A -s /sbin/init -o /var/log/wtmp -i -1 -j WRITE
lidsconf -A -s /sbin/init -o /var/log/lastlog -i -1 -j WRITE
lidsconf -A -s /sbin/dhcpcd -o CAP_NET_RAW -j GRANT #do poprawnego działania dhcp
lidsconf -A -s /sbin/dhcpcd -o CAP_NET_BIND_SERVICE 68-68 -j GRANT
lidsconf -A -s /sbin/dhcpcd -o /etc -j WRITE
lidsconf -A -s /usr/sbin/cron -o CAP_SETUID -j GRANT #cron
lidsconf -A -s /usr/sbin/cron -o /etc/shadow -j READONLY
lidsconf -A -s /sbin/iptables -o CAP_NET_RAW -j GRANT #iptables
lidsconf -A -s /sbin/iptables -o CAP_SETUID -j GRANT
lidsconf -A -s /bin/ping -o CAP_NET_RAW -j GRANT
lidsconf -A -s /bin/ping -o LIDS_EXEC -j ENABLE #ping najczesciej
wykorzystywany jest w sploitach do uzyskania praw roota. To ograniczenie
pozwala /bin/ping uruchamianie tylko siebie
lidsconf -A -s /bin/ping6 -o CAP_NET_RAW -j GRANT
lidsconf -A -s /bin/ping6 -o LIDS_EXEC -j ENABLE
lidsconf -A -s /sbin/agetty -o /var/log/wtmp -j WRITE
lidsconf -A -s /sbin/hwclock -o /etc/adjtime -j WRITE #aktualizujemy czas
systemowy
lidsconf -A -s /sbin/devfsd -o /lib/dev-state -j WRITE #żebyśmy mogli logować się na innych konsolach
lidsconf -A -o /usr/share/zoneinfo/Europe/Warsaw -j READONLY
lidsconf -A -s /usr/sbin/gpm -o CAP_SYS_RAWIO -i 1 -j GRANT #obsluga myszki na konsoli
Tak zabezpieczony system, pozwala na normalną pracę użytkowników i gwarantuje jego bezpieczeństwo. Na wyjaśnienie zasługuje kilka linijek. Programowi "ping" przyznajemy atrybut LIDS_EXEC. Co ten atrybut daje? Otóż chroni programy przed nadużyciami. Ping jako, że ma przyznany bit suid używany jest często do odpalenia powłoki z prawami roota. Atrybut LIDS_EXEC gwarantuje, że ping będzie mógł wywoływać tylko sam siebie. Jeśli używasz programu, który musi działać z bitem suid, a nie chcesz, żeby padł ofiarą nadużycia dodaj mu ten atrybut. Jednak co nam po tak zabezpieczonym systemie, skoro dostęp mają tylko użytkownicy lokalni? Dopiszmy teraz kilka reguł pozwalających na pracę zdalną przez ssh.
lidsconf -A -o /usr/sbin/sshd -j READONLY
lidsconf -A -o /etc/ssh/sshd_config -j DENY
lidsconf -A -o /etc/ssh/ssh_host_key -j DENY
lidsconf -A -o /etc/ssh/ssh_host_dsa_key -j DENY
lidsconf -A -o /etc/ssh/ssh_host_rsa_key -j DENY
lidsconf -A -s /usr/sbin/sshd -o /etc/ssh/sshd_config -j READONLY
lidsconf -A -s /usr/sbin/sshd -o /etc/ssh/ssh_host_key -j READONLY
lidsconf -A -s /usr/sbin/sshd -o /etc/ssh/ssh_host_dsa_key -j READONLY
lidsconf -A -s /usr/sbin/sshd -o /etc/ssh/ssh_host_rsa_key -j READONLY
lidsconf -A -s /usr/sbin/sshd -o /etc/passwd -j READONLY
lidsconf -A -s /usr/sbin/sshd -o /etc/shadow -j READONLY
lidsconf -A -s /usr/sbin/sshd -o /var/log/wtmp -j WRITE
lidsconf -A -s /usr/sbin/sshd -o /var/log/lastlog -j WRITE
lidsconf -A -s /usr/sbin/sshd -o /var/log/messages -j APPEND
lidsconf -A -s /usr/sbin/sshd -o CAP_SETUID -j GRANT
lidsconf -A -s /usr/sbin/sshd -o CAP_PROTECTED -j GRANT
Sshd dostaje prawo do otwarcia portu 22 (CAP_NET_BIND_SERVICE) w fazie
ładowania systemu, zapisu do logów oraz odczytu shadow do przeprowadzenia autoryzacji oraz własnych plików konfiguracyjnych.
W LIDSie zaimplementowane są również mechanizmy TDE i TPE.
TPE - Trusted Path Execution. W tak uruchomionym LIDSie uruchamiane będą TYLKO pliki (binarki,biblioteki,moduły) chronione MINIMALNIE atrybutem READONLY. Poprawia to bardzo bezpieczeństwo systemu (chroni naprzykład przed atakami typu LD_PRELOAD) ponieważ uruchamiane są tylko pliki, których nie da się zmodyfikować więc muszą być prawdziwe. Pamiętajmy jednak, że pliki prywatne użytkowników będą uważane za niepochodzące z zaufanego źródła i LIDS odmówi ich uruchomienia, co może zaburzyć pracę naszych użytkowników. Aby włączyć ten tryb piszemy:
"lidsadm -I +TPE" (jeśli chcemy aby obowiązywał obrazu po zabootowaniu systemu) lub "lidsadm -S -- +TPE" (aby uruchomić w dowolnej chwili).
TDE - Trusted Domain Enforcement. Jeśli włączymy TDE w kernelu, LIDS wymusza swoją politykę dla każdego procesu. Uprzywilejowane procesy czytające dane z niechronionych plików (nie oznaczonych jako DENY albo READONLY) spychane są poza domenę TDE i tracą wszystkie swoje prawa. Znacząco poprawia to bezpieczeństwo jeśli jakiś program może być nadużyty przez dane z niechronionego pliku. Jeśli chcemy zapobiec wykluczeniu z domeny bezpieczeństwa nadajemy plikowi atrybut CAP_PROTECTED, tak jak to zrobiłem dla sshd i su. Su czyta dane ze standardowego strumienia wejścia, którego nie można oznaczyć jakimkolwiek atrybutem, wypchnięcie "su" z TDE pozbawia go
podstawowych funkcji do których jest napisany (zmiana ID użytkownika).
TDE zaimplementowany ma jeszcze mechanizm LIDS_SANDBOX. Do złudzenia przypominam on "chroot". Żeby ochronić program tym trybem wydajemy proste polecenie:
lidsconf -A -s /moj/program -o LIDS_SANDBOX -j ENABLE
Przyjmuje się, że każdy plik tak oznaczony NIE MOŻE NIC. Wszystko co potrzebne do działania programu (biblioteki,atrybuty) trzeba wyraźnie dodać. Pokażmy przykład kopii basha, który może wykonywać podstawowe polecenia i poruszać się po wyznaczonych katalogach.
devils shark # cp /bin/bash /home/shark/shark
devils shark # ldd /home/shark/shark (bibloteki używane przez basha)
libdl.so.2 => /lib/libdl.so.2 (0x40030000)
libc.so.6 => /lib/libc.so.6 (0x40034000)
/lib/ld-linux.so.2 (0x40000000)
ACL'e:
lidsconf -A -o /home/shark/shark -j READONLY
lidsconf -A POSTBOOT -s /home/shark/shark -o LIDS_SANDBOX -j ENABLE
lidsconf -A POSTBOOT -s /home/shark/shark -o /lib/libdl.so.2 -j READONLY
lidsconf -A POSTBOOT -s /home/shark/shark -o /lib/libc.so.6 -j READONLY
lidsconf -A POSTBOOT -s /home/shark/shark -o /lib/ld-linux.so.2 -j READONLY
lidsconf -A POSTBOOT -s /home/shark/shark -o /etc/ld.so.preload -j READONLY
lidsconf -A POSTBOOT -s /home/shark/shark -o /etc/ld.so.cache -j READONLY
Tak utworzony shell nie może NIC. Każde polecenie jakie może wykonać trzeba dodać ręcznie np:
lidsconf -A POSTBOOT -s /home/shark/shark -o /home/shark -j WRITE
Widzimy, że mamy możliwość zrobić idealne zamknięte środowisko, które
utemperuje zamiary nawet najbardziej nachalnych użytkowników.
Możemy również wsadzić w TDE każdą usługę zapewniając jej dostęp tylko do tego co jest jej wymagane do działania.
Jeśli chcemy zaktualizować system, można bez problemu wyłączyć LIDSa tylko na tej konsoli z której aktualizację przeprowadzimy, jak? Bardzo prosto. "lidsadm -S -- -LIDS" spowoduje to wyłączenie wszystkich ograniczeń na konsoli na której został uruchomiony. Po updejcie systemu, MUSIMY updejtować konfigurację LIDSa poleceniem "lidsconf -U", inaczej ochrona przestanie działać.
Można wykonywać jeszcze następujące przejścia.
-/+LIDS wyłącza/włącza lokalnie LIDSa
-/+LIDS_GLOBAL wyłącza/włącza GLOBALNIE LIDSa
+RELOAD_CONF wczytuje konfigurację od nowa
+POSTBOOT uruchamia stan POSTBOOT (zalecane używanie lidsadm -I, najlepiej dopisać to polecenie do skryptów startowych)
+SHUTDOWN włącza tryb tuż przed zamknięciem systemu.
-/+TPE wyłącza/włącza mechanizm TPE
-/+ACL_DISCOVERY wyłącza/włącza tryb uczenia. W trybie tym zabezpieczenia NIE działają, raportowane są tylko wszystkie czynności w logach. Przydaje się, gdy nie wiemy jaki program jakie operacje wykonuje, lub dlaczego się nie włącza.
4. Podsumowanie.
Czemu LIDS? Raz skonfigurowany, może być przeniesiony na dowolny system niemal bez poprawek (lub z ich minimalną ilością). Bardzo prosta obsługa. Mi się podoba. Bardzo poprawia bezpieczeństwo przy minimalnym wkładzie pracy.
5. Bibliografia
[1] www.lids.org
[2]
Moje pliki konfiguracyjne