Added docs for multi + code protocol

dev
sandeep 2023-10-19 16:12:20 +05:30
parent dc44105baf
commit f4e46f4773
11 changed files with 530 additions and 188 deletions

View File

@ -73,6 +73,8 @@
"template-guide/file",
"template-guide/javascript",
"template-guide/code",
"template-guide/multi",
"template-guide/flow",
{
"group":"Operators",
"pages":[

View File

@ -2,161 +2,19 @@
title: "Code"
---
## Code Requests (beta)
Nuclei enables the execution of external code on the host operating system. This feature allows security researchers, pentesters, and developers to extend the capabilities of Nuclei and perform complex actions beyond the scope of regular supported protocol-based testing.
By leveraging this capability, Nuclei can interact with the underlying operating system and execute custom scripts or commands, opening up a wide range of possibilities. It enables users to perform tasks such as system-level configurations, file operations, network interactions, and more. This level of control and flexibility empowers users to tailor their security testing workflows according to their specific requirements.
However, it's important to exercise caution while utilizing this feature, as executing external code on the host operating system carries inherent risks. It is crucial to ensure that the executed code is secure, thoroughly tested, and does not pose any unintended consequences or security risks to the target system.
## Template Signing (beta)
Template signing via the private-public key mechanism is a crucial aspect of ensuring the integrity and authenticity of templates. This mechanism involves the use of asymmetric cryptography, specifically ECDSA algorithm, to create a secure and verifiable signature.
In this process, a template author generates a private key that remains confidential and securely stored. The corresponding public key is then shared with the template consumers. When a template is created or modified, the author signs it using their private key, generating a unique signature that is attached to the template.
Template consumers can verify the authenticity and integrity of a signed template by using the author's public key. By applying the appropriate cryptographic algorithm (ECDSA), they can validate the signature and ensure that the template has not been tampered with since it was signed. This provides a level of trust, as any modifications or unauthorized changes to the template would result in a failed verification process.
By employing the private-public key mechanism, template signing adds an additional layer of security and trust to the template ecosystem. It helps establish the identity of the template author and ensures that the templates used in various systems are genuine and have not been altered maliciously.
### What does signing a template mean ?
Template signing is a mechanism to ensure the integrity and authenticity of templates. The primary goal is to provide template writers/consumers a way to trust crowdsource/custom templates ensuring that they are not tampered
All Official nuclei templates include a digital signature in them and are verified by nuclei while loading templates using ProjectDiscovery's public key shipped with nuclei binary itself.
Individuals / Organizations running nuclei in their work environment can generate their own key-pair with `nuclei` and sign their custom templates with their private key, thus ensuring that only authorized templates are being used in their environment.
This also allows entities to fully utilize the power of new protocols like `code` and `javascript` without worrying about malicious custom templates being used in their environment.
**Points to note**
- Template signing is optional for all protocols except `code`.
- Code File References (ex: `source: protocols/code/pyfile.py`) are allowed and content of these files is included in the template digest
- Payload File References (ex: `payloads: protocols/http/params.txt`) are not included in the template digest as it is treated as a payload/helper and not actual code that is being executed
- Template Signing is deterministic while both signing and verifying a template i.e if a code file is referenced in a template that is present outside of templates directory with `-lfa` flag then verification will fail if same template is used without `-lfa` flag. (Note this only applies to `-lfa` i.e local file access flag only)
## How to sign custom templates
Simplest and recommended way to generate key-pair and signing/verfifying templates is to use `nuclei` itself.
#### When Signing a template if key-pair does not exist then nuclei will prompt user to generate a new key-pair with options
```console
$ ./nuclei -t my-template.yaml -sign -v
[INF] Generating new key-pair for signing templates
[*] Enter User/Organization Name (exit to abort) : projectdiscovery/nuclei-templates
[*] Enter passphrase (exit to abort):
[*] Enter same passphrase again:
[INF] Successfully generated new key-pair for signing templates
```
> Note: Passphrase is optional and can be left blank when used private key is encrypted with passphrase using PEMCipherAES256 Algo
#### Signing a template with existing key-pair
```console
$ ./nuclei -t ~/nuclei-templates/http -sign -v
[INF] All templates signatures were elaborated success=6464 failed=0
```
### Template Digest
When a template is signed, a digest is generated and added to the template. This digest is a hash of the template content and is used to verify the integrity of the template. If the template is modified after signing, the digest will change, and the signature verification will fail which happens during template loading.
```yaml
# digest: 4a0a00473045022100eb01da6b97893e7868c584f330a0cd52df9bddac005860bb8595ba5b8aed58c9022050043feac68d69045cf320cba9298a2eb2e792ea4720d045d01e803de1943e7d:4a3eb6b4988d95847d4203be25ed1d46
```
It is in the format of `signature:fragment` where signature is digital signature of template which is used to verify integrity of template
and fragment is a metadata generated by md5 hashing public key to disable re-signing of code templates not written by you.
fragment is meant to act like a speed bump to prevent mass-signing of code protocol templates to prevent any unintended misuse.
### Where are keys stored ?
key-pair generated by nuclei are stored in 2 files in `$config/nuclei/keys` directory where `$config` is system specific config directory
```
$ la ~/.config/nuclei/keys
total 16
-rw------- 1 tarun staff 251B Oct 4 21:45 nuclei-user-private-key.pem # encrypted private key with passphrase
-rw------- 1 tarun staff 572B Oct 4 21:45 nuclei-user.crt # self signed certificate which includes public key and identifier (i.e user/org name)
```
### Sharing and Using Public Key
Public key is stored in $config/nuclei/keys/nuclei-user.crt and can be shared with other users / organizations to verify templates signed by you.
#### Using Public Key
- A simple way to use public key is to copy it to $config/nuclei/keys directory of other user's machine
- Another way is to use environment variable `NUCLEI_USER_CERTIFICATE=xxx` to specify path of public key or content of public key directly
```console
$ export NUCLEI_USER_CERTIFICATE=path/to/nuclei-user.crt
```
or
```console
$ export NUCLEI_USER_CERTIFICATE=$(cat path/to/nuclei-user.crt)
```
#### Verifying Templates
Everytime `nuclei` is run, it loads user certificate (aka public key) from above locations and uses it to verify templates.
`nuclei` also prints identifier of public key being used and warns user of unsigned custom templates
```
[INF] Executing 6219 signed templates from projectdiscovery/nuclei-templates
[WRN] Executing 687 unsigned templates. Use with caution.
```
### Managing Private Key
Private key is stored in $config/nuclei/keys/nuclei-user-private-key.pem and is encrypted with passphrase if provided while generating key-pair.
It is not used/loaded by default by nuclei and is only used on demand i.e when signing templates using `-sign` flag
Some Users might want to store / backup or move private key to different location or machine and `nuclei` doesn't enforce any restrictions on that.
#### Using Private Key
- A simple way to use private key is to copy it to $config/nuclei/keys directory of other user's machine
- Another way is to use environment variable `NUCLEI_USER_PRIVATE_KEY=xxx` to specify path of private key or content of private key directly
```console
$ export NUCLEI_USER_PRIVATE_KEY=path/to/nuclei-user-private-key.pem
```
or
```console
$ export NUCLEI_USER_PRIVATE_KEY=$(cat path/to/nuclei-user-private-key.pem)
```
> Note: You are responsible for securing and managing private key and nuclei has no accountability for any loss of private key
## Code
In the context of template creation, a code block is used to indicate the start of the requests for the template. This block marks the beginning of the code-related instructions.
To write code template, a code block is used to indicate the start of the requests for the template. This block marks the beginning of the code-related instructions.
```yaml
# Start the requests for the template right here
code:
```
## Engine
To execute the code, a list of engines is specified, which are searched sequentially until a valid one is found on the system. The engine names must match the corresponding binary names on the system.
To execute the code, a list of language interpreters, which are installed or available on the system environment, is specified. These interpreters can be and not limited to `bash` `sh` `py` `python3`, `go`, `ps`, among others, and they are searched sequentially until a suitable one is found. The identifiers for these interpreters should correspond to their respective names or identifiers recognized by the system environment.
```yaml
- engine:
@ -169,7 +27,7 @@ The code to be executed can be provided either as an external file or as a code
For an external file:
```yaml
source: protocols/code/pyfile.py
source: helpers/code/pyfile.py
```
For a code snippet:
@ -179,9 +37,9 @@ source: |
print("hello from " + sys.stdin.read())
```
The target is passed to the template via stdin, and the output of the executed code is available for further processing in matchers and extractors. In the case of the Code protocol, the body part represents all data printed to stdout during the execution of the code.
The target is passed to the template via stdin, and the output of the executed code is available for further processing in matchers and extractors. In the case of the Code protocol, the response part represents all data printed to stdout during the execution of the code.
#### Matchers / Extractor Parts
## Parts
Valid `part` values supported by **Code** protocol for Matchers / Extractor are -
@ -190,42 +48,52 @@ Valid `part` values supported by **Code** protocol for Matchers / Extractor are
| response | execution output (trailing whitespaces are filtered) |
| stderr | Raw Stderr Output(if any) |
#### **Example Code Template**
The provided example demonstrates the execution of a Python script within the template. The specified engines are searched in the given order, and the code snippet is executed accordingly. Additionally, a matcher is included to check if the code's stdout contains the phrase "hello from input." (input must be passed as target with nuclei)
The provided example demonstrates the execution of a bash and python code snippet within the template. The specified engines are searched in the given order, and the code snippet is executed accordingly. Additionally, dynamic template variables are used in the code snippet, which are replaced with their respective values during the execution of the template which shows the flexibility and customization that can be achieved using this protocol.
```yaml
id: py-code-snippet
id: code-template
info:
name: py-code-snippet
name: example code template
author: pdteam
severity: info
tags: code
description: |
py-code-snippet
variables:
OAST: "{{interactsh-url}}"
code:
- engine:
- sh
- bash
source: |
echo "$OAST" | base64
- engine:
- py
- python3
source: |
import sys
print("hello from " + sys.stdin.read())
matchers:
- type: word
words:
- "hello from input"
# digest: 4a0a00473045022067a69eb337ffa56d1c8e2cc57b7f74a5eb3294e6f366c9074778b2da3f1d795d02210096d6acda6acd2fe0ff005b08a9c0b72b63f599532ec6493f44b8518265d0e5fd:4a3eb6b4988d95847d4203be25ed1d46
```
import base64
import os
### Optional Fields for Code Protocol
text = os.getenv('OAST')
text_bytes = text.encode('utf-8')
base64_bytes = base64.b64encode(text_bytes)
base64_text = base64_bytes.decode('utf-8')
print(base64_text)
http:
- method: GET
path:
- "{{BaseURL}}/?x={{code_1_response}}"
- "{{BaseURL}}/?x={{code_2_response}}"
# digest: 4a0a0047304502202ce8fe9f5992782da6ba59da4e8ebfde9f19a12e247adc507040e9f1f1124b4e022100cf0bc7a44a557a6655f79a2b4789e103f5099f0f81a8d1bc4ad8aabe7829b1c5:8eeeebe39b11b16384b45bc7e9163000
```
Apart from required fields mentioned above, Code protocol also supports following optional fields to further customize the execution of code.
#### Args
## Args
Args are arguments that are sent to engine while executing the code. For example if we want to bypass execution policy in powershell for specific template this can be done by adding following args to the template.
@ -239,7 +107,7 @@ Args are arguments that are sent to engine while executing the code. For example
- -File
```
#### Pattern
## Pattern
Pattern field can be used to customize name / extension of temporary file while executing a code snippet in a template
@ -247,10 +115,7 @@ Pattern field can be used to customize name / extension of temporary file while
pattern: "*.ps1"
```
adding `pattern: "*.ps1"` will make sure that name of temporary file given pattern
### Example Code Template with Args and Pattern
adding `pattern: "*.ps1"` will make sure that name of temporary file given pattern.
Below is a example code template where we are executing a powershell script while customizing behaviour of execution policy and setting pattern to `*.ps1`
@ -261,9 +126,9 @@ info:
name: ps1-code-snippet
author: pdteam
severity: info
tags: code
description: |
ps1-code-snippet
tags: code
code:
- engine:
@ -288,12 +153,100 @@ code:
For more examples, please refer to example [code-templates](https://github.com/projectdiscovery/nuclei/blob/3a5f9d626ea7b632ccca601b658acd9758f8f01b/integration_tests/protocols/code) in integration tests.
It's important to exercise caution while utilizing this feature, as executing external code on the host operating system carries inherent risks. It is crucial to ensure that the executed code is secure, thoroughly tested, and does not pose any unintended consequences or security risks to the target system.
## Template Signing
Template signing via the private-public key mechanism is a crucial aspect of ensuring the integrity, authenticity and security of templates. This mechanism involves the use of asymmetric cryptography, specifically ECDSA algorithm, to create a secure and verifiable signature.
In this process, a template author generates a private key that remains confidential and securely stored. The corresponding public key is then shared with the template consumers. When a template is created or modified, the author signs it using their private key, generating a unique signature that is attached to the template.
Template consumers can verify the authenticity and integrity of a signed template by using the author's public key. By applying the appropriate cryptographic algorithm (ECDSA), they can validate the signature and ensure that the template has not been tampered with since it was signed. This provides a level of trust, as any modifications or unauthorized changes to the template would result in a failed verification process.
By employing the private-public key mechanism, template signing adds an additional layer of security and trust to the template ecosystem. It helps establish the identity of the template author and ensures that the templates used in various systems are genuine and have not been altered maliciously.
**What does signing a template mean?**
Template signing is a mechanism to ensure the integrity and authenticity of templates. The primary goal is to provide template writers/consumers a way to trust crowdsource/custom templates ensuring that they are not tampered
All [official nuclei templates](https://github.com/projectdiscovery/nuclei-templates) include a digital signature in them and are verified by nuclei while loading templates using ProjectDiscovery's public key shipped with nuclei binary itself.
Individuals / Organizations running nuclei in their work environment can generate their own key-pair with `nuclei` and sign their custom templates with their private key, thus ensuring that only authorized templates are being used in their environment.
This also allows entities to fully utilize the power of new protocols like `code` without worrying about malicious custom templates being used in their environment.
**NOTE:**
- **Template signing is optional for all protocols except `code`**.
- **Unsigned code templates are disabled and can not be executed using nuclei**.
- **Only signed code templates by the author (yourself) or ProjectDiscovery can be executed.**
- **Template signing is primarily introduced to ensure security of template to run code on host machine.**
- Code file references (ex: `source: protocols/code/pyfile.py`) are allowed and content of these files is included in the template digest.
- Payload file references (ex: `payloads: protocols/http/params.txt`) are not included in the template digest as it is treated as a payload/helper and not actual code that is being executed.
- Template signing is deterministic while both signing and verifying a template i.e if a code file is referenced in a template that is present outside of templates directory with `-lfa` flag then verification will fail if same template is used without `-lfa` flag. (Note this only applies to `-lfa` i.e local file access flag only)
### Signing Custom Template
Simplest and recommended way to generate key-pair and signing/verfifying templates is to use `nuclei` itself.
When Signing a template if key-pair does not exist then nuclei will prompt user to generate a new key-pair with options.
```console
$ ./nuclei -t templates.yaml -sign
[INF] Generating new key-pair for signing templates
[*] Enter User/Organization Name (exit to abort) : acme
[*] Enter passphrase (exit to abort):
[*] Enter same passphrase again:
[INF] Successfully generated new key-pair for signing templates
```
> **Note:** Passphrase is optional and can be left blank when used private key is encrypted with passphrase using PEMCipherAES256 Algo
Once key-pair is generated, you can sign any custom template using `-sign` flag as shown below.
```console
$ ./nuclei -t templates.yaml -sign
[INF] All templates signatures were elaborated success=1 failed=0
```
> **Note:** Every time you make any change in your code template, you need to resign it again to run with nuclei.
### Template Digest and Signing Keys
When a template is signed, a digest is generated and added to the template. This digest is a hash of the template content and is used to verify the integrity of the template. If the template is modified after signing, the digest will change, and the signature verification will fail during template loading.
```yaml
# digest: 4a0a00473045022100eb01da6b97893e7868c584f330a0cd52df9bddac005860bb8595ba5b8aed58c9022050043feac68d69045cf320cba9298a2eb2e792ea4720d045d01e803de1943e7d:4a3eb6b4988d95847d4203be25ed1d46
```
The digest is in the format of `signature:fragment`, where the signature is the digital signature of the template used to verify its integrity, and the fragment is metadata generated by MD5 hashing the public key to disable re-signing of code templates not written by you.
The key-pair generated by Nuclei is stored in two files in the `$CONFIG/nuclei/keys directory`, where `$CONFIG` is the system-specific config directory. The private key is stored in nuclei-user-private-key.pem, which is encrypted with a passphrase if provided. The public key is stored in nuclei-user.crt, which includes the public key and identifier (e.g., user/org name) in a self-signed certificate.
```bash
$ la ~/.config/nuclei/keys
total 16
-rw------- 1 tarun staff 251B Oct 4 21:45 nuclei-user-private-key.pem # encrypted private key with passphrase
-rw------- 1 tarun staff 572B Oct 4 21:45 nuclei-user.crt # self signed certificate which includes public key and identifier (i.e user/org name)
```
To use the public key for verification, you can either copy it to the `$CONFIG/nuclei/keys` directory on another user's machine or set the `NUCLEI_USER_CERTIFICATE` environment variable to the path or content of the public key.
To use the private key, you can copy it to the `$CONFIG/nuclei/keys` directory on another user's machine or set the `NUCLEI_USER_PRIVATE_KEY` environment variable to the path or content of the private key.
```console
$ export NUCLEI_USER_CERTIFICATE=$(cat path/to/nuclei-user.crt)
$ export NUCLEI_USER_PRIVATE_KEY=$(cat path/to/nuclei-user-private-key.pem)
```
It's important to note that you are responsible for securing and managing the private key, and Nuclei has no accountability for any loss of the private key.
By default, Nuclei loads the user certificate (public key) from the default locations mentioned above and uses it to verify templates. When running Nuclei, it will execute signed templates and warn about executing unsigned custom templates and block unsigned code templates. You can disable this warning by setting the `HIDE_TEMPLATE_SIG_WARNING` environment variable to `true`.
## FAQ
### I got this error when running a template . What does it mean ?
**Found X unsigned or tampered code template?**
```
```bash
./nuclei -u scanme.sh -t simple-code.yaml
__ _
@ -316,7 +269,7 @@ For more examples, please refer to example [code-templates](https://github.com/p
Here `simple-code.yaml` is a code protocol template which is not signed or content of template has been modified after signing which indicates loss of integrity of template.
If you are template writer then you can go ahead and sign the template using `-sign` flag and if you are template consumer then you should carefully examine the template before signing it.
### What does `re-signing code templates are not allowed for security reasons` error mean?
**Re-signing code templates are not allowed for security reasons?**
```bash
nuclei -u scanme.sh -t simple-code.yaml -sign

View File

@ -2,8 +2,6 @@
title: "DNS"
---
## DNS Requests
DNS protocol can be modelled in nuclei with ease. Fully Customizable DNS requests can be sent by nuclei to nameservers and matching/extracting can be performed on their response.
DNS Requests start with a **dns** block which specifies the start of the requests for the template.

View File

@ -2,8 +2,6 @@
title : "File"
---
## File Requests
Nuclei allows modelling templates that can match/extract on filesystem too.
```yaml

View File

@ -0,0 +1,224 @@
---
title : Flow
---
Template flow engine introduced in v3, brings two significant enhancements to Nuclei:
- The ability to conditionally execute requests
- The orchestration of request execution
These features are implemented using JavaScript (ECMAScript 5.1) via the [goja](https://github.com/dop251/goja) backend.
## Conditional Execution
Many times when writing complex templates we might need to add some extra checks (or conditional statements) before executing certain part of request.
An ideal example of this would be when [bruteforcing wordpress login](https://templates.nuclei.sh/public/wordpress-weak-credentials) with default usernames and passwords, but if we carefully re-evaluate this template, we can see that template is sending 276 requests without even checking, if the url actually exists or target site is actually a wordpress site.
With addition of flow in Nuclei v3 we can re-write this template to first check if target is a wordpress site, if yes then bruteforce login with default credentials and this can be achieved by simply adding one line of content i.e `flow: http(1) && http(2)` and nuclei will take care of everything else.
```yaml
id: wordpress-bruteforce
info:
name: WordPress Login Bruteforce
author: pdteam
severity: high
flow: http(1) && http(2)
http:
- method: GET
path:
- "{{BaseURL}}/wp-login.php"
matchers:
- type: word
words:
- "WordPress"
- method: POST
path:
- "{{BaseURL}}/wp-login.php"
body: |
log={{username}}&pwd={{password}}&wp-submit=Log+In
attack: clusterbomb
payloads:
users: helpers/wordlists/wp-users.txt
passwords: helpers/wordlists/wp-passwords.txt
matchers:
- type: dsl
dsl:
- status_code == 302
- contains_all(header, "/wp-admin","wordpress_logged_in")
condition: and
```
The update template now seems straight forward and easy to understand. we are first checking if target is a wordpress site and then executing bruteforce requests. This is just a simple example of conditional execution and flow accepts any Javascript (ECMAScript 5.1) expression/code so you are free to craft any conditional execution logic you want.
## Request Execution Orchestration
Flow is a powerful Nuclei feature that provides enhanced orchestration capabilities for executing requests. The simplicity of conditional execution is just the beginning. With flow, you can:
- Iterate over a list of values and execute a request for each one
- Extract values from a request, iterate over them, and perform another request for each
- Get and set values within the template context (global variables)
- Write output to stdout for debugging purposes or based on specific conditions
- Introduce custom logic during template execution
- Use ECMAScript 5.1 JavaScript features to build and modify variables at runtime
- Update variables at runtime and use them in subsequent requests.
Think of request execution orchestration as a bridge between JavaScript and Nuclei, offering two-way interaction within a specific template.
**Practical Example: Vhost Enumeration**
To better illustrate the power of flow, let's consider developing a template for vhost (virtual host) enumeration. This set of tasks typically requires writing a new tool from scratch. Here are the steps we need to follow:
1. Retrieve the SSL certificate for the provided IP (using tlsx)
- Extract `subject_cn` (CN) from the certificate
- Extract `subject_an` (SAN) from the certificate
- Remove wildcard prefixes from the values obtained in the steps above
2. Bruteforce the request using all the domains found from the SSL request
You can utilize flow to simplify this task. The JavaScript code below orchestrates the vhost enumeration:
```javascript
ssl();
for (let vhost of iterate(template["ssl_domains"])) {
set("vhost", vhost);
http();
}
```
In this code, we've introduced 5 extra lines of JavaScript. This allows the template to perform vhost enumeration. The best part? You can run this at scale with all features of Nuclei, using supported inputs like ASN, CIDR, URL.
Let's break down the JavaScript code:
1. `ssl()`: This function executes the SSL request.
2. `template["ssl_domains"]`: Retrieves the value of `ssl_domains` from the template context.
3. `iterate()`: Helper function that iterates over any value type while handling empty or null values.
4. `set("vhost", vhost)`: Creates a new variable `vhost` in the template and assigns the `vhost` variable's value to it.
5. `http()`: This function conducts the HTTP request.
By understanding and taking advantage of Nuclei's `flow`, you can redefine the way you orchestrate request executions, making your templates much more powerful and efficient.
Here is working template for vhost enumeration using flow:
```yaml
id: vhost-enum-flow
info:
name: vhost enum flow
author: tarunKoyalwar
severity: info
description: |
vhost enumeration by extracting potential vhost names from ssl certificate.
flow: |
ssl();
for (let vhost of iterate(template["ssl_domains"])) {
set("vhost", vhost);
http();
}
ssl:
- address: "{{Host}}:{{Port}}"
http:
- raw:
- |
GET / HTTP/1.1
Host: {{vhost}}
matchers:
- type: dsl
dsl:
- status_code != 400
- status_code != 502
extractors:
- type: dsl
dsl:
- '"VHOST: " + vhost + ", SC: " + status_code + ", CL: " + content_length'
```
## JS Bindings
This section contains a brief description of all nuclei JS bindings and their usage.
### Protocol Execution Function
In nuclei, any listed protocol can be invoked or executed in JavaScript using the `protocol_name()` format. For example, you can use `http()`, `dns()`, `ssl()`, etc.
If you want to execute a specific request of a protocol (refer to nuclei-flow-dns for an example), it can be achieved by passing either:
- The index of that request in the protocol (e.g.,`dns(1)`, `dns(2)`)
- The ID of that request in the protocol (e.g., `dns("extract-vps")`, `http("probe-http")`)
For more advanced scenarios where multiple requests of a single protocol need to be executed, you can specify their index or ID one after the other (e.g., dns("extract-vps","1")).
This flexibility in using either index numbers or ID strings to call specific protocol requests provides controls for tailored execution, allowing you to build more complex and efficient workflows. more complex use cases multiple requests of a single protocol can be executed by just specifying their index or id one after another (ex: `dns("extract-vps","1")`)
### Iterate Helper Function
Iterate is a nuclei js helper function which can be used to iterate over any type of value like **array**, **map**, **string**, **number** while handling empty/nil values.
This is addon helper function from nuclei to omit boilerplate code of checking if value is empty or not and then iterating over it
```javascript
iterate(123,{"a":1,"b":2,"c":3})
// iterate over array with custom separator
iterate([1,2,3,4,5], " ")
```
### Set Helper Function
When iterating over a values/array or some other use case we might want to invoke a request with custom/given value and this can be achieved by using `set()` helper function. When invoked/called it adds given variable to template context (global variables) and that value is used during execution of request/protocol. the format of `set()` is `set("variable_name",value)` ex: `set("username","admin")`.
```javascript
for (let vhost of myArray) {
set("vhost", vhost);
http(1)
}
```
**Note:** In above example we used `set("vhost", vhost)` which added `vhost` to template context (global variables) and then called `http(1)` which used this value in request.
### Template Context
A template context is nothing but a map/jsonl containing all this data along with internal/unexported data that is only available at runtime (ex: extracted values from previous requests, variables added using `set()` etc). This template context is available in javascript as `template` variable and can be used to access any data from it. ex: `template["dns_cname"]`, `template["ssl_subject_cn"]` etc.
```javascript
template["ssl_domains"] // returns value of ssl_domains from template context which is available after executing ssl request
template["ptrValue"] // returns value of ptrValue which was extracted using regex with internal: true
```
Lot of times we don't known what all data is available in template context and this can be easily found by printing it to stdout using `log()` function
```javascript
log(template)
```
### Log Helper Function
It is a nuclei js alternative to `console.log` and this pretty prints map data in readable format
**Note:** This should be used for debugging purposed only as this prints data to stdout
### Dedupe
Lot of times just having arrays/slices is not enough and we might need to remove duplicate variables . for example in earlier vhost enumeration we did not remove any duplicates as there is always a chance of duplicate values in `ssl_subject_cn` and `ssl_subject_an` and this can be achieved by using `dedupe()` object. This is nuclei js helper function to abstract away boilerplate code of removing duplicates from array/slice
```javascript
let uniq = new Dedupe(); // create new dedupe object
uniq.Add(template["ptrValue"])
uniq.Add(template["ssl_subject_cn"]);
uniq.Add(template["ssl_subject_an"]);
log(uniq.Values())
```
And that's it, this automatically converts any slice/array to map and removes duplicates from it and returns a slice/array of unique values
> Similar to DSL helper functions . we can either use built in functions available with `Javscript (ECMAScript 5.1)` or use DSL helper functions and its upto user to decide which one to uses.

View File

@ -2,8 +2,6 @@
title: "Headless"
---
## Headless Requests
Nuclei supports automation of a browser with simple DSL. Headless browser engine can be fully customized and user actions can be scripted allowing complete control over the browser. This allows for a variety of unique and custom workflows.
```yaml

View File

@ -1,7 +1,6 @@
---
title: "Advance HTTP"
---
## Advance requests
Weve enriched nuclei to allow advanced scanning of web servers. Users can now use multiple options to tune HTTP request workflows.

View File

@ -1,6 +1,7 @@
---
title: "RAW HTTP requests"
title: "RAW HTTP"
---
Another way to create request is using raw requests which comes with more flexibility and support of DSL helper functions, like the following ones (as of now it's suggested to leave the `Host` header as in the example with the variable `{{Hostname}}`), All the Matcher, Extractor capabilities can be used with RAW requests in same the way described above.
```yaml

View File

@ -1,5 +1,5 @@
---
title: "Unsafe HTTP Requests"
title: "Unsafe HTTP"
---
Nuclei supports [rawhttp](https://github.com/projectdiscovery/rawhttp) for complete request control and customization allowing **any kind of malformed requests** for issues like HTTP request smuggling, Host header injection, CRLF with malformed characters and more.

View File

@ -0,0 +1,171 @@
---
title: "Multi"
---
Nuclei provides support for a variety of protocols including HTTP, DNS, Network, SSL, and Code. This allows users to write Nuclei templates for vulnerabilities across these protocols. However, there may be instances where a vulnerability requires the synchronous execution of multiple protocols for testing or exploitation. A prime example of this is **subdomain takeovers**, which necessitates a check for the CNAME record of a subdomain, followed by a verification of string in HTTP response. While this was partially achievable with workflows in Nuclei, the introduction of **Nuclei v3.0** has made it possible to conveniently write a **template** that can execute multiple protocols synchronously. This allows for checks to be performed on the results of each protocol, along with other enhancements.
**Example:**
```yaml
id: dns-http-template
info:
name: dns + http takeover template
author: pdteam
severity: info
dns:
- name: "{{FQDN}}" # dns request
type: cname
http:
- method: GET # http request
path:
- "{{BaseURL}}"
matchers:
- type: dsl
dsl:
- contains(http_body,'Domain not found') # check for string from http response
- contains(dns_cname, 'github.io') # check for cname from dns response
condition: and
```
The example above demonstrates that there is no need for new logic or syntax. Simply write the logic for each protocol and then use the protocol-prefixed variable or the [dynamic extractor](https://docs.nuclei.sh/template-guide/operators/extractors#dynamic-extractor) to export that variable. This variable is then shared across all protocols. We refer to this as the **Template Context**, which contains all variables that are scoped at the template level.
## Features
The following features enhance the power of multi-protocol execution:
- Protocol-Scoped Shared Variables Across Protocols
- Data Export across Protocols using Dynamic Extractor
### Protocol Scoped Variables
In the previous example, we demonstrated how to export the DNS CNAME and use it in an HTTP request. However, you might encounter a scenario where a template includes more than four protocols, and you need to export various response fields such as `subject_dn`, `ns`, `cname`, `header`, and so on. While you could achieve this by adding more dynamic extractors, this approach could clutter the template and introduce redundant logic, making it difficult to track and maintain all the variables.
To address this issue, multi-protocol execution supports template-scoped protocol responses. This means that all response fields from all protocols in a template are available in the template context with a protocol prefix.
Here's an example to illustrate this:
Protocol | Response Field | Exported Variable |
-------- | -------------- | ----------------- |
ssl | subject_cn | ssl_subject_cn |
dns | cname | dns_cname |
http | header | http_header |
code | response | code_response |
This is just an example, but it's important to note that the response fields of all protocols used in a multi-protocol template are exported.
**Example:**
```yaml
id: dns-ssl-http-proto-prefix
info:
name: multi protocol request with response fields
author: pdteam
severity: info
dns:
- name: "{{FQDN}}" # DNS Request
type: cname
ssl:
- address: "{{Hostname}}" # ssl request
http:
- method: GET # http request
path:
- "{{BaseURL}}"
matchers:
- type: dsl
dsl:
- contains(http_body,'ProjectDiscovery.io') # check for http string
- trim_suffix(dns_cname,'.ghost.io.') == 'projectdiscovery' # check for cname (extracted information from dns response)
- ssl_subject_cn == 'blog.projectdiscovery.io'
condition: and
```
To list all exported response fields write a multi protocol template and run it with `-v -svd` flag and it will print all exported response fields
Example:
```bash
nuclei -t multi-protocol-template.yaml -u scanme.sh -debug -svd
```
### Data Export across Protocols
If you are unfamiliar with dynamic extractors, we recommend reading the [dynamic extractor](https://docs.nuclei.sh/template-guide/operators/extractors#dynamic-extractor) section first.
Previously, Dynamic Extractors were only supported for specific protocols or workflows. However, with multi-protocol execution, dynamically extracted values are stored in the template context and can be used across all protocols.
**Example:**
```yaml
id: dns-http-template
info:
name: dns + http takeover template
author: pdteam
severity: info
dns:
- name: "{{FQDN}}" # dns request
type: cname
extractors:
- type: dsl
name: exported_cname
dsl:
- cname
internal: true
http:
- method: GET # http request
path:
- "{{BaseURL}}"
matchers:
- type: dsl
dsl:
- contains(body,'Domain not found') # check for http string
- contains(exported_cname, 'github.io') # check for cname (extracted information from dns response)
condition: and
```
## How Multi Protocol Works?
At this point we have seen how multi protocol templates look like and what are the features it brings to the table. Now let's see how multi protocol templates work and things to keep in mind while writing them.
- Multi Protocol Templates are executed in order of protocols defined in template.
- Protocols in multi protocol templates are executed in serial i.e one after another.
- Response fields of protocols are exported to template context as soon as that protocol is executed.
- Variables are scoped at template level and evaluated after each protocol execution.
- Multi protocol brings limited indirect support for preprocessing(using variables) and postprocessing(using dynamic extractors) for protocols.
## FAQ
**What Protocols are supported in Multi-Protocol Execution Mode?**
> There is no restriction around any protocol and any protocol available/implemented in nuclei engine can be used in multi protocol templates
**How many protocols can be used in Multi-Protocol Execution Mode?**
> There is no restriction around number of protocols but currently duplicated protocols are not supported i.e dns -> http -> ssl -> http. Please open a issue if you have a vulnerabilty/usecase that requires duplicated protocols
**What happens if a protocol fails?**
> Multi Protocol Execution follows exit on error policy i.e if protocol fails to execute then execution of remaining protocols is skipped and template execution is stopped
**How is multi protocol execution different from workflows?**
> Workflow as name suggest is a workflow that executes templates based on workflow file
> - Workflow does not contain actual logic of vulnerability but just a workflow that executes different templates
> - Workflow supports conditional execution of multiple templates
> - Workflow has limited supported for variables and dynamic extractors
To summarize workflow is a step higher than template and manages execution of templates based on workflow file
**Is multi protocol execution supported in nuclei v2?**
> No, Multi Protocol Execution is only supported in nuclei v3 and above

View File

@ -2,8 +2,6 @@
title: "Network"
---
## Network Requests
Nuclei can act as an automatable **Netcat**, allowing users to send bytes across the wire and receive them, while providing matching and extracting capabilities on the response.
Network Requests start with a **network** block which specifies the start of the requests for the template.