How to Run Nuclei

Nuclei templates offer two primary execution methods:

Supported Input Formats

Nuclei supports various input formats to run template against, including urls, hosts, ips, cidrs, asn, openapi, swagger, proxify, burpsuite exported data and more. To learn more on using input specify options, you can refer nuclei input formats.

These inputs can be given to nuclei using -l and -input-mode flags.

  -l, -list string              path to file containing a list of target URLs/hosts to scan (one per line)
  -im, -input-mode string       mode of input file (list, burp, jsonl, yaml, openapi, swagger) (default "list")

Executing nuclei against a list of inputs (urls, hosts, ips, cidrs, asn) is as simple as running the following command:

  nuclei -l targets.txt

For running other input formats (burp, jsonl, yaml, openapi, swagger), you can use the -im flag to specify the input mode.

  nuclei -l targets.burp -im burp
  nuclei -l openapi.yaml -im openapi

and so on.

Executing Nuclei Templates

-t/templates

Default Templates

Most community templates from our nuclei-template repository are executed by default, directly from the standard installation path. The typical command is as follows:

nuclei -u https://example.com

However, there are some exceptions regarding the templates that run by default:

You can also run templates against a list of URLs:

nuclei -list http_urls.txt

Custom Templates

To run a custom template directory or multiple directories, use the following command structure:

nuclei -u https://example.com -t cves/ -t exposures/

Templates from custom GitHub repositories, stored under the github directory, can be executed with this command:

nuclei -u https://example.com -t github/private-repo

You can also directly run a template from any ProjectDiscovery Cloud Platform URL like this:

nuclei -u https://example.com -t https://cloud.projectdiscovery.io/public/tech-detect

Executing Template Workflows

-w/workflows

Workflows can be executed using the following command:

nuclei -u https://example.com -w workflows/

Similarly, Workflows can be executed against a list of URLs.

nuclei -list http_urls.txt -w workflows/wordpress-workflow.yaml

Types of Templates

Template Filters

Nuclei engine supports three basic filters to customize template execution.

  1. Tags (-tags)

    Filter based on tags field available in the template.

  2. Severity (-severity)

    Filter based on severity field available in the template.

  3. Author (-author)

    Filter based on author field available in the template.

As default, Filters are applied on installed path of templates and can be customized with manual template path input.

For example, below command will run all the templates installed at ~/nuclei-templates/ directory and has cve tags in it.

nuclei -u https://example.com -tags cve

And this example will run all the templates available under ~/nuclei-templates/exposures/ directory and has config tag in it.

nuclei -u https://example.com -tags config -t exposures/

Multiple filters works together with AND condition, below example runs all templates with cve tags AND has critical OR high severity AND geeknik as author of template.

nuclei -u https://example.com -tags cve -severity critical,high -author geeknik

Advanced Filters

Multiple filters can also be combined using the template condition flag (-tc) that allows complex expressions like the following ones:

nuclei -tc "contains(id,'xss') || contains(tags,'xss')"
nuclei -tc "contains(tags,'cve') && contains(tags,'ssrf')"
nuclei -tc "contains(name, 'Local File Inclusion')"

The supported fields are:

  • id string
  • name string
  • description string
  • tags slice of strings
  • authors slice of strings
  • severity string
  • protocol string
  • http_method slice of strings
  • body string (containing all request bodies if any)
  • matcher_type slice of string
  • extractor_type slice of string
  • description string

Also, every key-value pair from the template metadata section is accessible. All fields can be combined with logical operators (|| and &&) and used with DSL helper functions.

Similarly, all filters are supported in workflows as well.

nuclei -w workflows/wordpress-workflow.yaml -severity critical,high -list http_urls.txt

Workflows

In Workflows, Nuclei filters are applied on templates or sub-templates running via workflows, not on the workflows itself.

Public Templates

Nuclei has built-in support for automatic template download/update from nuclei templates project which provides community-contributed list of ready-to-use templates that is constantly updated.

Nuclei checks for new community template releases upon each execution and automatically downloads the latest version when available. optionally, this feature can be disabled using the -duc cli flag or the configuration file.

Custom Templates

Users can create custom templates on a personal public / private GitHub / AWS Bucket that they wish to run / update while using nuclei from any environment without manually downloading the GitHub repository everywhere.

To use this feature, users need to set the following environment variables:

Environment variables can also be provided to disable download from default and custom template locations:

# Disable download from the default nuclei-templates project
export DISABLE_NUCLEI_TEMPLATES_PUBLIC_DOWNLOAD=true

# Disable download from public / private GitHub project(s)
export DISABLE_NUCLEI_TEMPLATES_GITHUB_DOWNLOAD=true

# Disable download from public / private GitLab project(s)
export DISABLE_NUCLEI_TEMPLATES_GITLAB_DOWNLOAD=true

