Saltar a contenido

Análisis detallado de un rootkit para servidores web PHP

Sophos X-Ops analiza a fondo un malware muy prligroso

Author placeholder

SophosLabs ha conseguido recientemente un implante para Linux relacionado con entornos de BIG-IP Access Policy Management (APM) comprometidos que usan componentes de Apache y PHP. El malware muestra técnicas avanzadas, como la carga personalizada de ELF, el hooking de funciones y la aplicación de parches de código en tiempo de ejecución, para evadir la detección mientras mantiene un acceso persistente a través de webshells ocultos.

El programa ofrece un resultado ya conocido —la ejecución de código del lado del servidor bajo demanda, algo habitual en los webshells— pero lo lleva a cabo utilizando técnicas más sofisticadas específicas de Linux y Apache.

El malware se dirige a implementaciones que incluyen Apache, libphp, la carga de módulos APR, componentes webtop de BIG-IP APM y flujos de trabajo de actualización de BIG-IP, lo que sugiere que se desarrolló para entornos específicos. F5 relaciona la actividad c05d5254 con los sistemas BIG-IP APM afectados por CVE-2025-53521, una vulnerabilidad de ejecución remota de código (RCE) sin autenticación en BIG-IP APM que se aprovecha cuando se configura una política de acceso en un servidor virtual. Si crees que estás utilizando, o has utilizado, versiones afectadas de BIG-IP APM, sigue las instrucciones de F5 para la corrección y la evaluación de la vulnerabilidad antes de aplicar las recomendaciones genéricas de refuerzo de seguridad para Apache o PHP.

Nuestro análisis sugiere que la muestra que se analiza aquí representa una carga útil de segunda fase; durante el análisis paralelo de una muestra relacionada de umount, observamos un componente de instalación/propagación distinto, responsable de infectar /usr/sbin/httpd, de persistir en las imágenes de actualización de BIG-IP, de modificar las configuraciones de SELinux y de desplegar la carga útil analizada en este artículo. El cargador de primera fase busca flujos de trabajo de imágenes de actualización o instalación de BIG-IP en, por ejemplo, /mnt/tm_install. Cabe destacar que el tamaño del prefijo malicioso utilizado por el httpd infectado (0x5430) coincide con el tamaño de la carga útil incrustada en la muestra de umount, lo que sugiere claramente que esta última es la responsable de desplegar la primera.

La muestra de segunda fase oculta cadenas operativas clave con RC4, consigue ejecutarse antes de que se llame a la función main() de la aplicación del host al interceptar __libc_start_main, se dirige al módulo PHP de Apache enganchándose al cargador de módulos de Apache Portable Runtime (APR) (apr_dso_load) e inyecta un shell web PHP en la memoria. Esto último lo consigue manipulando el comportamiento de mmap dentro de libphp en tiempo de ejecución, de modo que solo el proceso infectado ve el contenido malicioso y nada llega a tocar el disco.

Además de este acceso web, el implante también crea un socket de dominio UNIX local y puede redirigir una conexión a /bin/bash, lo que permite el acceso interactivo sin abrir un puerto TCP de escucha.

Según los informes públicos actuales y nuestro análisis, los ataques observados se centran en entornos webtop de BIG-IP APM, más que en implementaciones genéricas de Apache/PHP o CMS comunes.

Nota: Mientras llevábamos a cabo esta investigación, nos enteramos de que unos investigadores de ESET habían realizado un análisis de este malware, al que llamaron «PoisonedRefresh». Nuestro análisis observó de forma independiente comportamientos que coinciden con los suyos y aporta más detalles.

SHA256 de la muestra: 26bd5b0722d1dbab5db749a063c49bc8638653ac2addfead7a9cb3d6d57bccc9

Por qué es importante

