Threat Intelligence Dashboard para equipos Blue Team. Escanea logs de servidores web, detecta patrones maliciosos (238 reglas en 14 categorias), enriquece las IPs maliciosas con datos de geolocalizacion/ASN/riesgo, calcula un risk score (0-100) y genera reportes en multiples formatos para integracion con SIEM.
time=2026-04-03T13:06:26.570-03:00 level=INFO msg="Iniciando IP-Flame Multi-Log Engine" version=3.2
time=2026-04-03T13:06:26.571-03:00 level=INFO msg="Patrones cargados" count=238 format=nginx-combined
time=2026-04-03T13:06:26.571-03:00 level=INFO msg="GeoLite2-City cargada"
time=2026-04-03T13:06:26.572-03:00 level=INFO msg="GeoLite2-ASN cargada"
time=2026-04-03T13:06:29.100-03:00 level=INFO msg="Enriquecimiento CTI" local=3421 api=258 note="258 IPs enviadas a ipquery.io para enriquecimiento"
time=2026-04-03T13:06:29.300-03:00 level=INFO msg=Resultados threat_actors=89 hits=1372 patterns=238
time=2026-04-03T13:06:29.350-03:00 level=INFO msg="Dashboard generado" path=output/flamed-ips.html
time=2026-04-03T13:06:29.400-03:00 level=INFO msg="Geo Intelligence dashboard" path=output/dashboard-geo.html
time=2026-04-03T13:06:29.410-03:00 level=INFO msg="Reporte JSON exportado" path=output/report.json
time=2026-04-03T13:06:29.420-03:00 level=INFO msg="IP-Flame finalizado" version=3.2
- Screenshots
- Caracteristicas
- Inicio rapido
- Uso con binario
- Uso con Docker
- Configuracion
- Archivos de salida
- Integracion con SIEM — Wazuh, Elasticsearch, Splunk
- Webhooks — Slack, Telegram, Discord, n8n
- Integracion con CrowdSec
- Risk scoring
- Transparencia de la API
- Bases de datos GeoIP
- Categorias de deteccion — 238 patrones en 14 categorias
- Dashboards — Wall of Shame + Geo Intelligence
- Licencia
- Deteccion de amenazas — 238 patrones en 14 categorias: CMS, config exposure, VCS, RCE/webshells, SQLi, XSS, command injection, Log4Shell/JNDI, SSRF/cloud metadata, scanners, CVEs activos, AI crawlers, protocol abuse, tool fingerprinting
- CTI hibrido — Resolucion local con GeoLite2 (City + ASN) con fallback automatico a ipquery.io API (incluye deteccion de VPN/Tor/Proxy/Datacenter y risk score). Log explicito cuando se envian IPs a la API externa
- Risk scoring — Puntuacion 0-100 por IP basada en: volumen de hits, diversidad de patrones, indicadores de anonimizacion (Tor/VPN/Proxy) y score de la API
- Deteccion case-insensitive — Match en lowercase + URL decode recursivo (2 niveles) para detectar evasiones con encoding
- Multiples formatos de salida — Wall of Shame HTML, Geo Intelligence dashboard (mapa Leaflet), JSON, JSONL (SIEM), threat-actors.txt (CrowdSec), pattern-summary.txt
- Geo Intelligence dashboard — Mapa interactivo con Leaflet, distribucion de riesgo, top paises/ISPs/patrones/hosts atacados, indicadores TOR/VPN/Proxy
- Host destino opcional — Columna condicional que muestra a que dominio/IP de tu infraestructura apunta cada ataque (requiere
log-host-field) - Webhooks — Alertas a Slack, Telegram, Discord, n8n o endpoint generico, filtradas por nivel de riesgo
- Modo watch — Monitoreo continuo tipo
tail -fcon intervalo configurable - Soporte multi-formato — Logs nginx/apache combined (W3C), formato key-value personalizado, e IIS W3C Extended
- Concurrencia — Escaneo paralelo de multiples archivos de log
- Paginacion y filtros — Dashboard HTML con paginacion configurable (25/50/100/250/todos), filtros por nivel de riesgo y filtro por pais (dropdown auto-poblado desde los resultados)
- Structured logging — Todos los paquetes usan
log/slog(modo texto por defecto, modo JSON con--log-jsonpara SIEM/observabilidad) - Variables de entorno — Configuracion via
IPFLAME_*como fallback (el archivo de config tiene precedencia) - Exit codes — 0=exito, 1=sin archivos de log, 2=error de configuracion (documentados para integracion con cron/systemd)
- Security hardening — Prevencion de path traversal, limite de longitud de patrones (256 chars), validacion de IPs en respuestas de API
- Binarios pre-compilados — Linux y macOS (amd64/arm64), zero dependencias, disponibles en GitHub Releases
- Linux (amd64/arm64), macOS (amd64/arm64) o Windows (amd64)
- Bases de datos GeoLite2 (opcionales, se descargan con
update-geoip.sh)
# Linux amd64
curl -Lo ip-flame https://github.com/hernannh/ipflame/releases/latest/download/ip-flame-linux-amd64
chmod +x ip-flame
# Linux arm64 (Raspberry Pi, AWS Graviton)
curl -Lo ip-flame https://github.com/hernannh/ipflame/releases/latest/download/ip-flame-linux-arm64
chmod +x ip-flame
# macOS Apple Silicon (M1/M2/M3)
curl -Lo ip-flame https://github.com/hernannh/ipflame/releases/latest/download/ip-flame-darwin-arm64
chmod +x ip-flame
# Windows amd64 (PowerShell)
Invoke-WebRequest -Uri https://github.com/hernannh/ipflame/releases/latest/download/ip-flame-windows-amd64.exe -OutFile ip-flame.exe# Clonar este repositorio (templates + config)
git clone https://github.com/hernannh/ipflame.git
cd ipflame
# Descargar bases GeoIP (opcional pero recomendado)
chmod +x update-geoip.sh
./update-geoip.sh
# Editar configuracion (ajustar web-log= a la ruta de tus logs)
nano config-ip-flame.txt
# Ejecutar
./ip-flame --config config-ip-flame.txtCada release incluye checksums-sha256.txt:
sha256sum -c checksums-sha256.txtdocker compose up --build./ip-flame [flags]
| Flag | Default | Descripcion |
|---|---|---|
-config |
config-ip-flame.txt |
Ruta al archivo de configuracion |
-whitelist |
whitelist.txt |
Ruta al archivo de whitelist |
-watch |
false |
Modo watch: monitoreo continuo de logs |
-interval |
30 |
Intervalo en segundos entre escaneos (modo watch) |
--log-json |
false |
Logging estructurado en formato JSON (salida a stderr). Ideal para SIEM/observabilidad |
| Codigo | Significado | Uso |
|---|---|---|
0 |
Exito | Escaneo completado correctamente |
1 |
Sin archivos de log | No se encontraron archivos que matcheen el glob de web-log |
2 |
Error de configuracion | Archivo de config invalido, parametros faltantes o error de parsing |
Estos codigos permiten integracion confiable con cron, systemd y scripts de orquestacion:
# Ejemplo con cron: alertar si no hay logs
/opt/ip-flame/ip-flame --config /opt/ip-flame/config.txt
EXIT_CODE=$?
if [ $EXIT_CODE -eq 1 ]; then
echo "WARN: ip-flame no encontro archivos de log" | mail -s "IP-Flame: sin logs" admin@example.com
fiEscanea los logs, genera todos los reportes y termina:
# Con config por defecto (busca config-ip-flame.txt en el directorio actual)
./ip-flame
# Especificando rutas
./ip-flame --config /etc/ipflame/config.txt --whitelist /etc/ipflame/whitelist.txt
# Con logging JSON (para redirigir a un SIEM o archivo)
./ip-flame --log-json 2>> /var/log/ip-flame-structured.jsonMantiene el proceso activo, escanea nuevas lineas de log en cada intervalo y regenera reportes si hay nuevos hits. Soporta rotacion de logs automaticamente.
# Watch con intervalo de 30 segundos (default)
./ip-flame --watch
# Watch con intervalo de 60 segundos
./ip-flame --watch --interval 60
# Watch con logging JSON
./ip-flame --watch --interval 60 --log-json
# Watch en background con nohup
nohup ./ip-flame --watch --interval 60 >> /var/log/ip-flame.log 2>&1 &Para detener el modo watch: Ctrl+C o enviar SIGINT/SIGTERM al proceso.
Si preferis ejecuciones puntuales en lugar de modo watch:
# Cada hora
0 * * * * /opt/ip-flame/ip-flame --config /opt/ip-flame/config.txt >> /var/log/ip-flame.log 2>&1
# Cada 15 minutos
*/15 * * * * /opt/ip-flame/ip-flame --config /opt/ip-flame/config.txt >> /var/log/ip-flame.log 2>&1Alternativa a cron, recomendada en sistemas modernos con systemd. Ofrece mejor logging (journald), control de dependencias y manejo de errores.
1. Crear el service unit — /etc/systemd/system/ip-flame.service:
[Unit]
Description=IP-Flame CTI — Threat Intelligence Scanner
After=network.target
[Service]
Type=oneshot
ExecStart=/opt/ip-flame/ip-flame --config /opt/ip-flame/config.txt --whitelist /opt/ip-flame/whitelist.txt
WorkingDirectory=/opt/ip-flame
StandardOutput=journal
StandardError=journal
# Seguridad: ejecutar como usuario sin privilegios
User=ipflame
Group=ipflame
# Hardening opcional
NoNewPrivileges=true
ProtectSystem=strict
ReadWritePaths=/opt/ip-flame/output
ReadOnlyPaths=/var/log/nginx /opt/ip-flame/config.txt /opt/ip-flame/whitelist.txt /opt/ip-flame/geoip
PrivateTmp=true2. Crear el timer unit — /etc/systemd/system/ip-flame.timer:
[Unit]
Description=IP-Flame CTI — Escaneo periodico
[Timer]
# Ejecutar cada 15 minutos
OnCalendar=*:0/15
# Distribuir ejecucion aleatoriamente en ventana de 60s (evita thundering herd)
RandomizedDelaySec=60
# Ejecutar inmediatamente si se perdio la ultima ejecucion (ej: servidor apagado)
Persistent=true
[Install]
WantedBy=timers.target3. Habilitar y arrancar:
# Recargar systemd
sudo systemctl daemon-reload
# Habilitar el timer (sobrevive reboots)
sudo systemctl enable ip-flame.timer
# Arrancar el timer ahora
sudo systemctl start ip-flame.timer
# Verificar estado
sudo systemctl status ip-flame.timer
sudo systemctl list-timers | grep ip-flame
# Ver logs de ejecuciones
sudo journalctl -u ip-flame.service -f
# Ejecutar manualmente (sin esperar al timer)
sudo systemctl start ip-flame.serviceVariantes de OnCalendar utiles:
OnCalendar=*:0/15 # Cada 15 minutos
OnCalendar=hourly # Cada hora
OnCalendar=*-*-* 06,18:00 # A las 06:00 y 18:00
OnCalendar=daily # Una vez al dia (medianoche)
OnCalendar=Mon *-*-* 03:00 # Lunes a las 03:00Si preferis usar el modo --watch en lugar del timer:
# /etc/systemd/system/ip-flame-watch.service
[Unit]
Description=IP-Flame CTI — Watch Mode (monitoreo continuo)
After=network.target
[Service]
Type=simple
ExecStart=/opt/ip-flame/ip-flame --config /opt/ip-flame/config.txt --watch --interval 60
WorkingDirectory=/opt/ip-flame
Restart=on-failure
RestartSec=10
StandardOutput=journal
StandardError=journal
User=ipflame
Group=ipflame
NoNewPrivileges=true
ProtectSystem=strict
ReadWritePaths=/opt/ip-flame/output
ReadOnlyPaths=/var/log/nginx /opt/ip-flame/config.txt /opt/ip-flame/whitelist.txt /opt/ip-flame/geoip
PrivateTmp=true
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
sudo systemctl enable --now ip-flame-watch.service
sudo journalctl -u ip-flame-watch.service -fLa imagen incluye el binario, templates y config por defecto. Solo necesitas montar los logs y el directorio de salida.
| Volumen host | Destino en contenedor | Modo | Necesario | Descripcion |
|---|---|---|---|---|
| Directorio de logs | /app/logs |
:ro |
Si | Logs del servidor web |
output/ |
/app/output |
rw | Si | Directorio de salida de reportes |
geoip/ |
/app/geoip |
:ro |
Opcional | Bases GeoLite2 (sin esto usa ipquery.io) |
config-ip-flame.txt |
/app/config-ip-flame.txt |
:ro |
Opcional | Solo si necesitas personalizar la config incluida |
whitelist.txt |
/app/whitelist.txt |
:ro |
Opcional | Solo si necesitas personalizar la whitelist incluida |
Importante: El
web-logen la config debe apuntar a la ruta dentro del contenedor:web-log=/app/logs/*log*
# Nginx
docker run --rm \
-v /var/log/nginx:/app/logs:ro \
-v ./output:/app/output \
ip-flame
# Apache
docker run --rm \
-v /var/log/apache2:/app/logs:ro \
-v ./output:/app/output \
ip-flame
# Con GeoIP local y config personalizada
docker run --rm \
-v /var/log/nginx:/app/logs:ro \
-v ./geoip:/app/geoip:ro \
-v ./mi-config.txt:/app/config-ip-flame.txt:ro \
-v ./output:/app/output \
ip-flame# Foreground
docker run --rm --name ip-flame-watch \
-v /var/log/nginx:/app/logs:ro \
-v ./geoip:/app/geoip:ro \
-v ./output:/app/output \
ip-flame ./ip-flame --watch --interval 60
# Background (daemon)
docker run -d --name ip-flame-watch \
--restart unless-stopped \
-v /var/log/nginx:/app/logs:ro \
-v ./geoip:/app/geoip:ro \
-v ./output:/app/output \
ip-flame ./ip-flame --watch --interval 60
# Ver logs del modo watch
docker logs -f ip-flame-watch
# Detener
docker stop ip-flame-watchEl docker-compose.yml incluido esta configurado para ejecucion puntual:
# Ejecucion puntual
docker compose up --build
# Watch en background
docker compose up -d --build
# Ver logs
docker compose logs -f
# Detener
docker compose downPara modo watch, agregar el comando en el compose:
command: ["./ip-flame", "--watch", "--interval", "60"]
restart: unless-stopped# Ejecutar cada hora como contenedor efimero
0 * * * * docker run --rm \
-v /var/log/nginx:/app/logs:ro \
-v /opt/ip-flame/geoip:/app/geoip:ro \
-v /opt/ip-flame/output:/app/output \
ip-flame >> /var/log/ip-flame.log 2>&1Ofelia es un job scheduler disenado para Docker — reemplaza al cron del host y permite definir schedules directamente en labels de docker-compose. No requiere instalar cron en el host ni dentro de los contenedores.
Opcion A — Labels en docker-compose.yml (recomendada):
services:
ip-flame:
build: .
container_name: ip-flame-run
restart: "no"
labels:
# Ofelia: ejecutar cada 15 minutos
ofelia.enabled: "true"
ofelia.job-exec.ip-flame-scan.schedule: "0 */15 * * * *"
ofelia.job-exec.ip-flame-scan.command: "./ip-flame"
ofelia.job-exec.ip-flame-scan.no-overlap: "true"
volumes:
- ./geoip:/app/geoip:ro
- /var/log/nginx:/app/logs:ro
- ./output:/app/output
ofelia:
image: mcuadros/ofelia:latest
container_name: ofelia-scheduler
restart: unless-stopped
depends_on:
- ip-flame
command: daemon --docker
volumes:
- /var/run/docker.sock:/var/run/docker.sock:roNota: El formato de schedule en Ofelia usa 6 campos (incluye segundos):
segundo minuto hora dia mes dia_semana.
Opcion B — Archivo de configuracion de Ofelia:
Si preferis no usar labels, crea un archivo ofelia.ini:
[job-exec "ip-flame-scan"]
schedule = 0 */15 * * * *
container = ip-flame-run
command = ./ip-flame
no-overlap = true
[job-exec "ip-flame-geoip-update"]
schedule = 0 0 3 * * 1
container = ip-flame-run
command = /bin/sh -c "apk add --no-cache curl && /app/update-geoip.sh"
no-overlap = true# docker-compose.yml con ofelia.ini
services:
ip-flame:
build: .
container_name: ip-flame-run
restart: "no"
volumes:
- ./geoip:/app/geoip:ro
- /var/log/nginx:/app/logs:ro
- ./output:/app/output
ofelia:
image: mcuadros/ofelia:latest
container_name: ofelia-scheduler
restart: unless-stopped
command: daemon --config /etc/ofelia/config.ini
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./ofelia.ini:/etc/ofelia/config.ini:roSchedules utiles para Ofelia:
0 */15 * * * * # Cada 15 minutos
0 0 * * * * # Cada hora
0 0 */6 * * * # Cada 6 horas
0 0 0 * * * # Diariamente a medianoche
0 0 3 * * 1 # Lunes a las 03:00 (para update de GeoIP)Verificar que Ofelia esta ejecutando los jobs:
docker logs -f ofelia-schedulerEl archivo de configuracion usa formato clave=valor. Las lineas vacias y las que comienzan con # se ignoran.
| Parametro | Descripcion | Ejemplo |
|---|---|---|
web-path= |
Directorio de salida (se agrega flamed-ips.html automaticamente) |
web-path=output/ |
web-log= |
Glob de archivos de log a escanear (soporta wildcards) | web-log=/var/log/nginx/*log* |
log-format= |
Formato del log: nginx-combined, kv o iis-w3c |
log-format=iis-w3c |
geoip-dir= |
Directorio con las bases GeoLite2 .mmdb |
geoip-dir=geoip |
offending-lines= |
Patrones de deteccion separados por coma (case-insensitive) | offending-lines=wp-login.php,.env,nikto |
log-ip-field= |
(solo kv) Campo que contiene la IP del cliente | log-ip-field=CLIENT-IP |
log-req-field= |
(solo kv) Campo que contiene el request HTTP | log-req-field=REQ |
log-ua-field= |
(solo kv) Campo que contiene el User-Agent | log-ua-field=UA |
log-status-field= |
(solo kv) Campo que contiene el status code HTTP | log-status-field=STATUS |
log-time-field= |
(solo kv) Campo que contiene el timestamp | log-time-field=TIME |
log-host-field= |
(solo kv) Campo que contiene el Host/dominio destino. Opcional — si no se configura, la columna no aparece en los reportes | log-host-field=HOST |
webhook= |
Configuracion de webhook (ver Webhooks) | webhook=slack,https://hooks.slack.com/... |
Todos los parametros de configuracion se pueden definir via variables de entorno con prefijo IPFLAME_. El archivo de configuracion tiene precedencia sobre las variables de entorno (si un parametro esta definido en ambos, se usa el valor del archivo).
| Variable de entorno | Equivalente en config | Descripcion |
|---|---|---|
IPFLAME_WEB_PATH |
web-path= |
Directorio de salida |
IPFLAME_WEB_LOG |
web-log= |
Glob de archivos de log |
IPFLAME_LOG_FORMAT |
log-format= |
Formato del log |
IPFLAME_GEOIP_DIR |
geoip-dir= |
Directorio de bases GeoLite2 |
IPFLAME_LOG_IP_FIELD |
log-ip-field= |
Campo IP (formato kv) |
IPFLAME_LOG_REQ_FIELD |
log-req-field= |
Campo request (formato kv) |
IPFLAME_LOG_UA_FIELD |
log-ua-field= |
Campo User-Agent (formato kv) |
IPFLAME_LOG_HOST_FIELD |
log-host-field= |
Campo Host (formato kv) |
Esto es util para entornos Docker/Kubernetes donde se prefiere configurar via environment en lugar de montar archivos:
# Ejecucion con variables de entorno (sin archivo de config)
IPFLAME_WEB_PATH=output/ \
IPFLAME_WEB_LOG="/var/log/nginx/*log*" \
IPFLAME_LOG_FORMAT=nginx-combined \
IPFLAME_GEOIP_DIR=geoip \
./ip-flame
# Docker con variables de entorno
docker run --rm \
-e IPFLAME_WEB_PATH=/app/output/ \
-e IPFLAME_WEB_LOG="/app/logs/*log*" \
-e IPFLAME_LOG_FORMAT=nginx-combined \
-e IPFLAME_GEOIP_DIR=/app/geoip \
-v /var/log/nginx:/app/logs:ro \
-v ./output:/app/output \
ip-flameEl archivo whitelist.txt contiene una IP por linea. Las lineas vacias y las que comienzan con # se ignoran.
# IPs internas / equipo de desarrollo
192.168.1.1
10.0.0.50
Nginx / Apache (formato combined estandar):
log-format=nginx-combined
web-log=/var/log/nginx/*log*
Nginx detras de Cloudflare (formato kv personalizado):
log-format=kv
log-ip-field=CLIENT-IP
log-req-field=REQ
log-ua-field=UA
log-status-field=STATUS
log-time-field=TIME
log-host-field=HOST
web-log=/var/log/nginx/*log*
Nota sobre
log-host-field: Este campo es opcional. Si se configura y los logs contienen el dato, se habilita automaticamente la columna "Host Destino" en el Wall of Shame, el campotarget_hosten los JSON, y el panel "Hosts mas atacados" en el Geo Intelligence dashboard. Si no se configura, estos elementos no aparecen — sin columnas vacias ni campos innecesarios.
Ejemplo de log_format en nginx.conf para formato kv:
log_format cloudflare
'CLIENT-IP="$http_cf_connecting_ip" '
'REAL-IP="$http_cf_connecting_ip" '
'CF-IP="$remote_addr" '
'HOST="$host" '
'TIME="[$time_local]" '
'REQ="$request" '
'STATUS=$status '
'BYTES=$body_bytes_sent '
'REFERER="$http_referer" '
'UA="$http_user_agent" '
'COUNTRY="$http_cf_ipcountry"';IIS (Internet Information Services) — formato W3C Extended:
log-format=iis-w3c
web-log=C:\inetpub\logs\LogFiles\W3SVC1\*.log
IP-Flame parsea automaticamente la linea #Fields: de cada archivo para detectar la posicion de los campos. Esto significa que funciona con cualquier combinacion de campos que IIS tenga configurada, no solo el formato por defecto.
Formato por defecto de IIS:
#Fields: date time s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) cs(Referer) sc-status sc-substatus sc-win32-status time-taken
2026-03-29 10:15:30 192.168.1.1 GET /wp-login.php - 80 - 45.33.32.1 Mozilla/5.0+(Windows+NT+10.0) - 404 0 0 125
Campos que IP-Flame extrae del log IIS:
| Campo IIS | Uso en IP-Flame |
|---|---|
c-ip |
IP del cliente (IP maliciosa) |
date + time |
Timestamp (se combinan) |
cs-method + cs-uri-stem + cs-uri-query |
Request reconstruido (ej: GET /path?query) |
sc-status |
Status code HTTP |
cs(User-Agent) |
User-Agent (los + se decodifican a espacios) |
Nota para Docker: En Windows, montar el directorio de logs de IIS como volumen:
docker run --rm \ -v C:\inetpub\logs\LogFiles\W3SVC1:/app/logs:ro \ -v .\config-ip-flame.txt:/app/config-ip-flame.txt:ro \ -v .\output:/app/output \ ip-flame
Configurar logging W3C en IIS:
- Abrir IIS Manager > Seleccionar el sitio > Logging
- Format: W3C
- En Select Fields, asegurarse de tener habilitados:
c-ip,cs-method,cs-uri-stem,cs-uri-query,sc-status,cs(User-Agent),date,time - Ruta por defecto de los logs:
C:\inetpub\logs\LogFiles\W3SVC1\
IP-Flame genera 6 archivos en el directorio configurado por web-path:
| Archivo | Formato | Uso | Audiencia |
|---|---|---|---|
flamed-ips.html |
HTML | Wall of Shame — tabla operativa con filtros por riesgo y pais, paginacion, columna Host condicional y detalle expandible por IP | SOC / Blue Team |
dashboard-geo.html |
HTML | Geo Intelligence — mapa Leaflet interactivo, distribucion de riesgo, top paises/ISPs/patrones/hosts, indicadores TOR/VPN/Proxy | Management / Executive |
report.json |
JSON | Reporte completo con summary y todos los threat actors | Analisis / Herramientas |
report.jsonl |
JSONL | Una linea JSON por threat actor | Ingestion SIEM (Wazuh, Elastic, Splunk) |
threat-actors.txt |
Texto | Lista plana de IPs | CrowdSec, fail2ban, iptables |
pattern-summary.txt |
Texto | Resumen de patrones ordenados por cantidad de hits | Analisis de tendencias |
{
"tool": "ip-flame",
"version": "3.2",
"generated_at": "2026-03-29T20:27:15-03:00",
"summary": {
"total_threat_actors": 3623,
"total_hits": 20952,
"risk_critical": 0,
"risk_high": 18,
"risk_medium": 254,
"risk_low": 3351
},
"threat_actors": [
{
"ip": "173.212.230.39",
"country": "France (FR)",
"city": "Lauterbourg",
"isp": "Contabo GmbH",
"asn": "AS51167",
"risk_score": 50,
"risk_level": "high",
"is_vpn": false,
"is_tor": false,
"is_proxy": false,
"is_datacenter": false,
"hit_count": 1174,
"first_seen": "19/Mar/2026:07:45:39 +0000",
"last_seen": "19/Mar/2026:07:45:47 +0000",
"top_request": "GET /media/.env HTTP/1.1",
"top_user_agent": "Mozilla/5.0 ...",
"matched_patterns": [".env", ".sql", "wp-config.php", "..."],
"hits": [
{
"timestamp": "19/Mar/2026:07:45:39 +0000",
"request": "GET /media/.env HTTP/1.1",
"status_code": "301",
"user_agent": "Mozilla/5.0 ...",
"matched_pattern": ".env"
}
],
"cti_source": "local"
}
]
}IP-Flame genera report.jsonl (una linea JSON por threat actor) disenado para ingestion directa en SIEM. Tambien se puede usar report.json (reporte completo) o el webhook generico para envio en tiempo real.
Editar /var/ossec/etc/ossec.conf en el manager para monitorear el archivo de salida:
<ossec_config>
<localfile>
<log_format>json</log_format>
<location>/opt/ip-flame/output/report.jsonl</location>
<label key="source">ip-flame</label>
</localfile>
</ossec_config>Si IP-Flame corre en un agente remoto, agregar el bloque
<localfile>en elossec.confdel agente, o usar centralized configuration desde el manager con<agent_config>.
Crear /var/ossec/etc/decoders/ipflame_decoder.xml:
<decoder name="ipflame">
<prematch>^{"ip":</prematch>
<plugin_decoder>JSON_Decoder</plugin_decoder>
</decoder>Crear /var/ossec/etc/rules/ipflame_rules.xml:
<group name="ipflame,threat_intel,">
<!-- Regla base: cualquier threat actor detectado por IP-Flame -->
<rule id="100100" level="3">
<decoded_as>ipflame</decoded_as>
<description>IP-Flame: threat actor detectado — $(ip) [$(risk_level)] score:$(risk_score)</description>
<group>ipflame,</group>
</rule>
<!-- Nivel medium -->
<rule id="100101" level="6">
<if_sid>100100</if_sid>
<field name="risk_level">medium</field>
<description>IP-Flame: threat actor MEDIUM — $(ip) score:$(risk_score) hits:$(hit_count) — $(country)</description>
<group>ipflame,medium,</group>
</rule>
<!-- Nivel high -->
<rule id="100102" level="10">
<if_sid>100100</if_sid>
<field name="risk_level">high</field>
<description>IP-Flame: threat actor HIGH — $(ip) score:$(risk_score) hits:$(hit_count) — $(country) $(isp)</description>
<group>ipflame,high,</group>
<options>alert_by_email</options>
</rule>
<!-- Nivel critical -->
<rule id="100103" level="14">
<if_sid>100100</if_sid>
<field name="risk_level">critical</field>
<description>IP-Flame: threat actor CRITICAL — $(ip) score:$(risk_score) hits:$(hit_count) — $(country) $(isp)</description>
<group>ipflame,critical,</group>
<options>alert_by_email</options>
</rule>
<!-- Threat actor usando Tor -->
<rule id="100104" level="12">
<if_sid>100100</if_sid>
<field name="is_tor">true</field>
<description>IP-Flame: threat actor desde TOR — $(ip) score:$(risk_score) — $(country)</description>
<group>ipflame,tor,</group>
</rule>
<!-- Threat actor usando VPN -->
<rule id="100105" level="8">
<if_sid>100100</if_sid>
<field name="is_vpn">true</field>
<description>IP-Flame: threat actor desde VPN — $(ip) score:$(risk_score) — $(country) $(isp)</description>
<group>ipflame,vpn,</group>
</rule>
<!-- Threat actor con muchos hits (posible scanner automatizado) -->
<rule id="100106" level="10" frequency="1" timeframe="1">
<if_sid>100100</if_sid>
<field name="hit_count" type="pcre2">\d{3,}</field>
<description>IP-Flame: scanner masivo — $(ip) hits:$(hit_count) — $(country) $(isp)</description>
<group>ipflame,scanner,</group>
</rule>
</group># Verificar que decoder y reglas no tengan errores de sintaxis
/var/ossec/bin/wazuh-logtest
# Reiniciar el manager
sudo systemctl restart wazuh-manager
# Verificar en los logs que el archivo se esta monitoreando
sudo tail -f /var/ossec/logs/ossec.log | grep ip-flameUna vez ingresados los datos, en el dashboard de Wazuh se pueden buscar con:
- Discover: filtrar por
rule.groups: ipflame - Alertas: los threat actors critical/high aparecen como alertas nivel 10-14
- Campos disponibles para filtros y visualizaciones:
| Campo Wazuh | Contenido |
|---|---|
data.ip |
IP del threat actor |
data.risk_score |
Score 0-100 |
data.risk_level |
critical / high / medium / low |
data.hit_count |
Cantidad de hits |
data.country |
Pais con codigo ISO |
data.isp |
Proveedor de internet |
data.asn |
Numero de sistema autonomo |
data.is_tor |
true/false |
data.is_vpn |
true/false |
data.is_proxy |
true/false |
data.first_seen |
Primer hit detectado |
data.last_seen |
Ultimo hit detectado |
data.matched_patterns[] |
Patrones que disparo |
data.cti_source |
Fuente CTI: local o api |
Para bloquear automaticamente IPs critical con Wazuh active response:
<!-- En ossec.conf del manager -->
<active-response>
<command>firewall-drop</command>
<location>local</location>
<rules_id>100103</rules_id> <!-- solo critical -->
<timeout>43200</timeout> <!-- 12 horas -->
</active-response>Crear un index template para que Elasticsearch mapee correctamente los campos de IP-Flame. Ejecutar en Kibana Dev Tools o via API:
PUT _index_template/ipflame
{
"index_patterns": ["ipflame-*"],
"template": {
"settings": {
"number_of_replicas": 1
},
"mappings": {
"properties": {
"ip": { "type": "ip" },
"country": { "type": "keyword" },
"country_code": { "type": "keyword" },
"city": { "type": "keyword" },
"isp": { "type": "keyword" },
"asn": { "type": "keyword" },
"risk_score": { "type": "integer" },
"risk_level": { "type": "keyword" },
"is_vpn": { "type": "boolean" },
"is_tor": { "type": "boolean" },
"is_proxy": { "type": "boolean" },
"is_datacenter": { "type": "boolean" },
"hit_count": { "type": "integer" },
"first_seen": { "type": "keyword" },
"last_seen": { "type": "keyword" },
"top_request": { "type": "text", "fields": { "keyword": { "type": "keyword" } } },
"top_user_agent": { "type": "text", "fields": { "keyword": { "type": "keyword" } } },
"matched_patterns": { "type": "keyword" },
"cti_source": { "type": "keyword" },
"hits": {
"type": "nested",
"properties": {
"timestamp": { "type": "keyword" },
"request": { "type": "text", "fields": { "keyword": { "type": "keyword" } } },
"status_code": { "type": "keyword" },
"user_agent": { "type": "text" },
"matched_pattern": { "type": "keyword" }
}
}
}
}
}
}Nota: El campo
ipse mapea como tipoipde Elasticsearch, lo que habilita busquedas por rango CIDR (ej:ip: 172.16.0.0/12).
# /etc/filebeat/filebeat.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /opt/ip-flame/output/report.jsonl
json.keys_under_root: true
json.add_error_key: true
fields:
event.dataset: ipflame
event.module: threat_intel
fields_under_root: true
# Procesadores opcionales: agregar timestamp de ingestion y geopoint
processors:
- add_host_metadata: ~
- timestamp:
field: "first_seen"
layouts:
- "02/Jan/2006:15:04:05 -0700"
ignore_failure: true
output.elasticsearch:
hosts: ["https://localhost:9200"]
index: "ipflame-%{+yyyy.MM.dd}"
# Descomentar si usas autenticacion
# username: "elastic"
# password: "changeme"
# ssl.certificate_authorities: ["/etc/filebeat/ca.crt"]
# Desactivar ILM si se quiere usar el index pattern fijo
setup.ilm.enabled: false
setup.template.name: "ipflame"
setup.template.pattern: "ipflame-*"# Validar configuracion
sudo filebeat test config
sudo filebeat test output
# Iniciar Filebeat
sudo systemctl enable --now filebeatPara entornos simples o pruebas, se puede usar _bulk API:
# Convertir JSONL a bulk format e ingestar
cat output/report.jsonl | while IFS= read -r line; do
echo '{"index":{"_index":"ipflame-'$(date +%Y.%m.%d)'"}}'
echo "$line"
done | curl -s -H "Content-Type: application/x-ndjson" \
-XPOST "http://localhost:9200/_bulk" --data-binary @-# Todos los threat actors critical
risk_level: "critical"
# IPs desde Tor
is_tor: true
# Threat actors con mas de 100 hits
hit_count >= 100
# IPs de un rango especifico (gracias al tipo ip)
ip: 172.0.0.0/8
# Threat actors que intentaron acceder a .env
matched_patterns: ".env"
# Combinada: threat actors high+ desde datacenter
risk_level: ("high" OR "critical") AND is_datacenter: true
Opcion A — Monitorear archivo JSONL:
# /opt/splunk/etc/system/local/inputs.conf
[monitor:///opt/ip-flame/output/report.jsonl]
disabled = false
sourcetype = ipflame:json
index = threat_intelOpcion B — Enviar con HTTP Event Collector (HEC):
- En Splunk: Settings > Data Inputs > HTTP Event Collector > New Token
- Anotar el token generado
- Enviar datos desde un script:
cat output/report.jsonl | while IFS= read -r line; do
curl -s -k "https://splunk:8088/services/collector/event" \
-H "Authorization: Splunk <HEC_TOKEN>" \
-d "{\"sourcetype\": \"ipflame:json\", \"index\": \"threat_intel\", \"event\": $line}"
done# /opt/splunk/etc/system/local/props.conf
[ipflame:json]
INDEXED_EXTRACTIONS = json
KV_MODE = json
TIME_FORMAT = %d/%b/%Y:%H:%M:%S %z
TIME_PREFIX = "first_seen"\s*:\s*"
SHOULD_LINEMERGE = false
LINE_BREAKER = ([\r\n]+)
TRUNCATE = 0
category = Custom
description = IP-Flame CTI Threat Intelligence# Todos los threat actors high y critical
index=threat_intel sourcetype="ipflame:json" (risk_level="high" OR risk_level="critical")
| table ip, risk_score, risk_level, hit_count, country, isp, matched_patterns
# Top 10 threat actors por score
index=threat_intel sourcetype="ipflame:json"
| sort - risk_score
| head 10
| table ip, risk_score, risk_level, hit_count, country, isp
# Threat actors desde Tor o VPN
index=threat_intel sourcetype="ipflame:json" (is_tor=true OR is_vpn=true)
| table ip, risk_score, is_tor, is_vpn, country, hit_count
# Patrones mas frecuentes
index=threat_intel sourcetype="ipflame:json"
| mvexpand matched_patterns
| stats count by matched_patterns
| sort - count
# Mapa geografico de threat actors (requiere campo country_code)
index=threat_intel sourcetype="ipflame:json"
| iplocation ip
| geostats count by risk_level
# Timeline de actividad
index=threat_intel sourcetype="ipflame:json"
| timechart count by risk_level
IP-Flame envia alertas via HTTP POST cuando detecta threat actors. Soporta multiples destinos simultaneos, cada uno con su propio filtro de nivel de riesgo minimo.
webhook=tipo,url[,min_risk_level][,telegram_chat_id]
| Parametro | Requerido | Descripcion |
|---|---|---|
tipo |
Si | slack, telegram, discord, generic |
url |
Si | URL completa del webhook |
min_risk_level |
No | Nivel minimo para alertar: low, medium (default), high, critical |
telegram_chat_id |
Solo Telegram | ID del chat/grupo destino |
Solo se envian threat actors cuyo risk_level sea igual o superior al min_risk_level configurado. Si ningun threat actor cumple el filtro, no se envia el webhook.
- Ir a api.slack.com/apps > Crear App > Incoming Webhooks > Activar
- Seleccionar el canal destino y copiar la Webhook URL
- Agregar a
config-ip-flame.txt:
webhook=slack,https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX
Solo alertar threat actors high y critical:
webhook=slack,https://hooks.slack.com/services/T00/B00/XXX,high
El mensaje en Slack se muestra con emojis por severidad:
🔥 IP-Flame Alert — 3 threat actors detectados
🔴 173.212.230.39 — score:75 (critical) hits:1174 — France Contabo GmbH
🟠 185.177.72.22 — score:50 (high) hits:974 — France Bucklog SARL
🟡 43.207.196.36 — score:40 (medium) hits:312 — Japan Amazon.com
- Crear un bot con @BotFather y copiar el token
- Agregar el bot al grupo o iniciar chat directo
- Obtener el
chat_id:- Para grupos: enviar un mensaje al grupo y consultar
https://api.telegram.org/bot<TOKEN>/getUpdates - Para chat directo: el
chat_ides tu user ID numerico
- Para grupos: enviar un mensaje al grupo y consultar
- Agregar a la configuracion (el chat_id va como 4to parametro):
webhook=telegram,https://api.telegram.org/bot123456:ABC-DEF/sendMessage,medium,-100123456789
- En el servidor de Discord: canal destino > Editar Canal > Integraciones > Webhooks
- Crear nuevo webhook, nombrar (ej: "IP-Flame"), copiar la URL
- Agregar a la configuracion:
webhook=discord,https://discord.com/api/webhooks/123456789012345678/ABCDEFGHIJK...
Solo alertar critical:
webhook=discord,https://discord.com/api/webhooks/123/ABC,critical
Para integracion directa con cualquier endpoint que acepte JSON via HTTP POST. IP-Flame envia el payload con header Content-Type: application/json.
webhook=generic,https://my-siem.example.com/api/alerts,medium
Estructura del payload generico:
{
"tool": "ip-flame",
"version": "3.2",
"generated_at": "2026-03-29T20:27:15-03:00",
"total": 3,
"threat_actors": [
{
"ip": "173.212.230.39",
"risk_score": 75,
"risk_level": "critical",
"hit_count": 1174,
"country": "France (FR)",
"asn": "AS51167",
"isp": "Contabo GmbH",
"first_seen": "19/Mar/2026:07:45:39 +0000",
"last_seen": "19/Mar/2026:07:45:47 +0000"
}
]
}n8n es una plataforma de automatizacion muy utilizada en equipos Blue Team para orquestar workflows de respuesta a incidentes. IP-Flame se integra con n8n usando el tipo generic apuntando a un nodo Webhook de n8n.
1. Crear el workflow en n8n:
- Agregar un nodo Webhook como trigger
- Configurar:
- HTTP Method:
POST - Path: elegir un path (ej:
ipflame-alert)
- HTTP Method:
- Copiar la Production URL o Test URL que genera n8n (ej:
https://n8n.tu-dominio.com/webhook/ipflame-alert)
2. Configurar IP-Flame:
webhook=generic,https://n8n.tu-dominio.com/webhook/ipflame-alert,high
3. Workflow de ejemplo — Triage automatico:
El nodo Webhook de n8n recibe el payload JSON de IP-Flame. A partir de ahi se puede construir un workflow como:
[Webhook: IP-Flame Alert]
│
├─► [IF: risk_level == "critical"]
│ ├─► [HTTP Request: bloquear IP en firewall/CrowdSec]
│ ├─► [Slack: notificar canal #incidents]
│ └─► [TheHive: crear alerta]
│
├─► [IF: risk_level == "high"]
│ ├─► [Slack: notificar canal #threats]
│ └─► [Google Sheets / Notion: registrar en tracker]
│
└─► [Loop: por cada threat actor]
└─► [HTTP Request: consultar AbuseIPDB / VirusTotal]
└─► [Enriquecer datos y guardar]
4. Acceder a los datos en n8n:
En los nodos posteriores al Webhook, los datos de IP-Flame estan disponibles como:
| Expresion n8n | Valor |
|---|---|
{{ $json.tool }} |
"ip-flame" |
{{ $json.total }} |
Cantidad de threat actors |
{{ $json.threat_actors[0].ip }} |
IP del primer threat actor |
{{ $json.threat_actors[0].risk_score }} |
Score de riesgo (0-100) |
{{ $json.threat_actors[0].risk_level }} |
"critical", "high", "medium", "low" |
{{ $json.threat_actors[0].is_tor }} |
true / false |
{{ $json.threat_actors[0].country }} |
Pais con codigo ISO |
5. Ejemplo con n8n self-hosted en Docker:
Si n8n corre en la misma red Docker que IP-Flame, usar el nombre del servicio como host:
# docker-compose.yml
services:
ip-flame:
build: .
# ...
depends_on:
- n8n
n8n:
image: n8nio/n8n
container_name: n8n
ports:
- "5678:5678"
volumes:
- n8n_data:/home/node/.n8n
volumes:
n8n_data:# En config-ip-flame.txt, usar el nombre del servicio Docker
webhook=generic,http://n8n:5678/webhook/ipflame-alert,high
6. Casos de uso Blue Team con n8n + IP-Flame:
| Caso de uso | Nodos n8n involucrados |
|---|---|
| Bloqueo automatico de IPs critical | Webhook → IF → HTTP Request (CrowdSec API / iptables) |
| Alerta multi-canal | Webhook → IF por nivel → Slack + Email + Telegram |
| Enriquecimiento CTI | Webhook → Loop → VirusTotal + AbuseIPDB → Merge → DB |
| Creacion de tickets | Webhook → IF → TheHive / Jira / ServiceNow |
| Reporte diario ejecutivo | Schedule Trigger → Read File (report.json) → Summarize → Email |
| Actualizacion de blocklists | Webhook → Code (extraer IPs) → HTTP Request (firewall API) |
| Correlacion con MISP | Webhook → Loop → MISP API (buscar indicadores) → Alerta si match |
Se pueden configurar varios webhooks simultaneos, cada uno con su propio filtro de nivel:
# Slack: solo critical (equipo de respuesta inmediata)
webhook=slack,https://hooks.slack.com/services/.../...,critical
# Telegram: high y critical (canal de monitoreo)
webhook=telegram,https://api.telegram.org/bot.../sendMessage,high,-100123456
# n8n: medium+ (workflow de triage automatico)
webhook=generic,https://n8n.internal/webhook/ipflame-alert,medium
# SIEM generico: todos los niveles
webhook=generic,https://siem.internal/api/ipflame,low
Todos los webhooks se envian en cada ejecucion (o tick del modo watch) si hay threat actors que cumplan el filtro.
El archivo threat-actors.txt se genera listo para alimentar CrowdSec:
# Bloquear todas las IPs detectadas por 30 dias
while IFS= read -r ip; do
[[ "$ip" =~ ^#.*$ || -z "$ip" ]] && continue
cscli decisions add --ip "$ip" --reason "ip-flame" --duration 720h
done < output/threat-actors.txtPara automatizar con cron:
# Ejecutar IP-Flame y alimentar CrowdSec cada hora
0 * * * * /opt/ip-flame/ip-flame --config /opt/ip-flame/config.txt && \
while IFS= read -r ip; do [[ "$ip" =~ ^#.*$ || -z "$ip" ]] && continue; \
cscli decisions add --ip "$ip" --reason "ip-flame" --duration 720h; \
done < /opt/ip-flame/output/threat-actors.txtCada IP maliciosa recibe un score de riesgo de 0 a 100 basado en 4 factores:
| Factor | Puntos max. | Criterio |
|---|---|---|
| Volumen de hits | 25 | 1 hit = 3pts, 5+ = 10pts, 20+ = 15pts, 50+ = 20pts, 100+ = 25pts |
| Diversidad de patrones | 25 | 1 patron = 3pts, 2 = 10pts, 3 = 15pts, 5+ = 20pts, 10+ = 25pts |
| Anonimizacion | 30 | VPN = 15pts, Proxy = 20pts, Tor = 30pts |
| API risk score | 20 | Score de ipquery.io (0-100) escalado a 0-20 |
Niveles:
| Score | Nivel | Significado |
|---|---|---|
| 75-100 | critical |
Amenaza activa, multiples vectores, anonimizacion |
| 50-74 | high |
Scanner agresivo o explotacion activa |
| 25-49 | medium |
Reconocimiento o escaneo moderado |
| 0-24 | low |
Actividad aislada, posible ruido |
Cuando IP-Flame no puede resolver una IP con las bases GeoLite2 locales, usa la API de ipquery.io como fallback. En este caso:
- Se registra un log explicito indicando cuantas IPs se envian a la API y por que
- Los datos enviados son exclusivamente las direcciones IP (no se envian logs, requests ni user-agents)
- Las respuestas de la API se validan (la IP devuelta debe coincidir con la consultada)
- El campo
cti_sourceen los reportes indica si los datos provienen de resolucionlocaloapi
time=2026-04-03T13:06:28.500-03:00 level=INFO msg="Enriquecimiento CTI" local=3421 api=258 note="258 IPs enviadas a ipquery.io para enriquecimiento"
IP-Flame usa las bases de datos MaxMind GeoLite2 para resolucion local (sin llamadas a API):
# Descargar GeoLite2 (sin registro requerido)
./update-geoip.shLas bases se descargan desde el mirror de P3TERX y se guardan en el directorio geoip/.
Automatizacion con cron (actualizacion semanal):
0 3 * * 1 /opt/ip-flame/update-geoip.sh >> /var/log/ip-flame-geoip.log 2>&1Si las bases no estan disponibles, IP-Flame usa automaticamente la API de ipquery.io como fallback (free tier ilimitado, batches de hasta 10,000 IPs).
IP-Flame incluye 238 patrones en 14 categorias, disenados para cubrir el ciclo completo de un ataque web — desde reconocimiento hasta post-explotacion. Los patrones son case-insensitive y se aplica URL decode recursivo (2 niveles) para detectar evasiones con encoding (%2e%2e = .., %252e = double encoding).
Security hardening: Los patrones custom (definidos via offending-lines= en la config) tienen un limite de longitud de 256 caracteres para prevenir ataques ReDoS.
| # | Categoria | Patrones | MITRE ATT&CK | Descripcion |
|---|---|---|---|---|
| 1 | CMS | 18 | T1190 | Explotacion de WordPress, Joomla, Drupal, Magento, phpMyAdmin, Adminer |
| 2 | CONFIG | 25 | T1552.001 | Archivos de configuracion, secretos, credenciales y backups expuestos |
| 3 | VCS | 7 | T1213 | Repositorios de codigo fuente expuestos (Git, SVN, Mercurial, Bazaar) |
| 4 | RCE | 22 | T1059 | Webshells (clasicas + modernas), code injection, path traversal, LFI |
| 5 | SQLI | 10 | T1190 | Payloads de SQL Injection: UNION, boolean-based, time-based, exfiltracion |
| 6 | XSS | 10 | T1189 | Cross-Site Scripting: script injection, event handlers, cookie theft |
| 7 | CMDI | 10 | T1059.004 | Command injection: shell execution, subshell, download & execute |
| 8 | LOG4J | 5 | T1190 | Log4Shell (CVE-2021-44228): JNDI injection via LDAP, RMI, DNS |
| 9 | SSRF | 7 | T1552.005 | Server-Side Request Forgery: cloud metadata (AWS, GCP, Azure, DO) |
| 10 | SCAN | 22 | T1595 | Paneles admin, server status, info disclosure, mail servers |
| 11 | CVE | 18 | T1190 | Endpoints de CVEs explotados activamente (Actuator, Ignition, Grafana, etc.) |
| 12 | CRAWLER | 10 | T1593 | AI crawlers agresivos y scrapers (GPTBot, ClaudeBot, Bytespider, etc.) |
| 13 | PROTO | 10 | T1190 | TLS en HTTP, WebDAV, proxy abuse, Docker socket, etcd |
| 14 | TOOLS | 18 | T1595.002 | Fingerprints de herramientas de scanning en User-Agent |
Patrones que detectan intentos de acceso a endpoints conocidos de CMS populares. WordPress representa ~43% de la web, lo que lo convierte en el CMS mas atacado.
xmlrpc.php, wp-login.php, wp-admin/, wp-config.php, wp-content/uploads/,
wp-includes/, wp-json/wp/v2/users, wp-json/oembed/, /?author=1, wp-cron.php,
administrator/index.php, /user/login, /downloader/,
/phpmyadmin, /pma/, /phpMyAdmin, /adminer, /dbadmin, /myadmin
Archivos de configuracion que contienen credenciales, tokens API, connection strings. Su exposicion es el vector #1 de compromiso en aplicaciones modernas segun el OWASP Top 10 (A01:2021 Broken Access Control).
.env, .env.local, .env.production, .env.backup, .env.dev, .env.staging,
.env.old, .env.save, .env.bak, /backup, /backups, .sql, .bak, .tar.gz,
.zip, .gz, .rar, config.php, database.yml, settings.py,
docker-compose.yml, docker-compose.override.yml, /.aws/credentials,
/.aws/config, id_rsa, id_ecdsa, id_ed25519, .DS_Store, web.config,
.npmrc, .dockerenv, .bash_history, .mysql_history, .psql_history,
/wp-config.php.bak, /wp-config.php.old, /wp-config.php.save, /config.php.bak
El acceso a directorios de control de versiones permite descargar el codigo fuente completo, incluyendo credenciales hardcodeadas y logica de negocio.
.git/config, .git/HEAD, .git/COMMIT_EDITMSG, .gitignore, .git/objects/,
/.svn/entries, /.svn/wc.db, /.hg/, /.bzr/
Webshells clasicas (c99, r57) y modernas (Behinder, Godzilla, AntSword), junto con tecnicas de code injection y path traversal para LFI/RFI.
cmd.php, shell.php, c99.php, r57.php, b374k, alfa.php, wso.php,
indoxploit, p0wny, weevely, antsword, behinder, godzilla,
eval(, base64_decode(, assert(, system(, exec(, passthru(, shell_exec(,
../../../, %2e%2e%2f, %2e%2e%5c, /proc/self/environ,
/etc/passwd, /etc/shadow, passwd%00, /cgi-bin/, .cgi, XDEBUG_SESSION,
/vendor/phpunit, /vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
Payloads que explotan inyeccion SQL para extraer datos, bypass de autenticacion o ejecucion de comandos via base de datos. Cubre las 3 tecnicas principales: UNION-based, boolean-based y time-based.
UNION SELECT, UNION ALL SELECT, OR 1=1, ' AND ',
information_schema, SLEEP(, BENCHMARK(, WAITFOR DELAY,
/bin/sleep, INTO OUTFILE, INTO DUMPFILE, LOAD_FILE(
Nota: Estos patrones pueden generar falsos positivos en aplicaciones que usan SQL en query strings. Usar whitelist para IPs internas.
Payloads que intentan inyectar JavaScript en el contexto del navegador para robo de sesiones, keylogging o redireccion maliciosa.
<script, javascript:, onerror=, onload=, onmouseover=, onfocus=,
alert(, prompt(, confirm(, document.cookie, document.domain
Tecnicas de inyeccion de comandos del sistema operativo a traves de parametros HTTP. Incluye separadores de comandos, subshells y download-and-execute.
;ls, ;cat , |cat , ;id, |id, $IFS, /bin/sh, /bin/bash,
;wget , ;curl , |wget , |curl , $({
Payloads del CVE-2021-44228 (Log4Shell), una de las vulnerabilidades mas explotadas de la historia. Detecta la inyeccion JNDI tanto en formato original como URL-encoded.
${jndi:, %24%7bjndi, ${jndi:ldap, ${jndi:rmi, ${jndi:dns
Importancia: Log4Shell sigue siendo explotado activamente. El URL decode recursivo de IP-Flame detecta variantes con double encoding (
%2524%257Bjndi).
Intentos de acceder a servicios de metadata de cloud providers para obtener credenciales IAM, tokens de servicio y configuracion interna. Es el vector principal de escalamiento en incidentes cloud.
/latest/meta-data/, /metadata/v1/, /metadata.google.internal,
/metadata/instance, 169.254.169.254, /computeMetadata/v1/, gopher://
| Patron | Cloud Provider | Dato expuesto |
|---|---|---|
/latest/meta-data/ |
AWS EC2 (IMDSv1) | Credenciales IAM, tokens de sesion |
/metadata/v1/ |
DigitalOcean | Token de API del droplet |
/metadata.google.internal |
Google Cloud | Service account tokens |
/metadata/instance |
Azure | Managed identity tokens |
169.254.169.254 |
Todos | Link-local metadata endpoint |
/computeMetadata/v1/ |
GCP | Metadata con header requerido |
gopher:// |
N/A | Protocol smuggling para SSRF |
Endpoints que revelan informacion del servidor, interfaces de administracion expuestas, y servicios de mail que son target de credential stuffing.
/admin, /login, /console, /manager/html, /host-manager/html,
/jenkins, /solr/, /server-status, /nginx_status, /.htaccess,
/web.config, /elmah.axd, /trace.axd, /Autodiscover/Autodiscover.xml,
/owa/auth/, /boaform/admin, /GponForm/, /cgi-bin/luci,
/mail/, /webmail/, /roundcube, /zimbra
Endpoints especificos de CVEs con exploits publicos. Incluye Spring Boot Actuator, Laravel Ignition, Grafana, Kubernetes API y mas.
/actuator/env, /actuator/health, /actuator/mappings, /actuator/beans,
/actuator/, /_ignition/execute-solution, /api/v1/totp/,
/.well-known/openid-configuration, /cgi-bin/%%32%65%%32%65/,
/api/v1/pods, /api/v1/namespaces, /api/v1/secrets, /apis/apps/v1,
/healthz, /portainer, /metrics, /telescope/requests, /horizon/,
/ManagerServlet, /CFIDE/administrator, /ColdFusion/administrator,
/solr/admin/, /spring-security-oauth-problem
User-Agents de bots de IA y scrapers que consumen recursos y extraen contenido sin autorizacion.
GPTBot, ClaudeBot, CCBot, anthropic-ai, Bytespider,
PetalBot, AhrefsBot, SemrushBot, MJ12bot, DotBot
Trafico anomalo a nivel de protocolo: TLS handshakes en puertos HTTP, metodos WebDAV, proxy abuse, y acceso a sockets de containers.
\x16\x03\x01, \x16\x03\x00, \x16\x03\x03, \x80\x4c\x01,
CONNECT , PROPFIND, SEARCH ,
/.well-known/acme-challenge/../, /docker.sock,
/var/run/docker.sock, etcd
Fingerprints que identifican herramientas ofensivas en el header User-Agent. La presencia de estas herramientas indica reconocimiento activo o escaneo automatizado.
python-requests, Go-http-client, qqtang, masscan, zgrab, nuclei,
nikto, sqlmap, dirsearch, gobuster, wfuzz, nmap scripting engine,
httpx, ffuf, feroxbuster, katana, subfinder, jaeles, Tsunami,
CensysInspect, Shodan
IP-Flame genera dos dashboards HTML independientes, cada uno para una audiencia distinta. Branding: Sockets AR — Threat Intelligence Dashboard v3.2.
Dashboard operativo para el SOC / Blue Team:
- Tabla de threat actors ordenada por risk score
- Filtros interactivos por nivel de riesgo (Critical / High / Medium / Low)
- Filtro por pais — Dropdown auto-poblado desde los resultados, combinable con el filtro de riesgo
- Paginacion configurable (25 / 50 / 100 / 250 / Todos)
- Columna "Host Destino" condicional (solo si
log-host-fieldesta configurado) - Detalle expandible por IP con todos los hits, timestamps, status codes coloreados y patrones matcheados
- Tags de amenaza por IP: TOR, VPN, PROXY, DATACENTER
- Risk score visual con barra de progreso y nivel
Executive summary visual para management y reportes:
- Mapa interactivo con Leaflet (dark theme CartoDB) — marcadores por pais con tamanio proporcional a hits y color por nivel de riesgo maximo, popups con detalle
- KPI cards — threat actors, hits, paises, hosts atacados, patrones detectados
- Distribucion de riesgo — donut chart (CSS puro, sin dependencias)
- Top paises atacantes — barras horizontales con cantidad de IPs y hits
- Top patrones detectados — barras con hits por patron
- Top hosts atacados — barras (condicional, solo con
log-host-field) - Top ISPs atacantes — barras con cantidad de IPs por ISP
- Indicadores de amenaza — conteo de threat actors TOR, VPN, Proxy, Datacenter
Dependencias del Geo dashboard: Leaflet 1.9 (~40KB, CDN), Tailwind CSS (CDN), CartoDB dark tiles (OpenStreetMap). No requiere API keys ni backend.
Desarrollado por Hernan Herrera — Sockets AR.