# Disable download from public / private AWS Bucket(s)
export DISABLE_NUCLEI_TEMPLATES_AWS_DOWNLOAD=true

# Disable download from public / private Azure Blob Storage
export DISABLE_NUCLEI_TEMPLATES_AZURE_DOWNLOAD=true

Once the environment variables are set, following command to download the custom templates:

nuclei -update-templates

This command will clone the repository containing the custom templates to the default nuclei templates directory ($HOME/nuclei-templates/github/).

The directory structure of the custom templates looks as follows:

tree $HOME/nuclei-templates/

nuclei-templates/
└── github/$GH_REPO_NAME # Custom templates downloaded from public / private GitHub project
└── gitlab/$GL_REPO_NAME # Custom templates downloaded from public / private GitLab project
└── s3/$BUCKET_NAME # Custom templates downloaded from public / private AWS Bucket
└── azure/$CONTAINER_NAME # Custom templates downloaded from public / private Azure Blob Storage

Users can then use the custom templates with the -t flag as follows:

nuclei -t github/my_custom_template -u https://example.com

The nuclei engine can be updated to latest version by using the -update flag.

Writing your own unique templates will always keep you one step ahead of others.

Nuclei Flags

nuclei -h

This will display help for the tool. Here are all the switches it supports.

Nuclei is a fast, template based vulnerability scanner focusing
on extensive configurability, massive extensibility and ease of use.

Usage:
  nuclei [flags]

Flags:
TARGET:
   -u, -target string[]          target URLs/hosts to scan
   -l, -list string              path to file containing a list of target URLs/hosts to scan (one per line)
   -eh, -exclude-hosts string[]  hosts to exclude to scan from the input list (ip, cidr, hostname)
   -resume string                resume scan using resume.cfg (clustering will be disabled)
   -sa, -scan-all-ips            scan all the IP's associated with dns record
   -iv, -ip-version string[]     IP version to scan of hostname (4,6) - (default 4)

TARGET-FORMAT:
   -im, -input-mode string        mode of input file (list, burp, jsonl, yaml, openapi, swagger) (default "list")
   -ro, -required-only            use only required fields in input format when generating requests
   -sfv, -skip-format-validation  skip format validation (like missing vars) when parsing input file

TEMPLATES:
   -nt, -new-templates                    run only new templates added in latest nuclei-templates release
   -ntv, -new-templates-version string[]  run new templates added in specific version
   -as, -automatic-scan                   automatic web scan using wappalyzer technology detection to tags mapping
   -t, -templates string[]                list of template or template directory to run (comma-separated, file)
   -turl, -template-url string[]          template url or list containing template urls to run (comma-separated, file)
   -w, -workflows string[]                list of workflow or workflow directory to run (comma-separated, file)
   -wurl, -workflow-url string[]          workflow url or list containing workflow urls to run (comma-separated, file)
   -validate                              validate the passed templates to nuclei
   -nss, -no-strict-syntax                disable strict syntax check on templates
   -td, -template-display                 displays the templates content
   -tl                                    list all available templates
   -sign                                  signs the templates with the private key defined in NUCLEI_SIGNATURE_PRIVATE_KEY env variable
   -code                                  enable loading code protocol-based templates
   -dut, -disable-unsigned-templates      disable running unsigned templates or templates with mismatched signature

FILTERING:
   -a, -author string[]               templates to run based on authors (comma-separated, file)
   -tags string[]                     templates to run based on tags (comma-separated, file)
   -etags, -exclude-tags string[]     templates to exclude based on tags (comma-separated, file)
   -itags, -include-tags string[]     tags to be executed even if they are excluded either by default or configuration
   -id, -template-id string[]         templates to run based on template ids (comma-separated, file, allow-wildcard)
   -eid, -exclude-id string[]         templates to exclude based on template ids (comma-separated, file)
   -it, -include-templates string[]   path to template file or directory to be executed even if they are excluded either by default or configuration
   -et, -exclude-templates string[]   path to template file or directory to exclude (comma-separated, file)
   -em, -exclude-matchers string[]    template matchers to exclude in result
   -s, -severity value[]              templates to run based on severity. Possible values: info, low, medium, high, critical, unknown
   -es, -exclude-severity value[]     templates to exclude based on severity. Possible values: info, low, medium, high, critical, unknown
   -pt, -type value[]                 templates to run based on protocol type. Possible values: dns, file, http, headless, tcp, workflow, ssl, websocket, whois, code, javascript
   -ept, -exclude-type value[]        templates to exclude based on protocol type. Possible values: dns, file, http, headless, tcp, workflow, ssl, websocket, whois, code, javascript
   -tc, -template-condition string[]  templates to run based on expression condition