Cuando los defensores oyen «web shell», suelen pensar en un pequeño script del lado del servidor, a menudo escrito en PHP, JSP o ASP, colocado en un directorio accesible desde la web para permitir la ejecución remota persistente de código a través de solicitudes HTTP normales. El script existe como un archivo en el disco, quizá ofuscado u oculto entre contenido legítimo, pero detectable de todos modos.

Esa suposición ha marcado la lógica de detección durante años. Los analistas buscan scripts sospechosos en los directorios raíz de la web, prestan atención a nombres de parámetros reveladores en las peticiones HTTP y se basan en la supervisión de la integridad de los archivos para detectar cambios inesperados.

Algunas familias de web shells se hicieron famosas precisamente porque demostraron lo potente que podía ser ese sencillo modelo de ataque. China Chopper, por ejemplo, es un web shell muy conocido que, según MITRE, proporciona acceso a través de servidores web y permite acciones como la ejecución de comandos HTTP POST, operaciones con archivos y acceso a la terminal de comandos.

Esta muestra desafía ese modelo tradicional de tres maneras:

  • Distribución de web shell sin archivos: la funcionalidad de web shell sigue existiendo, pero ya no está anclada a un archivo de script estático en el disco. En su lugar, el implante intercepta la carga de archivos PHP específicos y antepone un web shell a su representación en memoria en el momento de la llamada a mmap()
  • A nivel de procesono solo a nivel de aplicación: el implante redirige llamadas a funciones seleccionadas de libc y libphp dentro de los procesos de trabajo de Apache, de modo que todos los componentes basados en PHP que se ejecutan en ese proceso —plugins, escáneres, scripts locales— se ejecutan dentro de un entorno de ejecución manipulado
  • Doble canal de acceso: los atacantes pueden usar tanto una carga útil PHP basada en HTTP como una puerta trasera de socket UNIX local que les proporciona un shell interactivo sin necesidad de un puerto TCP a la escucha

El resultado es una primitiva de acceso que, para el atacante, se comporta como un shell web, pero que es mucho más difícil de detectar si solo usas métodos centrados en archivos o basados solo en PHP. En un host comprometido, cualquier cosa que se ejecute a través del entorno de ejecución libphp manipulado puede ver una versión diferente de los archivos PHP objetivo a la que realmente existe en el disco, lo que socava las suposiciones de las herramientas tradicionales de inspección de archivos.

Aunque no tenemos pruebas suficientes para atribuir este malware a un actor malicioso concreto, la selección de objetivos y la implementación sugieren una gran sofisticación operativa.

Resumen del web shell

A nivel conceptual, la muestra combina tres ideas:

  1. Ejecutarse al principio del ciclo de vida del proceso
  2. El implante se ejecuta antes de la lógica normal de la aplicación del host al interceptar la secuencia de inicio de libc a través de __libc_start_main.
  3. Actúa solo cuando hay PHP presente
  4. Al engancharse a las funciones de Apache Portable Runtime (APR), sobre todo a apr_dso_load, el implante espera a que Apache cargue el módulo php (libphp) antes de alterar el comportamiento del proceso.
  5. Proporciona múltiples vías de acceso

Cada una de estas técnicas es relativamente sencilla por sí sola; la sofisticación radica en cómo se combinan para formar un mecanismo de acceso coherente y estable dirigido específicamente a las implementaciones de Apache/PHP.

Nuestro análisis

El binario estaba desmontado y enlazado estáticamente, lo que limitaba los enfoques de triaje convencionales, como el análisis de importaciones o las simples búsquedas de cadenas. La muestra también elude la ruta habitual de inicio del enlazador dinámico, aportando en su lugar su propia lógica de cargador y ganchos de inicio.

En lugar de partir de las importaciones, nos centramos en:

  • Pivotes de flujo de control, especialmente en torno al inicio del proceso
  • Rutinas de descifrado de cadenas en tiempo de ejecución
  • Resolución de símbolos y lógica de instalación de ganchos
  • Uso de la introspección de procesos de Linux a través de /proc
  • Puntos de transición en los que los datos cifrados u opacos se convierten en texto sin formato y ejecutables

