Historia dereferencji wskaźnika NULL w systemie macOS

Karol Mazurek

Znalezienie błędu podczas fuzzingu to dopiero początek poszukiwania realnej podatności. Pomimo tego, że udało się znaleźć błąd, dotarcie do exploita to często długi proces. Nie każdy błąd jest podatny na wykorzystanie, czego świetnym przykładem jest mój poprzedni artykuł (Case Study: Analyzing macOS IONVMeFamily Driver Denial of Service Issue). Czasami jestem przekonany, że dana podatność może być wykorzystana, jednak później napotykam na swego rodzaju mur, na który składa się szereg mitygacji wprowadzonych do systemu operacyjnego na przestrzeni lat.

Podczas ostatniej sesji fuzzingu odkryłem błąd, który po analizie i inżynierii wstecznej okazał się niemożliwy do wykorzystania ze względu na zabezpieczenia zaimplementowane w macOS. Jedno z tych zabezpieczeń dotyczy bezpośrednio dereferencji wskaźnika NULL.

Napotkałem wiele wartościowych źródeł na ten temat, ale ich znalezienie zajęło mi dużo czasu. Dlatego zdecydowałem się napisać artykuł podsumowujący kluczowe kwestie oraz zawierający linki do tych materiałów dla osób poszukujących odpowiedzi na pytanie:

Dlaczego dereferencja wskaźnika NULL w macOS dla architektury ARM64 i nowszej nie jest już exploitowalna?

Wprowadzenie: Dereferencja wskaźnika NULL na Apple Silicon

Dereferencja wskaźnika NULL następuje, gdy oprogramowanie próbuje uzyskać dostęp do pamięci pod adresem 0 (adres NULL) poprzez wskaźnik ustawiony na NULL. Na architekturze ARM64 (takiej jak Apple Silicon) adres 0 zazwyczaj nie jest mapowany w pamięci wirtualnej, podobnie jak na innych architekturach. W związku z tym dereferencja wskaźnika NULL zazwyczaj powoduje błąd dostępu do pamięci. W kontekście jądra systemowego taki błąd prowadzi do natychmiastowej paniki jądra zamiast odczytu lub zapisu prawidłowych danych. Konsekwencją jest awaria systemu (Denial of Service), która występuje po zatrzymaniu przez jądro wykonywania kodu. Takie zachowanie jądra ma na celu ochronę systemu.

Dereferencja wskaźnika NULL to błąd programistyczny, który nie prowadzi do wykonania kodu kontrolowanego przez atakującego – po prostu powoduje awarię. Poniżej znajduje się prosty przykład, który można skompilować i uruchomić, aby zobaczyć ten efekt na własne oczy:

//clang -o null_dereference null_dereference.c
#include <stdio.h>

int main() {
    int *ptr = NULL;  // Inicjalizacja wskaźnika na NULL
    int value = *ptr; // Próba dereferencji wskaźnika NULL

    printf("Wartość: %d\n", value); // Ta linia nigdy nie zostanie wykonana, jeśli dereferencja spowoduje awarię

    return 0;
}Code language: PHP (php)

W przeszłości atakujący znajdowali sposoby na wykorzystanie dereferencji wskaźnika NULL w jądrze systemu przy spełnieniu określonych warunków.

Jak można to wyexploitować?

Klasyczny scenariusz exploitacji polegał na zmapowaniu kontrolowanej strony pamięci pod tym adresem, co miało na celu oszukanie jądra tak, aby nie generowało błędu przy dostępie do adresu zero. Jeżeli udało się to zrobić, jądro zamiast awarii mogło odczytać lub wykonać dane dostarczone przez atakującego, potencjalnie prowadząc do wykonania kodu w trybie jądra.

Na systemach opartych na ARM64 Apple wprowadziło ochronę pamięci, dzięki której adres zero pozostaje niemapowany podczas normalnej pracy. Każda próba użycia wskaźnika NULL prowadzi do błędu dostępu do danych (data abort). W rezultacie dereferencja wskaźnika NULL w jądrze systemu zwykle skutkuje zatrzymaniem działania systemu ze względów bezpieczeństwa.

