From 79857d58862c2930dec077d050db94d46cd040d9 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Mon, 25 May 2020 09:21:13 +0200 Subject: [PATCH] Typos, syntax and indent --- GUIDE.md | 261 +++++++++++++++++++++++++++---------------------------- 1 file changed, 128 insertions(+), 133 deletions(-) diff --git a/GUIDE.md b/GUIDE.md index a7b690a57b..66ec04fa4d 100644 --- a/GUIDE.md +++ b/GUIDE.md @@ -2,12 +2,11 @@ **Nuclei** is based on the concepts of `YAML` based template files that define how the requests will be sent and processed. This allows easy extensibility capabilities to nuclei. -The templates are written in `YAML` which specifies a simple human readable format to quickly define the execution process. +The templates are written in `YAML` which specifies a simple human readable format to quickly define the execution process. Let's start with the basics and define our own workflow file for detecting the presence of a `.git/config` file on a webserver and take it from there. -Table of Contents -================= +## Table of Contents * [Templating Guide](#templating-guide) * [Template Details](#template-details) @@ -47,33 +46,32 @@ id: git-config ID must not contain spaces. This is done to allow easier output parsing. -### **Info** +### Info - -Next important piece of information about a template is the **info** block. Info block provides more context on the purpose of the template and the **author**. It can also contain a **severity** field which indicates the severity of the template. +Next important piece of information about a template is the **info** block. Info block provides more context on the purpose of the template and the **author**. It can also contain a **severity** field which indicates the severity of the template. Let's add an **info** block to our template as well. ```yaml info: - # name is the name of the template + # Name is the name of the template name: Git Config File Detection Template - # author is the name of the author for the template + # Author is the name of the author for the template author: Ice3man - # severity is the severity for the template. + # Severity is the severity for the template. severity: medium ``` -Actual requests and corresponding matchers are placed below the info block and they perform the task of making requests to target servers and finding if the template request was succesful. +Actual requests and corresponding matchers are placed below the info block and they perform the task of making requests to target servers and finding if the template request was successful. Each template file can contain multiple requests to be made. The template is iterated and one by one the desired HTTP/DNS requests are made to the target sites. -### **HTTP Requests** +### HTTP Requests -Requests start with a request block which specifies the start of the requests for the template. +Requests start with a request block which specifies the start of the requests for the template. ```yaml -# start the requests for the template right here +# Start the requests for the template right here requests: ``` @@ -82,12 +80,12 @@ At this point you can define raw requests like the following ones (as of now it' ```yaml requests: - raw: - - | + - | GET /path1/ HTTP/1.1 User-Agent: chrome Host: {{Hostname}} Accept: a1/b1 - - | + - | POST /path2/ HTTP/1.1 User-Agent: chrome Host: {{Hostname}} @@ -96,21 +94,21 @@ requests: This is the request Body ``` -Otherwise you can define structured requests as described in the following paragraphs. Requests can be fine tuned to perform the exact tasks as desired. Nuclei requests are fully configurable meaning you can configure and define each and every single thing about the requests that will be sent to the target servers. A recent addition in raw requests has been the introduction of intruder-like functionailities. It's possible to define placeholders as `{{placeholder}}`, and perform Sniper, Pitchfork and ClusterBomb attacks. The wordlist for these attacks needs to be defined during the request definition under the `Payload` field. Finally all DSL functionalities are fully available and supported, and can be used to manipulate the final values. Here follows an example: +Otherwise you can define structured requests as described in the following paragraphs. Requests can be fine tuned to perform the exact tasks as desired. Nuclei requests are fully configurable meaning you can configure and define each and every single thing about the requests that will be sent to the target servers. A recent addition in raw requests has been the introduction of intruder-like functionalities. It's possible to define placeholders as `{{placeholder}}`, and perform Sniper, Pitchfork and ClusterBomb attacks. The wordlist for these attacks needs to be defined during the request definition under the `Payload` field. Finally all DSL functionalities are fully available and supported, and can be used to manipulate the final values. Here follows an example: ```yaml id: dummy-raw info: - name: Example-Fuzzing + name: Example-Fuzzing requests: - payloads: param_a: /home/user/wordlist_param_a.txt param_b: /home/user/wordlist_param_b.txt - attack: clusterbomb # sniper, pitchfork, clusterbomb + attack: clusterbomb # Available options: sniper, pitchfork and clusterbomb raw: # Request with simple param and header manipulation with DSL functions - - | + - | POST /?param_a={{param_a}}¶mb={{param_b}} HTTP/1.1 User-Agent: {{param_a}} Host: {{Hostname}} @@ -119,74 +117,72 @@ requests: This is the Body # Request with body manipulation - - | + - | DELETE / HTTP/1.1 User-Agent: nuclei Host: {{Hostname}} This is the body {{sha256(param_a)}} # Yet another one - - | + - | PUT / HTTP/1.1 Host: {{Hostname}} This is again the request body {{html_escape(param_a)}} + {{hex_encode(param_b))}} matchers: - type: word - words: + words: - "title" - "body" ``` This functionality is **not optimized** for speed as the internal http library needs to be set explicitly with connection reuse policy. -#### **Method** +#### Method -First thing in the request is **method**. Request method can be **GET**, **POST**, **PUT**, **DELETE**, etc depending on the needs. +First thing in the request is **method**. Request method can be **GET**, **POST**, **PUT**, **DELETE**, etc depending on the needs. ```yaml -# method is the method for the request +# Method is the method for the request method: GET ``` -#### **Redirects** +#### Redirects -Redirection conditions can be specified per each template. By default, redirects are not followed. However, if desired, they can be enabled with `redirects: true` in request details. 10 Redirects are followed at max by default which should be good enough for most use cases. More fine grained control can be excercised over number of redirects followed by using `max-redirects` field. +Redirection conditions can be specified per each template. By default, redirects are not followed. However, if desired, they can be enabled with `redirects: true` in request details. 10 redirects are followed at maximum by default which should be good enough for most use cases. More fine grained control can be exercised over number of redirects followed by using `max-redirects` field. -An example of the usage - +An example of the usage: ```yaml requests: - method: GET - path: + path: - "{{BaseURL}}/login.php redirects: true max-redirects: 3 ``` +#### Path -#### **Path** - -The next part of the requests is the **path** of the request path. Dynamic variables can be placed in the path to modify its behaviour on runtime. Variables start with `{{` and end with `}}` and are case-sensitive. +The next part of the requests is the **path** of the request path. Dynamic variables can be placed in the path to modify its behavior on runtime. Variables start with `{{` and end with `}}` and are case-sensitive. 1. **BaseURL** - Placing BaseURL as a variable in the path will lead to it being replaced on runtime in the request by the original URL as specified in the target file. 2. **Hostname** - Hostname variable is replaced by the hostname of the target on runtime. -Some sample dynamic variable replacement examples - +Some sample dynamic variable replacement examples: ```yaml path: {{BaseURL}}/.git/config -# this path will be replaced on execution with BaseURL -# When BaseURL = https://abc.com -# path will get replaced to the following - -https://abc.com/.git/config +# This path will be replaced on execution with BaseURL +# If BaseURL is set to https://abc.com then the +# path will get replaced to the following: https://abc.com/.git/config ``` Multiple paths can also be specified in one request which will be requested for the target. -#### **Headers** +#### Headers -Headers can also be specified to be sent along with the requests. Headers are placed in form of Key-Value pairs. An example header configuration is - +Headers can also be specified to be sent along with the requests. Headers are placed in form of key/value pairs. An example header configuration looks like this: ```yaml # headers contains the headers for the request @@ -197,22 +193,22 @@ headers: Origin: https://google.com ``` -#### **Body** +#### Body -Body specifies a body to be sent along with the request. For instance - +Body specifies a body to be sent along with the request. For instance: ```yaml -# body is a string sent along with the request -body: "{\"some random json\"}" +# Body is a string sent along with the request +body: "{\"some random JSON\"}" ``` -#### **Matchers** +#### Matchers -Matchers are the core of nuclei. They are what make the tool so powerful. Multiple type of combinations and checks can be added to ensure that the results you get are free from false positives. +Matchers are the core of nuclei. They are what make the tool so powerful. Multiple type of combinations and checks can be added to ensure that the results you get are free from false-positives. -##### **Types** +##### Types -Multiple matchers can be specified in a request. There are basically 6 types of matchers - +Multiple matchers can be specified in a request. There are basically 6 types of matchers: | Matcher Type | Part Matched | | ------------ | -------------------------- | @@ -227,9 +223,9 @@ To match status codes for responses, you can use the following syntax. ```yaml matcher: - # match the status codes + # Match the status codes - type: status - # some status codes we want to match + # Some status codes we want to match status: - 200 - 302 @@ -239,27 +235,27 @@ To match binary for hexadecimal responses, you can use the following syntax. ```yaml matchers: - - type: binary - binary: - - "504B0304" # zip - - "526172211A070100" # rar RAR archive version 5.0 - - "FD377A585A0000" # xz tar.xz - condition: or - part: body + - type: binary + binary: + - "504B0304" # zip archive + - "526172211A070100" # rar RAR archive version 5.0 + - "FD377A585A0000" # xz tar.xz archive + condition: or + part: body ``` To match size, similar structure can be followed. If the status code of response from the site matches any single one specified in the matcher, the request is marked as successful. -**Word** and **Regex** matchers can be further configured depending on the needs of the users. +**Word** and **Regex** matchers can be further configured depending on the needs of the users. -Complex matchers of type **Dsl** allows to build more elaborated expressions with helper functions, this is an example of a complex dsl matcher: +Complex matchers of type **dsl** allows to build more elaborated expressions with helper functions, this is an example of a complex DSL matcher: ```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 of cookies is contained in the uppercase body + - 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 http response can be matched: @@ -267,9 +263,9 @@ Every part of a http response can be matched: | Response Part | Description | Example | |------------------|-------------------------------------------------|---------------------------| | content_length | Header Content-Length | content_length >= 1024 | -| status_code | Respone Status Code | status_code==200 | +| status_code | Response Status Code | status_code==200 | | all_headers | Unique string containing all headers | len(all_headers) | -| body | Body as tring | len(body) | +| body | Body as string | len(body) | | header_name | Lowercase header name with "-" converted to "_" | len(user_agent) | | raw | Headers + Response | len(raw) | @@ -312,16 +308,16 @@ The helper functions are: | contains | Verify if a string contains another one | contains("Hello", "lo") // Result: True | | regex | Verify a regex versus a string | regex("H([a-z]+)o", "Hello") // Result: True | -##### **Conditions** +##### Conditions -Multiple words and regexes can be specified in a single matcher and can be configured with different conditions like **AND** and **OR**. +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** +##### Matched Parts -Multiple parts of the response can also be matched for the request. +Multiple parts of the response can also be matched for the request. | Part | Matched Part | | ------ | ------------------------------------ | @@ -329,57 +325,57 @@ Multiple parts of the response can also be matched for the request. | header | Header of the response | | all | Both body and header of the response | -Example matchers for response body using AND condition - +Example matchers for response body using the AND condition: ```yaml matcher: - # match the body word + # Match the body word - type: word - # some words we want to match - words: + # Some words we want to match + words: - "[core]" - "[config]" - # both words must be found in the response body + # Both words must be found in the response body condition: and - # we want to match request body (default) + # 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. -##### **Multiple Matchers** +##### Multiple Matchers -Multiple matchers can be used in a single template to fingerprint multiple conditions with a single request. +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: + - 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** +##### 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. +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 @@ -390,7 +386,7 @@ While using multiple matchers the default condition is to follow OR operation in - "PHPSESSID" condition: or part: header - + - type: word words: - "PHP" @@ -401,7 +397,7 @@ While using multiple matchers the default condition is to follow OR operation in Extractors are another important feature of nuclei. Extractors can be used to extract and display in results a match from the response body or headers based on a regular expression. -Currently only `regex` type extractors are supported. A sample extractor for extracting API keys from the response body is as follows - +Currently only `regex` type extractors are supported. A sample extractor for extracting API keys from the response body is as follows: ```yaml # A list of extractors for text extraction @@ -417,7 +413,7 @@ extractors: #### **Example HTTP Template** -The final template file for the `.git/config` file mentioned above is as follows - +The final template file for the `.git/config` file mentioned above is as follows: ```yaml id: git-config @@ -437,78 +433,77 @@ requests: - "[core]" ``` -### **DNS Requests** +### DNS Requests -Requests start with a dns block which specifies the start of the requests for the template. +Requests start with a dns block which specifies the start of the requests for the template. ```yaml -# start the requests for the template right here +# Start the requests for the template right here dns: ``` DNS requests can be fine tuned to perform the exact tasks as desired. Nuclei requests are fully configurable meaning you can configure and define each and every single thing about the requests that will be sent to the target servers. -#### **Type** +#### Type -First thing in the request is **type**. Request type can be **A**, **NS**, **CNAME**, **SOA**, **PTR**, **MX**, **TXT**, **AAAA**. +First thing in the request is **type**. Request type can be **A**, **NS**, **CNAME**, **SOA**, **PTR**, **MX**, **TXT**, **AAAA**. ```yaml # type is the type for the dns request type: A ``` -#### **Name** +#### Name -The next part of the requests is the **name** of the request path. Dynamic variables can be placed in the path to modify its value on runtime. Variables start with `{{` and end with `}}` and are case-sensitive. +The next part of the requests is the **name** of the request path. 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. **FQDN** - variable is replaced by the hostname/fqdn of the target on runtime. +1. **FQDN** - variable is replaced by the hostname/FQDN of the target on runtime. -Some sample dynamic variable replacement examples - +Some sample dynamic variable replacement examples: ```yaml name: {{FQDN}}.com -# this value will be replaced on execution with FQDN -# When FQDN = https://this.is.an.example -# name will get replaced to the following - -this.is.an.example.com +# This value will be replaced on execution with the FQDN. +# If FQDN is https://this.is.an.example then the +# name will get replaced to the following: this.is.an.example.com ``` As of now the tool supports only one question per request. -#### **Class** +#### Class -Class type can be **INET**, **CSNET**, **CHAOS**, **HESIOD**, **NONE**, **ANY**. Usually it's enough to just leave it as **INET** +Class type can be **INET**, **CSNET**, **CHAOS**, **HESIOD**, **NONE** and **ANY**. Usually it's enough to just leave it as **INET**. ```yaml # method is the class for the dns request class: inet ``` -#### **Recursion** +#### Recursion -Recursion is a boolean value, and determines if the resolver should only return cached results, or traverse the whole dns root tree to retrieve fresh results. Generally it's better to leave it as **true** +Recursion is a boolean value, and determines if the resolver should only return cached results, or traverse the whole dns root tree to retrieve fresh results. Generally it's better to leave it as **true**. ```yaml -# recursion is a boolean determining if the request is recursive +# Recursion is a boolean determining if the request is recursive recursion: true ``` -#### **Retries** +#### Retries -Retries is the number of attempts a dns query is retried before giving up among different resolvers. It's recommended a reasonable value, like **3**. +Retries is the number of attempts a dns query is retried before giving up among different resolvers. It's recommended a reasonable value, like **3**. ```yaml -# retries is a number of retries before giving up on dns resolution +# Retries is a number of retries before giving up on dns resolution retries: 3 ``` -#### **Matchers** +#### Matchers Matchers are just equal to HTTP, but the search is performed on the whole dns response, therefore it's not necessary to specify the **part**. Multiple type of combinations and checks can be added to ensure that the results you get are free from false positives. The complex **dsl** matcher type allows to build complex queries as described in the HTTP section. -##### **Types** +##### Types -Multiple matchers can be specified in a request. There are basically 5 types of matchers - +Multiple matchers can be specified in a request. There are basically 5 types of matchers: | Matcher Type | Part Matched | | ------------ | -------------------------- | @@ -520,7 +515,7 @@ Multiple matchers can be specified in a request. There are basically 5 types of ## **Example DNS Template** -The final example template file for performing `A` query, and check if CNAME and A records are in the response is as follows - +The final example template file for performing `A` query, and check if CNAME and A records are in the response is as follows: ```yaml id: dummy-cname-a @@ -531,12 +526,12 @@ info: severity: none dns: - - name: "{{FQDN}}" - type: A - class: inet - recursion: true - retries: 3 - matchers: + - name: "{{FQDN}}" + type: A + class: inet + recursion: true + retries: 3 + matchers: - type: word words: # The response must contains a CNAME record