Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
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
CVE-2019-11043 — Exploit Python pour CVE-2019-11043 ciblant le sous-dépassement de tampon (buffer underflow) de PHP-FPM afin d'obtenir une exécution de code à distance via l'écrasement d'octets nuls et la manipulation de variables FastCGI. | Kitploit
Outils/GitHubGitHub/lindemer/cve-2019-11043
Analyse des VulnérabilitésExploitationExploitation d'Applications WebTests d'IntrusionApprentissage et ÉducationDéveloppement de Charges Utiles
GitHublindemer/cve-2019-11043

CVE-2019-11043

Exploit Python pour CVE-2019-11043 ciblant le sous-dépassement de tampon (buffer underflow) de PHP-FPM afin d'obtenir une exécution de code à distance via l'écrasement d'octets nuls et la manipulation de variables FastCGI.

Voir le dépôt
427il y a 5 ansPas encore vérifié

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

CVE-2019-11043

Exécution de code à distance PHP-FPM

Screencast : https://youtu.be/d6benC5FVZM

Aperçu

Cet exploit zero-day dans les configurations PHP-FPM courantes a été découvert lors du concours Realworld CTF en 2019. Une expression régulière est utilisée pour analyser l'URI demandée, mais les caractères de nouvelle ligne %0a ne correspondent pas. Cela déclenche un bug dans FastCGI qui calcule incorrectement la longueur de la chaîne de requête et écrit un octet nul à un emplacement avant le début du tampon prévu. En sélectionnant soigneusement la longueur de la chaîne de requête, un attaquant peut utiliser ce bug pour écraser des variables PHP internes sur le serveur et exécuter du code shell arbitraire.

L'implémentation originale de cet exploit en Go se trouve ici. J'ai utilisé ceci, un article et le rapport de bug original comme ressources d'apprentissage afin d'implémenter l'exploit en Python.

Instructions

Docker sur Linux Exécutez sudo docker run --rm -ti -p 8080:80 reproduce-cve-2019-11043 pour instancier un serveur NGINX/PHP-FPM minimal avec un script vide à /script.php. Le Dockerfile de cette image est disponible ici, bien qu'il ne soit pas nécessaire pour exécuter la commande susmentionnée.

Docker sur Mac Exécutez sudo docker-compuse up -d depuis le répertoire /php/CVE-2019-11043 du dépôt vulhub. (Compose est inclus avec Docker pour Mac.)