Este tipo de análisis está cobrando cada vez más importancia, ya que el malware para Linux sigue alejándose de los simples implantes en disco para pasar a cargadores personalizados, generación de código en tiempo de ejecución, ejecución en memoria y manipulación de procesos.

Aunque estas técnicas siguen generando señales observables que los defensores pueden utilizar, a menudo sustituyen los artefactos evidentes del sistema de archivos por cadenas de comportamiento que requieren más contexto o una inspección más profunda para identificarlas.

Esta muestra es un buen ejemplo: en lugar de colocar un shell web convencional de la forma habitual, modifica cómo se presentan determinados archivos PHP al proceso en ejecución durante el tiempo de ejecución. Aunque la capacidad a la que tiene acceso el atacante es similar a la de un shell web tradicional, la implementación elimina muchos de los indicios en los que suelen basarse los defensores. Esto pone de relieve la importancia de un enfoque de defensa en profundidad que combine la visibilidad del sistema de archivos, la memoria, los procesos y el comportamiento.

Cadenas RC4: siguiendo las pistas

Uno de los primeros obstáculos para entender la muestra fue su uso extensivo del descifrado de cadenas en tiempo de ejecución. Muchas de las cadenas más importantes se almacenan cifradas en la sección .rodata y solo se descifran cuando es necesario mediante una rutina RC4 compacta.

El malware utiliza el cifrado de flujo RC4 con una clave de 16 bytes codificada de forma fija: TrswBWIl90Z5e38n.

Esto oculta las cadenas operativas clave a un simple análisis estático, lo que dificulta entender la funcionalidad de la muestra solo mediante la extracción convencional de cadenas. Durante nuestro análisis, identificamos y desciframos varias cadenas cifradas distintas, entre ellas nombres de funciones, nombres de bibliotecas y nombres de archivos de destino.

Una vez descifradas en tiempo de ejecución, estas cadenas revelan el verdadero alcance y la intención del implante:

  • /proc/self/exe y /proc/self/maps se usan para la autoinspección del proceso
  • __libc_start_main, la rutina de inicio de libc
  • apr_dso_load y apr_time_now, funciones de APR dentro de Apache
  • libphp, el módulo PHP al que se dirige dentro del proceso de Apache
  • API de archivos y memoria como open, close y mmap
  • Primitivas de subprocesos como pthread_create y pthread_detach

Por separado, ninguna de estas cadenas llama especialmente la atención, pero juntas dibujan el panorama de una muestra que entiende el funcionamiento interno de los procesos de Linux, el tiempo de ejecución de Apache y el modelo de ejecución de PHP.

Consejo: En esta muestra, RC4 parece funcionar principalmente como mecanismo de ofuscación: oculta las cadenas operativas a una extracción estática directa y retrasa el análisis hasta el momento de la ejecución. Vale la pena señalar aquí que, como ocurre con cualquier muestra, que las cadenas generadas parezcan inofensivas no significa necesariamente que un binario sea benigno. En las investigaciones de servidores Linux, el descifrado de cadenas en tiempo de ejecución, la resolución dinámica de API y la revelación retardada de datos de configuración son cada vez más comunes en las familias de malware para Linux más sofisticadas.

La carrera por la ejecución de «main»

En Linux, la mayoría de los programas no llaman directamente a main. La ejecución pasa por el código de inicialización de libc, que prepara el entorno del proceso y luego invoca a main. Un componente clave de esta secuencia es __libc_start_main, que realiza la inicialización y llama al punto de entrada del programa.