Aby to wyexploitować atakujący musiałby być w stanie umieścić kontrolowane dane pod adresem zero i sprawić, aby jądro z nich korzystało. Jednak, jak zobaczymy, nowoczesne wersje macOS sprawiają, że jest to niezwykle trudne.

Historyczne wykorzystanie dereferencji wskaźnika NULL w macOS

W starszych wersjach macOS (na architekturach Intel) atakujący stosowali technikę mapowania fałszywego obiektu pod adresem NULL w przestrzeni użytkownika, tak aby jądro, błędnie dereferując wskaźnik NULL, uzyskało dostęp do spreparowanych danych zamiast wygenerować błąd. Wymagało to obejścia standardowych mechanizmów systemowych blokujących mapowanie niskich adresów pamięci.

Istniało kilka przypadków, kiedy było to możliwe.

__PAGEZERO

W macOS 64-bitowe procesy nie mogą mapować pamięci pod adresem 0, ponieważ system rezerwuje duży, niemapowany region, aby wychwytywać błędy wskaźników NULL. W każdym pliku Mach-O można znaleźć segment __PAGEZERO:

Dla 64-bitowych binariów Mach-O pierwsze 4 GB przestrzeni adresowej są zarezerwowane i niedostępne.

Technika mapowania strony NULL w 32-bitowych binariach

Jednak w starszych wersjach macOS, gdy obsługiwano jeszcze aplikacje 32-bitowe, można było skompilować binarkę 32-bitową (-m32) z flagą linkera wyłączającą rezerwację __PAGEZERO (-pagezero_size 0x0):

// clang -o poc poc.c -framework IOKit -m32 -pagezero_size 0x0Code language: JSON / JSON with Comments (json)

Ten przestarzały mechanizm pozwalał procesowi przydzielić pamięć pod adresem 0. Atakujący wykorzystywali to do umieszczania shellcode’u lub fałszywych obiektów pod adresem NULL i tym samym wywoływania podatności jądra.

// 1. Deallocate the NULL page region:
err = vm_deallocate(mach_task_self(), 0x0, 0x1000); 

// 2. Allocate memory at address 0:
vm_address_t addr = 0;
err = vm_allocate(mach_task_self(), &addr, 0x1000, 0);

// 3. Fill the NULL page with controlled data:
char* np = 0;
for (int i = 0; i < 0x1000; i++){
  np[i] = '\x41';
}Code language: JavaScript (javascript)

Przykładowo, Piotr Bania z Cisco Talos w 2016 roku wykazał, że możliwe było wykorzystanie błędu w sterowniku grafiki Intel. Skompilował 32-bitowy payload bez segmentu __PAGEZERO, mapując stronę pod adresem 0 i zmuszając jądro do wykonania wskaźnika funkcji ze strony NULL. Skutkowało to wykonaniem kodu w trybie jądra i obejściem KASLR.

Wymagało to wyłączenia ochrony SMEP, co omówimy później.

TPWN 0-day (OS X Yosemite, 2015)

Przed tym znany był exploit z 2015 roku autorstwa Luca Todesco, skierowany przeciwko OS X Yosemite. Łączył on błąd polegający na dereferencji wskaźnika NULL w IOKit z wyciekiem informacji w celu uzyskania uprawnień roota. Exploit nosił nazwę „tpwn” i jest publicznie dostępny. Poniżej przedstawiono uproszczony przebieg exploitu:

[Initial User Access][Information Leak Vulnerability][Obtain kalloc.1024 zone pointer][Bypass Kernel ASLR][Memory Corruption Primitive][NULL Pointer Dereference in IOKit][OR 0x10 anywhere in kernel memory][Corrupt vtable pointer][Trigger IOServiceRelease][Execute code at vtable+0x20][Stack pivot (RSP = RAX)][Execute ROP chain][Set UID to 0 (root)][Clean up memory corruption][Adjust task counts][Unlock IOAudioEngine locks][Root privileges achieved]Code language: CSS (css)

