Linux Kernel Runtime Guard – ochrona przed (jeszcze) nieznanymi exploitami

dodał 14 lutego 2018 o 07:47 w kategorii Błędy, Prywatność, Włamania  z tagami:
Linux Kernel Runtime Guard – ochrona przed (jeszcze) nieznanymi exploitami

W dobie wszechobecnych exploitów warto zastanowić się nad zabezpieczeniami. Solar Designer, założyciel inicjatywy OpenWall niedawno poinformował o pojawieniu się nowego projektu do proaktywnej ochrony systemów opartych na Linuxie.

LKRG, bo o nim mowa, to opracowany przez naszego rodaka, Adama „pi3” Zabrockiego, moduł jądra składający się z trzech różnych podsystemów proaktywnej ochrony. Kluczową kwestią jest to, że rozwiązanie zostało zaprojektowane z myślą o wykrywaniu wystąpienia pewnych scenariuszy ataków, a nie konkretnych, znanych podatności. Dzięki temu istnieje możliwość, że okaże się „ostatnim bastionem” w momencie, kiedy złośliwe oprogramowanie spróbuje skorzystać z technik exploitacji, które nie są jeszcze znane.

Jak wygląda ochrona zapewniana przez LKRG?

Podsystem integralności oferowany przez LKRG ochroni przed nieautoryzowanym nadpisywaniem pamięci jądra systemu. Jego działanie polega na okresowym wyliczaniu sum kontrolnych z newralgicznych miejsc jądra za pomocą algorymu SipHash, który został zaprojektowany do zastosowania w wydajnym uwierzytelnianiu informacji. Wspomniana procedura jest również uruchamiana po wykryciu aktywności modułów jądra lub po wystąpieniu określonych zdarzeń w systemie (np. zmiana interfejsu sieciowego). Analogiczną funkcję na Windowsie pełni PatchGuard.

Drugim aspektem ochrony jest podsystem wykrywania exploitów, który monitoruje, czy w systemie nie występują nietypowe sytuacje, takie jak np. nadpisanie process credentials i uzyskanie zwiększonych uprawnień przez proces bez żadnej wiarygodnej przyczyny. Podejrzane procesy tego typu są natychmiast zabijane, zanim uda im się doprowadzić atak do końca.

Eksperymentalna wersja modułu oferuje również trzecią funkcję pod nazwą „Protected Features”. Dzięki niej możliwe jest np. zablokowanie zapisu do logów systemowych w trybie innym niż append-only, nawet jeżeli operacja została zainicjowana przez administratora. Skutecznie uniemożliwia to „zacieranie śladów” przez potencjalnego atakującego. Zdjęcie blokady wymaga wydania polecenia kernelowi i uwierzytelnienia się specjalnym hasłem, które administrator powinien przechowywać poza systemem.

Podobne funkcje silnej ochrony mają zastosowanie również w stosunku do zwykłych plików i procesów. Istnieje np. możliwość zabezpieczenia procesu ssh-agent przed debugowaniem, wykonaniem zrzutu pamięci i innymi tego typu interakcjami, które mogą prowadzić do „wyciągnięcia” kluczy prywatnych z pamięci procesu. Podobnie jak w przypadku logów, na zabezpieczony proces nie będzie mógł wpłynąć nawet root.

Czy rzeczywiście ktoś może zaatakować mój kernel?

Każde oprogramowanie zawiera błędy. Przez to, że Linux jest mniej popularny wśród użytkowników końcowych, odkryte podatności niekiedy odbijają się znacznie mniejszym echem, niż w analogicznych sytuacjach związanych z Windowsem. Przykładami prawdziwych exploitów na jądro Linux są choćby CVE-2014-9322CVE-2017-5123, CVE-2017-6074, czy CVE-2017-1000112. Wszystkie z wymienionych potencjalnie mogą prowadzić do przejęcia uprawnień administracyjnych na zaatakowanym systemie.

Wykorzystanie błędu w implementacji obsługi protokołu DCCP do eskalacji uprawnień użytkownika na administratora.

Obecność modułu LKRG rzeczywiście uniemożliwia wykorzystanie wymienionych wyżej podatności na niezałatanych systemach, pomimo że nie był projektowany pod kątem wykrywania tych konkretnych exploitów. Niestety, jak to zwykle bywa, bezpieczeństwo kosztuje. Okresowe sprawdzanie integralności jądra oraz działanie podsystemu detekcji exploitów, według oficjalnych benchmarków autora, wiąże się ze spadkiem wydajności sięgającym około 6.5%.

Uważny czytelnik zauważy, że takie rozwiązanie nie chroni również przed popularnym atakiem Meltdown, który odbywa się na innej warstwie abstrakcji. Ataki wycelowane w podatności znajdujące się poza jądrem (w tym przypadku wręcz w samym procesorze) nie zostaną wykryte. Analogicznie z atakami, które są całkowicie pasywne i nie zostawiają zbyt wielu śladów, ale pozwalają np. na zrzucenie pamięci jądra. Autor deklaruje jednak możliwość pojawienia się specjalizowanej detekcji takich ataków w następnych wersjach modułu. Ponadto, gdyby w przyszłości pojawił się nieznany exploit umożliwiający nadpisywanie pamięci jądra (nawet na poziomie sprzętu!), obecność LKRG faktycznie mogłaby przeszkodzić w jego wykorzystaniu.

Innym powiązanym aspektem jest to, że LKRG nie rozróżnia exploitów od „modyfikacji jądra w dobrej wierze”, co uniemożliwi uruchomienie rozwiązań polegających na łataniu jądra w sposób inny niż oficjalnie rekomendowane. Przykładem może być choćby KSplice, choć nadal da się go użyć, jeżeli LKRG zostanie załadowany dopiero po dokonaniu patchowania).

Podsumowanie

Autor omawianego modułu podchodzi do sprawy realistycznie i wyraźnie podkreśla to, że omawiany tutaj moduł nie jest „lekiem na wszystko”, tym bardziej że możliwość ominięcia zabezpieczeń wynika z samego sposobu jego działania. Moduł zaskakująco dobrze radzi sobie jednak z wykrywaniem ataków zero-day. W dobie wszechobecnych zagrożeń warto jednak rozważyć jego instalację, szczególnie na serwerach, jeżeli w danym zastosowaniu wyższy priorytet nad maksymalną wydajnością ma dla nas zwiększone bezpieczeństwo. Jeśli projekt Was interesuje, zajrzyjcie na jego stronę lub do dedykowanej Wiki, gdzie znajdziecie bardziej obszerne informacje i odpowiedzi na ewentualnie nurtujące Was pytania. Z autorem można porozmawiać na naszym kanale IRC (#[email protected]).