Table of Contents
- Table of Contents
- Overview
- What is Fuzzing?
- Fuzzing Parts
- Supported Fuzzing Parts
- HTTP Request Part Values
- Example HTTP request & parts
- Fuzzing Rule Types
- Loading HTTP Traffic
- HTTP Traffic From Tools
- Generating Requests from API Schema Files
- Providing HTTP Input to Nuclei
- Fuzzing Rule Format
- Pre-Condition
- Example Templates
- Error Based SQLi in Body
- Host Header Injection
- Learn More
- Conclusion
- Join our Discord to share your thoughts!
Authors
At ProjectDiscovery, our goal is to democratize security. Nuclei, our flagship project, plays a pivotal role in achieving this by offering a fast, adaptable, and potent vulnerability scanner, powered by the innovative nuclei-templates. The launch of Nuclei v3.0 was a significant step, incorporating comprehensive capabilities for developing checks against Common Vulnerabilities and Exposures (CVEs). Earlier, with Nuclei v2.8.0, we ventured into Query Fuzzing.
Overview
Nuclei v3.2.0 represents a crucial advancement in fuzzing capabilities. This version introduces complete support for crafting fuzzing templates, covering everything from importing HTTP Traffic from tools like Proxify, httpx, and Burp Suite to generating requests from API schema files like OpenAPI and Swagger. Let’s explore the fuzzing enhancements in Nuclei v3.2.0 in greater detail!
bash
1nuclei -l fuzzplayground-proxify.yaml -im yaml -t fuzz/23__ _4____ __ _______/ /__ (_)5/ __ \/ / / / ___/ / _ \/ /6/ / / / /_/ / /__/ / __/ /7/_/ /_/\__,_/\___/_/\___/_/ v3.2.0-dev89projectdiscovery.io1011[INF] Current nuclei version: v3.2.0 (latest)12[INF] Current nuclei-templates version: v9.7.7 (latest)13[WRN] Scan results upload to cloud is disabled.14[INF] New templates added in latest release: 8215[INF] Templates loaded for current scan: 1416[WRN] Executing 15 unsigned templates. Use with caution.17[INF] Targets loaded for current scan: 918[fuzz-query-num] [http] [info] http://127.0.0.1:8082/blog/post?postId=200&source=proxify19[fuzz-body-generic] [http] [info] http://127.0.0.1:8082/user20[body-params-error-sqli] [http] [info] http://127.0.0.1:8082/user21[path-based-sqli] [http] [info] http://127.0.0.1:8082/user/55%2520OR%2520True/profile22[fuzz-body-generic] [http] [info] http://127.0.0.1:8082/user23[fuzz-query-num] [http] [info] http://127.0.0.1:8082/blog/post?postId=201&source=proxify24[fuzz-body-generic] [http] [info] http://127.0.0.1:8082/user25[body-multipart-error-sqli] [http] [info] http://127.0.0.1:8082/user26[fuzz-body-generic] [http] [info] http://127.0.0.1:8082/user27[cookie-fuzzing-error-sqli] [http] [info] http://127.0.0.1:8082/blog/posts28[host-header-injection] [http] [info] http://127.0.0.1:8082/host-header-lab
What is Fuzzing?
Fuzzing is a technique for uncovering unknown or yet-to-be-discovered vulnerabilities within an application by employing established strategies and methodologies, often referred to as rules. These rules are systematically applied to different components of HTTP requests to detect alterations in the application's response or behavior.
Fuzzing Parts
Supported Fuzzing Parts
As mentioned earlier, fuzzing rules are applied to various parts of HTTP requests. We call these parts part:
in Nuclei templates; with the release of Nuclei v2.8.0, we introduced support for Query Fuzzing (part: Query
), but with this release, we have added support for all other parts of HTTP requests along with abstractions. Here is the list of supported parts in Nuclei v3.2.0:
part: query
- Query Fuzzing (Introduced in Nuclei v2.8.0)part: path
- Path Fuzzingpart: header
- Header Fuzzingpart: cookie
- Cookie Fuzzingpart: body
- Body Fuzzing
When writing fuzzing rules, each rule is scoped to a specific part of the HTTP request. This means that a rule written for part: Query
will only be applied to the query parameters of the HTTP request and not to any other part of the request.
HTTP Request Part Values
While Query, Path, Header, and Cookie are only represented in a fixed format in HTTP requests, Body is represented in various formats such as JSON, XML, Form, multipart-form data, etc. Usually, when writing templates for fuzzing, the rules would need to be written for each format separately, which would be a tedious task and include duplicate rules. To solve this problem,
Nuclei Abstracts Values of Every Part as a Key-Value Pair
Example HTTP request & parts
In the below example HTTP request, the key-value pairs of each part would be as follows:
http
1POST /reset-password?token=x0x0x0&source=app HTTP/1.12Host: 127.0.0.1:80823User-Agent: Go-http-client/1.14Cookie: PHPSESSID=12345678905Content-Length: 236Content-Type: application/json7Accept-Encoding: gzip8Connection: close910{"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 |
value \x08\x96\x01\x12\x07\x74
This abstraction significantly enhances efficiency, as it allows for the creation of a single rule for the Body that applies across all formats. For instance, when testing for SQL injection vulnerabilities in body values, a solitary rule can be effectively utilized for various formats, including JSON, XML, form, and multipart-form data. This streamlined approach simplifies the testing process and broadens the scope of vulnerability detection.
Fuzzing Rule Types
Each rule performs a specific action on the value, and nuclei supports the following types of rules:
prefix
- Add payload as a prefix to the valuepostfix
- Add payload as a postfix to the valuereplace
- Replace the value with payloadinfix
- Add payload as an infix to the valuereplace-regex
- Replace the value with payload using regex
Loading HTTP Traffic
Nuclei now supports various input formats to load HTTP requests, and these can be grouped into two categories:
HTTP Traffic From Tools
Generating Requests from API Schema Files
- OpenAPI
- Swagger
- Postman (via OpenAPI)
Providing HTTP Input to Nuclei
Files of the above formats can be provided to the existing flag -l -list
along with the new flag -im -input-mode
to specify the input mode or format of the file. Example:
bash
1$ nuclei -l ginandjuice. proxify.jsonl -im jsonl
bash
1$ ./nuclei -h target-format2Nuclei is a fast, template based vulnerability scanner focusing3on extensive configurability, massive extensibility and ease of use.45Usage:6./nuclei [flags]78Flags:9TARGET-FORMAT:10-im, -input-mode string mode of input file (list, burp, jsonl, yaml, openapi, swagger) (default "list")11-ro, -required-only use only required fields in input format when generating requests12-sfv, -skip-format-validation skip format validation (like missing vars) when parsing input file
Nuclei also enhances request generation with new options: use -V
flag to override/pass variables, choose between essential or all fields for requests, and skip format validation for testing with dedicated flags.
Fuzzing Rule Format
Fuzzing rule[s] are written in the HTTP protocol section under fuzzing
key. Here is a general format for writing a fuzzing rule:
yaml
1http:2...3payloads:4injection: # Variable name for payload5- "'"6...7fuzzing:8- part: query # One of query, path, header, cookie, body9type: postfix # Type of rule (prefix, postfix, replace, infix,replace-regex)10mode: single # mutation mode (single, multiple) (ex: replace all existing kv pairs at once or one by one)11# replace-regex: # (optional) regex to be used in replace-regex type12# keys-regex: # (optional) limit this rule to specific keys of the request part using regex13# keys: # (optional) limit this rule to specific keys of request part14# values: # (optional) limit this rule to specific values of the request part using regex15fuzz:16- '{{injection}}' # The payload to be injected
Pre-Condition
With Nuclei now supporting a wide range of input formats and rules for all segments of HTTP requests, it might seem that crafting any rule is straightforward. However, there's a significant aspect to consider: the challenge of managing request volume or noise. Specifically, when conducting fuzzing on targets protected by Web Application Firewalls (WAF), indiscriminate fuzzing can lead to issues such as IP bans. The most efficient strategy to mitigate this concern is to employ fuzzing judiciously, which is where the role of pre condition becomes crucial, it evaluate whether a specific fuzzing template should be activated for a particular HTTP request, ensuring targeted and effective fuzzing practices.
pre-condition can be considered a twin of matchers in nuclei templates. They support all matcher types, including DSL, and the only difference here is the purpose of each.
Here's a basic filter to only execute this template if the request is POST and must have some body:
yaml
1- pre-condition:2- type: dsl3dsl:4- method == POST5- len(body) > 06condition: and
-v -svd
flags to see all variables available in filters before applying the filter.Example Templates
Error Based SQLi in Body
The following template is configured to run on all requests that use the POST method and have a non-empty body. It appends the specified payload as a postfix to every value within the body.
yaml
1http:2# filter checks if the template should be executed on a given request3- pre-condition:4- type: dsl5dsl:6- method == POST7- len(body) > 08condition: and9# payloads that will be used in fuzzing10payloads:11injection: # Variable name for payload12- "'"13- "\""14- ";"15# fuzzing rules16fuzzing:17- part: body # This rule will be applied to the Body18type: postfix # postfix type of rule (i.e., payload will be added at the end of exiting value)19mode: single # single mode (i.e., existing values will be replaced one at a time)20fuzz: # format of payload to be injected21- '{{injection}}' # here, we are directly using the value of the injection variable
For the complete template, see body-error-sqli.yaml
Host Header Injection
Host Header Injection is a vulnerability where an attacker injects a malicious host header, often exploited through techniques like HTTP Request Smuggling or Reset Password Poisoning. The template described aims to exploit this vulnerability by tampering with the host header in reset password requests, redirecting them via updated Proxy Headers to a server under the attacker's control.
yaml
1http:2# filter to determine if the template should be executed3- pre-condition:4- type: dsl5dsl:6- 'method == "POST"' # only run if method is POST7- 'contains(path,"reset")' # only run if path contains reset word8condition: and9# fuzzing rules10fuzzing:11- part: header # This rule will be applied to the header12type: replace # replace the type of rule (i.e., existing values will be replaced with payload)13mode: multiple # multiple mode (i.e., all existing values will be replaced/used at once)14fuzz:15X-Forwarded-For: "{{domain}}" # here {{domain}} is attacker-controlled server16X-Forwarded-Host: "{{domain}}"17Forwarded: "{{domain}}"18X-Real-IP: "{{domain}}"19X-Original-URL: "{{domain}}"20X-Rewrite-URL: "{{domain}}"21Host: "{{domain}}"
A difference to note here compared to the previous template is that we are not directly using payloads and specifying key/value pairs in fuzzing. This is because we attempt to add or replace multiple headers specified under the fuzz
key in HTTP requests instead of updating the value.
fuzz
key in the HTTP request, as shown in the above example.Learn More
You can read the updated documentation on fuzzing here!
Along with support for scanning targets behind, Nuclei v3.2.0 also includes a number of major enhancements:
- Read the Nuclei v3.2 release blog for all features and changes!
- Read Scanning Login-Protected Targets with Nuclei v3.2 to learn more about the new authenticated scanning features in nuclei v3.2.
Conclusion
Nuclei v3.2 represents a significant advancement in fuzzing capabilities, incorporating essential features that enable you to create custom fuzzing templates. Additionally, we've introduced the ability to import HTTP traffic from a range of tools and generate requests based on API schema files. We believe these enhancements will prove invaluable, and we eagerly anticipate witnessing the innovative ways you utilize them.
Join our Discord to share your thoughts!
We would love to hear about your applications and the awesome templates you will build in our #showcase
discord channel 🚀 .
Happy Fuzzing!