Los binarios ELF habituales de Linux siguen una ruta muy trillada: el kernel carga el binario, el enlazador dinámico (ld.so) resuelve las dependencias y, a continuación, el código de inicio de libc prepara el entorno y llama a main. Muchas herramientas de seguridad y observabilidad se aprovechan de esta secuencia para obtener visibilidad sobre el inicio de los procesos. Nuestra muestra se desvía de esta ruta de dos maneras. En primer lugar, en el punto de entrada sin procesar, salta directamente a una rutina de cargador personalizada en lugar de llamar a __libc_start_main como es habitual. En lugar de limitarse a ejecutar código adicional, el cargador vuelve a abrir su propia imagen a través de /proc/self/exe, busca el desplazamiento donde comienza el ejecutable original conservado y carga manualmente ese ELF incrustado en la memoria.

A screenshot of a typical _start routine in a disassembler

Figura 1: Una rutina típica _start de un ELF de 32 bits desensamblado y enlazado estáticamente. Incluso sin símbolos, el punto de entrada muestra el comportamiento habitual de inicio del tiempo de ejecución de C: alineación de la pila, configuración de los argumentos de inicio y una llamada a una libc rutina de inicio. Esto hizo que el punto de entrada infectado de httpd destacara, ya que, en lugar de seguir este patrón, pasaba la pila sin procesar directamente a un cargador personalizado y se detenía si esa rutina devolvía un valor.

A screenshot of a custom loader routine in a disassembler

Figura 2: El punto de entrada del programa (_start) transfiere la ejecución directamente a una rutina de cargador personalizada. En un ejecutable convencional de Linux, _start normalmente pasaría a __libc_start_main, que a su vez invoca main(). La ausencia de esa secuencia de inicio tan conocida llamó la atención de inmediato durante el análisis y llevó al descubrimiento de la lógica personalizada de carga del ELF y de interceptación del inicio del implante.

A continuación, el cargador analiza el ELF incrustado, recorre sus segmentos PT_LOAD, asigna una nueva región de memoria, copia el contenido de los segmentos en su lugar, aplica las protecciones de memoria adecuadas, gestiona el intérprete original cuando es necesario y redirige la ejecución a través de su propio envoltorio __libc_start_main.

A routine in the malicious sample, shown in a disassembler screenshot

Figura 3: El implante descifra y resuelve __libc_start_main, conserva la rutina de inicio original de libc y la sobrescribe con un envoltorio (con un gancho en __libc_start_main) para que el código del implante se ejecute antes de la función main real del programa.

En la práctica, este enfoque de «trae tu propio cargador» ofrece al actor malicioso varias ventajas:

  • Evita la ruta de inicio convencional del enlazador dinámico, lo que podría reducir la visibilidad frente a los controles que se basan en esa secuencia como punto de supervisión
  • Le da al atacante un control preciso sobre cuándo y cómo se intercepta el inicio de libc
  • Proporciona un punto de acceso único y limpio al resto del implante

Desde la perspectiva de quien se defiende, es otro recordatorio de que confiar en la ruta normal del cargador como punto de interceptación ya no es suficiente ante amenazas de Linux más sofisticadas.

La muestra apunta explícitamente a __libc_start_main y la sustituye por una función contenedora. Conceptualmente, el flujo cambia de:

_start -> __libc_start_main(main, ...) -> main()

a:

_start -> custom loader -> real __libc_start_main(wrapper, ...) -> wrapper() -> real main()
wrapper() runs implant initialization
wrapper() then calls the real main

Esto le da al implante una ventana de ejecución temprana y fiable antes de que la aplicación anfitriona realice ninguna tarea significativa. También proporciona un punto de pivote estable, independientemente de cómo se comporte el resto de la aplicación, lo que permite que el malware se inicialice una vez y luego se camufle en un proceso que, por lo demás, es legítimo.

Interceptar la lógica de inicio de esta manera también proporciona al actor malicioso:

  • Un punto de ejecución único y estable
  • La capacidad de resolver API e instalar hooks antes de que comiencen los hilos de la aplicación
  • Una forma de hacer que el comportamiento malicioso posterior parezca nativo del proceso

Desde una perspectiva forense, también adelanta los indicadores en la línea temporal del proceso, a menudo antes de que los marcos de registro estén completamente inicializados.

