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.
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").
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.
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
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.
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:
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:
|