OUTPUT:
   -o, -output string            output file to write found issues/vulnerabilities
   -sresp, -store-resp           store all request/response passed through nuclei to output directory
   -srd, -store-resp-dir string  store all request/response passed through nuclei to custom directory (default "output")
   -silent                       display findings only
   -nc, -no-color                disable output content coloring (ANSI escape codes)
   -j, -jsonl                    write output in JSONL(ines) format
   -irr, -include-rr -omit-raw   include request/response pairs in the JSON, JSONL, and Markdown outputs (for findings only) [DEPRECATED use -omit-raw] (default true)
   -or, -omit-raw                omit request/response pairs in the JSON, JSONL, and Markdown outputs (for findings only)
   -ot, -omit-template           omit encoded template in the JSON, JSONL output
   -nm, -no-meta                 disable printing result metadata in cli output
   -ts, -timestamp               enables printing timestamp in cli output
   -rdb, -report-db string       nuclei reporting database (always use this to persist report data)
   -ms, -matcher-status          display match failure status
   -me, -markdown-export string  directory to export results in markdown format
   -se, -sarif-export string     file to export results in SARIF format
   -je, -json-export string      file to export results in JSON format
   -jle, -jsonl-export string    file to export results in JSONL(ine) format

CONFIGURATIONS:
   -config string                        path to the nuclei configuration file
   -fr, -follow-redirects                enable following redirects for http templates
   -fhr, -follow-host-redirects          follow redirects on the same host
   -mr, -max-redirects int               max number of redirects to follow for http templates (default 10)
   -dr, -disable-redirects               disable redirects for http templates
   -rc, -report-config string            nuclei reporting module configuration file
   -H, -header string[]                  custom header/cookie to include in all http request in header:value format (cli, file)
   -V, -var value                        custom vars in key=value format
   -r, -resolvers string                 file containing resolver list for nuclei
   -sr, -system-resolvers                use system DNS resolving as error fallback
   -dc, -disable-clustering              disable clustering of requests
   -passive                              enable passive HTTP response processing mode
   -fh2, -force-http2                    force http2 connection on requests
   -ev, -env-vars                        enable environment variables to be used in template
   -cc, -client-cert string              client certificate file (PEM-encoded) used for authenticating against scanned hosts
   -ck, -client-key string               client key file (PEM-encoded) used for authenticating against scanned hosts
   -ca, -client-ca string                client certificate authority file (PEM-encoded) used for authenticating against scanned hosts
   -sml, -show-match-line                show match lines for file templates, works with extractors only
   -ztls                                 use ztls library with autofallback to standard one for tls13 [Deprecated] autofallback to ztls is enabled by default
   -sni string                           tls sni hostname to use (default: input domain name)
   -dt, -dialer-timeout value            timeout for network requests.
   -dka, -dialer-keep-alive value        keep-alive duration for network requests.
   -lfa, -allow-local-file-access        allows file (payload) access anywhere on the system
   -lna, -restrict-local-network-access  blocks connections to the local / private network
   -i, -interface string                 network interface to use for network scan
   -at, -attack-type string              type of payload combinations to perform (batteringram,pitchfork,clusterbomb)
   -sip, -source-ip string               source ip address to use for network scan
   -rsr, -response-size-read int         max response size to read in bytes (default 10485760)
   -rss, -response-size-save int         max response size to read in bytes (default 1048576)
   -reset                                reset removes all nuclei configuration and data files (including nuclei-templates)
   -tlsi, -tls-impersonate               enable experimental client hello (ja3) tls randomization

INTERACTSH:
   -iserver, -interactsh-server string  interactsh server url for self-hosted instance (default: oast.pro,oast.live,oast.site,oast.online,oast.fun,oast.me)
   -itoken, -interactsh-token string    authentication token for self-hosted interactsh server
   -interactions-cache-size int         number of requests to keep in the interactions cache (default 5000)
   -interactions-eviction int           number of seconds to wait before evicting requests from cache (default 60)
   -interactions-poll-duration int      number of seconds to wait before each interaction poll request (default 5)
   -interactions-cooldown-period int    extra time for interaction polling before exiting (default 5)
   -ni, -no-interactsh                  disable interactsh server for OAST testing, exclude OAST based templates

FUZZING:
   -ft, -fuzzing-type string  overrides fuzzing type set in template (replace, prefix, postfix, infix)
   -fm, -fuzzing-mode string  overrides fuzzing mode set in template (multiple, single)
   -fuzz                      enable loading fuzzing templates

UNCOVER:
   -uc, -uncover                  enable uncover engine
   -uq, -uncover-query string[]   uncover search query
   -ue, -uncover-engine string[]  uncover search engine (shodan,censys,fofa,shodan-idb,quake,hunter,zoomeye,netlas,criminalip,publicwww,hunterhow) (default shodan)
   -uf, -uncover-field string     uncover fields to return (ip,port,host) (default "ip:port")
   -ul, -uncover-limit int        uncover results to return (default 100)
   -ur, -uncover-ratelimit int    override ratelimit of engines with unknown ratelimit (default 60 req/min) (default 60)

