Ubunlog Diego Germán González  

Qué es PHP2 Shell y cómo afectó a los sitios web

En esta infografía explicamos lo más relevante sobre PHP2Shell

Continuando con nuestra serie de artículos sobre el problema de seguridad más grave conocido en lo que queda del año, llegó el momento de explicar qué es PHP2Shell y cómo solucionarlo en Ubuntu.

Como explicamos anteriormente, PHP es un lenguaje de programación de código abierto pensado para usarse del lado del servidor. Según las estadísticas disponibles públicamente, lo utilizan alrededor del setenta y cinco por ciento de los sitios web (incluido este blog).

Qué es PHP2Shell y cómo afectó a los sitios web

Para entender qué hace PHP2Shell, primero tenemos que entender el concepto de motor PHP.

El motor PHP (que recibe técnicamente el nombre de Zend Engine en sus últimas versiones) es el programa intérprete encargado de leer, traducir y ejecutar el código PHP en un servidor web. Su trabajo es convertir las instrucciones escritas en PHP en resultados útiles (formatos HTML, JSON, datos, etc.).

El proceso de trabajo es el siguiente:

Paso 1: Análisis léxico

El procesador lee el código carácter por carácter y lo clasifica en palabras clave, variables, operadores, números y otros componentes importantes.

Paso 2: Parsing

En esta etapa, el motor analiza el resultado del paso anterior para comprobar que tenga sentido según las reglas del lenguaje.

Paso 3: Compilación a opcodes

En este paso, el motor convierte el código PHP en opcodes (códigos de operación), que son instrucciones de bajo nivel que facilitan a la máquina virtual de PHP la ejecución del código más rápidamente.

Paso 4: Ejecución

Aquí, la máquina virtual de PHP ejecuta los opcodes uno por uno, mientras interactúa con el sistema de archivos, la memoria RAM y las bases de datos para lograr el resultado final. Desde la versión PHP 5.5, el motor incluye OPcache, una extensión que guarda en la memoria RAM los opcodes ya compilados. Esto hace posible que, en las siguientes peticiones, el motor se salte los pasos 1, 2 y 3 y pase directamente al 4.

PHP2Shell

El nombre PHP2Shell se le asignó a una familia de vulnerabilidades críticas de seguridad de memoria que se determinó que afectaban directamente al núcleo, al motor y al intérprete del lenguaje PHP.

Estas dos vulnerabilidades están integrada por:

  • CVE-2026-109618: Descripta como corrupción de memoria por agotamiento de memoria (out-of-memory). Sucede cuando una petición agota el límite configurado (memory_limit) durante el tiempo asignado para la inicialización de los datos de entrada; esto hace que las rutinas de limpieza traten estructuras incompletas como válidas, permitiendo la ejecución de código malicioso.
  • CVE-2026-109619: Descripta como reutilización de estado global obsoleto o liberado (use-after-free)[5]. Sucede cuando un proceso de trabajo (worker) guarda punteros a memoria liberada de una petición anterior y una petición posterior en el mismo worker vuelve a utilizarlos.

Mediante estas vulnerabilidades, los atacantes pueden:

  • Lograr la ejecución remota de código con los privilegios del proceso del servidor web, aunque el atacante no esté autenticado.
  • Permitir la filtración de información sensible de la memoria del proceso, con la consiguiente exposición de contraseñas, claves API, tokens de autenticación y certificados utilizados por otros procesos.
  • Obtener acceso, por más seguro que sea el código de la aplicación. Esto lo logran al actuar sobre el motor de PHP y no sobre las aplicaciones (como WordPress, Drupal o Joomla).
  • Afectar a gran parte de las versiones de PHP, desde la versión 5.4 hasta las ramas 8.x que no fueron actualizadas.

¿Cómo y para qué usan esta vulnerabilidad los atacantes?

La explotación depende de cuál de las dos vulnerabilidades se aproveche:

CVE-2026-109618 (corrupción por agotamiento de memoria / OOM)

  1. Inducción del límite de memoria: el delincuente informático envía una petición HTTP pensada para gastar rápidamente la memoria del proceso de trabajo (*worker*) hasta llegar al límite fijado por la directiva memory_limit. Esto puede hacerlo enviando múltiples archivos o campos de formulario complejos.
  2. Interrupción abrupta con longjmp(): cuando se detecta la falta de memoria, PHP interrumpe inmediatamente el flujo normal y va directamente a la rutina de cierre de la petición (request shutdown).
  3. Corrupción de estructuras y ejecución: cuando se hace este salto, se omiten la inicialización y la limpieza ordenada de variables, lo que hace que permanezcan estructuras internas en un estado incompleto e inválido. El atacante logra manipular previamente la memoria (heap spraying), enviando parámetros de formulario en forma masiva con estructuras de C. Durante la fase de apagado, PHP lee la memoria inconsistente y, cuando evalúa punteros a funciones o destructores corruptos, la ejecución utiliza las instrucciones del atacante, lo que permite la ejecución remota de código.