Consejo: Un comportamiento inusual en las primeras fases de la vida de un proceso, como el acceso a /proc o cambios en los permisos de memoria, puede ser más revelador que la actividad posterior.

Atacando a Apache a través de APR

Tras conseguir una ejecución temprana, el implante no intenta manipular inmediatamente todo lo que hay en el proceso. En su lugar, espera a que se dé una condición específica: que Apache cargue el módulo PHP (libphp).

APR proporciona API para la carga dinámica de módulos, incluida apr_dso_load, que carga objetos compartidos en tiempo de ejecución. Interceptar esta función le da al implante un punto de observación natural para la inicialización del módulo, sin tener que adivinar ni codificar de forma fija el orden de carga. En lugar de intervenir en todos los procesos de Apache sin distinción, el malware puede esperar hasta que se presente el entorno objetivo deseado antes de activarse.

Nuestra muestra intercepta apr_dso_load e inspecciona las rutas de los módulos a medida que se cargan. Cuando el malware detecta libphp, modifica el comportamiento dentro de ese módulo.

A hook in the implant, shown in a screenshot of a disassembler

Figura 4: El implante se engancha a apr_dso_load de APR y controla explícitamente su comportamiento en función del módulo PHP, volviendo inmediatamente a menos que libphp se esté cargando.

Al mismo tiempo, la muestra se engancha a apr_time_now, la función de «hora actual» de APR. Esta API parece inofensiva, pero se invoca con frecuencia en un proceso de Apache en ejecución.

Según nuestra evaluación, el implante usa esta API de invocación frecuente como un disparador retardado para acciones posteriores, incluido el inicio del proceso de fondo responsable de la puerta trasera del socket UNIX local.

Este enfoque sugiere madurez operativa en los siguientes aspectos:

  • El implante limita su alcance al entorno para el que está diseñado
  • Evita desestabilizar los servicios al actuar demasiado pronto o de forma demasiado amplia
  • Aprovecha las propias abstracciones de tiempo de ejecución de la plataforma de destino en lugar de luchar contra ellas

Esta activación selectiva es un tema recurrente en todo el implante. En lugar de modificar el proceso nada más iniciarse, el malware espera repetidamente a que se den condiciones específicas de tiempo de ejecución antes de habilitar funcionalidades adicionales.

Consejo: En los procesos de Apache, investiga los cambios en la protección de memoria o las modificaciones en las páginas ejecutables que se produzcan poco después de que se cargue libphp.

 

Localizar libphp en la memoria

Una vez cargado PHP, el implante necesita saber dónde reside en la memoria del proceso. Linux muestra esta información a través de /proc/self/maps, que enumera todas las asignaciones de memoria junto con sus rangos de direcciones y archivos de respaldo.

El implante analiza este archivo para localizar las direcciones de inicio y fin de la asignación de libphp. A continuación, estas direcciones se utilizan para limitar las modificaciones posteriores al módulo objetivo previsto. En lugar de aplicar parches en la memoria a ciegas, el implante identifica la asignación del ejecutable libphp y limita sus cambios a esa región. Esto se consigue siguiendo estos pasos:

leer /proc/self/maps -> encontrar libphp -> mprotect RWX -> aplicar parches de reubicación -> mprotect RX

Leer /proc/self/maps no es intrínsecamente malicioso. Los depuradores, los perfiladores y las herramientas de gestión de memoria pueden inspeccionar legítimamente las asignaciones de los procesos. Sin embargo, resulta mucho más sospechoso cuando va seguido inmediatamente de cambios en los permisos de memoria, la aplicación de parches de reubicación y escrituras en regiones ejecutables de una biblioteca compartida objetivo.

Esta secuencia resulta especialmente anómala en los procesos de trabajo de Apache, donde los trabajadores tienen pocos motivos para inspeccionar sus propias asignaciones de memoria y luego modificar inmediatamente las páginas ejecutables.

