
Exploit para CVE-2026-17544: escritura fuera de límites (OOB) en PHP bcmath convertida en RCE solo en memoria, saltándose disable_functions y open_basedir con un resolvedor sin offsets en tiempo de ejecución.
Una prueba de concepto armada para CVE-2026-17544, una escritura fuera de límites en la extensión bcmath reescrita de PHP (bc_str2num). Esto convierte el crash solo-DoS públicamente conocido en una primitiva de ejecución remota de código completa, universal y de solo memoria que evade tanto disable_functions como open_basedir al mismo tiempo.
Solo uso educativo / de investigación autorizado. Ejecuta esto únicamente contra sistemas que poseas o para los que tengas autorización explícita de prueba.
![]()
bc_str2num trunca una parte fraccionaria con un scale manual, vuelve a recortar los ceros finales, pero no actualiza fractional_end. El búfer se dimensiona para la longitud re-recortada mientras que la copia usa la longitud previa al recorte → escritura de ceros fuera de límites controlada en el heap de Zend MM.zend_string vecino (preservando la longitud) → use-after-free por desincronización de refcount → R/W relativo de cadena gigante → lectura arbitraria absoluta a prueba de fallos → resolución de símbolos en tiempo de ejecución → una llamada a función nativa completamente solo-datos.zend_class_entry falso + function_table en línea + un zend_function{ handler = zif_shell_exec } falso, y luego lo invoca como método. La salida del comando se devuelve como cadena y se entrega en la respuesta/stdout..data y el símbolo objetivo se resuelven en tiempo de ejecución escaneando la memoria, por lo que un único archivo funciona entre distintas compilaciones y distribuciones.Esto es una primitiva de escape de sandbox / post-explotación, no una RCE solo con entrada remota.
| Escenario | Resultado |
|---|---|
El atacante ya puede ejecutar PHP (webshell, deserialización, sumidero eval), pero está limitado por disable_functions + open_basedir | ✅ RCE nativa (este PoC) |
Una única llamada a bcmath con entrada del atacante produce una escritura de ceros OOB ciega, sin retroalimentación. La RCE completa requiere ejecución arbitraria de PHP para preparar el heap, construir las primitivas R/W y ejecutar el resolvedor; nada de esto se puede expresar como argumento de función. Por lo tanto, el techo realista para una exposición solo con entrada es una denegación de servicio remota; la ejecución de código requiere un contexto de ejecución PHP existente que este PoC libera de la sandbox.
El bug solo existe en la versión reescrita de bcmath (línea PHP 8.4 / 8.5):
Verificado de extremo a extremo (uid=0, salida capturada) en PHP 8.4.23 y PHP 8.5.8, amd64, con el mismo archivo sin modificar: el diseño de las estructuras de Zend es idéntico en 8.4 / 8.5.
bcmath habilitado..text hasta la cabecera ELF; esto es seguro en cualquier binario mapeado de forma contigua. Solo las compilaciones artificiales -z separate-code con huecos de 2 MB sin mapear no se pueden auto-resolver con un escaneo ciego (no visto en producción).exit() por petición no mate al servidor: php-fpm, Apache mod_php, o el servidor integrado con PHP_CLI_SERVER_WORKERS>0.php exploit.php "id; uname -a"
Despliega como, p. ej., shell.php, luego:
GET /shell.php?cmd=id
POST cmd=id
La salida del comando se captura mediante zif_shell_exec y se escribe en el cuerpo de la respuesta.
bccomp() vulnerable para que la escritura de ceros OOB aterrice solo en el refcount de un zend_string vecino (preservando la longitud).zend_reference falso (mediante indirección) produce una lectura arbitraria absoluta a prueba de fallos que nunca toca la cabecera con refcount del objetivo..text filtrado: bajar paso a paso por páginas hasta la magia ELF (base), parsear las cabeceras de programa para encontrar .data, y luego escanear .data en busca del zend_function_entry de shell_exec cuyo handler apunta a .text.zend_class_entry falso, un en línea con un único bucket (hash correcto, cadena de colisión terminada) y un falso cuyo handler es ; corromper el puntero de clase del objeto de prueba e invocar el método. La salida se devuelve y se imprime.exploit.php — el exploit universal de solo memoria (CLI + web).Proporcionado para investigación y educación en seguridad. El autor no es responsable del mal uso. No lo despliegues contra sistemas que no estés autorizado a probar.
La aplicación solo llama a una función bcmath con entrada de usuario sin procesar, p. ej. bccomp($_POST['v']) | ❌ Solo DoS / crash |
| Rama PHP | Vulnerable |
|---|
| 7.x, 8.0 – 8.3 | No (libbcmath antiguo, bc_str2num diferente) |
| 8.4.0 – 8.4.23 | Sí |
| 8.5.0 – 8.5.8 | Sí |
| ≥ 8.4.24 / ≥ 8.5.9 | Corregido |
function_tablezend_stringzend_internal_functionzif_shell_exec