Memory Tagging Extension (MTE)
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Memory Tagging Extension (MTE) jest zaprojektowany w celu zwiększenia niezawodności i bezpieczeństwa oprogramowania poprzez wykrywanie i zapobieganie błędom związanym z pamięcią, takim jak przepełnienia bufora i luki typu use-after-free. MTE, jako część architektury ARM, zapewnia mechanizm do przypisania małego tagu do każdej alokacji pamięci oraz odpowiedniego tagu do każdego wskaźnika odnoszącego się do tej pamięci. Takie podejście pozwala na wykrywanie nielegalnych dostępu do pamięci w czasie rzeczywistym, znacznie zmniejszając ryzyko wykorzystania takich luk do wykonywania dowolnego kodu.
MTE działa poprzez dzielenie pamięci na małe, stałe bloki, z których każdy blok ma przypisany tag, zazwyczaj o wielkości kilku bitów.
Gdy tworzony jest wskaźnik wskazujący na tę pamięć, otrzymuje ten sam tag. Tag ten jest przechowywany w niewykorzystanych bitach wskaźnika pamięci, skutecznie łącząc wskaźnik z odpowiadającym mu blokiem pamięci.
Gdy program uzyskuje dostęp do pamięci za pośrednictwem wskaźnika, sprzęt MTE sprawdza, czy tag wskaźnika pasuje do tagu bloku pamięci. Jeśli tagi nie pasują, wskazuje to na nielegalny dostęp do pamięci.
Tagi wewnątrz wskaźnika są przechowywane w 4 bitach w górnym bajcie:
Dlatego pozwala to na 16 różnych wartości tagów.
Każde 16B pamięci fizycznej ma odpowiadający tag pamięci.
Tagi pamięci są przechowywane w dedykowanym obszarze RAM (niedostępnym do normalnego użytku). Posiadając 4 bity tagów dla każdego 16B tagów pamięci, do 3% RAM.
ARM wprowadza następujące instrukcje do manipulacji tymi tagami w dedykowanej pamięci RAM:
CPU sprawdza tagi podczas wykonywania instrukcji, jeśli wystąpi niezgodność, zgłasza wyjątek. Jest to najwolniejszy i najbezpieczniejszy tryb.
CPU sprawdza tagi asynchronicznie, a gdy znajdzie niezgodność, ustawia bit wyjątku w jednym z rejestrów systemowych. Jest szybszy niż poprzedni, ale nie jest w stanie wskazać dokładnej instrukcji, która spowodowała niezgodność i nie zgłasza wyjątku natychmiast, dając czas atakującemu na dokończenie ataku.
???
Nazywane KASAN opartym na tagach sprzętowych, KASAN opartym na MTE lub MTE w jądrze.
Alokatory jądra (takie jak kmalloc
) będą wywoływać ten moduł, który przygotuje tag do użycia (losowo) i dołączy go do przydzielonej przestrzeni jądra oraz do zwróconego wskaźnika.
Należy zauważyć, że oznaczy tylko wystarczającą ilość granulek pamięci (po 16B każda) dla żądanej wielkości. Jeśli więc żądana wielkość wynosiła 35, a przydzielono blok 60B, oznaczy pierwsze 16*3 = 48B tym tagiem, a reszta będzie oznaczona tzw. nieprawidłowym tagiem (0xE).
Tag 0xF jest wskaźnikiem pasującym do wszystkiego. Pamięć z tym wskaźnikiem pozwala na użycie dowolnego tagu do uzyskania dostępu do jej pamięci (brak niezgodności). Może to uniemożliwić MET wykrycie ataku, jeśli ten tag jest używany w zaatakowanej pamięci.
Dlatego istnieje tylko 14 wartości, które można wykorzystać do generowania tagów, ponieważ 0xE i 0xF są zarezerwowane, co daje prawdopodobieństwo ponownego użycia tagów na poziomie 1/17 -> około 7%.
Jeśli jądro uzyska dostęp do nieprawidłowej granulki tagu, niezgodność zostanie wykryta. Jeśli uzyska dostęp do innej lokalizacji pamięci, jeśli pamięć ma inny tag (lub nieprawidłowy tag), niezgodność zostanie wykryta. Jeśli atakujący ma szczęście i pamięć używa tego samego tagu, nie zostanie to wykryte. Szanse wynoszą około 7%.
Inny błąd występuje w ostatniej granulce przydzielonej pamięci. Jeśli aplikacja zażądała 35B, przydzielono jej granulę od 32 do 48. Dlatego bajty od 36 do 47 używają tego samego tagu, ale nie zostały zażądane. Jeśli atakujący uzyska dostęp do tych dodatkowych bajtów, nie zostanie to wykryte.
Gdy kfree()
jest wykonywane, pamięć jest ponownie oznaczana nieprawidłowym tagiem pamięci, więc w przypadku użycia po zwolnieniu, gdy pamięć jest ponownie uzyskiwana, niezgodność jest wykrywana.
Jednak w przypadku użycia po zwolnieniu, jeśli ten sam blok jest ponownie przydzielany z TYM SAMYM tagiem co wcześniej, atakujący będzie mógł wykorzystać ten dostęp i nie zostanie to wykryte (około 7% szans).
Co więcej, tylko slab
i page_alloc
używają oznaczonej pamięci, ale w przyszłości będzie to również używane w vmalloc
, stack
i globals
(w momencie nagrania te mogą być nadal narażone na nadużycia).
Gdy niezgodność jest wykrywana, jądro panikuje, aby zapobiec dalszemu wykorzystywaniu i ponownym próbom wykorzystania (MTE nie ma fałszywych pozytywów).
Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)