RATE-LIMIT:
   -rl, -rate-limit int               maximum number of requests to send per second (default 150)
   -rlm, -rate-limit-minute int       maximum number of requests to send per minute
   -bs, -bulk-size int                maximum number of hosts to be analyzed in parallel per template (default 25)
   -c, -concurrency int               maximum number of templates to be executed in parallel (default 25)
   -hbs, -headless-bulk-size int      maximum number of headless hosts to be analyzed in parallel per template (default 10)
   -headc, -headless-concurrency int  maximum number of headless templates to be executed in parallel (default 10)
   -jsc, -js-concurrency int          maximum number of javascript runtimes to be executed in parallel (default 120)
   -pc, -payload-concurrency int      max payload concurrency for each template (default 25)

OPTIMIZATIONS:
   -timeout int                     time to wait in seconds before timeout (default 10)
   -retries int                     number of times to retry a failed request (default 1)
   -ldp, -leave-default-ports       leave default HTTP/HTTPS ports (eg. host:80,host:443)
   -mhe, -max-host-error int        max errors for a host before skipping from scan (default 30)
   -te, -track-error string[]       adds given error to max-host-error watchlist (standard, file)
   -nmhe, -no-mhe                   disable skipping host from scan based on errors
   -project                         use a project folder to avoid sending same request multiple times
   -project-path string             set a specific project path 
   -spm, -stop-at-first-match       stop processing HTTP requests after the first match (may break template/workflow logic)
   -stream                          stream mode - start elaborating without sorting the input
   -ss, -scan-strategy value        strategy to use while scanning(auto/host-spray/template-spray) (default auto)
   -irt, -input-read-timeout value  timeout on input read (default 3m0s)
   -nh, -no-httpx                   disable httpx probing for non-url input
   -no-stdin                        disable stdin processing

HEADLESS:
   -headless                        enable templates that require headless browser support (root user on Linux will disable sandbox)
   -page-timeout int                seconds to wait for each page in headless mode (default 20)
   -sb, -show-browser               show the browser on the screen when running templates with headless mode
   -ho, -headless-options string[]  start headless chrome with additional options
   -sc, -system-chrome              use local installed Chrome browser instead of nuclei installed
   -lha, -list-headless-action      list available headless actions

DEBUG:
   -debug                    show all requests and responses
   -dreq, -debug-req         show all sent requests
   -dresp, -debug-resp       show all received responses
   -p, -proxy string[]       list of http/socks5 proxy to use (comma separated or file input)
   -pi, -proxy-internal      proxy all internal requests
   -ldf, -list-dsl-function  list all supported DSL function signatures
   -tlog, -trace-log string  file to write sent requests trace log
   -elog, -error-log string  file to write sent requests error log
   -version                  show nuclei version
   -hm, -hang-monitor        enable nuclei hang monitoring
   -v, -verbose              show verbose output
   -profile-mem string       optional nuclei memory profile dump file
   -vv                       display templates loaded for scan
   -svd, -show-var-dump      show variables dump for debugging
   -ep, -enable-pprof        enable pprof debugging server
   -tv, -templates-version   shows the version of the installed nuclei-templates
   -hc, -health-check        run diagnostic check up

UPDATE:
   -up, -update                      update nuclei engine to the latest released version
   -ut, -update-templates            update nuclei-templates to latest released version
   -ud, -update-template-dir string  custom directory to install / update nuclei-templates
   -duc, -disable-update-check       disable automatic nuclei/templates update check

STATISTICS:
   -stats                    display statistics about the running scan
   -sj, -stats-json          display statistics in JSONL(ines) format
   -si, -stats-interval int  number of seconds to wait between showing a statistics update (default 5)
   -mp, -metrics-port int    port to expose nuclei metrics on (default 9092)

CLOUD:
   -auth                  configure projectdiscovery cloud (pdcp) api key (default true)
   -cup, -cloud-upload    upload scan results to pdcp dashboard
   -sid, -scan-id string  upload scan results to given scan id

AUTHENTICATION:
   -sf, -secret-file string[]  path to config file containing secrets for nuclei authenticated scan
   -ps, -prefetch-secrets      prefetch secrets from the secrets file

From Nuclei v3.0.0 -metrics port has been removed and merged with -stats when using -stats flag metrics will be by default available at localhost:9092/metrics and metrics-port can be configured by -metrics-port flag

Rate Limits

Nuclei have multiple rate limit controls for multiple factors, including a number of templates to execute in parallel, a number of hosts to be scanned in parallel for each template, and the global number of request / per second you wanted to make/limit using nuclei, here is an example of each flag with description.

FlagDescription
rate-limitControl the total number of request to send per seconds
bulk-sizeControl the number of hosts to process in parallel for each template
cControl the number of templates to process in parallel