Todesco opracował również mechanizm ochronny o nazwie NULLGuard, aby zabezpieczyć się przed błędami dereferencji wskaźnika NULL. Później zostały one złagodzone w OS X 10.11 (El Capitan) dzięki wprowadzeniu System Integrity Protection (SIP) oraz innych zabezpieczeń.

W tamtym okresie dereferencje NULL mogły stanowić etap eskalacji uprawnień, pod warunkiem, że spełnione były inne warunki.

macOS OS X 10.11 (El Capitan) – IOKit Driver Exploits Race (2015–2016)

Wiele luk zostało znalezionych w tamtym czasie w sterownikach jądra macOS, gdzie wskaźnik NULL był używany jako odniesienie do obiektu. Poprzez mapowanie strony NULL w złośliwym procesie oraz wywołanie wyścigu lub wymuszenie ustawienia wskaźnika na NULL, badacze mogli przejąć kontrolę nad wskaźnikiem rozkazów (instruction pointer), na przykład:

  • CVE-2016-1846 w sterowniku NVIDIA GeForce odkryty przez Iana Beera. Umożliwiał on użytkownikowi zmapowanie adresu zero i umieszczenie tam fałszywego obiektu C++. Sterownik wywoływał funkcję wirtualną na obiekcie o wartości NULL, skacząc do wskaźnika kontrolowanego przez atakującego, pochodzącego z fałszywej tablicy wirtualnych metod.
┌────────────────────────────────────────────────────────────────┐
│                       Process Virtual Memory                   │
├────────────────────────────────────────────────────────────────┤
│                                                                │
│  ┌─────────────┐                                               │
│  │ NULL Page   │ ◄── 1. vm_deallocate(0x0, 0x1000)             │
│  │ (0x0-0xFFF) │ ◄── 2. vm_allocate(&addr=0, 0x1000, 0)        │
│  │             │ ◄── 3. Fill with 0x41 bytes                   │
│  └─────────────┘                                               │
│      │                                                         │
│      ▼                                                         │
│  ┌─────────────┐                                               │
│  │ Fake VTable │                                               │
│  │ 0x41414141  │ ◄── Function pointers in VTable               │
│  │ 0x41414141(will be called by kernel)                │
│  │ ...         │                                               │
│  └─────────────┘                                               │
│                                                                │
└────────────────────────────────────────────────────────────────┘

┌────────────────────────────────────────────────────────────────┐
│                       Kernel Execution Flow                    │
├────────────────────────────────────────────────────────────────┤
│                                                                │
│  Thread 1                      Thread 2                        │
│  ┌─────────────┐              ┌─────────────┐                  │
│  │ Open driver │              │ Wait for    │                  │
│  │ connection  │──┐        ┌──│ spinlock    │                  │
│  └─────────────┘  │        │  └─────────────┘                  │
│         │         │        │         │                         │
│         ▼         │        │         ▼                         │
│  ┌─────────────┐  │        │  ┌─────────────┐                  │
│  │ Release     │  │        │  │ Acquire     │                  │
│  │ spinlock    │──┼────────┼─▶│ spinlock    │                  │
│  └─────────────┘  │        │  └─────────────┘                  │
│         │         │        │         │                         │
│         ▼         │        │         ▼                         │
│  ┌─────────────┐  │        │  ┌─────────────┐                  │
│  │ Close driver│  │        │  │ Call IOKit  │                  │
│  │ connection  │◄─┘        └─▶│ method      │                  │
│  └─────────────┘              └─────────────┘                  │
│                                        │                       │
│                                        ▼                       │
│                               ┌─────────────────────────┐      │
│                               │ nvCommandQueue::        │      │
│                               │ GetHandleIndex accesses │      │
│                               │ NULL pointer at +0x5b8  │      │
│                               └─────────────────────────┘      │
│                                        │                       │
│                                        ▼                       │
│                               ┌───────────────────────────┐    │
│                               │ Virtual method call on    │    │
│                               │ NULL object jumps to      │    │
│                               │ address 0x4141414141414141|    │
│                               └───────────────────────────┘    │
│                                                                │
└────────────────────────────────────────────────────────────────┘Code language: PHP (php)
  • Błąd w IOAudioEngine (CVE-2016-1821) – obiekt ustawiony zastał jako NULL, a następnie był użyty, co pozwoliło atakującemu umieścić fałszywą tablicę reserved->streams pod adresem zero i przekierować wykonanie.

