mirror of
https://github.com/projectdiscovery/nuclei.git
synced 2025-12-18 06:45:25 +00:00
* add reserved networkPort in template * add 'port' field in network request * add integration test * add exclude-ports and update docs * misc update --------- Co-authored-by: sandeep <8293321+ehsandeep@users.noreply.github.com>
169 lines
5.9 KiB
Plaintext
169 lines
5.9 KiB
Plaintext
---
|
|
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.
|
|
|
|
```yaml
|
|
# Start the requests for the template right here
|
|
tcp:
|
|
```
|
|
|
|
### Inputs
|
|
|
|
First thing in the request is **inputs**. Inputs are the data that will be sent to the server, and optionally any data to read from the server.
|
|
|
|
At it's most simple, just specify a string, and it will be sent across the network socket.
|
|
|
|
```yaml
|
|
# inputs is the list of inputs to send to the server
|
|
inputs:
|
|
- data: "TEST\r\n"
|
|
```
|
|
|
|
You can also send hex encoded text that will be first decoded and the raw bytes will be sent to the server.
|
|
|
|
```yaml
|
|
inputs:
|
|
- data: "50494e47"
|
|
type: hex
|
|
- data: "\r\n"
|
|
```
|
|
|
|
Helper function expressions can also be defined in input and will be first evaluated and then sent to the server. The last Hex Encoded example can be sent with helper functions this way -
|
|
|
|
```yaml
|
|
inputs:
|
|
- data: 'hex_decode("50494e47")\r\n'
|
|
```
|
|
|
|
One last thing that can be done with inputs is reading data from the socket. Specifying `read-size` with a non-zero value will do the trick. You can also assign the read data some name, so matching can be done on that part.
|
|
|
|
```yaml
|
|
inputs:
|
|
- read-size: 8
|
|
```
|
|
|
|
Example with reading a number of bytes, and only matching on them.
|
|
|
|
```yaml
|
|
inputs:
|
|
- read-size: 8
|
|
name: prefix
|
|
...
|
|
matchers:
|
|
- type: word
|
|
part: prefix
|
|
words:
|
|
- "CAFEBABE"
|
|
```
|
|
|
|
Multiple steps can be chained together in sequence to do network reading / writing.
|
|
|
|
### Host
|
|
|
|
The next part of the requests is the **host** to connect to. Dynamic variables can be placed in the path to modify its value on runtime. Variables start with `{{` and end with `}}` and are case-sensitive.
|
|
|
|
1. **Hostname** - variable is replaced by the hostname provided on command line.
|
|
|
|
An example name value:
|
|
|
|
```yaml
|
|
host:
|
|
- "{{Hostname}}"
|
|
```
|
|
|
|
Nuclei can also do TLS connection to the target server. Just add `tls://` as prefix before the **Hostname** and you're good to go.
|
|
|
|
```yaml
|
|
host:
|
|
- "tls://{{Hostname}}"
|
|
```
|
|
|
|
If a port is specified in the host, the user supplied port is ignored and the template port takes precedence.
|
|
|
|
### Port
|
|
|
|
Starting from Nuclei v2.9.15, a new field called `port` has been introduced in network templates. This field allows users to specify the port separately instead of including it in the host field.
|
|
|
|
Previously, if you wanted to write a network template for an exploit targeting SSH, you would have to specify both the hostname and the port in the host field, like this:
|
|
```yaml
|
|
host:
|
|
- "{{Hostname}}"
|
|
- "{{Host}}:22"
|
|
```
|
|
|
|
In the above example, two network requests are sent: one to the port specified in the input/target, and another to the default SSH port (22).
|
|
|
|
The reason behind introducing the port field is to provide users with more flexibility when running network templates on both default and non-default ports. For example, if a user knows that the SSH service is running on a non-default port of 2222 (after performing a port scan with service discovery), they can simply run:
|
|
|
|
```bash
|
|
$ nuclei -u scanme.sh:2222 -id xyz-ssh-exploit
|
|
```
|
|
|
|
In this case, Nuclei will use port 2222 instead of the default port 22. If the user doesn't specify any port in the input, port 22 will be used by default. However, this approach may not be straightforward to understand and can generate warnings in logs since one request is expected to fail.
|
|
|
|
Another issue with the previous design of writing network templates is that requests can be sent to unexpected ports. For example, if a web service is running on port 8443 and the user runs:
|
|
|
|
```bash
|
|
$ nuclei -u scanme.sh:8443
|
|
```
|
|
|
|
In this case, `xyz-ssh-exploit` template will send one request to `scanme.sh:22` and another request to `scanme.sh:8443`, which may return unexpected responses and eventually result in errors. This is particularly problematic in automation scenarios.
|
|
|
|
To address these issues while maintaining the existing functionality, network templates can now be written in the following way:
|
|
|
|
```yaml
|
|
host:
|
|
- "{{Hostname}}"
|
|
port: 22
|
|
```
|
|
In this new design, the functionality to run templates on non-standard ports will still exist, except for the default reserved ports (`80`, `443`, `8080`, `8443`, `8081`, `53`). Additionally, the list of default reserved ports can be customized by adding a new field called exclude-ports:
|
|
|
|
```yaml
|
|
exclude-ports: 80,443
|
|
```
|
|
When `exclude-ports` is used, the default reserved ports list will be overwritten. This means that if you want to run a network template on port `80`, you will have to explicitly specify it in the port field.
|
|
|
|
#### Matchers / Extractor Parts
|
|
|
|
Valid `part` values supported by **Network** protocol for Matchers / Extractor are -
|
|
|
|
| Value | Description |
|
|
|------------------|-------------------------------------|
|
|
| request | Network Request |
|
|
| data | Final Data Read From Network Socket |
|
|
| raw / body / all | All Data received from Socket |
|
|
|
|
### **Example Network Template**
|
|
|
|
The final example template file for a `hex` encoded input to detect MongoDB running on servers with working matchers is provided below.
|
|
|
|
```yaml
|
|
id: input-expressions-mongodb-detect
|
|
|
|
info:
|
|
name: Input Expression MongoDB Detection
|
|
author: pdteam
|
|
severity: info
|
|
reference: https://github.com/orleven/Tentacle
|
|
|
|
tcp:
|
|
- inputs:
|
|
- data: "{{hex_decode('3a000000a741000000000000d40700000000000061646d696e2e24636d640000000000ffffffff130000001069736d6173746572000100000000')}}"
|
|
host:
|
|
- "{{Hostname}}"
|
|
port: 27017
|
|
read-size: 2048
|
|
matchers:
|
|
- type: word
|
|
words:
|
|
- "logicalSessionTimeout"
|
|
- "localTime"
|
|
```
|
|
|
|
More complete examples are provided [here](/template-example/network). |