Feel free to play with these flags to tune your nuclei scan speed and accuracy. For more details on tuning these flag, you can refer mass-scanning-cli

rate-limit flag takes precedence over the other two flags, the number of requests/seconds can’t go beyond the value defined for rate-limit flag regardless the value of c and bulk-size flag.

Traffic Tagging

Many BugBounty platform/programs requires you to identify the HTTP traffic you make, this can be achieved by setting custom header using config file at $HOME/.config/nuclei/config.yaml or CLI flag -H / header

Setting custom header using config file

# Headers to include with each request.
header:
  - 'X-BugBounty-Hacker: h1/geekboy'
  - 'User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) / nuclei'

Setting custom header using CLI flag

nuclei -header 'User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) / nuclei' -list urls.txt -tags cves

Template Exclusion

Nuclei supports a variety of methods for excluding / blocking templates from execution. By default, nuclei excludes the tags/templates listed below from execution to avoid unexpected fuzz based scans and some that are not supposed to run for mass scan, and these can be easily overwritten with nuclei configuration file / flags.

Nuclei engine supports two ways to manually exclude templates from scan,

  1. Exclude Templates (-exclude-templates/exclude)

    exclude-templates flag is used to exclude single or multiple templates and directory, multiple -exclude-templates flag can be used to provide multiple values.

  2. Exclude Tags (-exclude-tags/etags)

    exclude-tags flag is used to exclude templates based in defined tags, single or multiple can be used to exclude templates.

Example of excluding single template

nuclei -list urls.txt -t cves/ -exclude-templates cves/2020/CVE-2020-XXXX.yaml

Example of multiple template exclusion

nuclei -list urls.txt -exclude-templates exposed-panels/ -exclude-templates technologies/

Example of excluding templates with single tag

nuclei -l urls.txt -t cves/ -etags xss

Example of excluding templates with multiple tags

nuclei -l urls.txt -t cves/ -etags sqli,rce
  • .nuclei-ignore list - default list of tags and templates excluded from nuclei scan as default.

.nuclei-ignore file is not supposed to be modified by user, as it gets used by nuclei internally, to overwrite ignore list, utilize nuclei configuration file.

To prioritize certain templates or tags over the .nuclei-ignore file or denylist, you must use the -include-templates or -include-tags flags. This will ensure that the specified templates or tags take precedence over any .nuclei-ignore or denylist entries.

Example of running blocked templates

nuclei -l urls.txt -include-tags iot,misc,fuzz

Example of executing a specific template that is in the denylist

Say that you have custom templates globbed (*) in the denylist on the Nuclei configuration file.

# ...

exclude-templates:
  - 'custom/**/*.yaml'

But you just want to execute a specific template.

nuclei -l urls.txt -include-templates custom/specific-template.yaml

List Template Path

-tl option in Nuclei is used to list the paths of templates, rather than executing them. This can help you inspect which templates would be used for scan given your current template filter.

# Command to list templates (-tl)
nuclei -tags cve -severity critical,high -author geeknik -tl

Scan on internet database

Nuclei supports integration with uncover module that supports services like Shodan, Censys, Hunter, Zoomeye, many more to execute Nuclei on these databases.

Here are uncover options to use -

nuclei -h uncover

UNCOVER:
   -uc, -uncover                  enable uncover engine
   -uq, -uncover-query string[]   uncover search query
   -ue, -uncover-engine string[]  uncover search engine (shodan,shodan-idb,fofa,censys,quake,hunter,zoomeye,netlas,criminalip) (default shodan)
   -uf, -uncover-field string     uncover fields to return (ip,port,host) (default "ip:port")
   -ul, -uncover-limit int        uncover results to return (default 100)
   -ucd, -uncover-delay int       delay between uncover query requests in seconds (0 to disable) (default 1)

You need to set the API key of the engine you are using as an environment variable in your shell.

export SHODAN_API_KEY=xxx
export CENSYS_API_ID=xxx
export CENSYS_API_SECRET=xxx
export FOFA_EMAIL=xxx
export FOFA_KEY=xxx
export QUAKE_TOKEN=xxx
export HUNTER_API_KEY=xxx
export ZOOMEYE_API_KEY=xxx

Required API keys can be obtained by signing up on following platform Shodan, Censys, Fofa, Quake, Hunter and ZoomEye .

Example of template execution using a search query.

export SHODAN_API_KEY=xxx
nuclei -id 'CVE-2021-26855' -uq 'vuln:CVE-2021-26855' -ue shodan

It can also read queries from templates metadata and execute template against hosts returned by uncover for that query.

Example of template execution using template-defined search queries.

Template snippet of CVE-2021-26855

metadata:
  shodan-query: 'vuln:CVE-2021-26855'
nuclei -t cves/2021/CVE-2021-26855.yaml -uncover
nuclei -tags cve -uncover

