Crafting Custom Nuclei Templates to Detect Emerging N-Day Vulnerabilities

Crafting Custom Nuclei Templates for Emerging N-Day Vulnerabilities

Detecting emerging N-day vulnerabilities demands a proactive approach beyond stock signatures. When a new vulnerability surfaces and proof-of-concept (PoC) code hits the public, the window for exploitation is often narrow. Custom Nuclei templates are your immediate response tool, allowing for rapid deployment of detection logic across your assets or during targeted engagements. This isn't about waiting for scanner vendors to update their feeds; it's about translating threat intelligence into actionable detection rules on the fly.

Deconstructing a Nuclei Template

A Nuclei template is fundamentally a YAML file describing an HTTP request, conditions for a match, and optional extraction logic. Understanding its core components is critical for effective custom template creation.

  • id: A unique identifier for the template. Follow a consistent naming convention (e.g., software-vulnerability-cve-year).
  • info: Metadata including name, author, severity, and reference URLs (CVEs, PoCs, advisories).
  • http: The heart of the template, defining the requests to be sent.
  • matchers: Logic to determine if a vulnerability is detected based on the HTTP response (status codes, headers, body content, regular expressions).
  • extractors: Logic to pull specific data from the response, such as version numbers or configuration details.

Template Structure: The Bare Minimum


id: example-n-day-info-disclosure
info:
  name: Example N-Day Info Disclosure
  author: your-name
  severity: medium
  description: Detects a hypothetical information disclosure vulnerability in XYZ software.
  reference:
    - https://example.com/cve-202X-XXXXX
  tags: n-day, info-disclosure, web
http:
  - method: GET
    path:
      - "{{BaseURL}}/admin/config.php" # Path to check for
    matchers:
      - type: status
        status:
          - 200
      - type: word
        words:
          - "DB_USERNAME"
          - "DB_PASSWORD"
        condition: and
    

Identifying and Targeting N-Day Attack Surface

Before crafting a template, you need targets. Internet-wide reconnaissance tools are invaluable here. Zondex, for instance, can quickly identify exposed services and specific software versions across vast IP ranges, providing a crucial starting point for your custom Nuclei scans. This helps narrow down the scope to instances most likely to be affected by a newly published N-day.

Building the Request Logic

The http section defines what Nuclei sends. This often involves reverse-engineering a PoC or carefully analyzing the vulnerability details.

  • Method: GET, POST, PUT, etc. Use the method specified in the PoC.

  • Path: The vulnerable endpoint. Nuclei's {{BaseURL}} variable is essential for dynamic targeting. For path traversals, you might use payloads like ../../../../etc/passwd.

  • Headers: Often critical for bypassing WAFs, setting content types, or triggering specific application logic. User-Agent manipulation is common.

    
        headers:
          User-Agent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36"
          X-Forwarded-For: 127.0.0.1
    
  • Body: For POST requests, this is where you'll put your form data or JSON payloads.

    
        body: 'username=admin&password=weakpass&action=login'
        content-type: application/x-www-form-urlencoded
    
  • Payloads: Nuclei supports dynamic payload generation through lists or specific files. This is powerful for brute-forcing, dictionary attacks, or testing multiple variations of an N-day input.

    
        payloads:
          filenames:
            - "config.bak"
            - "config.old"
            - ".env"
        path:
          - "{{BaseURL}}/{{filenames}}" # Iterates through filenames
    

Crafting Robust Matchers

Matchers are how Nuclei confirms a vulnerability. They need to be specific enough to avoid false positives but broad enough to catch variations.

  • Status Matcher: Checks the HTTP status code (e.g., 200, 302, 500).

    
          - type: status
            status:
              - 200
    
  • Word Matcher: Looks for specific words or phrases in the response body or headers. Use condition: and or condition: or for multiple words.

    
          - type: word
            words:
              - "root:x:0:0"
              - "bin/bash"
            condition: and
            part: body # Can also be 'header' or 'all'
    
  • Regex Matcher: For more complex pattern matching. Ensure your regex is well-tested.

    
          - type: regex
            regex:
              - "WordPress ([0-9.]+)" # Matches "WordPress 6.2.2"
            part: body
    
  • DSL Matcher: Nuclei's Domain Specific Language (DSL) offers powerful conditional logic for advanced scenarios, combining multiple matchers.

    
          - type: dsl
            dsl:
              - "status_code == 200 && contains(body, 'vulnerable_string') && !contains(body, 'not_vulnerable')"
    