Consejo: El acceso a /proc/self/maps seguido de actividad de mprotect(), la aplicación de parches de relocalización o escrituras en regiones de memoria ejecutables son comportamientos muy sospechosos que vale la pena investigar, sobre todo en los procesos de trabajo de Apache.

 

Redirigir la ejecución dentro de libphp

Muchos defensores estarán familiarizados con el hooking de malware a través de LD_PRELOAD o la manipulación de entradas PLT/GOT. Nuestra muestra adopta un enfoque más preciso, combinando el hooking basado en la reubicación con la reescritura directa de los destinos de llamada dentro de libphp, de modo que las operaciones seleccionadas se desvían primero hacia código controlado por el implante.

Antes de aplicar estas modificaciones, el implante cambia temporalmente las protecciones de memoria en la asignación de libphp a la que apunta, modifica la reubicación y los destinos de las llamadas seleccionados, y luego restaura las protecciones originales.

Desde el punto de vista de la implementación, la muestra recorre los datos de reubicación asociados a libphp y ajusta los destinos de las llamadas relativos al PC para un pequeño conjunto de funciones. Desde el punto de vista de quien se defiende, los detalles precisos de la mecánica de reubicación importan menos que el resultado.

Dentro del contexto del módulo PHP, la muestra redirige de forma silenciosa las llamadas que normalmente invocarían API de archivos y memoria como open, close, mmap y __fxstat, y así obtiene el control sobre cómo PHP abre, dimensiona, asigna y, en última instancia, ejecuta los archivos de script objetivo. Estos ganchos constituyen la base del mecanismo de entrega del shell web en memoria que se describe a continuación. Esto también le da al actor malicioso otra ventaja: no necesita inyectar una nueva biblioteca compartida en la ruta normal del cargador.

Entrega de un shell web mediante mapeo de memoria

En nuestra opinión, este fue el aspecto más característico de la muestra. El implante intercepta los intentos de PHP de abrir tres archivos de script específicos:

  • apm_css.php3
  • full_wt.php3
  • webtop_popup_css.php3

Probablemente se eligieron estos nombres de archivo porque ya existían en el entorno webtop de BIG-IP APM al que se dirigía el ataque, por lo que es poco probable que despierten sospechas.

Cuando PHP abre uno de estos archivos, el implante registra el descriptor del archivo. Cuando ese archivo se asigna posteriormente a la memoria, el implante crea una vista modificada en memoria que contiene tanto el shell web incrustado como el contenido original del script.

El archivo en el disco no tiene por qué contener en absoluto el contenido final del shell web; la ejecución se deriva de la representación modificada en memoria creada por el implante en tiempo de ejecución.

The mmap() hook in the implant, shown in a screenshot of a disassembler

Figura 5: El gancho mmap() comprueba si la asignación pertenece a un descriptor de archivo de script PHP rastreado. Si es así, llama al mmap() original y antepone el shell web PHP incrustado al contenido asignado en memoria, dejando el archivo en el disco sin cambios.

La carga útil PHP incrustada se comporta como un shell web clásico, con algunas características destacadas:

  • Lee los bytes sin procesar de la solicitud desde php://input
  • Comprueba si hay un prefijo mágico corto (BSOHAzPB) al principio del cuerpo de la solicitud
  • Descifra el resto utilizando un pequeño cifrado de flujo
  • Ejecuta el contenido descifrado mediante eval
  • Devuelve el estado HTTP 201 y establece Content-Type: text/css; charset=utf-8 para camuflarse entre las solicitudes normales de recursos

La carga útil está basada en plantillas, con cadenas clave que se reescriben en tiempo de ejecución, lo que complica aún más la coincidencia de firmas estáticas. En nuestra muestra, el marcador de solicitud (BSOHAzPB) y la clave del shell web (wSLjN1beuR) se insertaron en el PHP en tiempo de ejecución, en lugar de almacenarse directamente en su forma final.

