
Originalmente un honeypot para CVE-2026-20131
Un honeypot de baja interacción que simula la superficie web de un Cisco Secure Firewall Management Center (FMC) y captura tráfico de ataque de serialización Java sin autenticación (sondas de deserialización insegura tipo CVE).
\xac\xed\x00\x05 (y Base64 rO0AB…) y extrae cadenas de shell o URL mediante expresiones regulares y heurísticas.requests en un volumen de descargas no ejecutable.Registros JSON de una sola línea (compatibles con Splunk y ELK), alertas Telegram opcionales, artefactos de segunda etapa con hash y un usuario de contenedor no root. El proyecto está dirigido a investigadores que necesiten una trampa de estilo FMC enfocada, sin código de integración adicional.
git clone https://github.com/Hassan-Pouladi/Cisco-FMC-honeypot
cd FMC-Trap
cp .env.example .env
Edita .env según sea necesario (consulta Variables de entorno). Para despliegues detrás del Caddy incluido, establece TRUST_X_FORWARDED_FOR=1 para que las direcciones IP de los clientes en los registros reflejen al cliente original.
Edita Caddyfile: reemplaza los nombres de host de marcador de posición por tu dominio (y www si corresponde):
example.com, www.example.com {
reverse_proxy fmc-trap:5000
}
Opcionalmente, descomenta el bloque global email [email protected] en Caddyfile para recibir avisos de caducidad de Let’s Encrypt.
yourdomain.com a la IP pública de tu servidor, y www si se usa.ufw allow 80,443/tcp).La aplicación se ejecuta con UID 10001 dentro del contenedor. El directorio ./data montado debe ser escribible:
mkdir -p data/logs data/downloads
sudo chown -R 10001:10001 data/logs data/downloads
Sin la propiedad correcta, las solicitudes POST de exploits pueden devolver 500 (Permission denied al escribir registros o blobs sin procesar).
docker compose up -d --build
docker compose ps
curl -sI https://yourdomain.com/
Espera HTTP/2 200 (o 301 o 302) y Via: Caddy. En un navegador, https://yourdomain.com/ debería mostrar la página de inicio de sesión simulada de FMC.
Para saber dónde leer eventos, payloads y la salida de Docker, consulta Cómo encontrar registros, descargas y salida del servicio y Operaciones comunes.
Todo lo que sigue es relativo a tu directorio de proyecto (la carpeta que contiene docker-compose.yml, normalmente FMC-Trap después de clonar). Las rutas están en el host; Docker las monta dentro del contenedor.
Cuando algo aparece en el archivo de registro: fmc-trap.json recibe un objeto JSON por línea cuando una solicitud coincide con el comportamiento de una sonda de deserialización (bytes mágicos en un POST). Las solicitudes GET ordinarias a la página de inicio de sesión falsa no se escriben en este archivo de forma predeterminada.
Cuando la carpeta de descargas tiene archivos: las entradas aparecen solo si el pipeline extrae una URL de una sonda y el recolector obtiene correctamente el contenido remoto permitido dentro de MAX_DOWNLOAD_MB. Si el directorio permanece vacío, puede que aún no haya URL que cumplan los requisitos, o que las descargas estén bloqueadas por la política de la aplicación.
Impresión legible de JSON (opcional): para una sola línea, canalízala con python -m json.tool o usa jq si está instalado.
Internet :443/:80 → Caddy (TLS, Let’s Encrypt) → fmc-trap:5000 (Gunicorn/Flask)
↓
./data/logs, ./data/downloads (bind mounts)
expose: "5000" en Compose).Compose pasa estas variables al servicio fmc-trap; consulta docker-compose.yml para más detalles.
Cada línea en data/logs/fmc-trap.json es un objeto JSON. Las claves comunes incluyen timestamp, event_type, src_ip, headers, raw_payload_hash, extracted_commands y downloaded_file_hash cuando se almacenó un archivo. Los blobs guardados en data/downloads/ usan modo 0400 (solo lectura para el propietario).
Para acceder a Gunicorn directamente sin Caddy, añade lo siguiente bajo fmc-trap en docker-compose.yml:
ports:
- "127.0.0.1:5000:5000"
No vincules la aplicación a 0.0.0.0 en producción cuando Caddy termina TLS.
.env en el host (nunca hagas commit de .env).Despliega solo en sistemas que poseas o en los que estés explícitamente autorizado a desplegar instrumentación. Los honeypots pueden recopilar tráfico de ataque y malware; cumple con la legislación aplicable y la política de la organización. Este software está destinado a la investigación de seguridad.
| Elemento | Notas |
|---|
| Docker y Docker Compose v2 | Instalar Docker |
| VPS u host | Se recomienda un segmento de red dedicado o aislado |
| Dominio (opcional) | Para HTTPS: configura el DNS y permite el tráfico entrante TCP 80 y TCP 443 al host |
| Qué | Ruta en el host | Cómo abrir o seguir |
|---|
| Registro de eventos (líneas JSON) | data/logs/fmc-trap.json | tail -f data/logs/fmc-trap.json (flujo en vivo), o ábrelo en un editor, o ingéstalo en Splunk o ELK |
| Payloads de segunda etapa descargados | data/downloads/ | Los archivos aparecen solo cuando el recolector guarda una respuesta remota; cada archivo se nombra con su hash SHA256 (64 caracteres hexadecimales), sin extensión. Enuméralos con ls -la data/downloads (Linux o macOS) o Get-ChildItem data\downloads (Windows PowerShell) |
| Salida del proceso de la aplicación | No es un archivo; Docker | docker compose logs -f fmc-trap |
| Caddy (TLS, proxy, ACME) | No es un archivo; Docker | docker compose logs -f caddy |
| Alertas de Telegram (opcional) | No se almacenan en data/ | Establece TELEGRAM_BOT_TOKEN y TELEGRAM_CHAT_ID en .env; las alertas se disparan cuando se registran eventos |
| Objetivo | Comando o acción |
|---|
| Ver si los contenedores están en ejecución | docker compose ps |
Reiniciar después de editar .env o Caddyfile | docker compose up -d --build (o docker compose up -d --force-recreate si solo cambió el entorno) |
| Detener el stack | docker compose down |
| Seguir nuevos eventos JSON continuamente | tail -f data/logs/fmc-trap.json |
| Inspeccionar los últimos eventos | tail -n 50 data/logs/fmc-trap.json |
| Contar los artefactos descargados | Abre data/downloads en tu administrador de archivos, o usa un conteo de archivos de shell en ese directorio (los archivos se nombran por SHA256) |
| Confirmar que la página del honeypot carga | Abre https://yourdomain.com/ en un navegador o usa curl -sI como en el paso de verificación |
| Variable | Propósito | Predeterminado / nota |
|---|
TRUST_X_FORWARDED_FOR | Usar el primer salto de X-Forwarded-For como src_ip | Se recomienda 1 con Caddy |
DECEPTION_STATUS | 200 devuelve un cuerpo HTML; 302 devuelve una redirección | 200 |
DECEPTION_REDIRECT_URL | Ruta de destino cuando el estado es 302 | / |
MAX_DOWNLOAD_MB | Límite del recolector por URL | 16 |
TELEGRAM_BOT_TOKEN / TELEGRAM_CHAT_ID | Alertas opcionales | Vacío desactiva las alertas |
FMC_SERVER_HEADER | Cabecera de respuesta Server | nginx |
VT_API_KEY | Reservado | Opcional |
| Síntoma | Resolución |
|---|
Permission denied al escribir en data/ | Ejecuta sudo chown -R 10001:10001 data/logs data/downloads |
Bind for 0.0.0.0:80 failed: port is already allocated | Otro servicio o contenedor está vinculado al puerto 80. Detén ese servicio o libera el 80; solo un proceso puede escuchar en el 80 por host. |
| Errores de Let’s Encrypt o ACME en los registros de Caddy | Confirma que DNS resuelve a este servidor y que 80 y 443 son accesibles desde internet. Compose configura DNS 1.1.1.1 y 8.8.8.8 para Caddy cuando el resolutor del host falla dentro de Docker. |
curl a HTTPS devuelve salida vacía o falla en el primer intento | Espera hasta que certificate obtained successfully aparezca en docker compose logs caddy. |
La IP del cliente en los registros es 172.x.x.x | Establece TRUST_X_FORWARDED_FOR=1 cuando uses Caddy y luego recrea los contenedores: docker compose up -d --force-recreate. |