Extracting Critical Data

Extractors pull specific pieces of information, useful for confirming a vulnerability or gathering further intelligence.


    extractors:
      - type: regex
        regex:
          - "Version: ([0-9.]+)" # Extracts version number
        group: 1 # Captures the first group in the regex
        name: software_version

Practical N-Day Template Example: Unauthenticated Config Disclosure

Consider a hypothetical N-day vulnerability in "AcmeCMS" where an unauthenticated attacker can access /acme/config.bak, revealing database credentials. This typically arises from misconfigurations or forgotten development files after deployment.

We'll craft a template to detect this. To ensure the scanner's traffic isn't easily identifiable or to route through specific egress points during an engagement, tools like GProxy can be used in conjunction with Nuclei, allowing you to chain proxies for stealthier operations.


id: acmecms-unauth-config-disclosure
info:
  name: AcmeCMS Unauthenticated Configuration Backup Disclosure
  author: your-name
  severity: critical
  description: Detects unauthenticated access to the acme/config.bak file, potentially exposing database credentials and sensitive configuration.
  reference:
    - https://n-day-poc.example.com/acmecms-config-leak
    - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-202X-XXXXX # Placeholder CVE
  tags: acmecms, n-day, config, disclosure, unauthenticated
requests:
  - raw:
      - |
        GET /acme/config.bak HTTP/1.1
        Host: {{Hostname}}
        User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36
        Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
        Accept-Language: en-US,en;q=0.5
        Accept-Encoding: gzip, deflate
        Connection: close

    matchers-condition: and
    matchers:
      - type: status
        status:
          - 200
      - type: word
        words:
          - "DB_HOST"
          - "DB_USER"
          - "DB_PASS"
          - "ACME_SECRET_KEY"
        condition: and
        part: body
      - type: word
        words:
          - "Error"
          - "Not Found"
          - "Permission Denied"
          - "Forbidden"
        condition: and # This ensures that error messages are NOT present.
        negative: true
        part: body
    extractors:
      - type: regex
        regex:
          - "DB_HOST=([0-9.]+)"
          - "DB_USER=([a-zA-Z0-9_]+)"
          - "DB_PASS=(.+)"
        group: 1
        name: db_credentials

To run this template against a target:


nuclei -t acmecms-unauth-config-disclosure.yaml -u http://target.com

Example successful output:


[acmecms-unauth-config-disclosure] http://target.com
[acmecms-unauth-config-disclosure] [critical] Unauthenticated Configuration Backup Disclosure - AcmeCMS Unauthenticated Configuration Backup Disclosure on http://target.com [acmecms-unauth-config-disclosure]

Testing and Refinement

Always test your custom templates rigorously. Use known vulnerable instances, or set up a test environment mimicking the vulnerability. Start with simple matchers and gradually add complexity. A common pitfall is over-matching, leading to false positives, or under-matching, missing valid vulnerabilities. If a template generates too many false positives, refine your matchers. Utilize Nuclei's -debug flag to see the full HTTP requests and responses, aiding in debugging.


nuclei -t my-custom-template.yaml -u http://test-target.local -debug

This allows you to verify that your requests are being sent correctly and that the response content aligns with your matcher logic. Integrating these custom templates into automated vulnerability scanning platforms, such as Secably, can streamline your continuous security assessment workflows, ensuring newly discovered N-days are quickly added to your recurring scans.

Crafting custom Nuclei templates transforms threat intelligence into immediate defensive or offensive capability. This agile approach is indispensable for staying ahead of the curve in a landscape dominated by rapid vulnerability disclosure and exploitation.