
Exploit pour CVE-2026-17544 : écriture hors limites (OOB) dans bcmath de PHP convertie en RCE en mémoire uniquement, contournant disable_functions et open_basedir avec un résolveur sans offset à l'exécution.
Un proof-of-concept armé pour CVE-2026-17544, une écriture hors limites dans l'extension bcmath réécrite de PHP (bc_str2num). Il transforme le crash public connu DoS uniquement en une primitive d'exécution de code à distance complète, universelle et en mémoire uniquement qui contourne à la fois disable_functions et open_basedir.
Recherche autorisée / usage éducatif uniquement. Exécutez ceci uniquement sur des systèmes que vous possédez ou que vous êtes explicitement autorisé à tester.
![]()
bc_str2num tronque une partie fractionnaire sur un scale manuel, re-supprime les zéros de fin, mais ne met pas à jour fractional_end. Le tampon est dimensionné pour la longueur re-trimée alors que la copie utilise la longueur avant trim → écriture contrôlée de zéros hors limites dans le tas de la Zend MM.zend_string voisin (longueur préservée) → use-after-free par désynchronisation du refcount → lecture/écriture relative via chaîne géante → lecture arbitraire absolue sans risque de faute → résolution de symboles à l'exécution → un appel de fonction native entièrement data-only.zend_class_entry + une function_table inline + une fausse zend_function{ handler = zif_shell_exec }, puis l'appelle comme méthode. La sortie de la commande est retournée sous forme de chaîne et délivrée dans la réponse/stdout..data et le symbole cible sont tous résolus à l'exécution en scannant la mémoire — un seul fichier fonctionne donc à travers différentes builds et distributions.Ceci est une primitive d'évasion de sandbox / de post-exploitation, pas une RCE uniquement par entrée à distance.
| Scénario | Résultat |
|---|---|
L'attaquant peut déjà exécuter du PHP (webshell, désérialisation, sink eval) mais est limité par disable_functions + open_basedir | ✅ RCE native (ce PoC) |
Un seul appel bcmath sur une entrée de l'attaquant donne une écriture de zéros OOB aveugle sans retour d'information. Une RCE complète nécessite une exécution PHP arbitraire pour préparer le tas, construire les primitives R/W et lancer le résolveur — rien de tout cela n'est exprimable comme argument de fonction. Le plafond réaliste pour une exposition uniquement par entrée est donc un déni de service à distance ; l'exécution de code nécessite un contexte d'exécution PHP existant que ce PoC libère ensuite de la sandbox.
Le bug ne se trouve que dans le bcmath réécrit (branche PHP 8.4 / 8.5) :
Vérifié de bout en bout (uid=0, sortie capturée) sur PHP 8.4.23 et PHP 8.5.8, amd64, avec le même fichier non modifié — la disposition des structures Zend est identique entre 8.4 / 8.5.
bcmath activé..text jusqu'à l'en-tête ELF ; c'est sûr sur tout binaire mappé de façon contiguë. Seules les builds artificielles -z separate-code avec des trous de 2 Mo non mappés ne peuvent pas être auto-résolues par un scan aveugle (non observé en production).exit() par requête ne tue pas le serveur : php-fpm, Apache mod_php, ou le serveur intégré avec PHP_CLI_SERVER_WORKERS>0.php exploit.php "id; uname -a"
Déployez-le par exemple sous shell.php, puis :
GET /shell.php?cmd=id
POST cmd=id
La sortie de la commande est capturée via zif_shell_exec et écrite dans le corps de la réponse.
bccomp() vulnérable afin que l'écriture de zéros OOB atterrisse uniquement sur le refcount d'un zend_string voisin (longueur préservée).zend_reference (via indirection) permet une lecture arbitraire absolue sans risque de faute qui ne touche jamais l'en-tête refcounté de la cible..text divulgué : descendez page par page jusqu'à la magie ELF (base), parsez les en-têtes de programme pour trouver .data, puis scannez .data pour trouver la zend_function_entry de shell_exec dont le handler pointe dans .text.zend_class_entry, une inline avec un seul bucket (hash correct, chaîne de collision terminée), et une fausse dont le handler est ; corrompez le pointeur de classe de l'objet sonde et invoquez la méthode. La sortie est retournée et affichée.exploit.php — l'exploit universel en mémoire uniquement (CLI + web).Fourni pour la recherche en sécurité et l'éducation. L'auteur n'est pas responsable d'un mauvais usage. Ne déployez pas contre des systèmes que vous n'êtes pas autorisé à tester.
L'application se contente d'appeler une fonction bcmath sur une entrée utilisateur brute, par ex. bccomp($_POST['v']) | ❌ Uniquement DoS / crash |
| Branche PHP | Vulnérable |
|---|
| 7.x, 8.0 – 8.3 | Non (ancien libbcmath, bc_str2num différent) |
| 8.4.0 – 8.4.23 | Oui |
| 8.5.0 – 8.5.8 | Oui |
| ≥ 8.4.24 / ≥ 8.5.9 | Corrigé |
function_tablezend_stringzend_internal_functionzif_shell_exec