sistema: OPERATIVO
← volver a todos los hacks
AGENTS MEDIUM NEW

Cuando la decisión más prudente de un agente ejecuta el exploit: module shadowing en auto mode

Un análisis de agosto de 2026 muestra que un agente de código que rechaza un binario sospechoso y escribe su propio decodificador en Python ejecuta, con esa decisión prudente, el código del atacante.

2026-09-05 // 7 min affects: claude-code, opus-5, coding-agents, python

¿Qué es esto?

El 26 de agosto de 2026, el investigador Johann Rehberger (Embrace The Red) publicó el detalle de una cadena de ataque que convierte la prudencia de un agente de código en ejecución remota de código. Simon Willison la difundió al día siguiente, 27 de agosto, y Adversa AI la incorporó a su recopilación del 3 de septiembre sobre seguridad de agentes de código. El punto de partida es trivial: el usuario pide al agente que resuma un sitio web. En las pruebas de laboratorio del investigador (muestra pequeña), el resultado fue la ejecución de código arbitrario en la máquina anfitriona en el 60–80 % de los intentos, con una llamada de retorno a un servidor de mando y control.

Lo relevante del hallazgo no es un fallo inédito en un producto concreto. Es una observación estructural sobre los agentes autónomos: el agente nunca sigue conscientemente una instrucción maliciosa. Toma una serie de decisiones individualmente razonables, y es el entorno el que está dispuesto para que la decisión «prudente» sea la trampa. Tras cierto debate, Willison prefirió hablar de «ataque por entorno confuso» en lugar de una inyección de prompt clásica: ningún texto del atacante llega a obedecerse como una orden.

Cómo funciona

La cadena se compone de pequeños pasos anodinos:

  1. El agente recupera una página. El servidor responde 415 Unsupported Media Type, así que el agente decide por su cuenta reintentar con curl en un shell, pasando de una herramienta de recuperación/resumen a la ejecución de comandos en crudo. El servidor nunca se lo dijo; simplemente hizo que ese camino resultara el evidente.
  2. curl sigue una redirección hacia un archivo ZIP con fichas plausibles, codificadas, junto a un binario decodificador nativo y un fichero llamado struct.py.
  3. El agente extrae el archivo en una carpeta temporal y rechaza correctamente ejecutar el binario no confiable.
  4. En su lugar, escribe su propio pequeño decodificador en Python y lo ejecuta, desde dentro de la carpeta extraída.

El paso 4 es el exploit. Python coloca el directorio actual en su ruta de búsqueda de módulos, y el módulo estándar base64 importa struct. Como el archivo contiene un fichero struct.py, Python carga primero la versión del atacante: es el module shadowing. El módulo malicioso reexporta la verdadera API de bajo nivel, de modo que la decodificación continúa con normalidad, mientras una expresión ofuscada se ejecuta durante la importación. En el laboratorio, esa expresión lanzaba un proceso hijo aislado que descargaba una carga posterior y abría un canal C2.

# El razonamiento del agente, en esencia:
#   «El binario suministrado no es confiable -> no lo ejecuto.»
#   «Escribo mi propio decodificador en su lugar -> es prudente.»
#   python3 -c 'import base64, zlib, json; ...'   # ejecutado desde ./archivo-extraido/
#
# Lo que ocurre en realidad:
#   base64 importa struct  ->  ./struct.py (atacante) se carga primero  ->  se ejecuta el código

La observación central, según el investigador: el agente no confía en el binario suministrado, pero sí en el decodificador que escribió él mismo. El binario señuelo solo existe para empujar al modelo a escribir su propio código en un directorio envenenado.

Por qué importa

Dos detalles elevan el caso por encima de un simple truco. Primero, las defensas en capas del proveedor habrían reducido la inyección de prompt indirecta a casi cero sobre un conjunto fijo de 72 escenarios; sin embargo, esta cadena, ausente de ese conjunto, funcionó la mayoría de las veces. Un «0,00 %» de titular y un exploit funcional pueden ser ciertos a la vez; una cifra única no describe la resiliencia frente a una cadena inédita.

Segundo, y más llamativo: en algunas ejecuciones el agente advirtió la compromisión a posteriori e intentó matar el proceso malicioso, y el clasificador de aprobación automática bloqueó el comando de limpieza. La misma capa de seguridad que había permitido lanzar el proceso malicioso impidió su terminación. Un clasificador «de mejor esfuerzo» que filtra comandos según su intención aparente no es una frontera de contención, y ocasionalmente puede volverse en su contra.

Este patrón excede con creces a un agente o un lenguaje. Todo agente que (a) pueda ser empujado de una herramienta restringida a la ejecución de shell en crudo, (b) escriba y ejecute código en un directorio de trabajo controlado por el atacante y (c) dependa de un clasificador de intención en lugar de aislamiento del sistema operativo, queda expuesto a la misma forma de ataque.

Defensas

El agente que redacta el informe y el investigador coinciden: el juicio del modelo no es la red de seguridad. La frontera debe imponerla el runtime que lo rodea.

  • Aísle los agentes no supervisados. Ejecute los agentes de código en un contenedor, una VM o un sandbox a nivel de sistema operativo, no directamente en una estación de trabajo con credenciales reales. Esa es la verdadera frontera de seguridad; el clasificador no lo es.
  • Restrinja la salida de red. Bloquee por defecto el tráfico saliente para que un proceso hijo no pueda alcanzar ni una carga remota ni un servidor C2.
  • Nunca ejecute código desde un directorio de trabajo no confiable. Cuando un agente deba ejecutar un script que escribió para procesar contenido descargado, láncelo desde un directorio limpio y vacío, no desde el archivo extraído.
  • Use el modo aislado de Python para esos pasos. Invocar python3 -I retira el directorio actual de la ruta de búsqueda de módulos e ignora las sobrescrituras de entorno, lo que neutraliza precisamente este vector. El agente a veces lo hacía por sí solo; conviértalo en el comportamiento por defecto de su arnés.
  • Mantenga los secretos fuera del alcance del agente. No exponga directorios personales, claves SSH ni credenciales de nube al runtime, para que una cadena exitosa no tenga nada valioso que robar.
  • Monitorice, y trate la aprobación como comodidad, no como prueba. Un comando aprobado automáticamente no es prueba de que sea seguro. Registre las llamadas a herramientas y vigile los saltos al shell, las descargas y la creación de procesos hijos.

Estado

ElementoDetalle
DivulgaciónEmbrace The Red (Johann Rehberger), 26 de agosto de 2026
CoberturaSimon Willison, 27 de agosto de 2026; recopilación de Adversa AI, 3 de septiembre de 2026
Tasa de éxito reportada60–80 % en muestras pequeñas de laboratorio
Respuesta del proveedorInforme clasificado como «Informativo» / conforme al diseño; el auto mode se describe como función de comodidad de mejor esfuerzo, no una garantía de seguridad
NaturalezaCadena por entorno confuso / module shadowing, no un fallo aislado parcheable; sin CVE asignado

Todas las cifras son los resultados propios del investigador sobre configuraciones de laboratorio concretas y muestras pequeñas, y no deben leerse como una tasa de éxito general para ningún producto.

Sources