W tych przypadkach mapowanie strony NULL dało atakującemu pełną kontrolę nad rejestrem RIP jądra.

Supervisor Mode Execution Prevention

Na starszych komputerach Mac brakowało lub były wyłączone sprzętowe zabezpieczenia przed wykonywaniem pamięci użytkownika w jądrze. W przykładzie Talos badacze zauważyli, że nowoczesne CPU posiadają SMEP, co zapobiega wykonywaniu kodu znajdującego się w pamięci użytkownika (np. strony NULL). Natomiast gdy SMEP nie był włączony, exploit mógł wykonywać shellcode bezpośrednio ze zmapowanej strony NULL.

Na nowszym sprzęcie, Apple zaczęło stosować SMEP, która zabrania wykonywania w trybie jądra kodu znajdującego się w pamięci przestrzeni użytkownika. Wprowadzono ją w OS X 10.11 (El Capitan) pod koniec 2016 roku.

Mitygacje Intela w macOS

Historyczne exploity pokazują, że gdy atakujący mógł zmapować adres zero, a jądro wykorzystywało tę pamięć jako wskaźnik lub kod, błąd dereferencji NULL mógł prowadzić do wykonania dowolnego kodu.

Apple załatało te luki pod koniec 2016 roku. Aktualizacje bezpieczeństwa Apple zmieniły klasyfikację takich błędów na problemy odmowy usługi i usunęły je poprzez dodanie kontroli NULL lub lepsze zarządzanie stanem:

Apple całkowicie usunęło wsparcie dla procesów 32-bitowych w macOS 10.15 i włączyło SMEP, eliminując możliwość mapowania strony NULL na maszynach opartych na Intelu.

Nowoczesne mitygacje w macOS na Apple Silicon

Przy przejściu na Apple Silicon (architektura ARM64) i nowoczesne wersje macOS (11.0 Big Sur i nowsze), Apple wprowadziło mocne zabezpieczenia, które uniemożliwiają wykorzystanie błędów dereferencji NULL.

Ścisłe zabezpieczenia mapowania strony NULL

Wszystkie procesy użytkownika na Apple Silicon są 64-bitowe, a jądro nie pozwoli na zmapowanie jakiejkolwiek pamięci pod adresem 0 w przestrzeni użytkownika. Dodatkowo w formacie Mach-O rezerwowany jest niski obszar adresowy (4 GB).

Źródło: Snake&Apple X.NU

Nawet bez tej rezerwacji jądro macOS narzuca minimalny adres (podobnie jak mmap_min_addr w Linuksie), który nie może zostać zaalokowany przez użytkownika. Oznacza to, że nie można umieścić danych pod adresem lub blisko adresu NULL.

Każda dereferencja wskaźnika NULL trafia w niezmapowany obszar, wywołując błąd zamiast uzyskiwać dostęp do pamięci kontrolowanej przez atakującego.

Kontrole wykonania i dostępu sprzętowego (PXN/PAN)

Apple Silicon korzysta z funkcjonalności ARMv8 analogicznych do SMEP/SMAP w Intelu. ARM64 posiada funkcję Privileged Execute Never (PXN), która zapobiega wykonywaniu przez jądro kodu z pamięci użytkownika.