Exécutez le script d'exploitation avec la commande python3 exploit.py http://localhost:8080/script.php (ou /index.php si la seconde option a été utilisée). Après une exécution réussie, un shell Web sera accessible en ajoutant des commandes à l'URL après ?a= (p. ex., http://localhost:8080/script.php?a=uname -a).

N.B. J'ai bien essayé de créer un playbook Ansible pour ce travail, mais je me suis heurté à un bug bloquant documenté ici. Il n'est pas possible de démarrer des services systemd sur les noyaux Linux récents (par exemple, toute version LTS d'Ubuntu) avec un playbook Ansible.

Théorie

Vulnérabilité

Les fichiers de configuration PHP-FPM contiennent une règle pour faire correspondre les requêtes URI entrantes aux scripts PHP, qui ressemble souvent à ceci :

location ~ [^/]\.php(/|$) {
  ...
  fastcgi_split_path_info       ^(.+?\.php)(/.*)$;
  fastcgi_param PATH_INFO       $fastcgi_path_info;
  fastcgi_pass                  php:9000;
  ...
}

Cela devrait correspondre à toute URI de la forme /script.php/pathinfo, mais . ne correspond en réalité pas aux caractères de nouvelle ligne %0a. Si l'URI contient une nouvelle ligne, cela déclenche le bug suivant dans l'implémentation PHP :

1141    int ptlen = strlen(pt);
1142    int slen = len - ptlen;
1143    int pilen = env_path_info ? strlen(env_path_info) : 0;
1144    int tflag = 0;
1145    char *path_info;
1146    if (apache_was_here) {
1147        /* recall that PATH_INFO won't exist */
1148        path_info = script_path_translated + ptlen;
1149        tflag = (slen != 0 && (!orig_path_info || strcmp(orig_path_info, path_info) != 0));
1150    } else {
1151        path_info = env_path_info ? env_path_info + pilen - slen : NULL;
1152        tflag = (orig_path_info != path_info);
1153    }

Le problème ici est que slen est correctement calculé comme la longueur de l'URI moins la longueur du chemin de la ressource, mais pilen est par erreur mis à 0. Cela définit path_info à une valeur négative à la ligne 1151, ce qui entraîne un sous-dépassement de tampon. Immédiatement après cette erreur de calcul dans le même fichier, on a :

1159    FCGI_PUTENV(request, "ORIG_PATH_INFO", orig_path_info);
1160    old = path_info[0];
1161    path_info[0] = 0;
1162    if (!orig_script_name ||
1163        strcmp(orig_script_name, env_path_info) != 0) {
1164        if (orig_script_name) {
1165            FCGI_PUTENV(request, "ORIG_SCRIPT_NAME", orig_script_name);
1166        }
1167        SG(request_info).request_uri = FCGI_PUTENV(request, "SCRIPT_NAME", env_path_info);
1168    } else {
1169        SG(request_info).request_uri = orig_script_name;
1170    }
1171    path_info[0] = old;

À la ligne 1161, un octet nul est écrit à l'emplacement mémoire mal calculé de l'étape précédente. Cela peut être exploité pour tirer parti d'une vulnérabilité à la ligne 1165, où FastCGI écrit une variable d'environnement. En écrivant l'octet nul dans le pointeur qui contrôle l'opération d'écriture de la variable d'environnement, nous pouvons insérer des variables PHP arbitraires dans l'environnement avec nos requêtes HTTP.

Exploitation

Structures de données internes de FastCGI

Les variables d'environnement dans FastCGI sont stockées en mémoire dans une séquence compacte de paires clé-valeur sous forme de chaînes. Le début et la fin du tampon contenant ces chaînes s'appellent _fcgi_data_seg. Le membre pos pointe vers le prochain emplacement disponible pour l'écriture. Si le tampon se remplit (pos > end), un nouveau tampon est alloué et le membre next pointe vers l'ancien.

118    typedef struct _fcgi_data_seg {
119        char                  *pos;
120        char                  *end;
121    	   struct _fcgi_data_seg *next;
122    	   char                   data[1];
123    } fcgi_data_seg;

FastCGI accède aux variables d'environnement individuelles via une table de hachage appelée _fcgi_hash.

125    typedef struct _fcgi_hash {
126    	   fcgi_hash_bucket  *hash_table[FCGI_HASH_TABLE_SIZE];
127    	   fcgi_hash_bucket  *list;
128        fcgi_hash_buckets *buckets;
129        fcgi_data_seg     *data;
130    } fcgi_hash;

L'idée ici est d'écraser l'octet de poids faible de pos afin de tromper FastCGI pour qu'il écrase une variable existante. Le code est censé prendre la chaîne ajoutée à notre chemin d'URI et la placer à l'emplacement de PATH_INFO. Cependant, nous voulons écraser PHP_VALUE, car cette valeur est immédiatement récupérée et chargée dans les paramètres PHP après le segment de code vulnérable.

Alignement des données

Comme vous pouvez le voir dans exploit.py, le principe général de cet exploit est de trouver une requête URI très longue qui alignera le tampon mémoire interne de FastCGI d'une manière que nous pouvons exploiter. L'idée est de trouver le nombre exact de caractères nécessaire pour que FastCGI alloue un nouveau tampon _fcgi_data_seg. Lorsque cela se produit, FastCGI écrira de manière prévisible notre PATH_INFO dans le nouveau tampon, suivi immédiatement par chacun de nos en-têtes HTTP comme nouvelles valeurs d'environnement. L'étape suivante consiste donc à trouver de combien de caractères nous devons compléter un en-tête HTTP arbitraire pour aligner la mémoire selon nos besoins. Étant limités à l'écriture d'un octet nul à un emplacement arbitraire, nous devons faire pointer pos vers un décalage prévisible par rapport à PHP_VALUE afin que la modification de l'octet de poids faible l'y déplace.

Télécharger l’outil