Projekt PaX
Piotr Powałowski
PaX w skrócie - co to jest?
PaX (PAge eXecute) jest patchem na jądro Linuxa implementującym dodatkowe zabezpieczenia systemu,
ograniczające możliwe wykorzystanie niedoskonałości systemu i oprogramowania pozwalających
na włamania. W szczególności PaX zabezpiecza system uniemożliwiając wykonywanie kodu nie
będącego częścią uruchomionego programu (np. umieszczonego w pamięci jako dane). Celem
projektu PaX nie jest jednakże "łatanie" błędów implementacyjnych Linuxa czy jego
poprawianie, lecz implementacja "mechanizmów obronnych" systemu przeciwdziałających i
powstrzymujących włamania.
Strona główna projektu PaX: http://pax.grsecurity.net/
. Można tam odnaleźć pełną dokumentację projektu, a także PaX'owe patche na najpopularniejsze jądra Linuxa.
PaX wprowadza dwa główne usprawnienia:
- rozgraniczenie pomiędzy pamięcią danych (oznaczając ją jako niewykonywalną) oraz
programu (oznaczając ją jako bez prawa do zapisu)
- randomizację rozłożenia przestrzeni adresowej (address space layout randomization
- ASLR)
Usprawnienia te efektywnie zabezpieczają system przed różnorakimi sposobami włamań, m.in:
wynikającymi z przepełnienie bufora czy polegającymi na wykonaniu kodu zewnętrznego (ataki
typu Code Injection czy return-to-libc).
Historia projektu PaX
Projekt PaX został napisany przez grupę programistów pod pseudonimem "The PaX Team". Główny auror PaX'a pragnie jednak pozostać anonimowy.
- Październik, 2000: Pierwsze wydanie PaX'a z podstawową implementacją metody PAGEEXEC.
- Wrzesień, 2002: Implementacja VMA Mirroringu, przekształcona później w metody RANDEXEC oraz SEGMEXEC.
- Maj, 2004: Rozszerzenie PAGEEXEC o śledzenie wielkości segmentu kodu, zwiększające wydajność.
- Marzec, 2005: Wykrycie podatności VMA Mirroringu na włamania, nowa wersja PaX'a.
- Kwiecień, 2005: Z powodu wykrytych podatności, projekt PaX oficjalnie został zakończony. Kod rozwijany dalej przy współpracy PaX Team i GrSecurity.
PaX stał się częścią innych projektów zorientowanych na poprawę bezpieczeństwa systemu Linux, m.in: Adamantix (Trusted Debian), GrSecurity, OpenBSD, Hardened Gentoo czy Hardened Debian.
Struktura projektu PaX
PaX zawiera implementację następujących metod:
- NOEXEC - zabrania tworzenia mapowania pamięci przez działające procesy zezwalającego jednocześnie na pisanie i wykonywanie.
- PAGEEXEC - zabezpieczenie stron pamięci przed wykonywaniem
- SEGMEXEC - zabezpieczenie stron pamięci przed wykonywaniem, przy zastosowaniu segmentacji oraz Mirroringu VMA(dla architektury IA-32 (x86))
- ASRL - randomizacja rozłożenia przestrzeni adresowej (Adress Space Layout Randomization)
- KERNEXEC - zabezpieczenie stron pamięci przed wykonywaniem w przestrzeni jądra
- RANDUSTACK- randomizacja stosu w przestrzeni użytkownika.
- RANDKSTACK- randomizacja stosu w przestrzeni jądra.
SEGMEXEC - dokładniej
SEGMEXEC jest PaX'ową implementacją metody zabezpieczającej stron pamięci przed wykonywaniem.
Wykorzystuje ona mechanizmy segmentacji stosowane dla architektury IA-32 (procesorów Intel x86).
SEGMEXEC emuluje funkcjonalność NX (No eXecute) poprzez podzielenie przestrzeni adresowej
użytkownika na dwie równe części. Dolna część przechowuje mapowania dostępu do danych, górna
do kodu wykonywalnego. Przestrzeń jest więc dzielona na części wielkości 1.5 GB. PaX mirroruje
wszystkie wykonywalne mapowania w dolnej połowie na górną.
Gdy wywoływana jest instrukcja fetch odwołująca się do dolnej części (segmentu danych), jej
adres docelowy jest tłumaczony na mirror. Jeśli w mirrorze kod do wykonania nie jest
mapowany, proces jest zabijany.
Pomimo iż SEGMEXEC dzieli przestrzeń adresową na pół, wydajność emulacji wzrasta, jeżeli jest
ona wykonywana w architekturze IA-32 (x86). Ponadto, warto zaznaczyć że mapowanie w górnej i
dolnej części podziału odwołuje się do tej samej pamięci fizycznej, przez co nie wykorzystuje
dwukrotnie większej ilości pamięci RAM.
Według tego samego schematu działa również metoda KERNEXEC, z tą różnicą iż jest ona przeznaczona
wyłącznie dla jądra.
Wymieniona wcześniej metoda PAGEEXEC była pierwszą implementacją funkcjonalności NX. Jednakże
dla architekury x86 została wyparta przez SEGMEXEC.
ASRL - dokładniej
ASRL (Adress Space Layout Randomization) ma za zadanie wprowadzenie losowości w adresach
wykorzystywanych przez proces, m.in. w położeniu stosu, kodu plików bibliotek, kodu
wykonywalnego, stosu i innych. Ważnym jest, aby względne rozmieszczenie tych adresów było
od siebie niezależne i różne dla różnych uruchomień procesu. Pozwala to na zabezpieczenie
systemu przed atakami typu ret2libc czy uruchamianiem kodu wykorzusując obce dane (execute
existing code in original program order with arbitrary data).
Oto przykład rozdysponowania pamięci prosesu przy zastosowaniu ASRL:
Zielonym kolorem oznaczono pamięć z prawami do zapisu, niebieskim wykonywalną. Przy ponownym
uruchomieniu proceu otrzymujemy zupełnie inne rozmieszczenie:
Do losowania położenia w pamięci stosuje się randomizację jedynie "środkowych" bitów adresu.
Bity najbardziej i najmniej znaczące pozostają niezmienione. W architekturze 32 bitowej (i386)
losuje się więc odpowiednio:
- dla adresów stosu: bity 4-27
- dla adresów obszaru mmap(): bity 12-27
- dla adresów obszaru wykonywalnego: bity 12-27
Oczywiście dla innych architektur liczby te są inne. W szczególności dla komputerów 64 bitowych
są one większe, lecz nie dwukrotnie.
W analogiczny sposób działają metody RANDUSTACK oraz RANDUSTACK.
Możliwe typy włamań i ich interakcja z PaX'em
PaX wyróżnia i stara się zabezpieczyć system przed trzema typami włamań:
- (1) Wykonanie lub umieszczenie kodu zewnętrznego (introduce/execute arbitrary code)
- (2) Wykonanie kodu programu w nieodpowiedniej kolejności (execute existing code out of original program order)
- (3) Wykonanie kodu programu przy zastosowaniu zewnętrznych danych (execute existing code in original program order with arbitrary data)
Dla przykładu atak typu return-to-libc zalicza się do drugiej kategorii.
Wymienione powyżej metody zabezpieczania systemu zmniejszają szanse wystąpienia powyższych.
Użycie ASRL niweluje możliwość wystąpienia ataków drugiego i trzeciego rodzaju, gdyż wymagają
one znajomości względnego rozmieszczenia wykorzystywanych przez proces fragmentów pamięci (np.
w celu zmiany wskaźnika powrotu na stosie (2) czy danych wykorzystywanych przez proces (3)).
Oczywiście możliwe jest odgadnięcie położenia interesujących atakującego danych lub dokonanie
ataku siłowego, lecz przy dobranej losowości szanse jego powodzenia są zerowe, a niepowodzenie
w większości przypadków doprowadzi do crashu systemu. Pax dzięki zastosowaniu SEGMEXEC oraz
mirroringowi VMA generalnie uniemożliwia ataki typu pierwszego.
Należy jednak zaznaczyć, iż każdy z tych ataków ma szansę się powieść, zależnie od wiedzy i
potrzebnych zasobów atakującego:
- Atak metodą trzecią jest możliwy ze 100% skutecznością jeśli atakujący
do przeprowadzenia ataku nie potrzebuje zaawansowanej wiedzy nt. adresów
wykorzystywanych przez atakowany proces.
- Ataki metodami drugą i trzecią są możliwe ze 100% skutecznością jeżeli
atakujący do przeprowadzenia ataku potrzebuje wiedzy nt. adresów
wykorzystywanych przez atakowany proces, ale może ją uzyskać przeglądając
jego przestrzeń adresową.
- Ataki metodami drugą i trzecią są możliwe z pewną nikłą skutecznością jeżeli
atakujący do przeprowadzenia ataku potrzebuje wiedzy nt. adresów
wykorzystywanych przez atakowany proces, nie może jej uzyskać przeglądając
jego przestrzeń adresową, ale zastosuje podejście "ataku siłowego" lub spróbuje
zgadywać. Należy zaznaczyć, iż zgadywanie miałoby polegać w tym wypadku na odgadnięciu
przynajmniej 24 bitów, a prawdopodobieństwo tego jest ok. 1 do 16000000.
- Atak metodą pierwszą jest możliwy jeśli atakujący może zmusić atakowany proces
do stworzenia, pisania i mmap'owania pliku. Jednakże w tym wypadku wymagane jest
najpierw dokonanie ataku typu drugiego (co pozwala tu również zastosować powyższą
analizę).
PaX - problemy
Niestety okazuje się, iż niektóre programy wymagają dostępu do pamięci w sposób blokowany przez
PaX,a lub bazują na założeniach, które przy jego działaniu okazują się nie być prawdziwe.
Przykładowo korzystają ze stałych czy przewidywanych zależności w przestrzeni adresowej, bądź
podejmują próby wygenerowania kodu, który jest wykonywany poza pamięcią. PaX naturalnie nie
pozwoli na takie zachowanie i natychmiast zakończy działanie występnego programu.
Najbardziej godne uwagi z tego rodzaju aplikacji, wydają się XFree, Xorg, mpalyer i narzędzia
dla multimediów oparte o xine-lib. Najprostszy sposób na rozwiązanie problemów to wyłączenie
zabezpieczeń PaX. Służy do tego narzędzie 'chpax' (jako część systemu PaX), pozwalające na
kontrolowanie rozmaitych zabezpieczeń stosowanych przez PaX'a. Podczas instalacji pakietu
chpax, instalowany jest również standardowy skrypt init/conf.d, który ze względu na dobrze
znane problemy, ustawia uzasadnione opcje domyślne. Chcąc włączyć ustawianie tych uprawnień,
przy każdym uruchomieniu systemu, należy wykonać następującą komendę:
emerge
chpax ; rc-update add chpax default ; /etc/inid.d/chpax start.
W systemie Gentoo istnieje jeszcze inne narzędzie służące do kontroli nad PaX'em - paxctl.
Pozwala ono na wyłączanie/włączanie ochrony dla poszczególnych plików wykonywalnych.
Linki