Natomiast Privileged Access Never (PAN) uniemożliwia przypadkowy odczyt/zapis z/do pamięci użytkownika przez jądro bez wyraźnego zezwolenia. Jądro oznacza całą pamięć użytkownika jako PXN, więc nawet gdyby wykonanie zostało przekierowane do strony użytkownika (np. adres 0), procesor odmówi wykonania.

PAN zapobiega także odczytowi danych umieszczonych przez atakującego na stronie NULL (co jednak mogłoby być zrealizowane z wykorzystaniem specjalnej sekwencji instrukcji).

1. Attacker maps shellcode at user-space NULL (0x0).  
2. Exploit hijacks kernel control flow to 0x0.  
3. Hardware checks:  
   ├─ PXN=1 → Instruction Fetch Fault (Execution denied)
   └─ PAN=1 → Data Access Fault (Access denied if kernel reads 0x0).  
4. System halts exploit via fault.Code language: PHP (php)

Te zabezpieczenia sprzętowe sprawiają, że wykonywanie shellcode ze strony NULL jest niemożliwe – próba wywoła błąd.

Kody uwierzytelniania wskaźników (PAC)

Duże udoskonalenie w architekturze ARM64e Apple to Pointer Authentication, wprowadzone na chipach A12/M1 (ARMv8.3-A). Kody PAC dodają podpis kryptograficzny do wartości wskaźników (takich jak adresy powrotu i wskaźniki funkcji), który jest weryfikowany podczas użycia.

macOS szeroko stosuje PAC w jądrze, aby chronić przed zmianą wartości wskaźników. Jeśli błąd dereferencji NULL jest wykorzystany do manipulacji wskaźnikiem jądra, PAC najprawdopodobniej wykryje modyfikację.

   Regular pointer:  0x00007FFFFFFFFFF8  (64-bit address)
                     └────────────────┘ 
                          address
   
   PAC pointer:      0xA23F7FFFFFFFFFF8
                     └────┘└──────────┘
                      │        │        
                      │        └─ original address
                      └─────────── cryptographic signature (PAC)

Funkcje jądra są podpisywane tajnymi kluczami (secret key). Fałszywy wskaźnik atakującego nie posiada prawidłowego podpisu, weryfikacja nie powiedzie się, gdy jądro spróbuje go uwierzytelnić.

PAC udaremnia próby sfałszowania wskaźników sterujących przepływem. Jest to bardzo istotne w przypadku eksploitów NULL deref, które historycznie polegały na zmuszaniu jądra do przeskakiwania do fałszywego wskaźnika funkcji atakującego.

Usunięcie starych wektorów exploitacji

Jak wspomniano, macOS nie wspiera już plików 32-bitowych (od macOS 10.15 Catalina), co eliminuje możliwość wyłączenia obszaru __PAGEZERO. Dodatkowo System Integrity Protection (SIP) oraz mechanizmy Kernel Integrity uniemożliwiają nawet użytkownikom z uprawnieniami root’a modyfikację niektórych fragmentów pamięci lub ładowanie niepodpisanego kodu jądra, utrudniając atak polegający na mapowaniu strony NULL.

Atakujący nie może wyłączyć tych zabezpieczeń bez uzyskania uprawnień jądra.

Ulepszone zarządzanie pamięcią jądra

Apple znacząco poprawiło obsługę wskaźników w jądrze XNU. Wiele interfejsów jądra przeprowadza teraz ścisłą walidację wskaźników. Po błędach z lat 2015–2016 Apple przeprowadziło audyt sterowników, wprowadzając kontrole NULL i zapewniając, że wskaźniki są ustawiane na NULL tylko wtedy, gdy jest to bezpieczne. Analiza kodu dekompilowanego metod zewnętrznych różnych sterowników wskazuje, że wiele z nich posiada prefiksy sugerujące, że są „oczyszczone” lub „bezpieczne”. Funkcje te pełnią rolę opakowań dla oryginalnych funkcji, na przykład:

 IOMobileFramebufferUserClient::s_set_matrix wywołuje IOMobileFramebufferUserClient::set_matrixCode language: CSS (css)