Consejo: Los mecanismos de detección de shells web deberían incluir el análisis del comportamiento en tiempo de ejecución y la inspección de la memoria, no solo el escaneo de archivos. Para este tipo de amenaza, es muy posible que el archivo PHP en el disco parezca inofensivo, mientras que la asignación en memoria contenga código malicioso.

Activación retardada mediante `apr_time_now`

En lugar de generar subprocesos o rutinas pesadas durante la fase inicial de arranque, el implante usa su gancho en `apr_time_now` como disparador retardado.

Cuando el proceso de Apache empieza a realizar llamadas de tiempo rutinarias, el implante genera y separa el subproceso de trabajo encargado de crear la puerta trasera del socket UNIX local. Este momento minimiza el riesgo de desestabilizar el servicio y ayuda al implante a camuflarse entre el comportamiento normal en tiempo de ejecución. Además, complica los entornos de análisis dinámico que solo observan un breve intervalo tras el inicio del proceso.

Además del shell web basado en HTTP, el implante también establece un socket AF_UNIX local en /run/bigtlog.pipe en lugar de exponer un listener TCP tradicional.

En Linux de 32 bits, las operaciones de socket suelen multiplexarse a través de la histórica llamada al sistema socketcall, que gestiona operaciones como socket, bind, listen y accept. El implante usa esta interfaz de forma compatible con los entornos x86-32.

Tras una breve comprobación de autenticación basada en el token Kzwd6jM5, el implante redirige los flujos estándar de entrada, salida y error al socket y ejecuta /bin/bash, lo que proporciona acceso interactivo al shell sin abrir un puerto de escucha TCP, lo que dificulta su detección solo mediante la supervisión de red. El listener permanece activo tras una autenticación correcta, utilizando fork() para crear un proceso de shell independiente mientras sigue aceptando conexiones adicionales.

Curiosamente, no pudimos encontrar ningún mecanismo integrado que permitiera al actor malicioso conectarse al socket. No había código de socket del lado del cliente ni referencias adicionales al token de autenticación, lo que sugiere que los dos métodos (el shell web y el socket) son capacidades independientes. Es posible que el actor malicioso pueda interactuar con el socket a través del shell web, pero de momento no tenemos pruebas que lo confirmen ni lo desmientan.

Screenshot of a disassembler, showing the implant handing a local socket connection to /bin/bash

Figura 6: El implante entrega una conexión de socket local directamente a /bin/bash redirigiendo los flujos estándar y ejecutando el binario del shell.

Consejo: Los puntos finales de IPC locales, sobre todo en /run, merecen un análisis minucioso en los casos de compromiso del lado del servidor.

Protección y defensa

Sophos detecta esta amenaza como Linux/Agnt-IC.

Búsqueda de amenazas

Estos comportamientos deben tratarse como pistas de investigación y correlacionarse con pruebas de integridad de archivos, procesos, memoria y específicas de BIG-IP, en lugar de utilizarse como confirmación por sí solos.

Señales en la capa web

Comprueba si hay:

  • Solicitudes a los endpoints .php3 mencionados anteriormente, sobre todo si son poco habituales en tu entorno.
  • Endpoints PHP que devuelven HTTP 201 mientras afirman ser CSS (Content-Type: text/css; charset=utf-8).
  • Solicitudes POST repetidas con una estructura constante o tamaños de cuerpo inusuales dirigidas a rutas PHP similares a CSS.

Señales a nivel de host

Comprueba si hay:

  • Procesos de trabajo de Apache que leen /proc/self/maps.
  • Cambios temporales en los permisos de memoria de las asignaciones de módulos PHP (RWX seguido de RX) en torno a libphp.
  • Creación de un socket de dominio UNIX en /run/bigtlog.pipe.
  • Procesos descendientes de Apache que redirigen stdio y ejecutan /bin/bash.

Consejos

Guía de respuesta ante incidentes

