mirror of
https://github.com/projectdiscovery/nuclei.git
synced 2025-12-20 13:15:23 +00:00
* Added xpath response matching support * Add validation for user-supplied XPath * xpath matcher comment fix * Added XPath matched documentation * minor changes: remove warnings --------- Co-authored-by: Tarun Koyalwar <tarun@projectdiscovery.io>
186 lines
5.7 KiB
Plaintext
186 lines
5.7 KiB
Plaintext
---
|
|
title: "Matchers"
|
|
---
|
|
|
|
## Matchers
|
|
|
|
Matchers allow different type of flexible comparisons on protocol responses. They are what makes nuclei so powerful, checks are very simple to write and multiple checks can be added as per need for very effective scanning.
|
|
|
|
### Types
|
|
|
|
Multiple matchers can be specified in a request. There are basically 7 types of matchers:
|
|
|
|
| Matcher Type | Part Matched |
|
|
|--------------|-----------------------------|
|
|
| status | Integer Comparisons of Part |
|
|
| size | Content Length of Part |
|
|
| word | Part for a protocol |
|
|
| regex | Part for a protocol |
|
|
| binary | Part for a protocol |
|
|
| dsl | Part for a protocol |
|
|
| xpath | Part for a protocol |
|
|
|
|
To match status codes for responses, you can use the following syntax.
|
|
|
|
```yaml
|
|
matchers:
|
|
# Match the status codes
|
|
- type: status
|
|
# Some status codes we want to match
|
|
status:
|
|
- 200
|
|
- 302
|
|
```
|
|
|
|
To match binary for hexadecimal responses, you can use the following syntax.
|
|
|
|
```yaml
|
|
matchers:
|
|
- type: binary
|
|
binary:
|
|
- "504B0304" # zip archive
|
|
- "526172211A070100" # RAR archive version 5.0
|
|
- "FD377A585A0000" # xz tar.xz archive
|
|
condition: or
|
|
part: body
|
|
```
|
|
|
|
Matchers also support hex encoded data which will be decoded and matched.
|
|
|
|
```yaml
|
|
matchers:
|
|
- type: word
|
|
encoding: hex
|
|
words:
|
|
- "50494e47"
|
|
part: body
|
|
```
|
|
|
|
**Word** and **Regex** matchers can be further configured depending on the needs of the users.
|
|
|
|
**XPath** matchers use XPath queries to match XML and HTML responses. If the XPath query returns any results, it's considered a match.
|
|
|
|
```yaml
|
|
matchers:
|
|
- type: xpath
|
|
part: body
|
|
xpath:
|
|
- "/html/head/title[contains(text(), 'Example Domain')]"
|
|
```
|
|
|
|
Complex matchers of type **dsl** allows building more elaborate expressions with helper functions. These function allow access to Protocol Response which contains variety of data based on each protocol. See protocol specific documentation to learn about different returned results.
|
|
|
|
|
|
```yaml
|
|
matchers:
|
|
- type: dsl
|
|
dsl:
|
|
- "len(body)<1024 && status_code==200" # Body length less than 1024 and 200 status code
|
|
- "contains(toupper(body), md5(cookie))" # Check if the MD5 sum of cookies is contained in the uppercase body
|
|
```
|
|
|
|
Every part of a Protocol response can be matched with DSL matcher. Some examples -
|
|
|
|
| Response Part | Description | Example |
|
|
|----------------|-------------------------------------------------|------------------------|
|
|
| content_length | Content-Length Header | content_length >= 1024 |
|
|
| status_code | Response Status Code | status_code==200 |
|
|
| all_headers | Unique string containing all headers | len(all_headers) |
|
|
| body | Body as string | len(body) |
|
|
| header_name | Lowercase header name with `-` converted to `_` | len(user_agent) |
|
|
| raw | Headers + Response | len(raw) |
|
|
|
|
|
|
### Conditions
|
|
|
|
Multiple words and regexes can be specified in a single matcher and can be configured with different conditions like **AND** and **OR**.
|
|
|
|
1. **AND** - Using AND conditions allows matching of all the words from the list of words for the matcher. Only then will the request be marked as successful when all the words have been matched.
|
|
2. **OR** - Using OR conditions allows matching of a single word from the list of matcher. The request will be marked as successful when even one of the word is matched for the matcher.
|
|
|
|
### Matched Parts
|
|
|
|
Multiple parts of the response can also be matched for the request, default matched part is `body` if not defined.
|
|
|
|
Example matchers for HTTP response body using the AND condition:
|
|
|
|
```yaml
|
|
matchers:
|
|
# Match the body word
|
|
- type: word
|
|
# Some words we want to match
|
|
words:
|
|
- "[core]"
|
|
- "[config]"
|
|
# Both words must be found in the response body
|
|
condition: and
|
|
# We want to match request body (default)
|
|
part: body
|
|
```
|
|
|
|
Similarly, matchers can be written to match anything that you want to find in the response body allowing unlimited creativity and extensibility.
|
|
|
|
### Negative Matchers
|
|
|
|
All types of matchers also support negative conditions, mostly useful when you look for a match with an exclusions. This can be used by adding `negative: true` in the **matchers** block.
|
|
|
|
Here is an example syntax using `negative` condition, this will return all the URLs not having `PHPSESSID` in the response header.
|
|
|
|
```yaml
|
|
matchers:
|
|
- type: word
|
|
words:
|
|
- "PHPSESSID"
|
|
part: header
|
|
negative: true
|
|
```
|
|
|
|
### Multiple Matchers
|
|
|
|
Multiple matchers can be used in a single template to fingerprint multiple conditions with a single request.
|
|
|
|
Here is an example of syntax for multiple matchers.
|
|
|
|
```yaml
|
|
matchers:
|
|
- type: word
|
|
name: php
|
|
words:
|
|
- "X-Powered-By: PHP"
|
|
- "PHPSESSID"
|
|
part: header
|
|
- type: word
|
|
name: node
|
|
words:
|
|
- "Server: NodeJS"
|
|
- "X-Powered-By: nodejs"
|
|
condition: or
|
|
part: header
|
|
- type: word
|
|
name: python
|
|
words:
|
|
- "Python/2."
|
|
- "Python/3."
|
|
condition: or
|
|
part: header
|
|
```
|
|
|
|
### Matchers Condition
|
|
|
|
While using multiple matchers the default condition is to follow OR operation in between all the matchers, AND operation can be used to make sure return the result if all matchers returns true.
|
|
|
|
```yaml
|
|
matchers-condition: and
|
|
matchers:
|
|
- type: word
|
|
words:
|
|
- "X-Powered-By: PHP"
|
|
- "PHPSESSID"
|
|
condition: or
|
|
part: header
|
|
|
|
- type: word
|
|
words:
|
|
- "PHP"
|
|
part: body
|
|
``` |