Overview
The template flow engine was introduced in nuclei v3, and brings two significant enhancements to Nuclei:- The ability to conditionally execute requests
- The orchestration of request execution
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 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.eflow: http(1) && http(2)
and nuclei will take care of everything else.
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.
- 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
- Extract
- Bruteforce the request using all the domains found from the SSL request
ssl()
: This function executes the SSL request.template["ssl_domains"]
: Retrieves the value ofssl_domains
from the template context.iterate()
: Helper function that iterates over any value type while handling empty or null values.set("vhost", vhost)
: Creates a new variablevhost
in the template and assigns thevhost
variable’s value to it.http()
: This function conducts the HTTP request.
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:
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 theprotocol_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")
)
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 itSet 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 usingset()
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")
.
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 usingset()
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.
log()
function
Log Helper Function
It is a nuclei js alternative toconsole.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 inssl_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
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.
Skip Internal Matchers in MultiProtocol / Flow Templates
Before nuclei v3.1.4 , A template likeCVE-2023-43177
which has multiple requests/protocols and uses flow
for logic, used to only return one result but it conflicted with logic when for
loop was used in flow
to fix this nuclei engine from v3.1.4 will print all events/results in a template and template writers can use internal: true
in matchers to skip printing of events/results just like dynamic extractors.
Note: this is only relevant if matchers/extractors are used in previous requests/protocols
Example of CVE-2023-6553
with new internal: true
logic would be