PHP2Shell: cómo la IA ayudó a destapar dos fallos críticos del núcleo de PHP desde 2012
Dos errores use-after-free en el motor de PHP, con una puntuación CVSS de 9,2, superaron una auditoría en 2024. Después, un esfuerzo asistido por IA los convirtió en exploits funcionales, con consecuencias para el mantenimiento del código heredado.
El 21 de octubre de 2026, el proyecto PHP publicó cuatro versiones de emergencia para corregir dos vulnerabilidades del motor que permiten la ejecución remota de código sin autenticación. Las correcciones llegaron en PHP 8.5.12, 8.4.27, 8.3.36 y 8.2.35, y ambos fallos, CVE-2026-109618 y CVE-2026-109619, tienen una puntuación CVSS v4.0 de 9,2. La debilidad de fondo es antigua. Según el informe técnico de Calif, la ruta de código afectada más antigua se remonta a PHP 5.4.0, una versión de 2012, de hace bastante más de una década. Parte de lo que hace llamativo este caso es la frecuencia con la que la debilidad ya se había detectado y se había dejado de lado.
01Dos errores, una misma causa
Ambos fallos residen en el entorno de ejecución de PHP, no en WordPress, Magento ni en ningún complemento. Calif informó de que un atacante sin autenticar podría ejecutar código en instalaciones estándar de Magento, WordPress, Drupal, Joomla, MediaWiki, Roundcube, phpMyAdmin, Nextcloud, Laravel y Symfony, entre otros. Sansec señala que, al estar el fallo en el motor, las tiendas resultan afectadas incluso cuando su propio código es correcto.
El mecanismo común es la forma en que PHP gestiona las condiciones fatales. Cuando una petición supera su memory_limit (128 MiB por defecto) o provoca otro error fatal, el motor en C no puede deshacer su pila paso a paso. Llama a zend_bailout(), un envoltorio de longjmp(). Un longjmp abandona el código C que se estuviera ejecutando, sin dar opción a terminar estructuras de datos a medio construir.
La tabla hash que hay detrás de todo array de PHP, incluido $_POST, ilustra el problema. El informe de Calif, según lo recoge Pentera, muestra que el contador de entradas se incrementa antes de asignar la clave, de modo que una ranura se cuenta como activa antes de que existan su clave y su valor. Si la asignación de la clave supera memory_limit, el bailout se dispara justo en ese punto. Un campo con un nombre anidado hace que PHP inserte el nombre exterior como nueva clave del array, así que el atacante controla la longitud de la clave. Si la dimensiona para rebasar memory_limit, el bailout cae sobre la asignación. Después, la limpieza da por buena la entrada inicializada a medias.
Los dos CVE se reparten según el ciclo de vida de la petición:
- CVE-2026-109618: corrupción de memoria durante la gestión de falta de memoria, desencadenada en el arranque de la petición, antes de que se ejecute ningún script de la aplicación.
- CVE-2026-109619: el estado interno propiedad de la petición sobrevive después de liberarse la memoria que lo respalda, y una petición posterior en el mismo worker puede usar ese estado obsoleto antes de que la inicialización normal lo restablezca. Rapid7 informa de que el aviso confirma RCE contra mod_php mediante la función de backtrace de errores fatales de PHP 8.5, activada por defecto, y una RCE vinculada al ciclo de vida de las sesiones contra mod_php y FPM.
CISA enumera como superficies expuestas Apache con mod_php (que PHP considera de mayor riesgo), PHP-FPM, php-cgi, FrankenPHP y LiteSpeed.
02Por qué permaneció oculto
Forzar una condición de falta de memoria es fácil de describir y difícil de lograr en remoto. Por defecto, PHP limita las subidas entrantes con post_max_size, que es de 8 MiB. Una petición tan pequeña no suele poder agotar un heap de 128 MiB. Calif encontró formas de sortearlo. PHP comprueba post_max_size contra el Content-Length declarado, pero no lo aplica a los bytes que realmente consume, de modo que Apache puede dejar pasar peticiones multipart en HTTP/1.1 con codificación chunked o en HTTP/2 sin longitud, sin una longitud declarada significativa. Una segunda vía agota memory_limit con una petición multipart que se mantiene por debajo de post_max_size.
La configuración sigue importando. CrowdStrike afirma que la ruta con codificación URL que demostró requiere aproximadamente memory_limit < 4 × post_max_size, algo que los valores por defecto de PHP no cumplen. Rapid7 constató igualmente que las pruebas de concepto públicas funcionan solo con una combinación concreta de sistema operativo, versión de PHP y servidor web, y que ninguna parece fiable de forma general. Eso es un límite de las herramientas públicas actuales. No hace que sea seguro dejar el error sin corregir.
La historia explica esa década de oscuridad. Los distintos relatos coinciden en que la idea de interrumpir la ejecución mediante el límite de memoria la publicó Stefan Esser en 2004. Un problema relacionado de falta de memoria en el análisis multipart se notificó en 2020 (algunos relatos dicen 2019), y una auditoría de OSTIF/Quarkslab de 2024 señaló un error relacionado, aunque sin demostrar su explotación. Cada vez, una corrupción plausible carecía de un camino demostrado hacia la ejecución de código, así que quedó como un error de robustez de baja prioridad. Convertir «podría corromper memoria» en «da una shell de forma fiable» exige un esfuerzo sostenido y especializado, y ese esfuerzo es lo que ha cambiado.
03Qué hizo realmente la IA
La atribución es más compleja de lo que sugieren los titulares. Calif afirma que halló el primer fallo el 1 de agosto de 2026 en el marco de la iniciativa «Patch the Planet» de OpenAI y lo notificó a PHP el 11 de agosto. Un análisis secundario señala que Calif describe un análisis con IA guiado por la hipótesis de un investigador, mientras que Wiz describe una IA que contribuye en el descubrimiento, el desarrollo del exploit, la detección de ataques y la validación del parche. El mismo análisis indica que Codex Security, de OpenAI, presentó un informe independiente de causa raíz el 11 de agosto y otros vectores de ataque el 18 de septiembre. Los nombres de los modelos (GPT-5.6 Sol y, según Wiz, también Gemini 4 Argon) proceden de fuentes secundarias, no del aviso de PHP.
No todos lo ven como un descubrimiento novedoso de la IA. Un crítico sostiene que todas las piezas de PHP2Shell ya estaban en datos de entrenamiento públicos. Esa lectura encaja con el historial expuesto, y además afina el argumento. La aportación del modelo parece menos la de detectar una clase de error nueva y más la del trabajo paciente de trazar rutas de ejecución, encadenar primitivas y construir un exploit funcional. Un relato describe agentes de IA que rastrean fallos en el orden de inicialización de la tabla hash y rutas en las que se hacía referencia a una tabla de estado no válida durante el análisis de POST. Las auditorías humanas no llegaron tan lejos.
04Divulgación, filtraciones y carrera por los parches
El proceso coordinado se vio alterado. PHP anunció el 20 de octubre que la versión saldría el 21 de octubre a las 14:00 UTC. Bitdefender informa de que Chainguard publicó imágenes de contenedor con la corrección más de seis horas antes del lanzamiento, rompiendo el embargo. Añade que PHP asegura que no se filtraron detalles técnicos, pero que un vídeo de un exploit aceleró el desarrollo de pruebas de concepto. Según Ars Technica, los investigadores de Sansec esperaban ataques masivos en los 15 minutos posteriores a la publicación. Según el artículo de Tech Xplore, responsables de Amazon dijeron que los atacantes empezaron a intentar explotar el fallo «de forma generalizada». El 26 de octubre, CISA añadió ambos CVE a su catálogo Known Exploited Vulnerabilities.
El mapa de parches es desigual. AWS enumera como rangos afectados 8.5.0–8.5.11, 8.4.0–8.4.26, 8.3.0–8.3.35 y 8.2.0–8.2.34, sin corrección oficial para PHP 5.4–8.1. Tenable añade que el equipo de PHP facilitó backports mínimos del código fuente para las versiones 7.4 a 8.1, mientras que de la 5.4 a la 7.3 no reciben nada del proyecto. Las configuraciones provisionales ayudan solo en parte. Para CVE-2026-109618, el aviso sugiere memory_limit=-1 establecido de forma no sobrescribible, un post_max_size bajo y límites de tamaño de petición en el proxy. Calif advierte de que eliminar el tope de memoria aumenta el riesgo de que el servidor se quede sin memoria. La postura de PHP es que ningún cambio de configuración mitiga por completo estas vulnerabilidades. Además, los operadores de flotas deben reiniciar PHP-FPM o el servidor web para que el entorno de ejecución parcheado se cargue de verdad.
05Qué significa para el código heredado
La lección práctica tiene que ver con la economía de la explotación. Michael Daniel, de la Cyber Threat Alliance, dijo a AFP que el tiempo que transcurre desde la prueba de concepto hasta los kits de exploits, antes de meses, se mide ahora en horas o días. También afirmó que la tasa histórica de explotación, del 5-6 % de las vulnerabilidades, no muestra señales de aumentar, de modo que lo que cambia es la velocidad, no el volumen. La expresión del antiguo responsable de la NSA Rob Joyce, citada por Daniel, es «gran incendio forestal purificador del software antiguo».
De ahí se derivan tres consecuencias de ingeniería:
- La «explotabilidad no demostrada» es una defensa más débil. Un hallazgo cerrado en 2024 por falta de una prueba de concepto puede reabrirse ahora a bajo coste. Un triaje que dependa de que el esfuerzo del atacante sea escaso envejecerá mal.
- El fin de vida útil es una frontera de seguridad. Las aplicaciones en PHP 8.1 o anterior ejecutan backports de procedencia incierta o directamente no tienen corrección. El coste de migrar es ahora un coste de parcheo.
- La IA defensiva solo escala si escala el triaje. Daniel advierte de que gran parte del ruido entrante es irreal o afecta a software nunca expuesto a internet, por lo que los responsables del mantenimiento necesitan mejores filtros a medida que se multipliquen los informes generados por IA.
Lo que sigue sin demostrarse es el equilibrio a largo plazo. Daniel espera que la IA se aplique al software antes de su lanzamiento, lo que podría traducirse en menos errores de este tipo en el código nuevo. Por ahora, un fallo de seguridad de memoria en un entorno de ejecución en C que sobrevivió 14 años, una auditoría y una notificación previa fue hallado, convertido en arma y parcheado en unas 11 semanas. Las herramientas de IA que cerraron esa brecha están también al alcance de los atacantes.
- PHP2Shell: A tale of two PHP remote vulnerabilities (Calif Research)calif.io
- Critical Vulnerabilities in PHP Require Immediate Patching (CISA)cisa.gov
- CVE-2026-109618 and CVE-2026-109619 (Rapid7)rapid7.com
- CrowdStrike: PHP2Shell technical detailscrowdstrike.com
- PHP web runtimes (AWS Security Bulletin)aws.amazon.com
- PHP2Shell technical advisory (Bitdefender)bitdefender.com
- PHP maintainers tell web devs to prepare for critical patches (Ars Technica)arstechnica.com
- AI discovery exposes decade-old PHP flaw (Tech Xplore / The Conversation)techxplore.com
[i]Compilado por el sistema editorial de Engineering Journal a partir de las fuentes indicadas y contrastado con ellas. Comunica cualquier error por la dirección de contacto.