Czas wrócić do kontynuowania serii artykułów poświęconych polskim projektom w branży security. Pierwszy artykuł gdzie możecie dowiedzieć się co nieco o rozwoju projektu PE-bear, znajdziecie na portalu Zaufana Trzecia Strona. Dzisiaj natomiast poświęcimy uwagę rozwiązaniu Linux Kernel Runtime Guard (LKRG), które z każdym wydaniem zyskuje coraz większe uznanie branżowych ekspertów. Jest liczącą się przeszkodą choćby dla Metasploita, znacznie utrudniając exploitację systemu Linux.
Co to jest LKRG
LKRG to moduł jądra Linuxowego, który odpowiada za jego ochronę przed podatnościami bezpieczeństwa lub technikami exploitacji. Jego działanie polega na weryfikacji integralności jądra w trybie informowania o podejrzanych anomaliach lub ich blokowania po wykryciu. Jego skuteczność potwierdzają choćby rekomendacje użycia LKRG jako ochrony przed podatnościami np. przez CISA (amerykańska Agencja ds. Cyberbezpieczeństwa i Bezpieczeństwa Infrastruktury) lub Red Canary. W sieci można także znaleźć badania naukowe, które podejmują aspekt wykorzystania LKRG w specyficznych środowiskach np. TEE. Nie można też pominąć opracowania Alexandra Popova, który poświęcił trochę czasu i pracy aby obejść LKRG.
Linux Kernel Runtime Guard jest możliwy do użytku praktycznie w każdej dystrybucji linuxowej. Część z nich dostarcza LKRG w swoim repozytorium (np. Rocky Linux, Gentoo, Arch, NixOS, OpenBMC, Yocto oraz inne), a w niektórych jest zainstalowany natywnie np. Whonix (znany jako TorBox) czy Kicksecure.
Kto tworzy LKRG?
LKRG został stworzony przez Adama “pi3” Zabrockiego, który jest uznanym w branży ekspertem bezpieczeństwa IT. Adam jest m.in. odkrywcą błędów w architekturze RISC-V, hypervisorach KVM, Hyper-V, mikrokodzie Intela, jądrze Linux, oprogramowaniu OpenSSH czy też Apache oraz innych. Jest on również autorem artykułu o exploitacji i obchodzeniu różnych mechanizmów mitygacji w magazynie Phrack. Był także prelegentem na konferencjach BlackHat, DefCon. Dwukrotnie nominowany do nagrody Pwnie Award. Obecnie pracuje w NVIDIA jako Director of Offensive Security oraz pracuje nad nowymi rozszerzeniami ISA do poprawy bezpieczeństwa procesorów RISC-V będąc zarazem Vice Chair grupy roboczej J-ext dla tejże architektury. Więcej o autorze możecie usłyszeć w jednym z odcinków Rozmowy Kontrolowanej.
W roli lidera projektu LKRG występuje także Solar Designer, legenda sceny bezpieczeństwa, a także twórca oprogramowania John The Ripper oraz projektu Openwall. Opracował kilka znanych technik exploitacji jak np. “return-to-libc attack”. W 2009 roku na konferencji Black Hat został wyróżniony nagrodą Pwnie Award w kategorii “Lifetime Achievement Award”.
Jak mogę użyć LKRG w praktyce?
LKRG nie jest inwazyjnym rozwiązaniem, ale jego efektywność bazuje na dostosowaniu konfiguracji pod środowisko w którym ma docelowo pracować. Rekomendujemy zatem skorzystanie z dokumentacji przed pierwszym wykorzystaniem. Instrukcja jak zainstalować, uruchomić i skonfigurować LKRG jest dostępna w repozytorium projektu na Githubie.
Zanim jednak rozpoczniecie testowanie lub używanie LKRG w praktyce – gorąco rekomendujemy zapoznanie się z odpowiedziami Adama oraz Solara.
Co słychać w projekcie?
Postanowiliśmy o to zapytać twórcę projektu Adama, a także lidera projektu Solara.
Adwersarz.pl: Jak oceniacie obecny rozwój LKRG – czy jesteście na etapie, który Was satysfakcjonuje? Czy projekt spełnia Wasze pierwotne założenia?
Adam: LKRG jest na etapie, na którym jest wystarczająco stabilny aby go używać, ale nie czujemy się jeszcze komfortowo żeby wydać wersję 1.0. Istnieje kilka obszarów, które wymagają poprawy, a niektóre części kodu mogłyby zostać napisane w bardziej stabilny i elegancki sposób. Niektóre z funkcji, które planujemy dodać powinny być częścią wersji 1.0, ale nie podjęliśmy jeszcze ostatecznej decyzji w tej sprawie.
Jeśli chodzi o “założenia” to zmieniają się one w czasie. Niektóre z nich są z pewnością spełnione, a inne nie.
Jakimi sukcesami LKRG może się już pochwalić w Waszej ocenie?
Adam: LKRG jest z pewnością używany na produkcji w wielu miejscach, a także jest badany w innych. Osobiście uważam, że to duży sukces, że ten projekt działa i chroni serwery produkcyjne (nie tylko pojedynczy serwer, ale czasami centra danych).
Co więcej, ludzie i społeczność rozpoznają ten projekt. Odcisnął on swoje piętno w społeczności i jest brany pod uwagę podczas oceny bezpieczeństwa Linuxa.
Jestem świadomy różnych prac uniwersyteckich, które odnoszą się do LKRG. Niektórzy ludzie napisali swoje prace dyplomowe oceniające LKRG lub porównujące go z innymi rozwiązaniami. Dodatkowo LKRG był badany przez znanych badaczy bezpieczeństwa, a niektóre frameworki exploitów ostrzegają w przypadku wykrycia LKRG.
Biorąc to wszystko pod uwagę, założyłbym, że LKRG ma co najmniej umiarkowany sukces 🙂
Czy LKRG powinno być uruchamiane domyślnie w najpopularniejszych dystrybucjach z przeznaczeniem zarówno na desktopy jak i serwery? Do tej pory jego użytek rekomendowaliście osobom i dystrybucjom, które są związane mocno z bezpieczeństwem i prywatnością.
Adam, Solar: Nie zmieniliśmy tutaj naszej opinii. Ogólnie rzecz biorąc LKRG nie jest przeznaczony do uruchamiania na komputerach stacjonarnych z systemem Linux (chociaż używam go na moim komputerze stacjonarnym, a moi znajomi, którzy używają Linuxa na komputerach stacjonarnych również go używają – Adam).
W typowych systemach/dystrybucjach Linuxa i tak nie ma zbyt wielu lokalnych zabezpieczeń w sposobie w jaki te systemy są konfigurowane i używane. Niezależnie od wszelkich lokalnie wykorzystywanych luk w jądrze Linuxa. Tak więc dodanie LKRG spowodowałoby niespójne bezpieczeństwa, a w szczególności w typowym systemie desktopowym opartym o Linux z jednym użytkownikiem. Istnieje tam jedno konto użytkownika, które używa “sudo” aby uzyskać dostęp do roota więc jest to efektywny odpowiednik roota.
LKRG i tak zapewnia istotne wzmocnienie bezpieczeństwa takich systemów – może wykryć exploit podatności przeglądarki internetowej próbujący uciec z piaskownicy (sandbox) przeglądarki internetowej. Może więc pomóc np. podatnym systemom wytrzymać ataki na nie w konkursie Pwn2Own. Nie jest to jednak sposób w jaki większość systemów użytkowników końcowych jest narażona na zagrożenia.
Pasjonat bezpieczeństwa może jednak rozsądnie używać LKRG na swoim systemie stacjonarnym. Przede wszystkim w celu zachowania spójności z innymi systemami oraz w celu wcześniejszego przetestowania kombinacji jądro + LKRG przed wdrożeniem na serwerach, którymi dana osoba zarządza.
Niemniej jednak uważamy, że uruchamianie LKRG na różnych serwerach z dostępem do Internetu powinno być korzystne. LKRG pomaga w systemach w których jest wielu użytkowników (lub przynajmniej pseudo-użytkowników dla wielu usług). Zwłaszcza tam gdzie jądra mogą nie być aktualizowane lub restartowane w odpowiednim czasie po wykryciu nowych luk.
Czy uzyskaliście kiedykolwiek informacje od użytkowników, że LKRG ocalił ich przed groźnym atakiem?
Adam, Solar: Wielu użytkowników zgłosiło, że LKRG blokuje programy typu exploit i ucieczki z kontenerów podczas testów lub symulacji ataków. Obecnie nie są nam znane przypadki blokowania prawdziwych ataków. Podejrzewamy, że wynika to z kilku powodów w tym z faktu, że włamania do systemów Linux nie są tak częste. Zwłaszcza tam gdzie komuś zależało na wdrożeniu LKRG, a zatem prawdopodobnie zależało mu również na zabezpieczeniu systemu na inne sposoby, a monitorowanie dzienników jest rzadkie.
Co więcej, podczas rozwoju LKRG odkryliśmy wiele błędów w jądrze Linuxa. W 2020 roku, gdy Adam aktywnie dodawał nowe funkcje LKRG znalazł ponad 5 błędów w jądrze Linux z których kilka było lukami bezpieczeństwa i otrzymało przypisane CVE.
LKRG cieszy się dosyć aktywną społecznością – czy dostaliście już jakieś ciekawe informacje o nietypowym zastosowaniu LKRG w praktyce lub używaniu go w jakichś niecodziennych środowiskach?
Adam: Z pewnością wiemy o ludziach wdrażających LKRG w urządzeniach/produktach IoT sprzedawanych na rynku chińskim. Niektóre z nich integrują LKRG z Androidem (co nie jest naszym standardowym przypadkiem użycia) skompilowanym za pomocą LLVM (zamiast gcc).
Solar, Adam: Niektóre osoby były bardzo zainteresowane uruchamianiem LKRG w czasie rzeczywistym (RT) jądra Linux na swoich systemach stacjonarnych. Sugerując, że moglibyśmy chcieć wspierać te jądra również dla urządzeń medycznych. Jądra RT byłyby dla nas nietrywialne do wsparcia, a medyczny przypadek użycia jest niespójny z LKRG, który przedkłada bezpieczeństwo nad ochronę. Więc przynajmniej na razie dodaliśmy (kontrowersyjne) zabezpieczenia aby zapobiec kompilacji LKRG dla jądra RT. Możemy ponownie rozważyć obsługę jądra RT w przyszłości.
Czy Metasploit nadal odpuszcza exploitację widząc LKRG na atakowanym systemie czy jednak już radzi sobie lepiej?
Adam: Jest to pozostawione indywidualnemu twórcy exploita. Jeśli exploit zignoruje takie zdarzenie z frameworka Metasploit to jest mało prawdopodobne, że atak się powiedzie.
Jak oceniacie dostępne obecnie metody obchodzenia zabezpieczeń zapewnianych przez LKRG?
Adam: Aby w pełni odpowiedzieć na to pytanie, czuję się zobowiązany odpowiedzieć na nieco inne pytanie. Dlaczego stworzyliśmy LKRG?
Pomysł napisania czegoś takiego jak LKRG narastał w mojej głowie od dłuższego czasu. Pierwsze poważne próby napisania czegoś podobnego sięgają 2009 roku i mojej pracy w CERN. Jednak decyzję o napisaniu pierwszej linii kodu LKRG z jego obecną funkcjonalnością (bardziej zaawansowaną w porównaniu do 2009 roku) podjąłem w 2015 roku. Pierwsza wersja LKRG (0.0) została wydana w styczniu 2018 roku pod parasolem Openwall.
Jak widać zmagałem się sam ze sobą czy istnieje potrzeba takiego projektu. Trochę czasu zajęło mi przekonanie samego siebie, że jest to coś ważnego i potrzebnego. Odpowiedź na pytanie “dlaczego napisałem LKRG” jest taka sama jak argumenty, które przekonały mnie do pociągnięcia za spust i stworzenia LKRG. Jest ich kilka:
- Od pewnego czasu (od 2003/2004 roku) jestem inżynierem ds. bezpieczeństwa ofensywnego koncentrującym się na rootkitach i exploitach. Zdałem sobie sprawę, że w zasadzie wiele technik “infekowania” jądra Linuxa nie zmieniło się w ogóle przez ostatnie ponad 20 lat.To samo dotyczy wielu technik exploitowania jądra.
- Inne systemy operacyjne również borykały się z podobnymi problemami. Próbowano jednak im zaradzić i opracowano niektóre z rozwiązań. Nie są one idealne oraz istnieją sposoby na ich ominięcie (choć nie jest to tanie), ale jest to lepsze niż bycie otwartym na te same ponad 20-letnie techniki.
- Z biegiem lat nauczyłem się, że nawet jeśli niektóre zabezpieczenia są niedoskonałe to mogą znacznie zmniejszyć niezawodność wykorzystania błędu (exploit) lub je utrudnić. W większości przypadków jest to wystarczająco dobre aby powstrzymać masowe ataki, które nie są wymierzone w konkretnych użytkowników, a tym samym chronić ich.
- Nauczyłem się również, że w przeważającej większości przypadków ludzie, którzy piszą rootkity lub exploity nie są tymi samymi ludźmi, którzy ich używają. Jeśli podczas ataku ci drudzy napotkają nietrywialną ochronę lub sam exploit nie jest wystarczająco niezawodny (np. z powodu LKRG), nie będą potrafili lub nie będą zawracać sobie głowy dostosowywaniem narzędzi i przeniosą się na inny cel.
- Jednak nawet jeśli będą w stanie i zechcą dostosować narzędzia, może być już za późno ponieważ LKRG podejmie odpowiednie działania (np. wywoła kernel panic), które będą widoczne dla właściciela systemu.
Warto dodać, że o ile mi wiadomo wszystkie technologie anty-exploitowe/bezpieczeństwa (w tym mitygacje) podążają tą samą ścieżką i są generalnie możliwe do obejścia, przykładowo:
- Firewalle są banalne do obejścia, ale wciąż się ich używa.
- Antywirusy są banalne do obejścia, ale ludzie płacą za nie pieniądze.
- Mitygacje:
- ASLR, a zwłaszcza KASLR są łatwe do obejścia, ale ludzie nadal chcą mieć je włączone w systemie.
- Pamięć niewykonywalna jest łatwa do obejścia, ale ludzie nadal chcą mieć ją włączoną w systemie.
- SMEP jest łatwy do obejścia, ale ludzie nadal chcą mieć go włączonego w systemie
- Ciasteczka stosu można obejść, ale ludzie wciąż kompilują z nimi kod binarny
- RelRO można obejść, ale ludzie nadal włączają tę flagę.
- Każdą technologię typu ATP (np. Capsule8, Crowdstrike, WDATP i wiele innych) można obejść lub całkowicie wyłączyć (niektóre z nich działają w trybie użytkownika!), ale ludzie płacą dużo pieniędzy, aby z nich korzystać.
LKRG nie różni się tutaj niczym z wyjątkiem “ceny” ponieważ wiele z tych technologii nie jest dostępnych za darmo.
Biorąc to wszystko pod uwagę doszedłem do wniosku, że LKRG może poprawić ekosystem Linuxa i przynieść użyteczne funkcje bezpieczeństwa z których każdy może skorzystać. Spowoduje to również przeniesienie niektórych “porównywalnych funkcji” z innych systemów operacyjnych do świata Linuxa takich jak Patch Guard, Advanced Threat Protection (ATP), monitorowanie i inne:
– https://en.wikipedia.org/wiki/Kernel_Patch_Protection
– https://digitalguardian.com/blog/what-advanced-threat-protection-atp
Krótko mówiąc, LKRG nie powinien być postrzegany jako samodzielna warstwa ochronna, ale raczej jako dodatkowa warstwa bezpieczeństwa, którą można dodać do istniejącej, a nie ją zastąpić.
W 2020 roku Michael Larabel przeprowadził ciekawe testy wydajnościowe LKRG. Wyniki wskazywały, że można spodziewać się 5% utraty wydajności systemu z uruchomionym LKRG. Czy od tamtego czasu zrealizowaliście jakieś optymalizacje czy jednak uważacie, że taki wynik jest ok?
Adam, Solar: Projekt Phoronix i sam Michael wykonali świetną robotę oceniając 2 różne wersje LKRG. Wdrożyliśmy optymalizacje między tymi 2 wersjami.
Wpływ na wydajność jest kontrowersyjnym tematem ponieważ tak naprawdę zależy od przypadku użycia i środowiska w którym LKRG jest wdrażany. Średnio, przy domyślnej konfiguracji koszt wydajności LKRG wynosi około 2,5% (co potwierdziły testy Phoronix). Jednak w niektórych przypadkach użycia w których nowe zadania i pliki tymczasowe są często tworzone i usuwane – wpływ na wydajność jest umiarkowanie wyższy (i był znacznie wyższy przed wspomnianymi optymalizacjami). W niektórych syntetycznych testach porównawczych powtarzających tylko pewną najbardziej dotkniętą operację w ciasnej pętli, wpływ na wydajność może wyglądać jak katastrofa (nawet dwa razy wolniej), ale nie odzwierciedla to ogólnego wpływu w rzeczywistych przypadkach użycia.
Co zaskakujące dla niektórych, kilka benchmarków ma tendencję do otrzymywania niewielkiego wzrostu wydajności pod LKRG – to znaczy iż LKRG sprawia, że są one szybsze. Trudno jest dokładnie określić dlaczego. Może to wskazywać, że typowy wpływ LKRG na wydajność (przynajmniej dla tych przypadków użycia) mieści się w zwykłych różnicach w wydajności systemu obserwowanych między podobnymi konfiguracjami systemu, kompilacjami oprogramowania, ponownym uruchomieniem systemu itp. W naszym przypadku, między obciążeniem LKRG a jego brakiem. Taka rozbieżność prawie zawsze istnieje, np. z powodu względnego czasu zdarzeń, ASLR i ograniczeń aliasingu pamięci podręcznej procesora.
Czy w coraz powszechnym wykorzystywaniu technologii typu Docker, Kubernetes oraz podobnych rozwiązań – uważacie, że LKRG będzie świetnym wsparciem dla serwerów?
Adam: Tak, LKRG może być korzystne w każdym środowisku z różnymi warstwami izolacji, które muszą być chronione i wzmacniane. Przestrzenie nazw są tego doskonałym przykładem, a niektóre ataki, które zostały zablokowane w symulacjach użytkowników (wspomniane w jednej z poprzednich odpowiedzi) były dokładnie próbami ucieczki Dockera przez interfejs UMH, który LKRG blokuje. To samo dotyczy piaskownic (np. opartych na seccomp)
Rozważacie wdrożenie dedykowanego wsparcia dla usług monitorujących (np. SIEM), które mogłyby agregować alerty z LKRG do ostrzegania o anomaliach?
Solar: Tak. Dzięki wsparciu firmy Binarly wdrożyliśmy wbudowane w LKRG zdalne rejestrowanie komunikatów jądra, w tym własnych alertów LKRG, za pośrednictwem prostej warstwy bezpieczeństwa transportu. Może to stać się częścią rozwiązania SIEM/EDR, choć obecnie nie mamy własnych planów w tym zakresie.
– https://www.openwall.com/presentations/BSidesZagreb2024-Linux-remote-logging
Czy spotkaliście się z przypadkiem, że LKRG stworzył komuś problemy w infrastrukturze i doprowadził do jakichś problemów?
Solar, Adam: Niektóre osoby zgłaszały fałszywe alarmy dotyczące wykrywanych “ataków”, co było spowodowane niekompatybilnością danych wersji/buildu LKRG i jądra. Potencjał takich problemów z kompatybilnością jest powodem, dla którego w nowym systemie zalecamy testowanie LKRG z wyłączonymi akcjami egzekwowania i włączanie go w pełni dopiero po potwierdzeniu, że przez jakiś czas nie występują fałszywe alarmy. Dokumentacja LKRG zawiera szczegółowe instrukcje na ten temat.
Zdajemy sobie również sprawę, że LKRG może powodować niedopuszczalny wpływ na wydajność w niektórych niezamierzonych środowiskach, takich jak przetwarzanie dźwięku lub wideo w czasie rzeczywistym w systemie stacjonarnym, co jest przypadkiem użycia bardziej wrażliwym na opóźnienia niż typowe obciążenia serwerowe, do których LKRG jest przeznaczony.
Poza tym, generalnie nie ma żadnych problemów.
Czy mieliście już jakieś oferty od firm lub korporacji lub innych podmiotów trzecich, którym spodobało się LKRG i chcieli wesprzeć rozwój projektu?
Solar: Tak, na przykład z Binarly, jak wspomniano powyżej. CIQ wspierało również paczkowanie LKRG dla Rocky Linux (i ogólnie dystrybucji Enterprise Linux wywodzących się z Red Hat) za pośrednictwem SIG/Security, a także publiczne wydanie i dyskusję na temat funkcji zdalnego logowania, o której mowa powyżej.
Czy poza Wami ktoś jeszcze uczestniczy w rozwoju projektu?
Adam: Tak, na różnych etapach projektu w rozwój LKRG zaangażowane były różne osoby. Oprócz mnie i Alexandra, chciałbym wspomnieć o Mariuszu Zaborskim (oshogbo), Witaliju Czikunowie, Jakubie “mrl5” Kołodziejczaku, Michaile Morfikowie i innych.
Na dzień dzisiejszy GitHub wymienia łącznie 17 współpracowników LKRG: https://github.com/lkrg-org/lkrg/graphs/contributors
Jakie są kolejne plany dla rozwoju LKRG?
Solar: Wydanie 1.0 będzie ważnym kamieniem milowym, nie tyle pod względem ulepszeń w stosunku do obecnego 0.9.8, ale miejmy nadzieję, że pod względem tego, jak LKRG jest postrzegane przez innych. Możemy zyskać nie tylko więcej użytkowników, ale także więcej współpracowników. To z kolei może wpłynąć na tempo rozwoju i koncentrację.
Idealnie byłoby, gdybyśmy przerobili kod źródłowy i drzewo LKRG na kilka głównych sposobów (takich jak upodobnienie stylu kodowania do jądra Linuxa), ale jest to jedna z tych rzeczy, które wciąż są odkładane na później.
Planowaliśmy, aby LKRG próbował ukryć specyfikę kompilacji własnej i jądra, aby utrudnić exploitom niezawodne atakowanie LKRG i jądra. Jest to coś, nad czym pracował również Ilya V. Matveychikov i co zademonstrował w swoim własnym projekcie Kiddy. Ilya i niezależnie Alexander Popov wcześniej zademonstrowali ataki na LKRG, które opierały się na jego ekspozycji, którą takie zmiany mogłyby zmniejszyć.
Moglibyśmy również spróbować zmniejszyć powierzchnię ataku jądra, z dodatkowymi pokrętłami do kontrolowania tego. Moglibyśmy nawet zacząć wykrywać i blokować niektóre ataki w przestrzeni użytkownika, które opierają się na złośliwych danych wejściowych przechodzących przez jądro (głównie poprzez wywołanie syscall execve).
Adam: Pracowaliśmy również nad wzmocnieniem interfejsu (e)BPF, który może zostać wydany lub nie 🙂
Podsumowanie
Adamowi oraz Solarowi bardzo dziękujemy za udzielone odpowiedzi, a Czytelników zachęcamy do przetestowania i wdrożenia LKRG w swoich środowiskach – może to być cenne wzmocnienie Waszej infrastruktury przed atakami!