We can update the nuclei configuration file to include these tags for all scans.

Nuclei Config

Since release of v2.3.2 nuclei uses goflags for clean CLI experience and long/short formatted flags.

goflags comes with auto-generated config file support that coverts all available CLI flags into config file, basically you can define all CLI flags into config file to avoid repetitive CLI flags that loads as default for every scan of nuclei.

Default path of nuclei config file is $HOME/.config/nuclei/config.yaml, uncomment and configure the flags you wish to run as default.

Here is an example config file:

# Headers to include with all HTTP request
header:
  - 'X-BugBounty-Hacker: h1/geekboy'

# Directory based template execution
templates:
  - cves/
  - vulnerabilities/
  - misconfiguration/

# Tags based template execution
tags: exposures,cve

# Template Filters
tags: exposures,cve
author: geeknik,pikpikcu,dhiyaneshdk
severity: critical,high,medium

# Template Allowlist
# 
# Note: This will take precedence over the .nuclei-ignore file and denylist
# entries (exclude-tags or exclude-templates list).
include-tags: dos,fuzz # Tag based inclusion
include-templates: # Template based inclusion
  - vulnerabilities/xxx
  - misconfiguration/xxxx

# Template Denylist
exclude-tags: info # Tag based exclusion
exclude-templates: # Template based exclusion
  - vulnerabilities/xxx
  - misconfiguration/xxxx

# Rate Limit configuration
rate-limit: 500
bulk-size: 50
concurrency: 50

Once configured, config file be used as default, additionally custom config file can be also provided using -config flag.

Running nuclei with custom config file

nuclei -config project.yaml -list urls.txt

Nuclei Result Dashboard

Nuclei now allows seamless integration with the ProjectDiscovery Cloud Platform to simplify the visualization of Nuclei results and generate swift reports. This highly requested feature from the community enables easier handling of scan results with minimal effort.

Follow the steps below to set up your PDCP Result Dashboard:

  1. Visit https://cloud.projectdiscovery.io to create free PDCP API key.
  1. Use the nuclei -auth command, enter your API key when prompted.
  2. To perform a scan and upload the results straight to the cloud, use the -cloud-upload option while running a nuclei scan.

An example command might look like this:

nuclei -target http://honey.scanme.sh -cloud-upload

And the output would be like this:

                     __     _
   ____  __  _______/ /__  (_)
  / __ \/ / / / ___/ / _ \/ /
 / / / / /_/ / /__/ /  __/ /
/_/ /_/\__,_/\___/_/\___/_/   v3.1.0

      projectdiscovery.io

[INF] Current nuclei version: v3.1.0 (latest)
[INF] Current nuclei-templates version: v9.6.9 (latest)
[INF] To view results on cloud dashboard, visit https://cloud.projectdiscovery.io/scans upon scan completion.
[INF] New templates added in latest release: 73
[INF] Templates loaded for current scan: 71
[INF] Executing 71 signed templates from projectdiscovery/nuclei-templates
[INF] Targets loaded for current scan: 1
[INF] Using Interactsh Server: oast.live
[CVE-2017-9506] [http] [medium] http://honey.scanme.sh/plugins/servlet/oauth/users/icon-uri?consumerUri=http://clk37fcdiuf176s376hgjzo3xsoq5bdad.oast.live
[CVE-2019-9978] [http] [medium] http://honey.scanme.sh/wp-admin/admin-post.php?swp_debug=load_options&swp_url=http://clk37fcdiuf176s376hgyk9ppdqe9a83z.oast.live
[CVE-2019-8451] [http] [medium] http://honey.scanme.sh/plugins/servlet/gadgets/makeRequest
[CVE-2015-8813] [http] [high] http://honey.scanme.sh/Umbraco/feedproxy.aspx?url=http://clk37fcdiuf176s376hgj885caqoc713k.oast.live
[CVE-2020-24148] [http] [critical] http://honey.scanme.sh/wp-admin/admin-ajax.php?action=moove_read_xml
[CVE-2020-5775] [http] [medium] http://honey.scanme.sh/external_content/retrieve/oembed?endpoint=http://clk37fcdiuf176s376hgyyxa48ih7jep5.oast.live&url=foo
[CVE-2020-7796] [http] [critical] http://honey.scanme.sh/zimlet/com_zimbra_webex/httpPost.jsp?companyId=http://clk37fcdiuf176s376hgi9b8sd33se5sr.oast.live%23
[CVE-2017-18638] [http] [high] http://honey.scanme.sh/composer/send_email?to=hVsp@XOvw&url=http://clk37fcdiuf176s376hgyf8y81i9oju3e.oast.live
[CVE-2018-15517] [http] [high] http://honey.scanme.sh/index.php/System/MailConnect/host/clk37fcdiuf176s376hgi5j3fsht3dchj.oast.live/port/80/secure/
[CVE-2021-45967] [http] [critical] http://honey.scanme.sh/services/pluginscript/..;/..;/..;/getFavicon?host=clk37fcdiuf176s376hgh1y3xjzb3yjpy.oast.live
[CVE-2021-26855] [http] [critical] http://honey.scanme.sh/owa/auth/x.js
[INF] Scan results uploaded! View them at https://cloud.projectdiscovery.io/scans/clk37krsr14s73afc3ag