Mimo audytu błędy te nadal występują, ale czy nadal stanowią zagrożenie?

Czy błędy dereferencji wskaźnika NULL nadal są exploitowalne na Apple Silicon?

W nowoczesnym systemie macOS na Apple Silicon dereferencja wskaźnika NULL w jądrze prawie na pewno nie jest możliwa do wykorzystania w celu wykonania kodu. Spowoduje to kernel panic (odmowę usługi), jak widzieliśmy, wiele warstw obrony uniemożliwia wykorzystanie jej do eskalacji uprawnień.

Powody, dla których exploitacja jest bezskuteczna na Apple Silicon:

  • Brak możliwości kontroli pamięci dla wskaźnika NULL. Atakujący nie może zmapować ani umieścić danych pod adresem 0. System oraz sprzęt zapewniają, że strona NULL jest niezmapowana i niedostępna dla programów użytkownika.
  • Jądro nie wykona kodu z pamięci użytkownika. Nawet gdyby wykonanie zostało przekierowane do adresu 0 lub innego adresu użytkownika, mechanizm PXN spowoduje błąd wykonania.
  • Jądro nie odczyta pamięci użytkownika. Mechanizm PAN uniemożliwi odczyt danych z adresu 0 (ani żadnego innego adresu z pamięci użytkownika), próba odczytu wywoła błąd.
  • Kontrole uwierzytelniania wskaźników. Uwierzytelnianie wskaźnika uniemożliwia jego sfałszowanie w celu oszukania jądra (np. fałszywy wskaźnik funkcji jako payload). Atakujący musiałby ominąć PAC, co nie jest trywialne i zazwyczaj wymaga oddzielnego ataku typu side-channel lub wycieku informacji (np. podatność PACMAN).

Te zabezpieczenia uniemożliwiają dokończenie działań związanych z exploitacją, jednak spróbujmy „wyobrazić sobie” jakby taka exploitacja mogła wyglądać.

Teoretyczna ścieżka exploitacji

Minimalnie potrzebujemy pięciu oddzielnych podatności:

  • Modyfikacja tabeli stron (PTE) – podatność pozwalająca na modyfikację tabeli stron jądra w celu zmapowania strony NULL z uprawnieniami do zapisu. Zadanie jest trudne do wykonania, ponieważ wymaga wykorzystania błędu lub zaawansowanej techniki użycia podatności typu memory corruption pozwalającej na manipulację wpisami w tabeli stron pamięci (PTE). Nigdy się z tym nie spotkałem.
  • Obejście PAC – wymagałoby to jednej z poniższych metod:
    • Wycieku tajnych kluczy PAC (przechowywane są w rejestrach systemowych, co mocno komplikuje sprawę),
    • Znalezienia „wyroczni” zdolnej do generowania poprawnych podpisów,
    • Wykorzystania ataku „side-channel”, takiego jak PACMAN,
    • Odkrycia podatności umożliwiającej obejście PAC.
  • Podatność pozwalająca zapisać dane w określonym miejscu pamięci (konkretnie zależałoby nam na zapisie pod adresem 0).
  • Obejście PXN – podatność umożliwiająca manipulację atrybutami tabeli stron w celu oznaczenia strony NULL jako dostępnej dla jądra i wykonywalnej (teoretycznie, pierwszy prymityw użyty do ponownego mapowania mógłby to umożliwić).
  • Dereferencja wskaźnika NULL – na końcu potrzebny jest błąd powodujący dereferencję NULL i wykonanie naszej instrukcji.

Ze względu na tę złożoność, dereferencje wskaźnika NULL w nowoczesnych systemach Apple Silicon są użyteczne jedynie jako podatności prowadzące do ataków typu Denial of Service (DoS).

Czy Apple nadal poprawia te błędy?

