Co zrobić by uczynić jądro mniej atrakcyjnym dla hackerów?

ZAINSTALUJ ZESTAW ŁAT NA JĄDRO - PAX
PINGWIN_Z_LATA
PAX W SKRÓCIE
PAX w przeciwieństwie do projektu SELinux, stara się zapobiegać powstawaniu błędów, a nie minimalizować ich skutki, dlatego nie stanowi alternatywy dla SELinuxa a raczej jego dopełnienie.
Podstawowa idea projektu PAX jest prosta, opiera się rozbiciu jednolitej pamięci procesu na dwie grupy: "kod" i "dane" pilnując, by nie dochodziło ani do zapisu w obszar kodu, jak również wykonywania danych. Choć od tego prostego pomysłu do rzeczywistej realizacji Pax'a jeszcze daleko, to zasadniczy pomysł jest właśnie taki.

PAX - na prawdę
Jak można się domyślić, w rzeczywistości PAX jest bardziej złożonym projektem niż to przedstawiliśmy. Nie chroni wyłącznie przed błędami typu odczyt/zapis, ale także przed całą gamą ataków opierających się na zaawansowanej wiedzy na temat przestrzeni pamięciowej procesu, jak również przed błędami łańcuchów formatujących itp.

Czym jest PAX ?
Aby zgłębić, w jaki sposób projekt chroni nas przed atakami, musimy najpierw ustalić "rysopis potencjalnego mordercy". Według twórców systemu, ataki możemy podzielić na trzy grupy charakteryzujące sposób ich działania.
  1. wprowadzany/wykonywany jest własny kod i dane
  2. wykonywany jest istniejący kod, ale w innym porządku
  3. wykonywany jest istniejący kod, zgodnie z narzuconym porządkiem, ale na własnych danych
Przykładowo, standardowy shellcode znajduje się w (1) grupie, a techniki typu ret2libc (return to libc) w (2).

Kubuś Puchatek a PAX
Po dokonaniu wnikliwej analizy i wykonaniu klasyfikacji zbrodniarzy na trzy grupy, twórcy PAX'a zadali sobie iście "Puchatkowe" pytanie:

"Co należy zrobić, gdy ktoś pragnie napisać 'zły kod' w naszej pamięci a potem go wykonać"

Odpowiedź której udzieli nawet miś o bardzo małym rozumku jest oczywiście:

Zabronić mu!

Powstaje tylko pytanie jak?
Twórcy PAX'a mają dwie odpowiedzi, w obu chodzi o mechanizm NOEXEC, ale istnieją dwie zasadnicze metody realizacji tego pomysłu, w zależności od architektury, na jakiej działamy. Pierwsza to non-executable pages czyli: PAGEEXEC a druga to SEGMEXEC.

NOEXEC
Twórcy projektu wykorzystali już istniejący pomysł, by strony pamięci podzielić na dwie zasadnicze kategorie: kod i dane, a właściwie strony wykonywalne i nie-wykonywalne (executable i non-executable) i w obrębie dostępu do stron dokonywać kontroli uprawnień.

Jeśli jakiś proces mówi nam, że potrzebuje pamięci, do której będzie pisał, przydzielamy mu ją bez żadnych oporów, jednakże pamięć ta zostaje "zaznaczona" i proces w trakcie dalszego działania nie będzie mógł "wykonać tej części pamięci".

Jak widać rozwiązanie dość proste na pozór, jednakże przyjęta strategia pociąga za sobą pewne konsekwencje.
Co zrobić z programami, które generują kod na bieżąco, (np. maszyna wirtualna javy, lub emulatory różnych środowisk), lub jak rozwiązuje to problem ataków ret2libc?

Odpowiedź brzmi: "w przedstawionej wersji nie rozwiązuje", należy wzbogacić PAX'a o dodatkowe narzędzia.

MAPOWANIE
Przede wszystkim skoro już mamy atrybuty no-executable na stosie i stercie, to należy rozszerzyć ten mechanizm o pliki, by atakujący nie obchodził naszego zabezpieczenia poprzez mapowanie plików do pamięci.
Twórcy PAX'a rozwiązali ten problem dla plików typu ELF, gdzie wykonywana może być jedynie sekcja kodu. Osiągnięto to poprzez restrykcje wprowadzone w mmap() i mprotect().
Należy oczywiście pilnować by atrybuty nie były zmieniane, jak również by atrybut wskazywal albo na zapis albo wykonanie nigdy zaś na oba naraz. Pożądana własność oznaczana jest czasem: W^X ( Write xor eXecute ).
Zanim omówimy dokładniej realizacje wymienionych pomysłów wprowadzimy jeszcze trzeci (również wykorzystywany w innych projektach nie tylko przez PAX) mianowicie:

LOSOWE ADRESY PAMIĘCI, CZYLI ADDRESS SPACE LAYOUT RANDOMIZATION ( ASLR)
Jak sama nazwa wskazuje chodzi o wprowadzenie losowości rozmieszczenia poszczególnych mapowań w wirtualnej przestrzeni adresowej. Jest to całkiem silne zabezpieczenie przed atakami, do których włamywacz potrzebuje wiedzy na temat rozmieszczenia zmapowanych elementów, a wiedzy tej nie może uzyskać w sposób bezpośredni. Ponieważ każde wywołanie naszego programu powoduje inne rozmieszczenie poszczególnych bloków, metody typu brute force search stają się bardzo "bruuuuuut", co niewątpliwie znajduje swoje odzwierciedlenie w logach systemu i z łatwością zostanie wychwycone przez "dobrego" administratora. (nie jest to zawsze prawdą, gdyż jak twierdzi cała rzesza ludzi "mocno zainteresowanych bezpieczeństwem :)" systemów komputerowych, ponieważ np. fork() nie zmienia rozmieszczenia, zatem jeśli atakowany jest np. demon sieciowy wtedy brute force może być skuteczny czyt. "jest").



PAX pod lupą:

Skoro już wiemy jak wygląda i do czego służy zestaw łatek PAX warto dowiedzieć się przynajmniej podstaw o realizacji tego projektu, gdyż ta jest momentami bardzo pomysłowa.

Zatem jeszcze raz dokładniej:
Ochrona wykonywalnej pamięci
pingwin_pod_lupa

PAGEEXEC

Kontrola wykonywalności stron pamięci jest realizowana poprzez wykorzystanie, bądź zasymulowanie bitu NX (No-eXecute). W niektórych architekturach takich jak np. AMD64, obsługę NX mamy za darmo dostarczoną sprzętowo przez producentów, niestety większość popularnych serii Pentium nie posiada tej dogodności ( choć Pentium poczynił pewne kroki w tym kierunku i seria Pentium 4 Prescott core posiada analogiczny bicik, nazwany jednak XD bit, od Execute Disable) w związku z powyższym należy dokonać żmudnego emulowania poprzez oprogramowanie.
PAX emuluje funkcjonalność NX na architekturach IA-32( i386) poprzez zabawę na TLB.
Jak wiemy i386 ma TLB rozbite na dwie części ITLB i DTLB, co pozwala na poziomie procesora tłumacząc adresy stron i wrzucając je do TLB kontrolować atrybuty.

Wyobraźmy sobie zwykłą pamięć procesu, jaką mamy w standardowym kernelu.
  • na czerwono jest pamięć jednocześnie wykonywalna i zapisywalna
  • na zielono pamięć zapisywalna
  • na niebiesko wykonywalna
pageexec1

Jak wiadomo z pierwszej części naszego dokumentu, choć znajdą się zwolennicy lednolitej kolorystyki, to wiemy czym ta jednolitość koloru grozi. Wobec bardzo dużej liczby błędów w różnych programach, łatwo jest dokonać włamania do słabo zabezpieczonego systemu. Po zastosowaniu PAGEEXEC obraz przedstawia się nieco inaczej

pageexec2 Dzięki PAX'owi obrazek nabiera kolorków, korzystając z mechanizmu PAGEEXEC i mmap() i mprotect() uzyskujemy pożądaną własność blokady przed wywołaniem zabronionych części pamięci.
Jak widać nie ma możliwości zapisania kodu w danych ani danych w kodzie.


Pageexec nie dzieli przestrzeni adresowej procesu, tylko gra na uprawnieniach mapowanych obiektów. W momencie próby wywołania zabronionego kodu, podnosi błąd zabezpieczeń. Okazuje się jednak, że o ile w architekturach posiadających sprzętową realizacje tej polityki, jak np. AMD64 wprowadzenie naszej filozofii mamy za darmo, o tyle na architekturach IA-32 odczuwalne jest znaczne spowolnienie, spowodowane narzutemi jaki niesie ze sobą dodatkowa, programowa kontrola adresów i parametrów stron. Twórcy zalecają korzystanie nie z PAGEEXEC ale SEGMEXEC, czyli ochrony na poziomie segmentów pamięci a nie kontroli uprawnień stron. Cała magia tego rozwiązania tkwi w tym, iż w momencie sprawdzania atrybutu danego obszaru pamięci, nie musimy sięgać do dalszych informacji, tylko samo położenie bloku w pamięci determinuje jego parametry.