CVE-2026-109619 (uso de memoria liberada / use-after-free)

  1. Generación del puntero descolgado (Producer): en este caso, el delincuente produce un error fatal o de memoria al principio del arranque de la petición, en las características activas por defecto (por ejemplo, en el seguimiento del progreso de carga de archivos session.upload_progress o en las trazas de errores fatales). Cuando termina la petición de manera anormal, PHP libera la memoria de la solicitud, pero mantiene punteros globales que apuntan a esa dirección ya liberada.
  2. Reutilización en peticiones posteriores (Consumer): como un mismo proceso de trabajo (worker) atiende varias peticiones HTTP consecutivas, una segunda petición enviada al mismo worker interactúa con ese estado global no reinicializado antes de que PHP limpie el puntero.
  3. PHP copia fragmentos de la memoria interna del proceso a través del puntero liberado dentro de la cookie de sesión PHPSESSID en la respuesta HTTP. Con esto, el delincuente informático logra extraer contraseñas, tokens de autenticación, claves API y certificados correspondientes a otras peticiones del servidor.
  4. Ejecución remota de código (RCE): el atacante sobrescribe el bloque de memoria liberado insertando estructuras de funciones falsas (incluidas llamadas a comandos del sistema, como system()). Cuando la siguiente petición ejecuta la rutina de actualización, el motor sigue el puntero manipulado y ejecuta la orden.
  5. Confusión de tipos en OPcache: en las versiones más actuales que utilizan la caché de código compilado (OPcache), los errores de asignación pueden permitir que distintos workers compartan metadatos obsoletos, lo que produce una confusión de tipos que logra corromper la memoria compartida.

El resultado de todas estas acciones es el siguiente:

Una vez explotada la vulnerabilidad, el atacante, con los privilegios del proceso del servidor web, puede:

  • Ejecutar comandos de la consola para identificar al usuario y el entorno.
  • Escribir scripts maliciosos en carpetas públicas o de subida para permitir el acceso posterior como puerta trasera.
  • Conectarse al servidor de forma remota.
  • Leer archivos de configuración y bases de datos, e intentar acceder a otros sistemas de la red.

Versiones de Ubuntu afectadas y cómo solucionarlo

Versión de Ubuntu Versión de PHP Paquete corregido
Ubuntu 14.04 LTS (Trusty) PHP 5 5.5.9+dfsg-1ubuntu4.29+esm18
Ubuntu 16.04 LTS (Xenial) PHP 7.0 7.0.33-0ubuntu0.16.04.16+esm22
Ubuntu 18.04 LTS (Bionic) PHP 7.2 7.2.24-0ubuntu0.18.04.17+esm14
Ubuntu 20.04 LTS (Focal) PHP 7.4 7.4.3-4ubuntu2.29+esm5
Ubuntu 22.04 LTS (Jammy) PHP 8.1 8.1.2-1ubuntu2.28
Ubuntu 24.04 LTS (Noble) PHP 8.3 8.3.6-0ubuntu0.24.04.13
Ubuntu 26.04 LTS (Resolute) PHP 8.5 8.5.4-0ubuntu1.5
Ubuntu 26.10 (Stonking) PHP 8.5 8.5.9-0ubuntu2.1
  • Ubuntu 14.04 y 16.04: requieren Ubuntu Pro y el complemento Legacy Support.
  • Ubuntu 18.04 y 20.04: requieren Ubuntu Pro con ESM.
  • Ubuntu 22.04 y posteriores: reciben la corrección mediante las actualizaciones estándar.

Para instalar los paquetes con las correcciones:

Actualizamos la lista de paquetes de los repositorios:

sudo apt update

Actualizamos los paquetes:

sudo apt upgrade

Comprobamos la versión instalada:

apt list '?installed ?name(^php[0-9.]+$)'

Reiniciamos los servicios que utilizan PHP:

sudo systemctl restart nombre_del_servicio

Si utilizamos PHP-FPM:

sudo systemctl restart phpX.X-fpm

Donde X.X debe sustituirse por el número de versión correspondiente.

Recuerda que todos estos pasos solo son necesarios si tienes aplicaciones que se ejecuten bajo PHP.

Artículo original

Leave A Comment

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.