Si sospechas que de tener este implante:

  1. Captura primero las pruebas volátiles
  2. Asume que hay doble acceso
  3. Reiniciar el servicio por sí solo no es garantía

Fortalecimiento y detección

Aunque cada entorno es diferente, hay varias medidas generales que pueden reducir la exposición o mejorar la visibilidad:

Reducción de la superficie de ataque

  • Si en tu entorno no es necesaria la ejecución de .php3, plantéate desactivarla tras un proceso de control de cambios y una revisión del impacto en las aplicaciones. No apliques esto como medida de mitigación generalizada a los sistemas BIG-IP APM sin seguir las directrices de F5
  • Da prioridad a las configuraciones que minimicen las rutas de ejecución de PHP de larga duración siempre que sea posible
  • Restringe ptrace (esto puede reducir algunas oportunidades de inspección e inyección entre procesos, pero no es necesariamente una medida de mitigación para el cargador dentro del proceso ni para el comportamiento de aplicación de parches):
echo 1 > /proc/sys/kernel/yama/ptrace_scope
  • Añade a la configuración de Apache:
<FilesMatch "\.php3$">
    Require all denied
</FilesMatch>
  •  

    • Minimiza las funcionalidades de ejecución de PHP innecesarias y revisa el impacto operativo de restringir funciones peligrosas cuando sea apropiado.

    Supervisión del comportamiento

    • Alerta ante combinaciones inusuales de actividad, como los trabajadores de Apache:
      • Lectura de /proc/self/maps
      • Modificación de las protecciones de memoria en libphp
      • Enlace de sockets UNIX en /run
      • Ejecución de /bin/bash
    • Considera sospechosas las respuestas HTTP 201 + text/css procedentes de endpoints PHP cuando no formen parte del comportamiento normal de la aplicación.
    • Planifica una respuesta que tenga en cuenta la memoria:
      • Incorpora la recopilación de datos de memoria de los procesos y la comparación entre el contenido de los módulos en disco y en memoria en los manuales de respuesta a incidentes para servidores web críticos.

    Conclusión

    Este implante demuestra cómo el malware moderno para Linux puede ofrecer capacidades típicas de los atacantes a través de sofisticados mecanismos de distribución. Aunque el PHP integrado se comporta, en última instancia, como un shell web tradicional, la infraestructura que lo rodea es considerablemente más avanzada: carga personalizada de ELF, interceptación temprana del arranque, supervisión de módulos compatible con APR, parches de reubicación y entrega de carga útil solo en memoria.

    Basándonos en nuestro análisis de las muestras relacionadas de umount y httpd infectadas, consideramos que esta campaña implica una arquitectura por etapas. Un componente de instalación parece encargarse del despliegue, la persistencia y la propagación, mientras que el componente httpd infectado se centra en la funcionalidad en tiempo de ejecución, la manipulación de procesos, la entrega del shell web y el acceso interactivo.

    Quizá el hallazgo más significativo sea que el shell web no tiene por qué existir en su forma definitiva en el disco. En su lugar, el implante altera la forma en que los archivos PHP seleccionados se presentan al proceso en ejecución, lo que significa que el contenido que observan Apache y PHP puede diferir del contenido visible en una inspección tradicional basada en archivos. Como resultado, los responsables de la respuesta que se centren exclusivamente en el sistema de archivos pueden pasar por alto pruebas cruciales.

    Esta muestra forma parte de una clase más amplia de amenazas para Linux que dependen menos de rastros evidentes en el disco y más de la manipulación en tiempo de ejecución. En estos casos, los defensores deberían centrarse en la correlación entre las distintas capas. La inspección del sistema de archivos por sí sola puede que no revele la intrusión, pero la telemetría de red, la inspección de protocolos, la supervisión de procesos, el análisis de memoria y la verificación de integridad pueden, cada uno de ellos, sacar a la luz diferentes partes de la cadena de ataque.