Tak, Apple nadal naprawia tego typu problemy i przyjmuje zgłoszenia na ich temat, ale nie zawsze traktuje je jako luki bezpieczeństwa. Nie wiem dlaczego czasem są one uznawane za problem bezpieczeństwa, a innym razem nie – omówię to dokładniej w kolejnym artykule. Patrząc na najnowsze aktualizacje zabezpieczeń w macOS, można zauważyć, że Apple klasyfikuje poprawki dotyczące dereferencji wskaźnika NULL jako rozwiązania problemów związanych z atakami typu Denial of Service, a nie jako luki umożliwiające wykonanie dowolnego kodu.

Nie pojawiły się publiczne doniesienia o wykorzystaniu błędu dereferencji NULL do eskalacji uprawnień od czasu wprowadzenia macOS Big Sur, co wskazuje, że nie jest on (błąd dereferencji NULL) już realnym wektorem ataku na Apple Silicon.

Ogólna architektura bezpieczeństwa Apple zamknęła ten rozdział w historii exploitów.

Check lista exploitowalności – przed zgłoszeniem błędu dereferencji wskaźnika NULL

Nie każda dereferencja wskaźnika NULL jest taka sama — czasami można wykorzystać przyczynę błędu do przekierowania wskaźnika do kontrolowanej przez atakującego pamięci jądra. Zanim jednak zgłosisz taki błąd, warto sprawdzić kilka rzeczy:

  • Sprawdź, czy wskaźnik pochodzi z alokacji na stercie i czy można wpłynąć na jego źródło.
  • Przetestuj, czy da się „zasypać” (heap spray) lub odpowiednio przygotować stertę (heap grooming), aby kontrolować lokalizację pamięci.
  • Ustal, czy wskaźnik jest obliczany na podstawie indeksu lub przesunięcia, które mogą być kontrolowane przez użytkownika.
  • Poszukaj błędów typu use-after-free, gdzie zwolniona pamięć może zostać ponownie zaalokowana z kontrolowanymi danymi.
  • Oceń, czy brak lub niewystarczające sprawdzenie wartości NULL pozwala na użycie nieoczekiwanych wskaźników.
  • Zbadaj alternatywne ścieżki wykonania kodu, które mogą omijać mechanizmy bezpieczeństwa i prowadzić do manipulacji wskaźnikiem.

Podsumowując, kluczowe jest ustalenie, czy jakiekolwiek dane kontrolowane przez użytkownika mogą wpływać na wartość wskaźnika używanego w dereferencji. Jeśli wszystkie powyższe punkty można wykluczyć, mamy do czynienia z rzeczywistą dereferencją wskaźnika NULL.

Na zakończenie

Choć błędy dereferencji wskaźnika NULL nie są już użyteczne w tworzeniu exploitów, mam nadzieję, że zainteresowała Cię historia zabezpieczeń powstałych w odpowiedzi na ten problem i zrozumiałeś, dlaczego dziś jest on praktycznie nie do wykorzystania w atakach.

Jeśli ten wpis Cię zaciekawił i chcesz dowiedzieć się więcej o cyberbezpieczeństwie, zachęcam do regularnego odwiedzania naszego bloga AFINE, gdzie publikujemy nowe analizy i artykuły. Jeśli interesuje Cię szczególnie system macOS, warto dodać do zakładek repozytorium Snake_Apple, w którym znajdziesz wszystkie moje materiały na ten temat.

Mam nadzieję, że dowiedziałeś się tutaj czegoś nowego!

Karol Mazurek
Head of Research

Czy Twoja firma jest bezpieczna w sieci?

Dołącz do grona naszych zadowolonych klientów i zabezpiecz swoją firmę przed cyberzagrożeniami już dziś!

Zostaw nam swoje dane kontaktowe, a nasz zespół skontaktuje się z Tobą, aby omówić szczegóły i dopasować ofertę do Twoich potrzeb. Dbamy o pełną dyskrecję i poufność Twoich danych, dlatego możesz nam zaufać.

Chciałbyś od razu zadać pytanie? Odwiedź naszą stronę kontaktową.