After the scan, a URL will be displayed on the command line interface. Visit this URL to check your results on the Cloud Dashboard.

Advanced Integration Options

Setting API key via environment variable

Avoid entering your API key via interactive prompt by setting it via environment variable.

export PDCP_API_KEY=XXXX-XXXX

Enabling result upload by default

If you want all your scans to automatically upload results to the cloud, enable the ENABLE_CLOUD_UPLOAD environment variable.

export ENABLE_CLOUD_UPLOAD=true

Disabling cloud upload warnings

To suppress warnings about result uploads, disable the DISABLE_CLOUD_UPLOAD_WRN environment variable.

export DISABLE_CLOUD_UPLOAD_WRN=true

Your configured PDCP API key stored in $HOME/.pdcp/credentials.yaml

Nuclei OSS results uploaded to the cloud platform are scheduled for automatic cleanup after 30 days, although this duration is subject to change as we gauge user feedback and requirement.

Nuclei Reporting

Nuclei comes with reporting module support with the release of v2.3.0 supporting GitHub, GitLab, and Jira integration, this allows nuclei engine to create automatic tickets on the supported platform based on found results.

PlatformGitHubGitLabJiraMarkdownSARIFElasticsearchSplunk HECMongoDB
Support

-rc, -report-config flag can be used to provide a config file to read configuration details of the platform to integrate. Here is an example config file for all supported platforms.

For example, to create tickets on GitHub, create a config file with the following content and replace the appropriate values:

# GitHub contains configuration options for GitHub issue tracker

github:
  username: '$user'
  owner: '$user'
  token: '$token'
  project-name: 'testing-project'
  issue-label: 'Nuclei'
  duplicate-issue-check: true

Alternatively if you use GitLab, create a config file following content and replace the appropriate values:

# GitLab contains configuration options for GitLab issue tracker

gitlab:
  username: '$user'
  base-url: 'gitlab.com'
  token: '$token'
  project-name: 'testing-project'
  issue-label: 'nuclei-label'
  severity-as-label: true
  duplicate-issue-check: true

To store results in Elasticsearch, create a config file with the following content and replace the appropriate values:

# elasticsearch contains configuration options for elasticsearch exporter
elasticsearch:
  # IP for elasticsearch instance
  ip: 127.0.0.1
  # Port is the port of elasticsearch instance
  port: 9200
  # IndexName is the name of the elasticsearch index
  index-name: nuclei

To forward results to Splunk HEC, create a config file with the following content and replace the appropriate values:

# splunkhec contains configuration options for splunkhec exporter
splunkhec:
  # Hostname for splunkhec instance
  host: '$hec_host'
  # Port is the port of splunkhec instance
  port: 8088
  # IndexName is the name of the splunkhec index
  index-name: nuclei
  # SSL enables ssl for splunkhec connection
  ssl: true
  # SSLVerification disables SSL verification for splunkhec
  ssl-verification: true
  # HEC Token for the splunkhec instance
  token: '$hec_token'

To forward results to Jira, create a config file with the following content and replace the appropriate values:

The Jira reporting options allows for custom fields, as well as using variables from the Nuclei templates in those custom fields. The supported variables currently are: $CVSSMetrics, $CVEID, $CWEID, $Host, $Severity, $CVSSScore, $Name

In addition, Jira is strict when it comes to custom field entry. If the field is a dropdown, Jira accepts only the case sensitive specific string and the API call is slightly different. To support this, there are three types of customfields.

  • name is the dropdown value
  • id is the ID value of the dropdown
  • freeform is if the customfield the entry of any value

To avoid duplication, the JQL query run can be slightly modified by the config file. The CLOSED_STATUS can be changed in the Jira template file using the status-not variable. summary ~ TEMPLATE_NAME AND summary ~ HOSTNAME AND status != CLOSED_STATUS

