Fuzzing Overview
Learn about fuzzing HTTP requests with Nuclei
Nuclei supports fuzzing of HTTP requests based on rules defined in the fuzzing
section of the HTTP request. This allows creating templates for generic Web Application vulnerabilities like SQLi, SSRF, CMDi, etc without any information of the target like a classic web fuzzer. We call this concept as Fuzzing for Unknown Vulnerabilities.
pre-condition
More often than not, we want to only attempt fuzzing on those requests where it makes sense. For example,
- Fuzz Body When Body is Present
- Ignore PreFlight and CONNECT requests
and so on. With Nuclei v3.2.4 we have introduced a new pre-condition
section which contains conditions when the fuzzing template should be executed.
pre-condition can be considered a twin of matchers in nuclei. They support all matcher types, including DSL, and the only difference is that this serves a different purpose.
For example, to only execute template on POST request with some body, you can use the following filter.
- pre-condition:
- type: dsl
dsl:
- method == POST
- len(body) > 0
condition: and
When writing/executing a template, you can use the -v -svd flags to see all variables available in filters before applying the filter.
Part
Part specifies what part of the request should be fuzzed based on the specified rules. Available options for this parameter are -
query (default
) - fuzz query parameters for URL
fuzzing:
- part: query # fuzz parameters in URL query
path - fuzz path parameters for requests
fuzzing:
- part: path # fuzz path parameters
header - fuzz header parameters for requests
fuzzing:
- part: header # fuzz headers
cookie - fuzz cookie parameters for requests
fuzzing:
- part: cookie # fuzz cookies
body - fuzz body parameters for requests
fuzzing:
- part: body # fuzz parameters in body
Type
Type specifies the type of replacement to perform for the fuzzing rule value. Available options for this parameter are -
- replace (
default
) - replace the value with payload - prefix - prefix the value with payload
- postfix - postfix the value with payload
- infix - infix the value with payload (place in between)
- replace-regex - replace the value with payload using regex
fuzzing:
- part: query
type: postfix # Fuzz query and postfix payload to params
Key-Value Abstraction
In a HTTP request, there are various parts like query, path, headers, cookies, and body and each part has different in various formats. For example, the query part is a key-value pair, the path part is a list of values, the body part can be a JSON, XML, or form-data.
To effectively abstract these parts and allow them to be fuzzed, Nuclei exposes these values as key
and value
pairs. This allows users to fuzz based on the key or value of the request part.
For example, Below sample HTTP request can be abstracted as key-value pairs as shown below.
POST /reset-password?token=x0x0x0&source=app HTTP/1.1
Host: 127.0.0.1:8082
User-Agent: Go-http-client/1.1
Cookie: PHPSESSID=1234567890
Content-Length: 23
Content-Type: application/json
Accept-Encoding: gzip
Connection: close
{"password":"12345678"}
part: Query
key | value |
---|---|
token | x0x0x0 |
source | app |
part: Path
key | value |
---|---|
value | /reset-password |
part: Header
key | value |
---|---|
Host | 127.0.0.1:8082 |
User-Agent | Go-http-client/1.1 |
Content-Length | 23 |
Content-Type | application/json |
Accept-Encoding | gzip |
Connection | close |
part: Cookie
key | value |
---|---|
PHPSESSID | 1234567890 |
part: Body
key | value |
---|---|
password | 12345678 |
Note: XML, JSON, Form, Multipart-FormData will be in kv format, but if the Body is binary or in any other format, the entire Body will be represented as a single key-value pair with key as value
and value as the entire Body.
key | value |
---|---|
value | “\x08\x96\x01\x12\x07\x74” |
This abstraction really levels up the game since you only need to write a single rule for the Body, and it will be applied to all formats. For example, if you check for SQLi in body values, a single rule will work on all formats, i.e., JSON, XML, Form, Multipart-FormData, etc.
Mode
Mode specifies the mode in which to perform the replacements. Available modes are -
- multiple (
default
) - replace all values at once - single - replace one value at a time
fuzzing:
- part: query
type: postfix
mode: multiple # Fuzz query postfixing payloads to all parameters at once
Note: default values are set/used when other options are not defined.
Component Data Filtering
Multiple filters are supported to restrict the scope of fuzzing to only interesting parameter keys and values. Nuclei HTTP Fuzzing engine converts request parts into Keys and Values which then can be filtered by their related options.
The following filter fields are supported -
- keys - list of parameter names to fuzz (exact match)
- keys-regex - list of parameter regex to fuzz
- values - list of value regex to fuzz
These filters can be used in combination to run highly targeted fuzzing based on the parameter input. A few examples of such filtering are provided below.
# fuzzing command injection based on parameter name value
fuzzing:
- part: query
type: replace
mode: single
keys:
- "daemon"
- "upload"
- "dir"
- "execute"
- "download"
- "log"
- "ip"
- "cli"
- "cmd"
# fuzzing openredirects based on parameter name regex
fuzzing:
- part: query
type: replace
mode: single
keys-regex:
- "redirect.*"
# fuzzing ssrf based on parameter value regex
fuzzing:
- part: query
type: replace
mode: single
values:
- "https?://.*"
Fuzz
Fuzz specifies the values to replace with a type
for a parameter. It supports payloads, DSL functions, etc and allows users to fully utilize the existing nuclei feature-set for fuzzing purposes.
# fuzz section for xss fuzzing with stop-at-first-match
payloads:
reflection:
- "6842'\"><9967"
stop-at-first-match: true
fuzzing:
- part: query
type: postfix
mode: single
fuzz:
- "{{reflection}}"
# using interactsh-url placeholder for oob testing
payloads:
redirect:
- "{{interactsh-url}}"
fuzzing:
- part: query
type: replace
mode: single
keys:
- "dest"
- "redirect"
- "uri"
fuzz:
- "https://{{redirect}}"
# using template-level variables for SSTI testing
variables:
first: "{{rand_int(10000, 99999)}}"
second: "{{rand_int(10000, 99999)}}"
result: "{{to_number(first)*to_number(second)}}"
http:
...
payloads:
reflection:
- '{{concat("{{", "§first§*§second§", "}}")}}'
fuzzing:
- part: query
type: postfix
mode: multiple
fuzz:
- "{{reflection}}"
Example Fuzzing template
An example sample template for fuzzing XSS vulnerabilities is provided below.
id: fuzz-reflection-xss
info:
name: Basic Reflection Potential XSS Detection
author: pdteam
severity: low
http:
- pre-condition:
- type: dsl
dsl:
- 'method == "GET"' # only run if method is GET
payloads:
reflection:
- "6842'\"><9967"
stop-at-first-match: true
fuzzing:
- part: query
type: postfix
mode: single
fuzz:
- "{{reflection}}"
matchers-condition: and
matchers:
- type: word
part: body
words:
- "{{reflection}}"
- type: word
part: header
words:
- "text/html"
More complete examples are provided here
Was this page helpful?