SEGMEXEC
Podejście to realizuje tę samą idee jednakże dzieląc przestrzeń procesu na dwie pamięci.
Jak wiemy 32 bity pozwalają na zaadresowanie 4GB pamięci, ale przecież jądro zabiera 1GB więc do podziału pozostaje 3GB. Mamy więc dwa razy po 1,5GB. Dolna część a więc 0 - 1,5GB to część na dane, natomiast Górna 1,5 - 3GB to część na kod i jego mapowania.
dane1


stos2 W tym podejściu część wykonywalna może trafić do części kodu, ale również danych, (jeśli zawiera jakieś dane) w tym przypadku robiona jest kopia i obydwa bloki wstawiane są na te same miejsca w obu częściach. Ważne by zauważyć różnice: zapisujemy cześć zawierającą także kod do sektora danych, ale nie ma obawy, ponieważ sektora danych nie można wykonać zatem zasada W^X jest zachowana. Warto zauważyć, z jaką łatwością wykrywamy, z jakim rodzajem mamy do czynienia wystarczy sprawdzić czy ardes < 60000000h. To jest zapewne miejsce, w którym SEGMEXEC
wyprzedza PAGEEXEC na architekturach IA-32.

RANDOMIZACJA pamięci
Dodatkowym zabezpieczeniem stosowanym przez PAX jest mieszanie adresów pamięci, przez co ciężko jest osobie, nie posiadającej dodatkowej wiedzy na temat rozmieszczenia zmapowanych części pamięci, uzyskać dostęp do pożądanych fragmentów. Jak widać każdorazowe wywołanie powoduje inne rozmieszczenie.
randomizacja

Ranodmizowana jest oczywiście przede wszystkim funkcja mmap(), ale nie tylko.
Wadą randomizacji w pamięci procesu jest fakt, iż powoduje ona fragmentacje, co może w skrajnych przypadkach blokować pewne programy, które przy zwykłym doborze adresów, dałyby sobie rade.

Jak się bronić przed PAX'em
Jak wiadomo wspaniałe systemy zabezpieczeń, bywają uciążliwe w codziennym życiu z tego prostego powodu, że sami korzystamy z programów, które "nie spełniają norm" bezpieczeństwa. Co zatem gdy system, nie pozwala nam na wykonanie naszego programu, np. wymagającego JVM. Twórcy PAX'a przyszli nam z pomocą i w tej kwestii i stworzyli wdzięczne narzędzie chpax i paxctl pozwalające wyjąć nasz program z pod jarzma zabezpieczeń.

Podsumowanie:
Pax to ciekawy projekt, pozwalający na zabezpieczenie się przed całą gamą ataków i błędów. Jednak w naszym przekonaniu jest on w wersji jeszcze na tyle nie rozwiniętej, iż cena wygody korzystania z systemu w odniesieniu do relatywnych korzyści jest zbyt mała by zachęcić nas do zabezpieczania się właśnie za pomocą tego systemu.

PAX w prawdziwym świecie
Twórcy systemu PAX przyznają, iż ich system nie broni w pełni przed włamaniami, ale dodają, że w ich mniemaniu jest to niemożliwe. (na płaszczyźnie systemów PAX'o podobnych) Otwarcie przedstawili ciekawą listę ataków przed którymi napewno system nie chroni:

  • ataki typu (3) są możliwe w 100%, jeśli atakujący nie potrzebuje dużej wiedzy na temat przestrzeni adresowej procesu

  • ataki (2),(3) są możliwe w 100%, jeśli atakujący potrzebuje informacji o przestrzeni adresowej, ale może tą wiedzę otrzymać ( np. gdy ma dostęp do /proc/(pid)/maps )

  • (2),(3) z małym prawdopodobieństwem, jeśli nie ma wiedzy o adresach, ani możliwości łatwego zdobycia

  • (1) jest możliwy, jeśli atakujący może stworzyć dany proces i mapowac pliki, ale to już wina podstawowego systemu, a nie luka w PAX'ie.


Na koniec warto wspomnieć iż jest cały szereg dystrybucji które chwaliły się posiadaniem PAX'a w standardowych dystrybucjach są to między innymi:

Adamantix, Hardened Gentoo, Hardened Debian
Poza tym PAX jest na wyposażeniu zestawu łat grsecurity.

Tak naprawdę to jedynym bezpiecznym linuxem jest:
proszek
Nie wymaga łat, łatwy w instalacji.
Zabezpieczony przed wszelkimi exploitami.



Valid HTML 4.01 Strict