jira:
  # cloud is the boolean which tells if Jira instance is running in the cloud or on-prem version is used
  cloud: true
  # update-existing is the boolean which tells if the existing, opened issue should be updated or new one should be created
  update-existing: false
  # URL is the jira application url
  url: https://localhost/jira
  # account-id is the account-id of the Jira user or username in case of on-prem Jira
  account-id: test-account-id
  # email is the email of the user for Jira instance
  email: test@test.com
  # token is the token for Jira instance or password in case of on-prem Jira
  token: test-token
  #project-name is the name of the project.
  project-name: test-project-name
  #issue-type is the name of the created issue type (case sensitive)
  issue-type: Bug
  # SeverityAsLabel (optional) sends the severity as the label of the created issue
  # User custom fields for Jira Cloud instead
  severity-as-label: true
  # Whatever your final status is that you want to use as a closed ticket - Closed, Done, Remediated, etc
  # When checking for duplicates, the JQL query will filter out status's that match this.
  # If it finds a match _and_ the ticket does have this status, a new one will be created.
  status-not: Closed
  # Customfield supports name, id and freeform. name and id are to be used when the custom field is a dropdown.
  # freeform can be used if the custom field is just a text entry
  # Variables can be used to pull various pieces of data from the finding itself.
  # Supported variables: $CVSSMetrics, $CVEID, $CWEID, $Host, $Severity, $CVSSScore, $Name
  custom_fields:
    customfield_00001:
      name: 'Nuclei'
    customfield_00002:
      freeform: $CVSSMetrics
    customfield_00003:
      freeform: $CVSSScore

To write results to a MongoDB database collection, update the config file with the connection information.

mongodb:
  # the connection string to the MongoDB database
  # (e.g., mongodb://root:example@localhost:27017/nuclei?ssl=false&authSource=admin)
  connection-string: ""
  # the name of the collection to store the issues
  collection-name: ""
  # excludes the Request and Response from the results (helps with filesize)
  omit-raw: false
  # determines the number of results to be kept in memory before writing it to the database or 0 to
  # persist all in memory and write all results at the end (default)
  batch-size: 0

Running nuclei with reporting module:

nuclei -l urls.txt -t cves/ -rc issue-tracker.yaml

Similarly, other platforms can be configured. Reporting module also supports basic filtering and duplicate checks to avoid duplicate ticket creation.

allow-list:
  severity: high,critical

This will ensure to only creating tickets for issues identified with high and critical severity; similarly, deny-list can be used to exclude issues with a specific severity.

If you are running periodic scans on the same assets, you might want to consider -rdb, -report-db flag that creates a local copy of the valid findings in the given directory utilized by reporting module to compare and create tickets for unique issues only.

nuclei -l urls.txt -t cves/ -rc issue-tracker.yaml -rdb prod

Markdown Export

Nuclei supports markdown export of valid findings with -me, -markdown-export flag, this flag takes directory as input to store markdown formatted reports.

Including request/response in the markdown report is optional, and included when -irr, -include-rr flag is used along with -me.

nuclei -l urls.txt -t cves/ -irr -markdown-export reports

SARIF Export

Nuclei supports SARIF export of valid findings with -se, -sarif-export flag. This flag takes a file as input to store SARIF formatted report.

nuclei -l urls.txt -t cves/ -sarif-export report.sarif

It is also possible to visualize Nuclei results using SARIF files.

  1. By uploading a SARIF file to SARIF Viewer

  2. By uploading a SARIF file to Github Actions

More info on the SARIF output is documented here.

These are not official viewers of Nuclei and Nuclei has no liability towards any of these options to visualize Nuclei results. These are just some publicly available options to visualize SARIF files.

Scan Metrics

Nuclei expose running scan metrics on a local port 9092 when -metrics flag is used and can be accessed at localhost:9092/metrics, default port to expose scan information is configurable using -metrics-port flag.

Here is an example to query metrics while running nuclei as following nuclei -t cves/ -l urls.txt -metrics

curl -s localhost:9092/metrics | jq .
{
  "duration": "0:00:03",
  "errors": "2",
  "hosts": "1",
  "matched": "0",
  "percent": "99",
  "requests": "350",
  "rps": "132",
  "startedAt": "2021-03-27T18:02:18.886745+05:30",
  "templates": "256",
  "total": "352"
}

Passive Scan

Nuclei engine supports passive mode scanning for HTTP based template utilizing file support, with this support we can run HTTP based templates against locally stored HTTP response data collected from any other tool.

nuclei -passive -target http_data
Passive mode support is limited for templates having {{BasedURL}} or {{BasedURL/}} as base path.

Running With Docker

If Nuclei was installed within a Docker container based on the installation instructions, the executable does not have the context of the host machine. This means that the executable will not be able to access local files such as those used for input lists or templates. To resolve this, the container should be run with volumes mapped to the local filesystem to allow access to these files.

Basic Usage

This example runs a Nuclei container against google.com, prints the results to JSON and removes the container once it has completed:

docker run --rm projectdiscovery/nuclei -u google.com -jsonl

Using Volumes

This example runs a Nuclei container against a list of URLs, writes the results to a .jsonl file and removes the container once it has completed.

# This assumes there's a file called `urls.txt` in the current directory
docker run --rm -v ./:/app/ projectdiscovery/nuclei -l /app/urls.txt -jsonl /app/results.jsonl
# The results will be written to `./results.jsonl` on the host machine once the container has completed