├── .github
├── ISSUE_TEMPLATE
│ ├── bug-report.yml
│ ├── config.yml
│ └── feature-request.yml
├── PULL_REQUEST_TEMPLATE.md
├── auto_assign.yml
├── dependabot.yml
├── release.yml
└── workflows
│ ├── auto-merge.yaml
│ ├── compat-checks.yaml
│ ├── generate-docs.yaml
│ ├── generate-pgo.yaml
│ ├── govulncheck.yaml
│ ├── perf-regression.yaml
│ ├── perf-test.yaml
│ ├── release.yaml
│ ├── stale.yaml
│ └── tests.yaml
├── .gitignore
├── .goreleaser.yml
├── .run
├── DSLFunctionsIT.run.xml
├── IntegrationTests.run.xml
├── RegressionTests.run.xml
└── UnitTests.run.xml
├── CONTRIBUTING.md
├── DEBUG.md
├── DESIGN.md
├── Dockerfile
├── Dockerfile.goreleaser
├── LICENSE.md
├── Makefile
├── README.md
├── README_CN.md
├── README_ES.md
├── README_ID.md
├── README_JP.md
├── README_KR.md
├── README_PT-BR.md
├── SYNTAX-REFERENCE.md
├── THANKS.md
├── cmd
├── docgen
│ └── docgen.go
├── functional-test
│ ├── main.go
│ ├── run.sh
│ ├── targets-1000.txt
│ ├── targets-150.txt
│ ├── targets-250.txt
│ ├── targets.txt
│ └── testcases.txt
├── generate-checksum
│ └── main.go
├── integration-test
│ ├── code.go
│ ├── custom-dir.go
│ ├── dns.go
│ ├── dsl.go
│ ├── file.go
│ ├── flow.go
│ ├── fuzz.go
│ ├── generic.go
│ ├── headless.go
│ ├── http.go
│ ├── integration-test.go
│ ├── interactsh.go
│ ├── javascript.go
│ ├── library.go
│ ├── loader.go
│ ├── matcher-status.go
│ ├── multi.go
│ ├── network.go
│ ├── offline-http.go
│ ├── profile-loader.go
│ ├── ssl.go
│ ├── template-dir.go
│ ├── template-path.go
│ ├── websocket.go
│ ├── whois.go
│ └── workflow.go
├── memogen
│ ├── function.tpl
│ └── memogen.go
├── nuclei
│ ├── issue-tracker-config.yaml
│ ├── main.go
│ ├── main_test.go
│ └── srv.yaml
├── scan-charts
│ └── main.go
├── tmc
│ ├── main.go
│ └── types.go
└── tools
│ ├── fuzzplayground
│ └── main.go
│ └── signer
│ └── main.go
├── examples
├── advanced
│ └── advanced.go
├── simple
│ └── simple.go
└── with_speed_control
│ └── main.go
├── gh_retry.sh
├── go.mod
├── go.sum
├── helm
├── Chart.yaml
├── templates
│ ├── NOTES.txt
│ ├── _helpers.tpl
│ ├── hpa.yaml
│ ├── interactsh-deployment.yaml
│ ├── interactsh-ingress.yaml
│ ├── interactsh-service.yaml
│ ├── nuclei-configmap.yaml
│ ├── nuclei-cron.yaml
│ └── serviceaccount.yaml
└── values.yaml
├── integration_tests
├── debug.sh
├── dsl
│ ├── hide-version-warning.yaml
│ └── show-version-warning.yaml
├── flow
│ ├── conditional-flow-negative.yaml
│ ├── conditional-flow.yaml
│ ├── dns-ns-probe.yaml
│ ├── flow-hide-matcher.yaml
│ ├── iterate-one-value-flow.yaml
│ └── iterate-values-flow.yaml
├── fuzz
│ ├── fuzz-body-generic-sqli.yaml
│ ├── fuzz-body-json-sqli.yaml
│ ├── fuzz-body-multipart-form-sqli.yaml
│ ├── fuzz-body-params-sqli.yaml
│ ├── fuzz-body-xml-sqli.yaml
│ ├── fuzz-cookie-error-sqli.yaml
│ ├── fuzz-headless.yaml
│ ├── fuzz-host-header-injection.yaml
│ ├── fuzz-mode.yaml
│ ├── fuzz-multi-mode.yaml
│ ├── fuzz-path-sqli.yaml
│ ├── fuzz-query-num-replace.yaml
│ ├── fuzz-query.yaml
│ ├── fuzz-type.yaml
│ └── testData
│ │ └── ginandjuice.proxify.yaml
├── generic
│ └── auth
│ │ └── certificate
│ │ ├── assets
│ │ ├── client.crt
│ │ ├── client.key
│ │ └── server.crt
│ │ └── http-get.yaml
├── library
│ ├── test.json
│ └── test.yaml
├── loader
│ ├── basic.yaml
│ ├── condition-matched.yaml
│ ├── excluded-template.yaml
│ ├── get-headers.yaml
│ ├── get.yaml
│ ├── template-list.yaml
│ └── workflow-list.yaml
├── profile-loader
│ └── basic.yml
├── protocols
│ ├── code
│ │ ├── pre-condition.yaml
│ │ ├── ps1-snippet.yaml
│ │ ├── py-env-var.yaml
│ │ ├── py-file.yaml
│ │ ├── py-interactsh.yaml
│ │ ├── py-nosig.yaml
│ │ ├── py-snippet.yaml
│ │ ├── pyfile.py
│ │ └── unsigned.yaml
│ ├── dns
│ │ ├── a.yaml
│ │ ├── aaaa.yaml
│ │ ├── caa.yaml
│ │ ├── cname-fingerprint.yaml
│ │ ├── cname.yaml
│ │ ├── dsl-matcher-variable.yaml
│ │ ├── ns.yaml
│ │ ├── payload.yaml
│ │ ├── ptr.yaml
│ │ ├── srv.yaml
│ │ ├── tlsa.yaml
│ │ ├── txt.yaml
│ │ └── variables.yaml
│ ├── file
│ │ ├── data
│ │ │ ├── test1.txt
│ │ │ ├── test2.txt
│ │ │ └── test3.txt
│ │ ├── extract.yaml
│ │ ├── matcher-with-and.yaml
│ │ ├── matcher-with-nested-and.yaml
│ │ └── matcher-with-or.yaml
│ ├── headless
│ │ ├── file-upload-negative.yaml
│ │ ├── file-upload.yaml
│ │ ├── headless-basic.yaml
│ │ ├── headless-dsl.yaml
│ │ ├── headless-extract-values.yaml
│ │ ├── headless-header-action.yaml
│ │ ├── headless-header-status-test.yaml
│ │ ├── headless-local.yaml
│ │ ├── headless-payloads.yaml
│ │ ├── headless-self-contained.yaml
│ │ ├── headless-waitevent.yaml
│ │ └── variables.yaml
│ ├── http
│ │ ├── annotation-timeout.yaml
│ │ ├── cl-body-with-header.yaml
│ │ ├── cl-body-without-header.yaml
│ │ ├── cli-with-constants.yaml
│ │ ├── custom-attack-type.yaml
│ │ ├── default-matcher-condition.yaml
│ │ ├── disable-path-automerge.yaml
│ │ ├── disable-redirects.yaml
│ │ ├── dsl-functions.yaml
│ │ ├── dsl-matcher-variable.yaml
│ │ ├── get-all-ips.yaml
│ │ ├── get-case-insensitive.yaml
│ │ ├── get-headers.yaml
│ │ ├── get-host-redirects.yaml
│ │ ├── get-override-sni.yaml
│ │ ├── get-query-string.yaml
│ │ ├── get-redirects-chain-headers.yaml
│ │ ├── get-redirects.yaml
│ │ ├── get-sni-unsafe.yaml
│ │ ├── get-sni.yaml
│ │ ├── get-without-scheme.yaml
│ │ ├── get.yaml
│ │ ├── http-matcher-extractor-dy-extractor.yaml
│ │ ├── http-paths.yaml
│ │ ├── http-preprocessor.yaml
│ │ ├── interactsh-requests-mc-and.yaml
│ │ ├── interactsh-stop-at-first-match.yaml
│ │ ├── interactsh.yaml
│ │ ├── matcher-status.yaml
│ │ ├── multi-http-var-sharing.yaml
│ │ ├── multi-request.yaml
│ │ ├── post-body.yaml
│ │ ├── post-json-body.yaml
│ │ ├── post-multipart-body.yaml
│ │ ├── race-multiple.yaml
│ │ ├── race-simple.yaml
│ │ ├── raw-cookie-reuse.yaml
│ │ ├── raw-dynamic-extractor.yaml
│ │ ├── raw-get-query.yaml
│ │ ├── raw-get.yaml
│ │ ├── raw-path-single-slash.yaml
│ │ ├── raw-path-trailing-slash.yaml
│ │ ├── raw-payload.yaml
│ │ ├── raw-post-body.yaml
│ │ ├── raw-unsafe-path-single-slash.yaml
│ │ ├── raw-unsafe-path.yaml
│ │ ├── raw-unsafe-request.yaml
│ │ ├── raw-unsafe-with-params.yaml
│ │ ├── raw-with-params.yaml
│ │ ├── redirect-match-url.yaml
│ │ ├── request-condition-new.yaml
│ │ ├── request-condition.yaml
│ │ ├── self-contained-file-input.yaml
│ │ ├── self-contained-with-params.yaml
│ │ ├── self-contained-with-path.yaml
│ │ ├── self-contained.yaml
│ │ ├── stop-at-first-match-with-extractors.yaml
│ │ ├── stop-at-first-match.yaml
│ │ ├── variable-dsl-function.yaml
│ │ └── variables.yaml
│ ├── javascript
│ │ ├── net-https.yaml
│ │ ├── net-multi-step.yaml
│ │ ├── redis-pass-brute.yaml
│ │ └── ssh-server-fingerprint.yaml
│ ├── keys
│ │ ├── README.md
│ │ ├── ci-private-key.pem
│ │ └── ci.crt
│ ├── multi
│ │ ├── dynamic-values.yaml
│ │ ├── evaluate-variables.yaml
│ │ └── exported-response-vars.yaml
│ ├── network
│ │ ├── basic.yaml
│ │ ├── hex.yaml
│ │ ├── multi-step.yaml
│ │ ├── net-https-timeout.yaml
│ │ ├── net-https.yaml
│ │ ├── network-port.yaml
│ │ ├── same-address.yaml
│ │ ├── self-contained.yaml
│ │ └── variables.yaml
│ ├── offlinehttp
│ │ ├── data
│ │ │ └── req-resp-with-http-keywords.txt
│ │ ├── offline-allowed-paths.yaml
│ │ ├── offline-raw.yaml
│ │ └── rfc-req-resp.yaml
│ ├── ssl
│ │ ├── basic-ztls.yaml
│ │ ├── basic.yaml
│ │ ├── custom-cipher.yaml
│ │ ├── custom-version.yaml
│ │ ├── multi-req.yaml
│ │ └── ssl-with-vars.yaml
│ ├── websocket
│ │ ├── basic.yaml
│ │ ├── cswsh.yaml
│ │ ├── no-cswsh.yaml
│ │ └── path.yaml
│ └── whois
│ │ └── basic.yaml
├── run.sh
├── subdomains.txt
├── test-issue-tracker-config1.yaml
├── test-issue-tracker-config2.yaml
└── workflow
│ ├── basic.yaml
│ ├── code-template-1.yaml
│ ├── code-template-2.yaml
│ ├── code-value-share-workflow.yaml
│ ├── complex-conditions.yaml
│ ├── condition-matched.yaml
│ ├── condition-unmatched.yaml
│ ├── dns-value-share-template-1.yaml
│ ├── dns-value-share-template-2.yaml
│ ├── dns-value-share-template-3.yaml
│ ├── dns-value-share-workflow.yaml
│ ├── headless-1.yaml
│ ├── http-1.yaml
│ ├── http-2.yaml
│ ├── http-3.yaml
│ ├── http-value-share-template-1.yaml
│ ├── http-value-share-template-2.yaml
│ ├── http-value-share-workflow.yaml
│ ├── match-1.yaml
│ ├── match-2.yaml
│ ├── match-3.yaml
│ ├── matcher-name.yaml
│ ├── multimatch-value-share-template.yaml
│ ├── multimatch-value-share-workflow.yaml
│ ├── multiprotocol-value-share-template.yaml
│ ├── multiprotocol-value-share-workflow.yaml
│ ├── nomatch-1.yaml
│ └── shared-cookie.yaml
├── internal
├── colorizer
│ └── colorizer.go
├── httpapi
│ └── apiendpoint.go
├── pdcp
│ ├── utils.go
│ └── writer.go
├── runner
│ ├── banner.go
│ ├── healthcheck.go
│ ├── inputs.go
│ ├── lazy.go
│ ├── options.go
│ ├── options_test.go
│ ├── proxy.go
│ ├── runner.go
│ ├── runner_test.go
│ └── templates.go
└── server
│ ├── dedupe.go
│ ├── nuclei_sdk.go
│ ├── requests_worker.go
│ ├── scope
│ ├── extensions.go
│ ├── scope.go
│ └── scope_test.go
│ ├── server.go
│ └── templates
│ └── index.html
├── lib
├── README.md
├── config.go
├── example_test.go
├── helper.go
├── multi.go
├── sdk.go
├── sdk_private.go
└── tests
│ └── sdk_test.go
├── nuclei-jsonschema.json
├── pkg
├── authprovider
│ ├── authx
│ │ ├── basic_auth.go
│ │ ├── bearer_auth.go
│ │ ├── cookies_auth.go
│ │ ├── dynamic.go
│ │ ├── file.go
│ │ ├── file_test.go
│ │ ├── headers_auth.go
│ │ ├── query_auth.go
│ │ ├── strategy.go
│ │ └── testData
│ │ │ └── example-auth.yaml
│ ├── file.go
│ ├── interface.go
│ └── multi.go
├── catalog
│ ├── aws
│ │ ├── catalog.go
│ │ └── catalog_test.go
│ ├── catalog.go
│ ├── config
│ │ ├── constants.go
│ │ ├── ignorefile.go
│ │ ├── nucleiconfig.go
│ │ └── template.go
│ ├── disk
│ │ ├── catalog.go
│ │ ├── find.go
│ │ ├── known-files.go
│ │ └── path.go
│ └── loader
│ │ ├── ai_loader.go
│ │ ├── filter
│ │ └── path_filter.go
│ │ ├── loader.go
│ │ ├── loader_test.go
│ │ └── remote_loader.go
├── core
│ ├── engine.go
│ ├── engine_test.go
│ ├── execute_options.go
│ ├── executors.go
│ ├── workflow_execute.go
│ ├── workflow_execute_test.go
│ └── workpool.go
├── external
│ └── customtemplates
│ │ ├── azure_blob.go
│ │ ├── github.go
│ │ ├── github_test.go
│ │ ├── gitlab.go
│ │ ├── s3.go
│ │ └── templates_provider.go
├── fuzz
│ ├── analyzers
│ │ ├── analyzers.go
│ │ └── time
│ │ │ ├── analyzer.go
│ │ │ ├── time_delay.go
│ │ │ └── time_delay_test.go
│ ├── component
│ │ ├── body.go
│ │ ├── body_test.go
│ │ ├── component.go
│ │ ├── cookie.go
│ │ ├── cookie_test.go
│ │ ├── headers.go
│ │ ├── headers_test.go
│ │ ├── path.go
│ │ ├── path_test.go
│ │ ├── query.go
│ │ ├── query_test.go
│ │ ├── value.go
│ │ └── value_test.go
│ ├── dataformat
│ │ ├── dataformat.go
│ │ ├── dataformat_test.go
│ │ ├── form.go
│ │ ├── json.go
│ │ ├── kv.go
│ │ ├── multipart.go
│ │ ├── raw.go
│ │ └── xml.go
│ ├── doc.go
│ ├── execute.go
│ ├── frequency
│ │ └── tracker.go
│ ├── fuzz.go
│ ├── fuzz_test.go
│ ├── parts.go
│ ├── parts_test.go
│ ├── stats
│ │ ├── db.go
│ │ ├── db_test.go
│ │ ├── simple.go
│ │ └── stats.go
│ └── type.go
├── input
│ ├── README.md
│ ├── formats
│ │ ├── README.md
│ │ ├── burp
│ │ │ ├── burp.go
│ │ │ └── burp_test.go
│ │ ├── formats.go
│ │ ├── json
│ │ │ ├── json.go
│ │ │ └── json_test.go
│ │ ├── openapi
│ │ │ ├── examples.go
│ │ │ ├── generator.go
│ │ │ ├── openapi.go
│ │ │ └── openapi_test.go
│ │ ├── swagger
│ │ │ ├── swagger.go
│ │ │ └── swagger_test.go
│ │ ├── testdata
│ │ │ ├── burp.xml
│ │ │ ├── ginandjuice.proxify.json
│ │ │ ├── ginandjuice.proxify.yaml
│ │ │ ├── openapi.yaml
│ │ │ ├── postman.json
│ │ │ └── swagger.yaml
│ │ └── yaml
│ │ │ ├── multidoc.go
│ │ │ └── multidoc_test.go
│ ├── provider
│ │ ├── chunked.go
│ │ ├── http
│ │ │ └── multiformat.go
│ │ ├── interface.go
│ │ ├── list
│ │ │ ├── hmap.go
│ │ │ ├── hmap_test.go
│ │ │ ├── tests
│ │ │ │ ├── AS134029.txt
│ │ │ │ └── AS14421.txt
│ │ │ └── utils.go
│ │ └── simple.go
│ ├── transform.go
│ ├── transform_test.go
│ └── types
│ │ ├── http.go
│ │ ├── http_test.go
│ │ └── probe.go
├── installer
│ ├── doc.go
│ ├── template.go
│ ├── template_test.go
│ ├── util.go
│ ├── versioncheck.go
│ ├── versioncheck_test.go
│ └── zipslip_unix_test.go
├── js
│ ├── CONTRIBUTE.md
│ ├── DESIGN.md
│ ├── THANKS.md
│ ├── compiler
│ │ ├── compiler.go
│ │ ├── compiler_test.go
│ │ ├── init.go
│ │ ├── non-pool.go
│ │ └── pool.go
│ ├── devtools
│ │ ├── README.md
│ │ ├── bindgen
│ │ │ ├── INSTALL.md
│ │ │ ├── README.md
│ │ │ ├── cmd
│ │ │ │ └── bindgen
│ │ │ │ │ └── main.go
│ │ │ ├── generator.go
│ │ │ ├── output.go
│ │ │ └── templates
│ │ │ │ ├── go_class.tmpl
│ │ │ │ ├── js_class.tmpl
│ │ │ │ └── markdown_class.tmpl
│ │ ├── scrapefuncs
│ │ │ ├── README.md
│ │ │ └── main.go
│ │ └── tsgen
│ │ │ ├── README.md
│ │ │ ├── astutil.go
│ │ │ ├── cmd
│ │ │ └── tsgen
│ │ │ │ ├── main.go
│ │ │ │ └── tsmodule.go.tmpl
│ │ │ ├── parser.go
│ │ │ ├── scrape.go
│ │ │ └── types.go
│ ├── generated
│ │ ├── README.md
│ │ ├── go
│ │ │ ├── libbytes
│ │ │ │ └── bytes.go
│ │ │ ├── libfs
│ │ │ │ └── fs.go
│ │ │ ├── libgoconsole
│ │ │ │ └── goconsole.go
│ │ │ ├── libikev2
│ │ │ │ └── ikev2.go
│ │ │ ├── libkerberos
│ │ │ │ └── kerberos.go
│ │ │ ├── libldap
│ │ │ │ └── ldap.go
│ │ │ ├── libmssql
│ │ │ │ └── mssql.go
│ │ │ ├── libmysql
│ │ │ │ └── mysql.go
│ │ │ ├── libnet
│ │ │ │ └── net.go
│ │ │ ├── liboracle
│ │ │ │ └── oracle.go
│ │ │ ├── libpop3
│ │ │ │ └── pop3.go
│ │ │ ├── libpostgres
│ │ │ │ └── postgres.go
│ │ │ ├── librdp
│ │ │ │ └── rdp.go
│ │ │ ├── libredis
│ │ │ │ └── redis.go
│ │ │ ├── librsync
│ │ │ │ └── rsync.go
│ │ │ ├── libsmb
│ │ │ │ └── smb.go
│ │ │ ├── libsmtp
│ │ │ │ └── smtp.go
│ │ │ ├── libssh
│ │ │ │ └── ssh.go
│ │ │ ├── libstructs
│ │ │ │ └── structs.go
│ │ │ ├── libtelnet
│ │ │ │ └── telnet.go
│ │ │ └── libvnc
│ │ │ │ └── vnc.go
│ │ └── ts
│ │ │ ├── bytes.ts
│ │ │ ├── fs.ts
│ │ │ ├── goconsole.ts
│ │ │ ├── ikev2.ts
│ │ │ ├── index.ts
│ │ │ ├── kerberos.ts
│ │ │ ├── ldap.ts
│ │ │ ├── mssql.ts
│ │ │ ├── mysql.ts
│ │ │ ├── net.ts
│ │ │ ├── oracle.ts
│ │ │ ├── pop3.ts
│ │ │ ├── postgres.ts
│ │ │ ├── rdp.ts
│ │ │ ├── redis.ts
│ │ │ ├── rsync.ts
│ │ │ ├── smb.ts
│ │ │ ├── smtp.ts
│ │ │ ├── ssh.ts
│ │ │ ├── structs.ts
│ │ │ ├── telnet.ts
│ │ │ └── vnc.ts
│ ├── global
│ │ ├── exports.js
│ │ ├── helpers.go
│ │ ├── js
│ │ │ ├── active_directory.js
│ │ │ └── dump.js
│ │ ├── scripts.go
│ │ └── scripts_test.go
│ ├── gojs
│ │ ├── gojs.go
│ │ └── set.go
│ ├── libs
│ │ ├── LICENSE.md
│ │ ├── bytes
│ │ │ └── buffer.go
│ │ ├── fs
│ │ │ └── fs.go
│ │ ├── goconsole
│ │ │ └── log.go
│ │ ├── ikev2
│ │ │ └── ikev2.go
│ │ ├── kerberos
│ │ │ ├── kerberosx.go
│ │ │ └── sendtokdc.go
│ │ ├── ldap
│ │ │ ├── adenum.go
│ │ │ ├── ldap.go
│ │ │ └── utils.go
│ │ ├── mssql
│ │ │ ├── memo.mssql.go
│ │ │ └── mssql.go
│ │ ├── mysql
│ │ │ ├── memo.mysql.go
│ │ │ ├── memo.mysql_private.go
│ │ │ ├── mysql.go
│ │ │ └── mysql_private.go
│ │ ├── net
│ │ │ └── net.go
│ │ ├── oracle
│ │ │ ├── memo.oracle.go
│ │ │ └── oracle.go
│ │ ├── pop3
│ │ │ ├── memo.pop3.go
│ │ │ └── pop3.go
│ │ ├── postgres
│ │ │ ├── memo.postgres.go
│ │ │ └── postgres.go
│ │ ├── rdp
│ │ │ ├── memo.rdp.go
│ │ │ └── rdp.go
│ │ ├── redis
│ │ │ ├── memo.redis.go
│ │ │ └── redis.go
│ │ ├── rsync
│ │ │ ├── memo.rsync.go
│ │ │ └── rsync.go
│ │ ├── smb
│ │ │ ├── memo.smb.go
│ │ │ ├── memo.smb_private.go
│ │ │ ├── memo.smbghost.go
│ │ │ ├── smb.go
│ │ │ ├── smb_private.go
│ │ │ └── smbghost.go
│ │ ├── smtp
│ │ │ ├── msg.go
│ │ │ └── smtp.go
│ │ ├── ssh
│ │ │ ├── memo.ssh.go
│ │ │ └── ssh.go
│ │ ├── structs
│ │ │ ├── smbexploit.js
│ │ │ └── structs.go
│ │ ├── telnet
│ │ │ ├── memo.telnet.go
│ │ │ └── telnet.go
│ │ └── vnc
│ │ │ ├── memo.vnc.go
│ │ │ └── vnc.go
│ └── utils
│ │ ├── nucleijs.go
│ │ ├── pgwrap
│ │ └── pgwrap.go
│ │ └── util.go
├── keys
│ ├── key.go
│ └── nuclei.crt
├── loader
│ ├── parser
│ │ └── parser.go
│ └── workflow
│ │ └── workflow_loader.go
├── model
│ ├── model.go
│ ├── model_test.go
│ ├── types
│ │ ├── severity
│ │ │ ├── severities.go
│ │ │ ├── severity.go
│ │ │ └── severity_test.go
│ │ ├── stringslice
│ │ │ ├── stringslice.go
│ │ │ └── stringslice_raw.go
│ │ └── userAgent
│ │ │ └── user_agent.go
│ └── worflow_loader.go
├── operators
│ ├── common
│ │ └── dsl
│ │ │ ├── dsl.go
│ │ │ └── dsl_test.go
│ ├── extractors
│ │ ├── compile.go
│ │ ├── doc.go
│ │ ├── extract.go
│ │ ├── extract_test.go
│ │ ├── extractor_types.go
│ │ ├── extractors.go
│ │ └── util.go
│ ├── matchers
│ │ ├── compile.go
│ │ ├── doc.go
│ │ ├── match.go
│ │ ├── match_test.go
│ │ ├── matchers.go
│ │ ├── matchers_types.go
│ │ ├── validate.go
│ │ └── validate_test.go
│ ├── operators.go
│ └── operators_test.go
├── output
│ ├── doc.go
│ ├── file_output_writer.go
│ ├── format_json.go
│ ├── format_screen.go
│ ├── multi_writer.go
│ ├── output.go
│ ├── output_stats.go
│ ├── output_test.go
│ ├── standard_writer.go
│ └── stats
│ │ ├── stats.go
│ │ ├── stats_test.go
│ │ └── waf
│ │ ├── regexes.json
│ │ ├── waf.go
│ │ └── waf_test.go
├── progress
│ ├── doc.go
│ └── progress.go
├── projectfile
│ ├── httputil.go
│ └── project.go
├── protocols
│ ├── code
│ │ ├── code.go
│ │ ├── code_test.go
│ │ └── helpers.go
│ ├── common
│ │ ├── automaticscan
│ │ │ ├── automaticscan.go
│ │ │ ├── automaticscan_test.go
│ │ │ ├── doc.go
│ │ │ └── util.go
│ │ ├── contextargs
│ │ │ ├── contextargs.go
│ │ │ ├── doc.go
│ │ │ ├── metainput.go
│ │ │ └── variables.go
│ │ ├── expressions
│ │ │ ├── expressions.go
│ │ │ ├── expressions_test.go
│ │ │ ├── variables.go
│ │ │ └── variables_test.go
│ │ ├── generators
│ │ │ ├── attack_types.go
│ │ │ ├── env.go
│ │ │ ├── generators.go
│ │ │ ├── generators_test.go
│ │ │ ├── load.go
│ │ │ ├── load_test.go
│ │ │ ├── maps.go
│ │ │ ├── maps_test.go
│ │ │ ├── options.go
│ │ │ ├── slice.go
│ │ │ └── validate.go
│ │ ├── globalmatchers
│ │ │ └── globalmatchers.go
│ │ ├── helpers
│ │ │ ├── deserialization
│ │ │ │ ├── deserialization.go
│ │ │ │ ├── helpers.go
│ │ │ │ ├── java.go
│ │ │ │ └── testdata
│ │ │ │ │ ├── Deserialize.java
│ │ │ │ │ ├── README.md
│ │ │ │ │ └── ValueObject.java
│ │ │ ├── eventcreator
│ │ │ │ └── eventcreator.go
│ │ │ ├── responsehighlighter
│ │ │ │ ├── hexdump.go
│ │ │ │ ├── response_highlighter.go
│ │ │ │ └── response_highlighter_test.go
│ │ │ └── writer
│ │ │ │ └── writer.go
│ │ ├── hosterrorscache
│ │ │ ├── hosterrorscache.go
│ │ │ └── hosterrorscache_test.go
│ │ ├── interactsh
│ │ │ ├── const.go
│ │ │ ├── interactsh.go
│ │ │ └── options.go
│ │ ├── marker
│ │ │ └── marker.go
│ │ ├── protocolinit
│ │ │ └── init.go
│ │ ├── protocolstate
│ │ │ ├── file.go
│ │ │ ├── headless.go
│ │ │ ├── js.go
│ │ │ ├── memguardian.go
│ │ │ ├── memoizer.go
│ │ │ └── state.go
│ │ ├── randomip
│ │ │ ├── randomip.go
│ │ │ └── randomip_test.go
│ │ ├── replacer
│ │ │ ├── replacer.go
│ │ │ └── replacer_test.go
│ │ ├── uncover
│ │ │ └── uncover.go
│ │ ├── utils
│ │ │ ├── excludematchers
│ │ │ │ ├── excludematchers.go
│ │ │ │ └── excludematchers_test.go
│ │ │ └── vardump
│ │ │ │ ├── dump.go
│ │ │ │ ├── dump_test.go
│ │ │ │ └── vars.go
│ │ └── variables
│ │ │ ├── doc.go
│ │ │ ├── variables.go
│ │ │ └── variables_test.go
│ ├── dns
│ │ ├── cluster.go
│ │ ├── dns.go
│ │ ├── dns_test.go
│ │ ├── dns_types.go
│ │ ├── dnsclientpool
│ │ │ └── clientpool.go
│ │ ├── operators.go
│ │ ├── operators_test.go
│ │ ├── request.go
│ │ └── request_test.go
│ ├── file
│ │ ├── file.go
│ │ ├── find.go
│ │ ├── find_test.go
│ │ ├── operators.go
│ │ ├── operators_test.go
│ │ ├── request.go
│ │ └── request_test.go
│ ├── headless
│ │ ├── engine
│ │ │ ├── action.go
│ │ │ ├── action_types.go
│ │ │ ├── engine.go
│ │ │ ├── hijack.go
│ │ │ ├── http_client.go
│ │ │ ├── instance.go
│ │ │ ├── page.go
│ │ │ ├── page_actions.go
│ │ │ ├── page_actions_test.go
│ │ │ ├── rules.go
│ │ │ └── util.go
│ │ ├── headless.go
│ │ ├── operators.go
│ │ ├── operators_test.go
│ │ └── request.go
│ ├── http
│ │ ├── build_request.go
│ │ ├── build_request_test.go
│ │ ├── cluster.go
│ │ ├── cluster_test.go
│ │ ├── http.go
│ │ ├── http_method_types.go
│ │ ├── http_test.go
│ │ ├── httpclientpool
│ │ │ ├── clientpool.go
│ │ │ ├── errors.go
│ │ │ └── options.go
│ │ ├── httputils
│ │ │ ├── misc.go
│ │ │ └── spm.go
│ │ ├── operators.go
│ │ ├── operators_test.go
│ │ ├── race
│ │ │ └── syncedreadcloser.go
│ │ ├── raw
│ │ │ ├── doc.go
│ │ │ ├── raw.go
│ │ │ └── raw_test.go
│ │ ├── request.go
│ │ ├── request_annotations.go
│ │ ├── request_annotations_test.go
│ │ ├── request_condition.go
│ │ ├── request_fuzz.go
│ │ ├── request_generator.go
│ │ ├── request_generator_test.go
│ │ ├── request_test.go
│ │ ├── signature.go
│ │ ├── signer
│ │ │ ├── aws-sign.go
│ │ │ └── signer.go
│ │ ├── signerpool
│ │ │ └── signerpool.go
│ │ ├── utils.go
│ │ └── validate.go
│ ├── javascript
│ │ ├── js.go
│ │ ├── js_test.go
│ │ └── testcases
│ │ │ ├── ms-sql-detect.yaml
│ │ │ ├── redis-pass-brute.yaml
│ │ │ └── ssh-server-fingerprint.yaml
│ ├── network
│ │ ├── network.go
│ │ ├── network_input_types.go
│ │ ├── network_test.go
│ │ ├── networkclientpool
│ │ │ └── clientpool.go
│ │ ├── operators.go
│ │ ├── operators_test.go
│ │ ├── request.go
│ │ └── request_test.go
│ ├── offlinehttp
│ │ ├── find.go
│ │ ├── find_test.go
│ │ ├── offlinehttp.go
│ │ ├── operators.go
│ │ ├── operators_test.go
│ │ ├── read_response.go
│ │ ├── read_response_test.go
│ │ └── request.go
│ ├── protocols.go
│ ├── ssl
│ │ ├── ssl.go
│ │ └── ssl_test.go
│ ├── utils
│ │ ├── fields.go
│ │ ├── http
│ │ │ ├── requtils.go
│ │ │ └── requtils_test.go
│ │ ├── utils.go
│ │ ├── utils_test.go
│ │ ├── variables.go
│ │ └── variables_test.go
│ ├── websocket
│ │ └── websocket.go
│ └── whois
│ │ ├── rdapclientpool
│ │ └── clientpool.go
│ │ └── whois.go
├── reporting
│ ├── client.go
│ ├── dedupe
│ │ ├── dedupe.go
│ │ └── dedupe_test.go
│ ├── exporters
│ │ ├── es
│ │ │ └── elasticsearch.go
│ │ ├── jsonexporter
│ │ │ └── jsonexporter.go
│ │ ├── jsonl
│ │ │ └── jsonl.go
│ │ ├── markdown
│ │ │ ├── markdown.go
│ │ │ └── util
│ │ │ │ ├── markdown_formatter.go
│ │ │ │ ├── markdown_utils.go
│ │ │ │ └── markdown_utils_test.go
│ │ ├── mongo
│ │ │ └── mongo.go
│ │ ├── sarif
│ │ │ └── sarif.go
│ │ └── splunk
│ │ │ └── splunkhec.go
│ ├── format
│ │ ├── format.go
│ │ ├── format_utils.go
│ │ └── format_utils_test.go
│ ├── options.go
│ ├── reporting.go
│ └── trackers
│ │ ├── filters
│ │ └── filters.go
│ │ ├── gitea
│ │ └── gitea.go
│ │ ├── github
│ │ └── github.go
│ │ ├── gitlab
│ │ └── gitlab.go
│ │ ├── jira
│ │ ├── jira.go
│ │ └── jira_test.go
│ │ └── linear
│ │ ├── jsonutil
│ │ └── jsonutil.go
│ │ └── linear.go
├── scan
│ ├── charts
│ │ ├── charts.go
│ │ └── echarts.go
│ ├── events
│ │ ├── scan_noop.go
│ │ ├── stats_build.go
│ │ └── utils.go
│ └── scan_context.go
├── templates
│ ├── cache.go
│ ├── cache_test.go
│ ├── cluster.go
│ ├── cluster_test.go
│ ├── compile.go
│ ├── compile_test.go
│ ├── doc.go
│ ├── extensions
│ │ └── extensions.go
│ ├── log.go
│ ├── log_test.go
│ ├── parser.go
│ ├── parser_config.go
│ ├── parser_error.go
│ ├── parser_stats.go
│ ├── parser_test.go
│ ├── parser_validate.go
│ ├── preprocessors.go
│ ├── signer
│ │ ├── .nuclei-config
│ │ │ └── nuclei
│ │ │ │ └── .templates-config.json
│ │ ├── default.go
│ │ ├── handler.go
│ │ ├── handler_test.go
│ │ ├── tmpl_signer.go
│ │ └── tmpl_signer_test.go
│ ├── stats.go
│ ├── tag_filter.go
│ ├── tag_filter_test.go
│ ├── template_sign.go
│ ├── templates.go
│ ├── templates_doc.go
│ ├── templates_doc_examples.go
│ ├── templates_test.go
│ ├── tests
│ │ ├── json-template.json
│ │ ├── match-1.yaml
│ │ ├── multiproto.json
│ │ ├── multiproto.yaml
│ │ ├── no-author.yaml
│ │ ├── no-req.yaml
│ │ ├── workflow-invalid.yaml
│ │ └── workflow.yaml
│ ├── types
│ │ └── types.go
│ └── workflows.go
├── testutils
│ ├── fuzzplayground
│ │ ├── db.go
│ │ └── server.go
│ ├── integration.go
│ ├── testheadless
│ │ ├── headless_local.go
│ │ └── headless_runtime.go
│ └── testutils.go
├── tmplexec
│ ├── README.md
│ ├── doc.go
│ ├── exec.go
│ ├── flow
│ │ ├── README.md
│ │ ├── builtin
│ │ │ └── dedupe.go
│ │ ├── doc.go
│ │ ├── flow_executor.go
│ │ ├── flow_executor_test.go
│ │ ├── flow_internal.go
│ │ ├── testcases
│ │ │ ├── condition-flow-extractors.yaml
│ │ │ ├── condition-flow-no-operators.yaml
│ │ │ ├── condition-flow.yaml
│ │ │ ├── nuclei-flow-dns-id.yaml
│ │ │ ├── nuclei-flow-dns-prefix.yaml
│ │ │ └── nuclei-flow-dns.yaml
│ │ ├── util.go
│ │ └── vm.go
│ ├── generic
│ │ └── exec.go
│ ├── interface.go
│ └── multiproto
│ │ ├── README.md
│ │ ├── doc.go
│ │ ├── multi.go
│ │ ├── multi_test.go
│ │ └── testcases
│ │ ├── multiprotodynamic.yaml
│ │ └── multiprotowithprefix.yaml
├── types
│ ├── interfaces.go
│ ├── nucleierr
│ │ └── kinds.go
│ ├── resume.go
│ ├── scanstrategy
│ │ └── scan_strategy.go
│ └── types.go
├── utils
│ ├── expand
│ │ └── expand.go
│ ├── http_probe.go
│ ├── index.go
│ ├── insertion_ordered_map.go
│ ├── insertion_ordered_map_test.go
│ ├── json
│ │ ├── doc.go
│ │ ├── json.go
│ │ ├── json_fallback.go
│ │ ├── jsoncodec.go
│ │ └── message.go
│ ├── monitor
│ │ ├── monitor.go
│ │ └── monitor_test.go
│ ├── stats
│ │ ├── doc.go
│ │ └── stats.go
│ ├── template_path.go
│ ├── utils.go
│ ├── utils_test.go
│ └── yaml
│ │ ├── preprocess.go
│ │ └── yaml_decode_wrapper.go
└── workflows
│ ├── doc.go
│ ├── workflows.go
│ └── workflows_test.go
└── static
├── Join-Discord.png
├── check-nuclei-documentation.png
├── learn-more-button.png
├── nuclei-cover-image.png
├── nuclei-cover.png
├── nuclei-flow.jpg
├── nuclei-getting-started.png
├── nuclei-logo.png
├── nuclei-template-example.png
├── nuclei-templates-teamcity-example.png
├── nuclei-templates-teamcity.png
├── nuclei-write-your-first-template.png
├── projectdiscovery-browse-results.gif
├── regression-cycle.md
├── regression-with-nuclei.jpg
└── teamcity-example.png
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 |
3 | contact_links:
4 |
5 | - name: Ask an question / advise on using nuclei
6 | url: https://github.com/projectdiscovery/nuclei/discussions/categories/q-a
7 | about: Ask a question or request support for using nuclei
8 |
9 | - name: Share idea / feature to discuss for nuclei
10 | url: https://github.com/projectdiscovery/nuclei/discussions/categories/ideas
11 | about: Share idea / feature to discuss for nuclei
12 |
13 | - name: Connect with PD Team (Discord)
14 | url: https://discord.gg/projectdiscovery
15 | about: Connect with PD Team for direct communication
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## Proposed changes
2 |
3 |
4 |
5 |
6 | ## Checklist
7 |
8 |
9 |
10 | - [ ] Pull request is created against the [dev](https://github.com/projectdiscovery/nuclei/tree/dev) branch
11 | - [ ] All checks passed (lint, unit/integration/regression tests etc.) with my changes
12 | - [ ] I have added tests that prove my fix is effective or that my feature works
13 | - [ ] I have added necessary documentation (if appropriate)
--------------------------------------------------------------------------------
/.github/auto_assign.yml:
--------------------------------------------------------------------------------
1 | addReviewers: true
2 | reviewers:
3 | - dogancanbakir
4 | - dwisiswant0
5 |
6 | numberOfReviewers: 1
7 | skipKeywords:
8 | - '@dependabot'
--------------------------------------------------------------------------------
/.github/release.yml:
--------------------------------------------------------------------------------
1 | changelog:
2 | exclude:
3 | authors:
4 | - dependabot
5 | categories:
6 | - title: 🎉 New Features
7 | labels:
8 | - "Type: Enhancement"
9 | - title: 🐞 Bug Fixes
10 | labels:
11 | - "Type: Bug"
12 | - title: 🔨 Maintenance
13 | labels:
14 | - "Type: Maintenance"
15 | - title: Other Changes
16 | labels:
17 | - "*"
--------------------------------------------------------------------------------
/.github/workflows/auto-merge.yaml:
--------------------------------------------------------------------------------
1 | name: 🤖 Auto Merge
2 |
3 | on:
4 | pull_request_review:
5 | types: [submitted]
6 | workflow_run:
7 | workflows: ["♾️ Compatibility Check"]
8 | types:
9 | - completed
10 |
11 | permissions:
12 | pull-requests: write
13 | issues: write
14 | repository-projects: write
15 |
16 | jobs:
17 | auto-merge:
18 | runs-on: ubuntu-latest
19 | if: github.actor == 'dependabot[bot]'
20 | steps:
21 | - uses: actions/checkout@v4
22 | with:
23 | token: ${{ secrets.DEPENDABOT_PAT }}
24 |
25 | - uses: ahmadnassri/action-dependabot-auto-merge@v2
26 | with:
27 | github-token: ${{ secrets.DEPENDABOT_PAT }}
28 | target: all
--------------------------------------------------------------------------------
/.github/workflows/compat-checks.yaml:
--------------------------------------------------------------------------------
1 | name: ♾️ Compatibility Checks
2 |
3 | on:
4 | pull_request:
5 | types: [opened, synchronize]
6 | branches:
7 | - dev
8 |
9 | jobs:
10 | check:
11 | if: github.actor == 'dependabot[bot]'
12 | runs-on: ubuntu-latest
13 | permissions:
14 | contents: write
15 | steps:
16 | - uses: actions/checkout@v4
17 | - uses: projectdiscovery/actions/setup/go/compat-checks@v1
18 | with:
19 | release-test: true
20 |
--------------------------------------------------------------------------------
/.github/workflows/generate-docs.yaml:
--------------------------------------------------------------------------------
1 | name: ⏰ Generate Docs
2 |
3 | on:
4 | push:
5 | branches:
6 | - dev
7 | workflow_dispatch:
8 |
9 | jobs:
10 | publish-docs:
11 | if: "${{ !endsWith(github.actor, '[bot]') }}"
12 | runs-on: ubuntu-latest
13 | steps:
14 | - uses: actions/checkout@v4
15 | - uses: projectdiscovery/actions/setup/go@v1
16 | - uses: projectdiscovery/actions/setup/git@v1
17 | - run: make syntax-docs
18 | - run: git status -s | wc -l | xargs -I {} echo CHANGES={} >> $GITHUB_OUTPUT
19 | id: status
20 | - uses: projectdiscovery/actions/commit@v1
21 | if: steps.status.outputs.CHANGES > 0
22 | with:
23 | files: |
24 | SYNTAX-REFERENCE.md
25 | nuclei-jsonschema.json
26 | message: 'docs: update syntax & JSON schema 🤖'
27 | - run: git push origin $GITHUB_REF
28 |
--------------------------------------------------------------------------------
/.github/workflows/govulncheck.yaml:
--------------------------------------------------------------------------------
1 | name: 🐛 govulncheck
2 |
3 | on:
4 | schedule:
5 | - cron: '0 0 * * 0' # Weekly
6 | workflow_dispatch:
7 |
8 | jobs:
9 | govulncheck:
10 | runs-on: ubuntu-latest
11 | if: github.repository == 'projectdiscovery/nuclei'
12 | permissions:
13 | actions: read
14 | contents: read
15 | security-events: write
16 | env:
17 | OUTPUT: "/tmp/results.sarif"
18 | steps:
19 | - uses: actions/checkout@v4
20 | - uses: projectdiscovery/actions/setup/go@v1
21 | - run: go install golang.org/x/vuln/cmd/govulncheck@latest
22 | - run: govulncheck -scan package -format sarif ./... > $OUTPUT
23 | - uses: github/codeql-action/upload-sarif@v3
24 | with:
25 | sarif_file: "${{ env.OUTPUT }}"
26 | category: "govulncheck"
27 |
--------------------------------------------------------------------------------
/.github/workflows/release.yaml:
--------------------------------------------------------------------------------
1 | name: 🎉 Release
2 |
3 | on:
4 | push:
5 | tags:
6 | - '*'
7 | workflow_dispatch:
8 |
9 | jobs:
10 | release:
11 | runs-on: ubuntu-latest-16-cores
12 | steps:
13 | - uses: actions/checkout@v4
14 | with:
15 | fetch-depth: 0
16 | - uses: projectdiscovery/actions/setup/go@v1
17 | - uses: docker/login-action@v3
18 | with:
19 | username: ${{ secrets.DOCKER_USERNAME }}
20 | password: ${{ secrets.DOCKER_TOKEN }}
21 | - uses: projectdiscovery/actions/goreleaser@v1
22 | with:
23 | release: true
24 | env:
25 | GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
26 | SLACK_WEBHOOK: "${{ secrets.RELEASE_SLACK_WEBHOOK }}"
27 | DISCORD_WEBHOOK_ID: "${{ secrets.DISCORD_WEBHOOK_ID }}"
28 | DISCORD_WEBHOOK_TOKEN: "${{ secrets.DISCORD_WEBHOOK_TOKEN }}"
29 |
--------------------------------------------------------------------------------
/.run/DSLFunctionsIT.run.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/.run/UnitTests.run.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | # Build
2 | FROM golang:1.23-alpine AS builder
3 |
4 | RUN apk add build-base
5 | WORKDIR /app
6 | COPY . /app
7 | RUN make verify
8 | RUN make build
9 |
10 | # Release
11 | FROM alpine:latest
12 |
13 | RUN apk add --no-cache bind-tools chromium ca-certificates
14 | COPY --from=builder /app/bin/nuclei /usr/local/bin/
15 |
16 | ENTRYPOINT ["nuclei"]
17 |
--------------------------------------------------------------------------------
/Dockerfile.goreleaser:
--------------------------------------------------------------------------------
1 | FROM alpine:latest
2 |
3 | LABEL org.opencontainers.image.authors="ProjectDiscovery"
4 | LABEL org.opencontainers.image.description="Nuclei is a fast, customizable vulnerability scanner powered by the global security community and built on a simple YAML-based DSL, enabling collaboration to tackle trending vulnerabilities on the internet. It helps you find vulnerabilities in your applications, APIs, networks, DNS, and cloud configurations."
5 | LABEL org.opencontainers.image.licenses="MIT"
6 | LABEL org.opencontainers.image.title="nuclei"
7 | LABEL org.opencontainers.image.url="https://github.com/projectdiscovery/nuclei"
8 |
9 | RUN apk add --no-cache bind-tools chromium ca-certificates
10 | COPY nuclei /usr/local/bin/
11 |
12 | ENTRYPOINT ["nuclei"]
--------------------------------------------------------------------------------
/cmd/functional-test/targets.txt:
--------------------------------------------------------------------------------
1 | scanme.sh
2 | scanme.sh?a=1
3 | scanme.sh?a=2
4 | scanme.sh?a=3
--------------------------------------------------------------------------------
/cmd/integration-test/interactsh.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import osutils "github.com/projectdiscovery/utils/os"
4 |
5 | // All Interactsh related testcases
6 | var interactshTestCases = []TestCaseInfo{
7 | {Path: "protocols/http/interactsh.yaml", TestCase: &httpInteractshRequest{}, DisableOn: func() bool { return osutils.IsWindows() || osutils.IsOSX() }},
8 | {Path: "protocols/http/interactsh-stop-at-first-match.yaml", TestCase: &httpInteractshStopAtFirstMatchRequest{}, DisableOn: func() bool { return true }}, // disable this test for now
9 | {Path: "protocols/http/default-matcher-condition.yaml", TestCase: &httpDefaultMatcherCondition{}, DisableOn: func() bool { return true }},
10 | {Path: "protocols/http/interactsh-requests-mc-and.yaml", TestCase: &httpInteractshRequestsWithMCAnd{}},
11 | }
12 |
--------------------------------------------------------------------------------
/cmd/integration-test/multi.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/projectdiscovery/nuclei/v3/pkg/testutils"
5 | )
6 |
7 | var multiProtoTestcases = []TestCaseInfo{
8 | {Path: "protocols/multi/dynamic-values.yaml", TestCase: &multiProtoDynamicExtractor{}},
9 | {Path: "protocols/multi/evaluate-variables.yaml", TestCase: &multiProtoDynamicExtractor{}},
10 | {Path: "protocols/multi/exported-response-vars.yaml", TestCase: &multiProtoDynamicExtractor{}},
11 | }
12 |
13 | type multiProtoDynamicExtractor struct{}
14 |
15 | // Execute executes a test case and returns an error if occurred
16 | func (h *multiProtoDynamicExtractor) Execute(templatePath string) error {
17 | results, err := testutils.RunNucleiTemplateAndGetResults(templatePath, "docs.projectdiscovery.io", debug)
18 | if err != nil {
19 | return err
20 | }
21 | return expectResultsCount(results, 1)
22 | }
23 |
--------------------------------------------------------------------------------
/cmd/integration-test/whois.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/projectdiscovery/nuclei/v3/pkg/testutils"
5 | )
6 |
7 | var whoisTestCases = []TestCaseInfo{
8 | {Path: "protocols/whois/basic.yaml", TestCase: &whoisBasic{}},
9 | }
10 |
11 | type whoisBasic struct{}
12 |
13 | // Execute executes a test case and returns an error if occurred
14 | func (h *whoisBasic) Execute(filePath string) error {
15 | results, err := testutils.RunNucleiTemplateAndGetResults(filePath, "https://example.com", debug)
16 | if err != nil {
17 | return err
18 | }
19 | return expectResultsCount(results, 1)
20 | }
21 |
--------------------------------------------------------------------------------
/cmd/memogen/function.tpl:
--------------------------------------------------------------------------------
1 | // Warning - This is generated code
2 | package {{.SourcePackage}}
3 |
4 | import (
5 | "github.com/projectdiscovery/utils/memoize"
6 |
7 | {{range .Imports}}
8 | {{.Name}} {{.Path}}
9 | {{end}}
10 | )
11 |
12 | {{range .Functions}}
13 | {{ .SignatureWithPrefix "memoized" }} {
14 | hash := "{{ .Name }}" {{range .Params}} + ":" + fmt.Sprint({{.Name}}) {{end}}
15 |
16 | v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
17 | return {{.Name}}({{.ParamsNames}})
18 | })
19 | if err != nil {
20 | return {{.ResultFirstFieldDefaultValue}}, err
21 | }
22 | if value, ok := v.({{.ResultFirstFieldType}}); ok {
23 | return value, nil
24 | }
25 |
26 | return {{.ResultFirstFieldDefaultValue}}, errors.New("could not convert cached result")
27 | }
28 | {{end}}
--------------------------------------------------------------------------------
/cmd/nuclei/srv.yaml:
--------------------------------------------------------------------------------
1 | id: basic-dns-a-example
2 |
3 | info:
4 | name: Test DNS A Query Template
5 | author: pdteam
6 | severity: info
7 |
8 | dns:
9 | - name: "{{FQDN}}"
10 | type: SRV
11 | class: inet
12 | recursion: true
13 | retries: 3
14 | matchers:
15 | - type: word
16 | part: all
17 | words:
18 | - "SRV"
19 |
--------------------------------------------------------------------------------
/cmd/scan-charts/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "flag"
5 |
6 | "github.com/projectdiscovery/nuclei/v3/pkg/scan/charts"
7 | )
8 |
9 | var (
10 | dir string
11 | address string
12 | output string
13 | )
14 |
15 | func main() {
16 | flag.StringVar(&dir, "dir", "", "directory to scan")
17 | flag.StringVar(&address, "address", ":9000", "address to run the server on")
18 | flag.StringVar(&output, "output", "", "output filename of generated html file")
19 | flag.Parse()
20 |
21 | if dir == "" {
22 | flag.Usage()
23 | return
24 | }
25 |
26 | server, err := charts.NewScanEventsCharts(dir)
27 | if err != nil {
28 | panic(err)
29 | }
30 | server.PrintInfo()
31 |
32 | if output != "" {
33 | if err = server.GenerateHTML(output); err != nil {
34 | panic(err)
35 | }
36 | return
37 | }
38 |
39 | server.Start(address)
40 | }
41 |
--------------------------------------------------------------------------------
/cmd/tools/fuzzplayground/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "flag"
5 |
6 | _ "github.com/mattn/go-sqlite3"
7 | "github.com/projectdiscovery/gologger"
8 | "github.com/projectdiscovery/nuclei/v3/pkg/testutils/fuzzplayground"
9 | )
10 |
11 | var (
12 | addr string
13 | )
14 |
15 | func main() {
16 | flag.StringVar(&addr, "addr", "localhost:8082", "playground server address")
17 | flag.Parse()
18 |
19 | defer fuzzplayground.Cleanup()
20 | server := fuzzplayground.GetPlaygroundServer()
21 | defer server.Close()
22 |
23 | // Start the server
24 | if err := server.Start(addr); err != nil {
25 | gologger.Fatal().Msgf("Could not start server: %s\n", err)
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/examples/simple/simple.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 |
6 | nuclei "github.com/projectdiscovery/nuclei/v3/lib"
7 | )
8 |
9 | func main() {
10 | ne, err := nuclei.NewNucleiEngineCtx(context.Background(),
11 | nuclei.WithTemplateFilters(nuclei.TemplateFilters{Tags: []string{"oast"}}),
12 | nuclei.EnableStatsWithOpts(nuclei.StatsOptions{MetricServerPort: 6064}), // optionally enable metrics server for better observability
13 | )
14 | if err != nil {
15 | panic(err)
16 | }
17 | // load targets and optionally probe non http/https targets
18 | ne.LoadTargets([]string{"http://honey.scanme.sh"}, false)
19 | err = ne.ExecuteWithCallback(nil)
20 | if err != nil {
21 | panic(err)
22 | }
23 | defer ne.Close()
24 | }
25 |
--------------------------------------------------------------------------------
/helm/Chart.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v2
2 | name: nuclei
3 | description: A Helm chart for Nuclei
4 | type: application
5 | version: 0.1.0
6 | appVersion: "2.5.7"
7 |
--------------------------------------------------------------------------------
/helm/templates/interactsh-service.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: {{ .Values.interactsh.service.name }}
5 | labels:
6 | {{- include "nuclei.labels" . | nindent 4 }}
7 | spec:
8 | type: {{ .Values.interactsh.service.type }}
9 | ports:
10 | - port: {{ .Values.interactsh.service.port }}
11 | targetPort: http
12 | protocol: TCP
13 | name: http
14 | selector:
15 | {{- include "nuclei.selectorLabels" . | nindent 4 }}
16 |
--------------------------------------------------------------------------------
/helm/templates/nuclei-configmap.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: v1
3 | kind: ConfigMap
4 | metadata:
5 | name: nuclei-conf
6 | data:
7 | nuclei.conf: |-
8 | {{ .Values.nuclei.config | indent 4 }}
9 |
10 | ---
11 | apiVersion: v1
12 | kind: ConfigMap
13 | metadata:
14 | name: nuclei-target-list
15 | data:
16 | target-list.txt: |-
17 | {{ .Values.nuclei.target_list | indent 4 }}
18 |
--------------------------------------------------------------------------------
/helm/templates/serviceaccount.yaml:
--------------------------------------------------------------------------------
1 | {{- if .Values.serviceAccount.create -}}
2 | apiVersion: v1
3 | kind: ServiceAccount
4 | metadata:
5 | name: {{ include "nuclei.serviceAccountName" . }}
6 | labels:
7 | {{- include "nuclei.labels" . | nindent 4 }}
8 | {{- with .Values.serviceAccount.annotations }}
9 | annotations:
10 | {{- toYaml . | nindent 4 }}
11 | {{- end }}
12 | {{- end }}
13 |
--------------------------------------------------------------------------------
/integration_tests/dsl/hide-version-warning.yaml:
--------------------------------------------------------------------------------
1 | id: basic-example
2 |
3 | info:
4 | name: Test HTTP Template
5 | author: pdteam
6 | severity: info
7 | reference: |
8 | test case for default behaviour of version warning (dsl parsing error)
9 |
10 | http:
11 | - method: GET
12 | path:
13 | - "{{BaseURL}}"
14 |
15 | matchers:
16 | - type: dsl
17 | dsl:
18 | - compare_versions("GG", '< 4.8.5')
--------------------------------------------------------------------------------
/integration_tests/dsl/show-version-warning.yaml:
--------------------------------------------------------------------------------
1 | id: basic-example
2 |
3 | info:
4 | name: Test HTTP Template
5 | author: pdteam
6 | severity: info
7 | reference: |
8 | test case where version warning is shown when env `SHOW_DSL_ERRORS=true` is set
9 |
10 | http:
11 | - method: GET
12 | path:
13 | - "{{BaseURL}}"
14 |
15 | matchers:
16 | - type: dsl
17 | dsl:
18 | - compare_versions("GG", '< 4.8.5')
--------------------------------------------------------------------------------
/integration_tests/flow/conditional-flow-negative.yaml:
--------------------------------------------------------------------------------
1 | id: ghost-blog-detection
2 | info:
3 | name: Ghost blog detection
4 | author: pdteam
5 | severity: info
6 |
7 |
8 | flow: dns() && http()
9 |
10 | dns:
11 | - name: "{{FQDN}}"
12 | type: CNAME
13 |
14 | matchers:
15 | - type: word
16 | words:
17 | - "ghost.io"
18 | internal: true
19 |
20 | http:
21 | - method: GET
22 | path:
23 | - "{{BaseURL}}"
24 |
25 | matchers:
26 | - type: word
27 | words:
28 | - "ghost.io"
--------------------------------------------------------------------------------
/integration_tests/flow/conditional-flow.yaml:
--------------------------------------------------------------------------------
1 | id: ghost-blog-detection
2 | info:
3 | name: Ghost blog detection
4 | author: pdteam
5 | severity: info
6 |
7 |
8 | flow: dns() && http()
9 |
10 | dns:
11 | - name: "{{FQDN}}"
12 | type: CNAME
13 |
14 | matchers:
15 | - type: word
16 | words:
17 | - ".vercel-dns.com"
18 | internal: true
19 |
20 | http:
21 | - method: GET
22 | path:
23 | - "{{BaseURL}}"
24 |
25 | matchers:
26 | - type: word
27 | words:
28 | - "html>"
--------------------------------------------------------------------------------
/integration_tests/flow/flow-hide-matcher.yaml:
--------------------------------------------------------------------------------
1 | id: flow-hide-matcher
2 |
3 | info:
4 | name: Test Flow Hide Matcher
5 | author: pdteam
6 | severity: info
7 | description: In Template any matcher can be marked as internal which hides it from the output.
8 |
9 | flow: http(1) && http(2)
10 |
11 | http:
12 | - method: GET
13 | path:
14 | - "{{BaseURL}}"
15 |
16 | matchers:
17 | - type: word
18 | words:
19 | - ok
20 | internal: true
21 |
22 | - method: GET
23 | path:
24 | - "{{BaseURL}}"
25 |
26 | matchers:
27 | - type: word
28 | words:
29 | - "Failed event"
--------------------------------------------------------------------------------
/integration_tests/flow/iterate-values-flow.yaml:
--------------------------------------------------------------------------------
1 | id: extract-emails
2 |
3 | info:
4 | name: Extract Email IDs from Response
5 | author: pdteam
6 | severity: info
7 |
8 |
9 | flow: |
10 | http(1)
11 | for(let email of template["emails"]) {
12 | set("email",email);
13 | http(2);
14 | }
15 |
16 | http:
17 | - method: GET
18 | path:
19 | - "{{BaseURL}}"
20 |
21 | extractors:
22 | - type: regex
23 | name: emails
24 | regex:
25 | - '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}'
26 | internal: true
27 |
28 | - method: GET
29 | path:
30 | - "{{BaseURL}}/user/{{base64(email)}}"
31 |
32 | matchers:
33 | - type: word
34 | words:
35 | - "Welcome"
36 |
37 | extractors:
38 | - type: dsl
39 | name: email
40 | dsl:
41 | - email
--------------------------------------------------------------------------------
/integration_tests/fuzz/fuzz-headless.yaml:
--------------------------------------------------------------------------------
1 | id: headless-query-fuzzing
2 |
3 | info:
4 | name: Example Query Fuzzing
5 | author: pdteam
6 | severity: info
7 |
8 | headless:
9 | - steps:
10 | - action: navigate
11 | args:
12 | url: "{{BaseURL}}"
13 | - action: waitload
14 |
15 | payloads:
16 | redirect:
17 | - "blog.com"
18 | - "portal.com"
19 |
20 | fuzzing:
21 | - part: query
22 | mode: single
23 | type: replace
24 | fuzz:
25 | - "https://{{redirect}}"
26 |
27 | matchers:
28 | - type: word
29 | part: body
30 | words:
31 | - "{{redirect}}"
32 |
--------------------------------------------------------------------------------
/integration_tests/fuzz/fuzz-mode.yaml:
--------------------------------------------------------------------------------
1 | id: fuzz-query
2 |
3 | info:
4 | name: Basic Fuzz URL Query
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}"
12 | fuzzing:
13 | - part: query
14 | type: postfix
15 | mode: multiple
16 | keys: ["id","name"]
17 | fuzz: ["fuzz-word"]
18 | matchers-condition: and
19 | matchers:
20 | - type: word
21 | part: body
22 | words:
23 | - "fuzz-word"
24 | - type: word
25 | part: header
26 | words:
27 | - "text/html"
28 |
--------------------------------------------------------------------------------
/integration_tests/fuzz/fuzz-multi-mode.yaml:
--------------------------------------------------------------------------------
1 | id: fuzz-multi-mode-test
2 |
3 | info:
4 | name: multi-mode fuzzing test
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - payloads:
10 | inject:
11 | - nuclei-v1
12 | - nuclei-v2
13 | - nuclei-v3
14 |
15 | fuzzing:
16 | - part: header
17 | type: replace
18 | mode: multiple
19 | fuzz:
20 | X-Client-Id: "{{inject}}"
21 | X-Secret-Id: "{{inject}}"
22 |
23 | matchers-condition: or
24 | matchers:
25 | - type: word
26 | words:
27 | - "nuclei-v3"
--------------------------------------------------------------------------------
/integration_tests/fuzz/fuzz-query.yaml:
--------------------------------------------------------------------------------
1 | id: fuzz-query
2 |
3 | info:
4 | name: Basic Fuzz URL Query
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}"
12 | fuzzing:
13 | - part: query
14 | type: postfix
15 | mode: single
16 | keys: ["id"]
17 | fuzz: ["6842'\"><"]
18 | matchers-condition: and
19 | matchers:
20 | - type: word
21 | part: body
22 | words:
23 | - "6842'\"><"
24 | - type: word
25 | part: header
26 | words:
27 | - "text/html"
28 |
--------------------------------------------------------------------------------
/integration_tests/fuzz/fuzz-type.yaml:
--------------------------------------------------------------------------------
1 | id: fuzz-type
2 |
3 | info:
4 | name: Basic Fuzz URL Query
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}"
12 | fuzzing:
13 | - part: query
14 | type: postfix
15 | mode: single
16 | keys: ["id"]
17 | fuzz: ["fuzz-word"]
18 | matchers-condition: and
19 | matchers:
20 | - type: word
21 | part: body
22 | words:
23 | - "fuzz-word"
24 | - type: word
25 | part: header
26 | words:
27 | - "text/html"
28 |
--------------------------------------------------------------------------------
/integration_tests/generic/auth/certificate/http-get.yaml:
--------------------------------------------------------------------------------
1 | id: basic-get-with-cert
2 |
3 | info:
4 | name: Basic GET with Cert
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}"
12 | matchers:
13 | - type: word
14 | words:
15 | - "Hello"
--------------------------------------------------------------------------------
/integration_tests/library/test.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "go-integration-test",
3 | "info": {
4 | "name": "Basic Go Integration Test",
5 | "author": "pdteam",
6 | "severity": "info"
7 | },
8 | "requests": [
9 | {
10 | "method": "GET",
11 | "path": [
12 | "{{BaseURL}}"
13 | ],
14 | "headers": {
15 | "test": "nuclei"
16 | },
17 | "matchers": [
18 | {
19 | "type": "word",
20 | "words": [
21 | "This is test headers matcher text"
22 | ]
23 | }
24 | ]
25 | }
26 | ]
27 | }
--------------------------------------------------------------------------------
/integration_tests/library/test.yaml:
--------------------------------------------------------------------------------
1 | id: go-integration-test
2 |
3 | info:
4 | name: Basic Go Integration Test
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}"
12 | headers:
13 | test: nuclei
14 | matchers:
15 | - type: word
16 | words:
17 | - "This is test headers matcher text"
--------------------------------------------------------------------------------
/integration_tests/loader/basic.yaml:
--------------------------------------------------------------------------------
1 | id: workflow-example
2 |
3 | info:
4 | name: Test Workflow Template
5 | author: pdteam
6 | severity: info
7 |
8 | workflows:
9 | - template: workflow/match-1.yaml
10 | - template: workflow/match-2.yaml
--------------------------------------------------------------------------------
/integration_tests/loader/condition-matched.yaml:
--------------------------------------------------------------------------------
1 | id: condition-matched-workflow
2 |
3 | info:
4 | name: Condition Matched Workflow
5 | author: pdteam
6 | severity: info
7 |
8 | workflows:
9 | - template: workflow/match-1.yaml
10 | subtemplates:
11 | - template: workflow/match-2.yaml
--------------------------------------------------------------------------------
/integration_tests/loader/excluded-template.yaml:
--------------------------------------------------------------------------------
1 | id: excluded-template
2 |
3 | info:
4 | name: Basic Excluded Template
5 | author: pdteam
6 | severity: info
7 | tags: fuzz
8 |
9 | http:
10 | - method: GET
11 | path:
12 | - "{{BaseURL}}"
13 | matchers:
14 | - type: word
15 | words:
16 | - "This is test matcher text"
--------------------------------------------------------------------------------
/integration_tests/loader/get-headers.yaml:
--------------------------------------------------------------------------------
1 | id: basic-get-headers
2 |
3 | info:
4 | name: Basic GET Headers Request
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}"
12 | headers:
13 | test: nuclei
14 | matchers:
15 | - type: word
16 | words:
17 | - "This is test headers matcher text"
--------------------------------------------------------------------------------
/integration_tests/loader/get.yaml:
--------------------------------------------------------------------------------
1 | id: basic-get
2 |
3 | info:
4 | name: Basic GET Request
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}"
12 | matchers:
13 | - type: word
14 | words:
15 | - "This is test matcher text"
--------------------------------------------------------------------------------
/integration_tests/loader/template-list.yaml:
--------------------------------------------------------------------------------
1 | loader/get.yaml
2 | loader/get-headers.yaml
3 |
--------------------------------------------------------------------------------
/integration_tests/loader/workflow-list.yaml:
--------------------------------------------------------------------------------
1 | loader/basic.yaml
2 | loader/condition-matched.yaml
3 |
--------------------------------------------------------------------------------
/integration_tests/profile-loader/basic.yml:
--------------------------------------------------------------------------------
1 | tags:
2 | - kev
--------------------------------------------------------------------------------
/integration_tests/protocols/code/pre-condition.yaml:
--------------------------------------------------------------------------------
1 | id: pre-condition-code
2 |
3 | info:
4 | name: example code template
5 | author: pdteam
6 | severity: info
7 |
8 |
9 | self-contained: true
10 |
11 | variables:
12 | OAST: "{{interactsh-url}}"
13 |
14 | code:
15 | - pre-condition: IsLinux()
16 | engine:
17 | - sh
18 | - bash
19 | source: |
20 | echo "$OAST" | base64
21 |
22 | matchers:
23 | - type: dsl
24 | dsl:
25 | - true
26 | # digest: 490a00463044022048c083c338c0195f5012122d40c1009d2e2030c583e56558e0d6249a41e6f3f4022070656adf748f4874018d7a01fce116db10a3acd1f9b03e12a83906fb625b5c50:4a3eb6b4988d95847d4203be25ed1d46
--------------------------------------------------------------------------------
/integration_tests/protocols/code/ps1-snippet.yaml:
--------------------------------------------------------------------------------
1 | id: ps1-code-snippet
2 |
3 | info:
4 | name: ps1-code-snippet
5 | author: pdteam
6 | severity: info
7 | tags: code
8 | description: |
9 | ps1-code-snippet
10 |
11 | code:
12 | - engine:
13 | - powershell
14 | - powershell.exe
15 | args:
16 | - -ExecutionPolicy
17 | - Bypass
18 | - -File
19 | pattern: "*.ps1"
20 | source: |
21 | $stdin = [Console]::In
22 | $line = $stdin.ReadLine()
23 | Write-Host "hello from $line"
24 |
25 | matchers:
26 | - type: word
27 | words:
28 | - "hello from input"
--------------------------------------------------------------------------------
/integration_tests/protocols/code/py-env-var.yaml:
--------------------------------------------------------------------------------
1 | id: py-code-snippet
2 |
3 | info:
4 | name: py-code-snippet
5 | author: pdteam
6 | severity: info
7 | tags: code
8 | description: |
9 | py-code-snippet
10 |
11 | code:
12 | - engine:
13 | - py
14 | - python3
15 | source: |
16 | import sys,os
17 | print("hello from " + sys.stdin.read() + " " + os.getenv('baz'))
18 |
19 | matchers:
20 | - type: word
21 | words:
22 | - "hello from input baz"
23 | # digest: 4b0a00483046022100cbbdb7214f669d111b671d271110872dc8af2ab41cf5c312b6e4f64126f55337022100a60547952a0c2bea58388f2d2effe8ad73cd6b6fc92e73eb3c8f88beab6105ec:4a3eb6b4988d95847d4203be25ed1d46
--------------------------------------------------------------------------------
/integration_tests/protocols/code/py-file.yaml:
--------------------------------------------------------------------------------
1 | id: py-file
2 |
3 | info:
4 | name: py-file
5 | author: pdteam
6 | severity: info
7 | tags: code
8 | description: |
9 | py-file
10 |
11 | code:
12 | - engine:
13 | - py
14 | - python3
15 | source: protocols/code/pyfile.py
16 |
17 | matchers:
18 | - type: word
19 | words:
20 | - "hello from input"
21 | # digest: 4a0a00473045022032b81e8bb7475abf27639b0ced71355497166d664698021f26498e7031d62a23022100e99ccde578bfc0b658f16427ae9a3d18922849d3ba3e022032ea0d2a8e77fadb:4a3eb6b4988d95847d4203be25ed1d46
--------------------------------------------------------------------------------
/integration_tests/protocols/code/py-interactsh.yaml:
--------------------------------------------------------------------------------
1 | id: testcode
2 |
3 | info:
4 | name: testcode
5 | author: testcode
6 | severity: info
7 | tags: code
8 | description: |
9 | testcode
10 |
11 | variables:
12 | i: "{{interactsh-url}}"
13 |
14 | code:
15 | - engine:
16 | - py
17 | - python3
18 | # Simulate interactsh interaction
19 | source: |
20 | import os
21 | from urllib.request import urlopen
22 | urlopen("http://" + os.getenv('i'))
23 |
24 | matchers:
25 | - type: word
26 | part: interactsh_protocol
27 | words:
28 | - "http"
29 | # digest: 4a0a0047304502201a5dd0eddfab4f02588a5a8ac1947a5fa41fed80b59d698ad5cc00456296efb6022100fe6e608e38c060964800f5f863a7cdc93f686f2d0f4b52854f73948b808b4511:4a3eb6b4988d95847d4203be25ed1d46
--------------------------------------------------------------------------------
/integration_tests/protocols/code/py-nosig.yaml:
--------------------------------------------------------------------------------
1 | id: py-nosig
2 |
3 | info:
4 | name: py-nosig
5 | author: pdteam
6 | severity: info
7 | tags: code
8 | description: |
9 | Python code without signature
10 |
11 | code:
12 | - engine:
13 | - py
14 | - python3
15 | source: |
16 | print("py unsigned code")
17 |
18 | matchers:
19 | - type: word
20 | words:
21 | - "py unsigned code"
--------------------------------------------------------------------------------
/integration_tests/protocols/code/py-snippet.yaml:
--------------------------------------------------------------------------------
1 | id: py-code-snippet
2 |
3 | info:
4 | name: py-code-snippet
5 | author: pdteam
6 | severity: info
7 | tags: code
8 | description: |
9 | py-code-snippet
10 |
11 | code:
12 | - engine:
13 | - py
14 | - python3
15 | - python
16 | source: |
17 | import sys
18 | print("hello from " + sys.stdin.read())
19 |
20 | matchers:
21 | - type: word
22 | words:
23 | - "hello from input"
24 | # digest: 4b0a00483046022100ced1702728cc68f906c4c7d2c4d05ed071bfabee1e36eec7ebecbeca795a170c022100d20fd41796f130a8f9c4972fee85386d67d61eb5fc1119b1afe2a851eb2f3e65:4a3eb6b4988d95847d4203be25ed1d46
--------------------------------------------------------------------------------
/integration_tests/protocols/code/pyfile.py:
--------------------------------------------------------------------------------
1 | import sys
2 | print("hello from " + sys.stdin.read())
--------------------------------------------------------------------------------
/integration_tests/protocols/code/unsigned.yaml:
--------------------------------------------------------------------------------
1 | id: unsigned-code-snippet
2 |
3 | info:
4 | name: unsigned-code-snippet
5 | author: pdteam
6 | severity: info
7 | tags: code
8 | description: |
9 | unsigned-code-snippet
10 |
11 | code:
12 | - engine:
13 | - py
14 | - python3
15 | source: |
16 | print("unsigned code")
17 |
18 | matchers:
19 | - type: word
20 | words:
21 | - "unsigned code"
--------------------------------------------------------------------------------
/integration_tests/protocols/dns/a.yaml:
--------------------------------------------------------------------------------
1 | id: dns-a-query-example
2 |
3 | info:
4 | name: Test DNS A Query Template
5 | author: pdteam
6 | severity: info
7 |
8 | dns:
9 | - name: "{{FQDN}}"
10 | type: A
11 | class: inet
12 | recursion: true
13 | retries: 3
14 | matchers:
15 | - type: word
16 | words:
17 | - "1.1.1.1"
18 |
--------------------------------------------------------------------------------
/integration_tests/protocols/dns/aaaa.yaml:
--------------------------------------------------------------------------------
1 | id: dns-aaaa-query-example
2 |
3 | info:
4 | name: Test DNS AAAA Query Template
5 | author: pdteam
6 | severity: info
7 |
8 | dns:
9 | - name: "{{FQDN}}"
10 | type: AAAA
11 | class: inet
12 | recursion: true
13 | retries: 3
14 | matchers:
15 | - type: word
16 | words:
17 | - "2606:4700:4700::1001"
18 |
--------------------------------------------------------------------------------
/integration_tests/protocols/dns/caa.yaml:
--------------------------------------------------------------------------------
1 | id: caa-fingerprinting
2 |
3 | info:
4 | name: CAA Fingerprint
5 | author: pdteam
6 | severity: info
7 | tags: dns,caa
8 |
9 | dns:
10 | - name: "{{FQDN}}"
11 | type: CAA
12 |
13 | matchers:
14 | - type: word
15 | words:
16 | - "IN\tCAA"
17 |
18 | extractors:
19 | - type: regex
20 | group: 1
21 | regex:
22 | - "IN\tCAA\t(.+)"
--------------------------------------------------------------------------------
/integration_tests/protocols/dns/cname-fingerprint.yaml:
--------------------------------------------------------------------------------
1 | id: cname-fingerprint
2 |
3 | info:
4 | name: CNAME Fingerprint
5 | author: pdteam
6 | severity: info
7 | tags: dns,cname
8 |
9 | dns:
10 | - name: "{{FQDN}}"
11 | type: NS
12 |
13 | matchers:
14 | - type: word
15 | words:
16 | - "IN\tCNAME"
17 |
18 | extractors:
19 | - type: regex
20 | group: 1
21 | regex:
22 | - "IN\tCNAME\t(.+)"
23 |
--------------------------------------------------------------------------------
/integration_tests/protocols/dns/cname.yaml:
--------------------------------------------------------------------------------
1 | id: dns-cname-query-example
2 |
3 | info:
4 | name: Test DNS CNAME Query Template
5 | author: pdteam
6 | severity: info
7 |
8 | dns:
9 | - name: "{{FQDN}}"
10 | type: CNAME
11 | class: inet
12 | recursion: true
13 | retries: 3
14 | matchers:
15 | - type: word
16 | part: all
17 | words:
18 | - "CNAME"
19 |
--------------------------------------------------------------------------------
/integration_tests/protocols/dns/dsl-matcher-variable.yaml:
--------------------------------------------------------------------------------
1 | id: dns-template
2 |
3 | info:
4 | name: basic dns template
5 | author: pdteam
6 | severity: info
7 |
8 | dns:
9 | - name: "{{FQDN}}"
10 | type: CNAME
11 |
12 | matchers:
13 | - type: dsl
14 | dsl:
15 | - "rcode == 0"
16 |
17 | extractors:
18 | - type: dsl
19 | dsl:
20 | - rcode
21 | - cname
22 | - a
23 | - aaaa
--------------------------------------------------------------------------------
/integration_tests/protocols/dns/ns.yaml:
--------------------------------------------------------------------------------
1 | id: dns-ns-query-example
2 |
3 | info:
4 | name: Test DNS NS Query Template
5 | author: pdteam
6 | severity: info
7 |
8 | dns:
9 | - name: "{{FQDN}}"
10 | type: NS
11 | class: inet
12 | recursion: true
13 | retries: 3
14 | matchers:
15 | - type: word
16 | part: all
17 | words:
18 | - "NS"
19 |
--------------------------------------------------------------------------------
/integration_tests/protocols/dns/payload.yaml:
--------------------------------------------------------------------------------
1 | id: dns-attack
2 |
3 | info:
4 | name: basic dns template
5 | author: pdteam
6 | severity: info
7 |
8 |
9 | dns:
10 | - name: "{{subdomain_wordlist}}.{{FQDN}}"
11 | type: A
12 |
13 | attack: batteringram
14 | payloads:
15 | subdomain_wordlist:
16 | - one
17 | - docs
18 | - drive
19 |
20 | matchers:
21 | - type: word
22 | words:
23 | - "IN\tA"
24 |
25 | extractors:
26 | - type: regex
27 | group: 1
28 | regex:
29 | - "IN\tA\t(.+)"
30 |
--------------------------------------------------------------------------------
/integration_tests/protocols/dns/ptr.yaml:
--------------------------------------------------------------------------------
1 | id: ptr-fingerprint
2 |
3 | info:
4 | name: PTR Fingerprint
5 | author: pdteam
6 | severity: info
7 | tags: dns,ptr
8 |
9 | dns:
10 | - name: "{{FQDN}}"
11 | type: PTR
12 |
13 | matchers:
14 | - type: word
15 | words:
16 | - "IN\tPTR"
17 |
18 | extractors:
19 | - type: regex
20 | group: 1
21 | regex:
22 | - "IN\tPTR\t(.+)"
--------------------------------------------------------------------------------
/integration_tests/protocols/dns/srv.yaml:
--------------------------------------------------------------------------------
1 | id: dns-a-query-example
2 |
3 | info:
4 | name: Test DNS SRV Query Template
5 | author: pdteam
6 | severity: info
7 |
8 | dns:
9 | - name: "{{FQDN}}"
10 | type: SRV
11 | class: inet
12 | recursion: true
13 | retries: 3
14 | matchers:
15 | - type: word
16 | part: all
17 | words:
18 | - "SRV"
19 |
--------------------------------------------------------------------------------
/integration_tests/protocols/dns/tlsa.yaml:
--------------------------------------------------------------------------------
1 | id: tlsa-fingerprinting
2 |
3 | info:
4 | name: TLSA Fingerprint
5 | author: pdteam
6 | severity: info
7 | tags: dns,tlsa
8 |
9 | dns:
10 | - name: "{{FQDN}}"
11 | type: TLSA
12 |
13 | matchers:
14 | - type: word
15 | words:
16 | - "IN\tTLSA"
17 |
18 | extractors:
19 | - type: regex
20 | group: 1
21 | regex:
22 | - "IN\tTLSA\t(.+)"
--------------------------------------------------------------------------------
/integration_tests/protocols/dns/txt.yaml:
--------------------------------------------------------------------------------
1 | id: dns-txt-query-example
2 |
3 | info:
4 | name: Test DNS TXT Query Template
5 | author: pdteam
6 | severity: info
7 |
8 | dns:
9 | - name: "{{FQDN}}"
10 | type: TXT
11 | class: inet
12 | recursion: true
13 | retries: 3
14 | matchers:
15 | - type: word
16 | part: all
17 | words:
18 | - "TXT"
19 |
--------------------------------------------------------------------------------
/integration_tests/protocols/dns/variables.yaml:
--------------------------------------------------------------------------------
1 | id: variables-example
2 |
3 | info:
4 | name: Variables Example
5 | author: pdteam
6 | severity: info
7 |
8 | variables:
9 | a1: "IN"
10 |
11 | dns:
12 | - name: "{{FQDN}}"
13 | type: A
14 | class: inet
15 | recursion: true
16 | retries: 3
17 | matchers:
18 | - type: word
19 | words:
20 | - "{{a1}}"
--------------------------------------------------------------------------------
/integration_tests/protocols/file/data/test1.txt:
--------------------------------------------------------------------------------
1 | AAA
2 | BBB
--------------------------------------------------------------------------------
/integration_tests/protocols/file/data/test2.txt:
--------------------------------------------------------------------------------
1 | CCC
2 | DDD
--------------------------------------------------------------------------------
/integration_tests/protocols/file/data/test3.txt:
--------------------------------------------------------------------------------
1 | 11 EE 11
2 | 11 FF 11
--------------------------------------------------------------------------------
/integration_tests/protocols/file/extract.yaml:
--------------------------------------------------------------------------------
1 | id: file-extract
2 |
3 | info:
4 | name: File with Extractor
5 | author: pdteam
6 | severity: info
7 | tags: file
8 |
9 | file:
10 | - extensions:
11 | - all
12 |
13 | extractors:
14 | - type: regex
15 | regex:
16 | - "(?m)11\\s(EE|FF)\\s11"
--------------------------------------------------------------------------------
/integration_tests/protocols/file/matcher-with-and.yaml:
--------------------------------------------------------------------------------
1 | id: file-matcher-with-and
2 |
3 | info:
4 | name: File Matcher With AND
5 | author: pdteam
6 | severity: info
7 | tags: file
8 |
9 | file:
10 | - extensions:
11 | - all
12 |
13 | matchers-condition: and
14 | matchers:
15 | - type: word
16 | words:
17 | - "CCC"
18 | - type: word
19 | words:
20 | - "DDD"
--------------------------------------------------------------------------------
/integration_tests/protocols/file/matcher-with-nested-and.yaml:
--------------------------------------------------------------------------------
1 | id: file-matcher-with-nested-and
2 |
3 | info:
4 | name: File Matcher With nested AND
5 | author: pdteam
6 | severity: info
7 | tags: file
8 |
9 | file:
10 | - extensions:
11 | - all
12 |
13 | matchers:
14 | - type: word
15 | words:
16 | - "CCC"
17 | - "DDD"
18 | condition: and
--------------------------------------------------------------------------------
/integration_tests/protocols/file/matcher-with-or.yaml:
--------------------------------------------------------------------------------
1 | id: file-matcher-with-or
2 |
3 | info:
4 | name: File Matcher With OR
5 | author: pdteam
6 | severity: info
7 | tags: file
8 |
9 | file:
10 | - extensions:
11 | - all
12 |
13 | matchers:
14 | - type: word
15 | words:
16 | - "AA"
17 | - type: word
18 | words:
19 | - "BB"
--------------------------------------------------------------------------------
/integration_tests/protocols/headless/file-upload-negative.yaml:
--------------------------------------------------------------------------------
1 | id: file-upload
2 | # template for testing when file upload is disabled
3 | info:
4 | name: Basic File Upload
5 | author: pdteam
6 | severity: info
7 |
8 | headless:
9 | - steps:
10 | - action: navigate
11 | args:
12 | url: "{{BaseURL}}"
13 | - action: waitload
14 | - action: files
15 | args:
16 | by: xpath
17 | xpath: /html/body/form/input[1]
18 | value: headless/file-upload.yaml
19 | - action: sleep
20 | args:
21 | duration: 2
22 | - action: click
23 | args:
24 | by: x
25 | xpath: /html/body/form/input[2]
26 | matchers:
27 | - type: word
28 | words:
29 | - "Basic File Upload"
--------------------------------------------------------------------------------
/integration_tests/protocols/headless/file-upload.yaml:
--------------------------------------------------------------------------------
1 | id: file-upload
2 |
3 | info:
4 | name: Basic File Upload
5 | author: pdteam
6 | severity: info
7 |
8 | headless:
9 | - steps:
10 | - action: navigate
11 | args:
12 | url: "{{BaseURL}}"
13 | - action: waitload
14 | - action: files
15 | args:
16 | by: xpath
17 | xpath: /html/body/form/input[1]
18 | value: protocols/headless/file-upload.yaml
19 | - action: sleep
20 | args:
21 | duration: 2
22 | - action: click
23 | args:
24 | by: x
25 | xpath: /html/body/form/input[2]
26 | matchers:
27 | - type: word
28 | words:
29 | - "Basic File Upload"
--------------------------------------------------------------------------------
/integration_tests/protocols/headless/headless-basic.yaml:
--------------------------------------------------------------------------------
1 | id: headless-basic
2 | info:
3 | name: Headless Basic
4 | author: pdteam
5 | severity: info
6 | tags: headless
7 |
8 | headless:
9 | - steps:
10 | - action: navigate
11 | args:
12 | url: "{{BaseURL}}/"
13 |
14 | - action: waitload
15 | matchers:
16 | - type: word
17 | words:
18 | - ""
--------------------------------------------------------------------------------
/integration_tests/protocols/headless/headless-dsl.yaml:
--------------------------------------------------------------------------------
1 | id: headless-dsl
2 |
3 | info:
4 | name: Headless DSL
5 | author: dwisiswant0
6 | severity: info
7 | tags: headless
8 |
9 | headless:
10 | - steps:
11 | - action: navigate
12 | args:
13 | url: "{{BaseURL}}/?_={{urlencode(concat('foo', '-', 'bar'))}}"
14 | - action: waitload
15 | matchers:
16 | - type: word
17 | words:
18 | - "foo-bar"
--------------------------------------------------------------------------------
/integration_tests/protocols/headless/headless-extract-values.yaml:
--------------------------------------------------------------------------------
1 |
2 | id: headless-extract-values
3 | info:
4 | name: Headless Extract Value
5 | author: pdteam
6 | severity: info
7 | tags: headless
8 |
9 | headless:
10 | - steps:
11 | - action: navigate
12 | args:
13 | url: "{{BaseURL}}"
14 | - action: waitload
15 | # From headless/extract-urls.yaml
16 | - action: script
17 | name: extract
18 | args:
19 | code: |
20 | () => '\n' + [...new Set(Array.from(document.querySelectorAll('[src], [href], [url], [action]')).map(i => i.src || i.href || i.url || i.action))].join('\r\n') + '\n'
21 |
22 | matchers:
23 | - type: word
24 | words:
25 | - "test.html"
26 |
27 | extractors:
28 | - type: kval
29 | part: extract
30 | kval:
31 | - extract
--------------------------------------------------------------------------------
/integration_tests/protocols/headless/headless-header-action.yaml:
--------------------------------------------------------------------------------
1 | id: headless-header-action
2 | info:
3 | name: Headless Header Action
4 | author: pdteam
5 | severity: info
6 | tags: headless
7 |
8 | headless:
9 | - steps:
10 | - action: setheader
11 | args:
12 | part: request
13 | key: Test
14 | value: test value
15 |
16 | - action: navigate
17 | args:
18 | url: "{{BaseURL}}/"
19 |
20 | - action: waitload
21 | matchers:
22 | - type: word
23 | words:
24 | - "test value"
--------------------------------------------------------------------------------
/integration_tests/protocols/headless/headless-header-status-test.yaml:
--------------------------------------------------------------------------------
1 | id: headless-header-status-test
2 |
3 | info:
4 | name: headless header + status test
5 | author: pdteam
6 | severity: info
7 |
8 | headless:
9 | - steps:
10 | - args:
11 | url: "{{BaseURL}}"
12 | action: navigate
13 | - action: waitload
14 |
15 | matchers-condition: and
16 | matchers:
17 | - type: word
18 | part: header
19 | words:
20 | - text/plain
21 |
22 | - type: status
23 | status:
24 | - 200
25 |
--------------------------------------------------------------------------------
/integration_tests/protocols/headless/headless-local.yaml:
--------------------------------------------------------------------------------
1 | id: nuclei-headless-local
2 |
3 | info:
4 | name: Nuclei Headless Local
5 | author: pdteam
6 | severity: high
7 |
8 | headless:
9 | - steps:
10 | - action: navigate
11 | args:
12 | url: "{{BaseURL}}"
13 |
14 | - action: waitload
15 |
--------------------------------------------------------------------------------
/integration_tests/protocols/headless/headless-payloads.yaml:
--------------------------------------------------------------------------------
1 | id: headless-payloads
2 |
3 | info:
4 | name: headless payloads example
5 | author: pdteam
6 | severity: info
7 | tags: headless
8 |
9 | headless:
10 | - attack: clusterbomb
11 | payloads:
12 | aa:
13 | - aa
14 | - bb
15 | bb:
16 | - cc
17 | - dd
18 | steps:
19 | - args:
20 | url: "{{BaseURL}}?aa={{aa}}&bb={{bb}}"
21 | action: navigate
22 | - action: waitload
23 | matchers:
24 | - type: word
25 | words:
26 | - "test"
--------------------------------------------------------------------------------
/integration_tests/protocols/headless/headless-self-contained.yaml:
--------------------------------------------------------------------------------
1 | id: headless-self-contained
2 | info:
3 | name: Headless Self Contained
4 | author: pdteam
5 | severity: info
6 | tags: headless
7 |
8 | self-contained: true
9 |
10 | headless:
11 | - steps:
12 | - action: navigate
13 | args:
14 | url: "https://postman-echo.com/get?q={{query}}"
15 |
16 | - action: waitload
17 | matchers:
18 | - type: word
19 | words:
20 | - "selfcontained"
--------------------------------------------------------------------------------
/integration_tests/protocols/headless/headless-waitevent.yaml:
--------------------------------------------------------------------------------
1 | id: headless-waitevent
2 |
3 | info:
4 | name: WaitEvent
5 | severity: info
6 | author: pdteam
7 |
8 | headless:
9 | - steps:
10 | # note waitevent must be used before navigating to any page
11 | # unlike waitload
12 | - action: waitevent
13 | args:
14 | event: 'Page.loadEventFired'
15 | max-duration: 15s
16 |
17 | - action: navigate
18 | args:
19 | url: "{{BaseURL}}/"
20 |
21 | matchers:
22 | - type: word
23 | words:
24 | - ""
--------------------------------------------------------------------------------
/integration_tests/protocols/headless/variables.yaml:
--------------------------------------------------------------------------------
1 | id: variables-example
2 |
3 | info:
4 | name: Variables Example
5 | author: pdteam
6 | severity: info
7 |
8 | variables:
9 | a1: "{{base64('hello')}}"
10 |
11 | headless:
12 | - steps:
13 | - args:
14 | url: "{{BaseURL}}"
15 | action: navigate
16 | - action: waitload
17 | matchers:
18 | - type: word
19 | words:
20 | - "{{a1}}"
--------------------------------------------------------------------------------
/integration_tests/protocols/http/annotation-timeout.yaml:
--------------------------------------------------------------------------------
1 | id: annotation-timeout
2 |
3 | info:
4 | name: Basic Annotation Timeout
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - raw:
10 | - |
11 | @timeout: 5s
12 | GET / HTTP/1.1
13 | Host: {{Hostname}}
14 |
15 | matchers:
16 | - type: word
17 | words:
18 | - "This is test matcher text"
--------------------------------------------------------------------------------
/integration_tests/protocols/http/cl-body-with-header.yaml:
--------------------------------------------------------------------------------
1 | id: cl-body-with-header
2 |
3 | info:
4 | name: CL Get Request - Body with header
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}"
12 | matchers:
13 | - type: dsl
14 | dsl:
15 | - "content_length==50000 && len(body)==14"
--------------------------------------------------------------------------------
/integration_tests/protocols/http/cl-body-without-header.yaml:
--------------------------------------------------------------------------------
1 | id: cl-body-without-header
2 |
3 | info:
4 | name: CL Get Request - Body without header
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}"
12 | matchers:
13 | - type: dsl
14 | dsl:
15 | - "content_length==14"
--------------------------------------------------------------------------------
/integration_tests/protocols/http/cli-with-constants.yaml:
--------------------------------------------------------------------------------
1 | id: cli-with-constants
2 |
3 | info:
4 | name: Cli Var with Constants
5 | author: pdteam
6 | severity: info
7 |
8 | constants:
9 | test: test-in-template
10 |
11 | http:
12 | - method: GET
13 | path:
14 | - "{{BaseURL}}?p={{test}}"
15 | matchers:
16 | - type: word
17 | words:
18 | - "test-in-template"
--------------------------------------------------------------------------------
/integration_tests/protocols/http/custom-attack-type.yaml:
--------------------------------------------------------------------------------
1 | id: custom-attack-type
2 |
3 | info:
4 | name: Custom Attack Type
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}/?a={{test}}&b={{values}}"
12 | payloads:
13 | test:
14 | - hello
15 | - another
16 | values:
17 | - data
18 | - hacking
19 | attack: pitchfork
20 | matchers:
21 | - type: word
22 | words:
23 | - "This is test custom payload"
24 |
--------------------------------------------------------------------------------
/integration_tests/protocols/http/default-matcher-condition.yaml:
--------------------------------------------------------------------------------
1 | id: default-matcher-condition
2 |
3 | info:
4 | name: default-matcher-condition
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - raw:
10 | - |
11 | GET /?action=curltest&url={{interactsh-url}} HTTP/1.1
12 | Host: {{Hostname}}
13 |
14 | matchers:
15 | - type: word
16 | part: interactsh_protocol
17 | words:
18 | - "dns"
19 |
20 | - type: status
21 | status:
22 | - 200
23 |
--------------------------------------------------------------------------------
/integration_tests/protocols/http/disable-path-automerge.yaml:
--------------------------------------------------------------------------------
1 | id: test
2 |
3 | info:
4 | name: test
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - raw:
10 | - |
11 | GET /api/v1/test?id=123 HTTP/1.1
12 | Host: {{Hostname}}
13 | - |
14 | GET HTTP/1.1
15 | Host: {{Hostname}}
16 | disable-path-automerge: true
17 | matchers:
18 | - type: status
19 | status:
20 | - 200
21 |
--------------------------------------------------------------------------------
/integration_tests/protocols/http/disable-redirects.yaml:
--------------------------------------------------------------------------------
1 | id: basic-disable-redirects
2 |
3 | info:
4 | name: Basic GET Redirects Request
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}"
12 | redirects: true
13 | max-redirects: 2
14 | matchers:
15 | - type: word
16 | words:
17 | - "This is test disable redirects matcher text"
18 |
--------------------------------------------------------------------------------
/integration_tests/protocols/http/dsl-matcher-variable.yaml:
--------------------------------------------------------------------------------
1 | id: dsl-matcher-variable
2 |
3 | info:
4 | name: dsl-matcher-variable
5 | author: pd-team
6 | severity: info
7 |
8 | http:
9 | -
10 | path:
11 | - "{{BaseURL}}"
12 | payloads:
13 | VALUES:
14 | - This
15 | - is
16 | - test
17 | - matcher
18 | - text
19 | matchers:
20 | -
21 | dsl:
22 | - 'contains(body,"{{VALUES}}")'
23 | type: dsl
--------------------------------------------------------------------------------
/integration_tests/protocols/http/get-all-ips.yaml:
--------------------------------------------------------------------------------
1 | id: get-all-ips
2 |
3 | info:
4 | name: Basic GET Request on all IPS
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}"
12 | matchers:
13 | - type: word
14 | words:
15 | - "ok"
--------------------------------------------------------------------------------
/integration_tests/protocols/http/get-case-insensitive.yaml:
--------------------------------------------------------------------------------
1 | id: basic-get-case-insensitive
2 |
3 | info:
4 | name: Basic GET Request
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}"
12 | matchers:
13 | - type: word
14 | case-insensitive: true
15 | words:
16 | - "ThIS is TEsT MAtcHEr TExT"
17 |
--------------------------------------------------------------------------------
/integration_tests/protocols/http/get-headers.yaml:
--------------------------------------------------------------------------------
1 | id: basic-get-headers
2 |
3 | info:
4 | name: Basic GET Headers Request
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}"
12 | headers:
13 | test: nuclei
14 | matchers:
15 | - type: word
16 | words:
17 | - "This is test headers matcher text"
--------------------------------------------------------------------------------
/integration_tests/protocols/http/get-host-redirects.yaml:
--------------------------------------------------------------------------------
1 | id: basic-get-host-redirects
2 |
3 | info:
4 | name: Basic GET Host Redirects Request
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}"
12 | host-redirects: true
13 | max-redirects: 3
14 | matchers:
15 | - type: dsl
16 | dsl:
17 | - "status_code==307"
--------------------------------------------------------------------------------
/integration_tests/protocols/http/get-override-sni.yaml:
--------------------------------------------------------------------------------
1 | id: basic-raw-http-example
2 |
3 | info:
4 | name: Test RAW GET Template
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - raw:
10 | - |
11 | @tls-sni:request.host
12 | GET / HTTP/1.1
13 | Host: test
14 |
15 | matchers:
16 | - type: word
17 | words:
18 | - "test-ok"
--------------------------------------------------------------------------------
/integration_tests/protocols/http/get-query-string.yaml:
--------------------------------------------------------------------------------
1 | id: basic-get-querystring
2 |
3 | info:
4 | name: Basic GET QueryString Request
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}?test=nuclei"
12 | matchers:
13 | - type: word
14 | words:
15 | - "This is test querystring matcher text"
--------------------------------------------------------------------------------
/integration_tests/protocols/http/get-redirects-chain-headers.yaml:
--------------------------------------------------------------------------------
1 | id: basic-get-redirects-chain-headers
2 |
3 | info:
4 | name: Basic GET Redirects Request With Chain header
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}"
12 | redirects: true
13 | max-redirects: 3
14 | matchers-condition: and
15 | matchers:
16 | - type: word
17 | part: header
18 | words:
19 | - "TestRedirectHeaderMatch"
20 |
21 | - type: status
22 | status:
23 | - 302
--------------------------------------------------------------------------------
/integration_tests/protocols/http/get-redirects.yaml:
--------------------------------------------------------------------------------
1 | id: basic-get-redirects
2 |
3 | info:
4 | name: Basic GET Redirects Request
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}"
12 | redirects: true
13 | max-redirects: 3
14 | matchers:
15 | - type: word
16 | words:
17 | - "This is test redirects matcher text"
--------------------------------------------------------------------------------
/integration_tests/protocols/http/get-sni-unsafe.yaml:
--------------------------------------------------------------------------------
1 | id: basic-unsafe-get
2 |
3 | info:
4 | name: Basic Unsafe GET Request with CLI SNI
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - raw:
10 | - |+
11 | GET / HTTP/1.1
12 | Host: {{Hostname}}
13 |
14 | unsafe: true
15 | matchers:
16 | - type: word
17 | words:
18 | - "test-ok"
--------------------------------------------------------------------------------
/integration_tests/protocols/http/get-sni.yaml:
--------------------------------------------------------------------------------
1 | id: basic-get-sni
2 |
3 | info:
4 | name: Basic GET Request with CLI SNI
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}"
12 | matchers:
13 | - type: word
14 | words:
15 | - "test-ok"
--------------------------------------------------------------------------------
/integration_tests/protocols/http/get-without-scheme.yaml:
--------------------------------------------------------------------------------
1 | id: get-without-scheme
2 |
3 | info:
4 | name: Basic GET Request without scheme
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}"
12 | matchers:
13 | - type: word
14 | words:
15 | - "ok"
--------------------------------------------------------------------------------
/integration_tests/protocols/http/get.yaml:
--------------------------------------------------------------------------------
1 | id: basic-get
2 |
3 | info:
4 | name: Basic GET Request
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}"
12 | matchers:
13 | - type: word
14 | words:
15 | - "This is test matcher text"
--------------------------------------------------------------------------------
/integration_tests/protocols/http/http-preprocessor.yaml:
--------------------------------------------------------------------------------
1 | id: http-preprocessor
2 |
3 | info:
4 | name: Test Http Preprocessor
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - raw:
10 | - |
11 | GET /?test={{randstr}} HTTP/1.1
12 | Host: {{Hostname}}
13 |
14 | matchers:
15 | - type: status
16 | status:
17 | - 200
--------------------------------------------------------------------------------
/integration_tests/protocols/http/interactsh-requests-mc-and.yaml:
--------------------------------------------------------------------------------
1 | id: interactsh-requests-mc-and
2 |
3 | info:
4 | name: interactsh multi request matcher condition
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - raw:
10 | - |
11 | GET /api/geoping/{{interactsh-url}} HTTP/1.1
12 | Host: {{Hostname}}
13 |
14 | - |
15 | GET / HTTP/1.1
16 | Host: {{Hostname}}
17 |
18 | matchers-condition: and
19 | matchers:
20 | - type: word
21 | part: interactsh_protocol # Confirms the DNS Interaction
22 | words:
23 | - "dns"
24 |
25 | - type: dsl
26 | dsl:
27 | - "status_code_2 == 200"
--------------------------------------------------------------------------------
/integration_tests/protocols/http/interactsh-stop-at-first-match.yaml:
--------------------------------------------------------------------------------
1 | id: interactsh-stop-at-first-match-integration-test
2 |
3 | info:
4 | name: Interactsh StopAtFirstMatch Integration Test
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}/?a=1"
12 | - "{{BaseURL}}/?a=2"
13 | - "{{BaseURL}}/?a=3"
14 | - "{{BaseURL}}/?a=4"
15 | - "{{BaseURL}}/?a=5"
16 | - "{{BaseURL}}/?a=6"
17 | - "{{BaseURL}}/?a=7"
18 | - "{{BaseURL}}/?a=8"
19 | - "{{BaseURL}}/?a=9"
20 | headers:
21 | url: 'http://{{interactsh-url}}'
22 |
23 | stop-at-first-match: true
24 |
25 | matchers:
26 | - type: word
27 | part: interactsh_protocol # Confirms DNS Interaction
28 | words:
29 | - "dns"
--------------------------------------------------------------------------------
/integration_tests/protocols/http/interactsh.yaml:
--------------------------------------------------------------------------------
1 | id: interactsh-integration-test
2 |
3 | info:
4 | name: Interactsh Integration Test
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}"
12 | headers:
13 | url: 'http://{{interactsh-url}}'
14 |
15 | matchers:
16 | - type: word
17 | part: interactsh_protocol # Confirms the HTTP Interaction
18 | words:
19 | - "dns"
--------------------------------------------------------------------------------
/integration_tests/protocols/http/multi-http-var-sharing.yaml:
--------------------------------------------------------------------------------
1 | id: multi-http-var-sharing
2 |
3 | info:
4 | name: Multi HTTP var sharing
5 | author: pdteam
6 | severity: info
7 | description: |
8 | A template which has multiple HTTP requests block and variables are shared between them
9 |
10 | http:
11 | - method: GET
12 | path:
13 | - "{{BaseURL}}"
14 |
15 | matchers:
16 | - type: word
17 | words:
18 | - "This is test matcher text"
19 | negative: true
20 | internal: true
21 |
22 | extractors:
23 | - type: dsl
24 | name: ffff
25 | dsl:
26 | - status_code
27 | internal: true
28 |
29 | - method: GET
30 | path:
31 | - "{{BaseURL}}/{{ffff}}"
32 |
33 | matchers:
34 | - type: status
35 | status:
36 | - 200
--------------------------------------------------------------------------------
/integration_tests/protocols/http/multi-request.yaml:
--------------------------------------------------------------------------------
1 | id: http-multi-request
2 |
3 | info:
4 | name: http multi request template
5 | author: pdteam
6 | severity: info
7 | description: template with multiple http request with combined logic
8 | reference: https://example-reference-link
9 |
10 | # requestURI is reflected back as response body here
11 | http:
12 | - raw:
13 | - |
14 | GET /ping HTTP/1.1
15 | Host: {{Hostname}}
16 |
17 | - |
18 | GET /pong HTTP/1.1
19 | Host: {{Hostname}}
20 |
21 | matchers:
22 | - type: dsl
23 | dsl:
24 | - 'body_1 == "ping"'
25 | - 'body_2 == "pong"'
26 | condition: and
--------------------------------------------------------------------------------
/integration_tests/protocols/http/post-body.yaml:
--------------------------------------------------------------------------------
1 | id: basic-post-body
2 |
3 | info:
4 | name: Basic POST Body Request
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: POST
10 | path:
11 | - "{{BaseURL}}"
12 | headers:
13 | Content-Type: application/x-www-form-urlencoded
14 | Content-Length: 1 # as long as there is a value, nuclei will auto-recalculate it.
15 | body: username=test&password=nuclei
16 | matchers:
17 | - type: word
18 | words:
19 | - "This is test post-body matcher text"
--------------------------------------------------------------------------------
/integration_tests/protocols/http/post-json-body.yaml:
--------------------------------------------------------------------------------
1 | id: basic-post-json-body
2 |
3 | info:
4 | name: Basic POST JSON Body Request
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: POST
10 | path:
11 | - "{{BaseURL}}"
12 | headers:
13 | Content-Type: application/json
14 | Content-Length: 1
15 | body: '{"username":"test","password":"nuclei"}'
16 | matchers:
17 | - type: word
18 | words:
19 | - "This is test post-json-body matcher text"
--------------------------------------------------------------------------------
/integration_tests/protocols/http/race-multiple.yaml:
--------------------------------------------------------------------------------
1 | id: race-condition-testing
2 |
3 | info:
4 | name: Race condition testing with multiple requests
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - raw:
10 | - |
11 | GET / HTTP/1.1
12 | Host: {{Hostname}}
13 |
14 | id=1
15 |
16 | - |
17 | GET / HTTP/1.1
18 | Host: {{Hostname}}
19 |
20 | id=2
21 |
22 | - |
23 | GET / HTTP/1.1
24 | Host: {{Hostname}}
25 |
26 | id=3
27 |
28 | - |
29 | GET / HTTP/1.1
30 | Host: {{Hostname}}
31 |
32 | id=4
33 |
34 | - |
35 | GET / HTTP/1.1
36 | Host: {{Hostname}}
37 |
38 | id=5
39 |
40 | threads: 5
41 | race: true
42 |
43 | matchers:
44 | - type: status
45 | status:
46 | - 200
--------------------------------------------------------------------------------
/integration_tests/protocols/http/race-simple.yaml:
--------------------------------------------------------------------------------
1 | id: race-condition-testing
2 |
3 | info:
4 | name: Race Condition testing
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - raw:
10 | - |
11 | GET / HTTP/1.1
12 | Host: {{Hostname}}
13 |
14 | test
15 |
16 | race: true
17 | race_count: 10
18 |
19 | matchers:
20 | - type: status
21 | part: header
22 | status:
23 | - 200
--------------------------------------------------------------------------------
/integration_tests/protocols/http/raw-get-query.yaml:
--------------------------------------------------------------------------------
1 | id: basic-raw-query-example
2 |
3 | info:
4 | name: Test RAW GET Query Template
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - raw:
10 | - |
11 | GET ?test=nuclei HTTP/1.1
12 | Host: {{Hostname}}
13 | Origin: {{BaseURL}}
14 |
15 | matchers:
16 | - type: word
17 | words:
18 | - "Test is test raw-get-query-matcher text"
--------------------------------------------------------------------------------
/integration_tests/protocols/http/raw-get.yaml:
--------------------------------------------------------------------------------
1 | id: basic-raw-http-example
2 |
3 | info:
4 | name: Test RAW GET Template
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - raw:
10 | - |
11 | GET / HTTP/1.1
12 | Host: {{Hostname}}
13 | Origin: {{BaseURL}}
14 |
15 | matchers:
16 | - type: word
17 | words:
18 | - "Test is test raw-get-matcher text"
--------------------------------------------------------------------------------
/integration_tests/protocols/http/raw-path-single-slash.yaml:
--------------------------------------------------------------------------------
1 | id: raw-path-single-slash
2 |
3 | info:
4 | name: Test RAW HTTP Template with single slash
5 | author: pdteam
6 | severity: info
7 |
8 | requests:
9 | - raw:
10 | - |
11 | GET / HTTP/1.1
12 | Host: {{Hostname}}
13 | Origin: {{BaseURL}}
--------------------------------------------------------------------------------
/integration_tests/protocols/http/raw-path-trailing-slash.yaml:
--------------------------------------------------------------------------------
1 | id: raw-path-trailing-slash
2 |
3 | info:
4 | name: Test RAW HTTP Template with trailing slash
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - raw:
10 | - |
11 | GET /test/..;/..;/ HTTP/1.1
12 | Host: {{Hostname}}
13 | Origin: {{BaseURL}}
--------------------------------------------------------------------------------
/integration_tests/protocols/http/raw-payload.yaml:
--------------------------------------------------------------------------------
1 | id: payload-raw-example
2 | info:
3 | name: Test RAW With Payload Template
4 | author: pdteam
5 | severity: info
6 |
7 | http:
8 | - payloads:
9 | username:
10 | - test
11 | password:
12 | - nuclei
13 | - guest
14 | attack: clusterbomb
15 | raw:
16 | - |
17 | POST / HTTP/1.1
18 | User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5)
19 | Host: {{Hostname}}
20 | Content-Type: application/x-www-form-urlencoded
21 | Content-Length: 1
22 | another_header: {{base64('§password§')}}
23 | Accept: */*
24 |
25 | username=§username§&password={{password}}
26 | matchers:
27 | - type: word
28 | words:
29 | - "Test is raw-payload matcher text"
--------------------------------------------------------------------------------
/integration_tests/protocols/http/raw-post-body.yaml:
--------------------------------------------------------------------------------
1 | id: basic-raw-http-body-example
2 |
3 | info:
4 | name: Test RAW POST Template
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - raw:
10 | - |
11 | POST / HTTP/1.1
12 | Host: {{Hostname}}
13 | Origin: {{BaseURL}}
14 | Content-Type: application/x-www-form-urlencoded
15 | Content-Length: 1
16 |
17 | username=test&password=nuclei
18 | matchers:
19 | - type: word
20 | words:
21 | - "Test is test raw-post-body-matcher text"
--------------------------------------------------------------------------------
/integration_tests/protocols/http/raw-unsafe-path-single-slash.yaml:
--------------------------------------------------------------------------------
1 | id: raw-unsafe-path-single-slash
2 |
3 | info:
4 | name: Test RAW Unsafe HTTP Template with single slash
5 | author: pdteam
6 | severity: info
7 |
8 | requests:
9 | - raw:
10 | - |+
11 | GET / HTTP/1.1
12 | Host: {{Hostname}}
13 | Origin: {{BaseURL}}
14 |
15 | unsafe: true
--------------------------------------------------------------------------------
/integration_tests/protocols/http/raw-unsafe-request.yaml:
--------------------------------------------------------------------------------
1 | id: basic-raw-unsafe-request-example
2 |
3 | info:
4 | name: Test RAW Unsafe Request Template
5 | author: pd-team
6 | severity: info
7 |
8 | http:
9 | - raw:
10 | - |+
11 | GET / HTTP/1.1
12 | Host:
13 | Content-Length: 4
14 |
15 | unsafe: true
16 | matchers-condition: and
17 | matchers:
18 | - type: word
19 | words:
20 | - "This is test raw-unsafe-matcher test"
--------------------------------------------------------------------------------
/integration_tests/protocols/http/raw-unsafe-with-params.yaml:
--------------------------------------------------------------------------------
1 | id: raw-unsafe-with-params
2 |
3 | info:
4 | name: Test RAW unsafe with params
5 | author: pdteam
6 | severity: info
7 | # this test is used to check automerge of params in both unsafe & safe requests
8 | # key1=value1 is added from inputURL
9 |
10 | http:
11 | - raw:
12 | - |+
13 | GET /?key2=value2 HTTP/1.1
14 | Host: {{Hostname}}
15 |
16 | unsafe: true
17 | matchers:
18 | - type: word
19 | words:
20 | - "Test is test raw-params-matcher text"
--------------------------------------------------------------------------------
/integration_tests/protocols/http/raw-with-params.yaml:
--------------------------------------------------------------------------------
1 | id: raw-with-params
2 |
3 | info:
4 | name: Test RAW Params Template
5 | author: pdteam
6 | severity: info
7 | # this test is used to check automerge of params in both unsafe & safe requests
8 | # key1=value1 is added from inputURL
9 |
10 | http:
11 | - raw:
12 | - |
13 | GET /?key2=value2 HTTP/1.1
14 | Host: {{Hostname}}
15 | Origin: {{BaseURL}}
16 |
17 | matchers:
18 | - type: word
19 | words:
20 | - "Test is test raw-params-matcher text"
--------------------------------------------------------------------------------
/integration_tests/protocols/http/redirect-match-url.yaml:
--------------------------------------------------------------------------------
1 | id: redirect-match-url
2 |
3 | info:
4 | name: Redirect Match URL
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}"
12 | stop-at-first-match: true # Confirm stop-at-first-match
13 | redirects: true # Confirm redirected URL matched value
14 | max-redirects: 3
15 | matchers:
16 | - type: word
17 | words:
18 | - "This is test redirects matcher text"
--------------------------------------------------------------------------------
/integration_tests/protocols/http/request-condition-new.yaml:
--------------------------------------------------------------------------------
1 | id: request-condition-new
2 |
3 | info:
4 | name: request-condition-new
5 | author: pd-team
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | id: first
11 | path:
12 | - "{{BaseURL}}/200"
13 | - method: GET
14 | path:
15 | - "{{BaseURL}}/400"
16 | matchers:
17 | - type: dsl
18 | dsl:
19 | - "first_status_code==200 && status_code==400"
--------------------------------------------------------------------------------
/integration_tests/protocols/http/request-condition.yaml:
--------------------------------------------------------------------------------
1 | id: request-condition
2 |
3 | info:
4 | name: request-condition
5 | author: pd-team
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}/200"
12 | - "{{BaseURL}}/400"
13 |
14 | matchers:
15 | - type: dsl
16 | dsl:
17 | - "status_code_1==200 && status_code_2==400"
--------------------------------------------------------------------------------
/integration_tests/protocols/http/self-contained-file-input.yaml:
--------------------------------------------------------------------------------
1 | id: self-contained-file-input
2 |
3 | info:
4 | name: Test Self Contained Template With File Input
5 | author: pdteam
6 | severity: info
7 |
8 | self-contained: true
9 | http:
10 | - method: GET
11 | path:
12 | - "http://127.0.0.1:5431/{{test}}"
13 | matchers:
14 | - type: word
15 | words:
16 | - This is self-contained response
17 |
18 | - raw:
19 | - |
20 | GET http://127.0.0.1:5431/{{test}} HTTP/1.1
21 | Host: {{Hostname}}
22 | matchers:
23 | - type: word
24 | words:
25 | - This is self-contained response
--------------------------------------------------------------------------------
/integration_tests/protocols/http/self-contained-with-params.yaml:
--------------------------------------------------------------------------------
1 | id: self-contained-with-params
2 |
3 | info:
4 | name: self contained with params
5 | author: pd-team
6 | severity: info
7 |
8 | self-contained: true
9 | http:
10 | - raw:
11 | - |
12 | GET http://127.0.0.1:5431/?something=here&key=value HTTP/1.1
13 | Host: {{Hostname}}
14 |
15 | matchers:
16 | - type: word
17 | words:
18 | - This is self-contained response
--------------------------------------------------------------------------------
/integration_tests/protocols/http/self-contained-with-path.yaml:
--------------------------------------------------------------------------------
1 | id: self-contained-with-path
2 |
3 | info:
4 | name: self-contained-with-path
5 | author: pd-team
6 | severity: info
7 |
8 | self-contained: true
9 | http:
10 | - raw:
11 | - |
12 | GET / HTTP/1.1
13 | Host: 127.0.0.1:5431
14 |
15 | matchers:
16 | - type: word
17 | words:
18 | - This is self-contained response
--------------------------------------------------------------------------------
/integration_tests/protocols/http/self-contained.yaml:
--------------------------------------------------------------------------------
1 | id: example-self-contained-input
2 |
3 | info:
4 | name: example-self-contained
5 | author: pd-team
6 | severity: info
7 |
8 | self-contained: true
9 | http:
10 | - raw:
11 | - |
12 | GET http://127.0.0.1:5431/ HTTP/1.1
13 | Host: {{Hostname}}
14 |
15 | matchers:
16 | - type: word
17 | words:
18 | - This is self-contained response
--------------------------------------------------------------------------------
/integration_tests/protocols/http/stop-at-first-match-with-extractors.yaml:
--------------------------------------------------------------------------------
1 | id: stop-at-first-match-with-extractors
2 |
3 | info:
4 | name: Stop at first match Request with extractors
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}?a=1"
12 | - "{{BaseURL}}?a=2"
13 | stop-at-first-match: true
14 | extractors:
15 | - type: kval
16 | part: header
17 | kval:
18 | - "date"
--------------------------------------------------------------------------------
/integration_tests/protocols/http/stop-at-first-match.yaml:
--------------------------------------------------------------------------------
1 | id: stop-at-first-match
2 |
3 | info:
4 | name: Stop at first match Request
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}?a=1"
12 | - "{{BaseURL}}?a=2"
13 | matchers:
14 | - type: word
15 | words:
16 | - "This is test"
17 | stop-at-first-match: true
--------------------------------------------------------------------------------
/integration_tests/protocols/http/variable-dsl-function.yaml:
--------------------------------------------------------------------------------
1 | id: basic-example
2 |
3 | info:
4 | name: Test HTTP Template
5 | author: pdteam
6 | severity: info
7 |
8 | variables:
9 | a1: "{{to_lower(rand_base(5))}}"
10 |
11 |
12 | http:
13 | - method: GET
14 | path:
15 | - "{{BaseURL}}/?x={{a1}}"
16 | - "{{BaseURL}}/?x={{a1}}"
17 |
18 | extractors:
19 | - type: dsl
20 | dsl:
21 | - a1
--------------------------------------------------------------------------------
/integration_tests/protocols/http/variables.yaml:
--------------------------------------------------------------------------------
1 | id: variables-example
2 |
3 | info:
4 | name: Variables Example
5 | author: pdteam
6 | severity: info
7 |
8 | variables:
9 | a1: "value"
10 | a2: "{{base64('{{Host}}')}}"
11 |
12 | http:
13 | - raw:
14 | - |
15 | GET / HTTP/1.1
16 | Host: {{FQDN}}
17 | Test: {{a1}}
18 | Another: {{a2}}
19 | Email: {{ username }}
20 | payloads:
21 | username:
22 | - jon.doe@{{ FQDN }}
23 | stop-at-first-match: true
24 | matchers-condition: or
25 | matchers:
26 | - type: word
27 | condition: and
28 | words:
29 | - "value"
30 | - "MTI3LjAuMC4x" # 127.0.0.1
31 | - "jon.doe@127.0.0.1"
32 |
--------------------------------------------------------------------------------
/integration_tests/protocols/javascript/net-https.yaml:
--------------------------------------------------------------------------------
1 | id: net-https
2 |
3 | info:
4 | name: net-https
5 | author: pdteam
6 | severity: info
7 | description: send and receive https data using net module
8 |
9 |
10 | javascript:
11 | - code: |
12 | let m = require('nuclei/net');
13 | let name=Host+':'+Port;
14 | let conn = m.OpenTLS('tcp', name);
15 | conn.Send('GET / HTTP/1.1\r\nHost:'+name+'\r\nConnection: close\r\n\r\n');
16 | resp = conn.RecvString();
17 |
18 | args:
19 | Host: "{{Host}}"
20 | Port: "443"
21 |
22 | matchers:
23 | - type: word
24 | words:
25 | - "HTTP/1.1 200 OK"
--------------------------------------------------------------------------------
/integration_tests/protocols/javascript/ssh-server-fingerprint.yaml:
--------------------------------------------------------------------------------
1 | id: ssh-server-fingerprint
2 |
3 | info:
4 | name: Fingerprint SSH Server Software
5 | author: Ice3man543,tarunKoyalwar
6 | severity: info
7 | metadata:
8 | shodan-query: port:22
9 |
10 |
11 | javascript:
12 | - code: |
13 | var m = require("nuclei/ssh");
14 | var c = m.SSHClient();
15 | var response = c.ConnectSSHInfoMode(Host, Port);
16 | to_json(response);
17 | args:
18 | Host: "{{Host}}"
19 | Port: "22"
20 |
21 | extractors:
22 | - type: json
23 | name: server
24 | json:
25 | - '.ServerID.Raw'
26 | part: response
27 |
--------------------------------------------------------------------------------
/integration_tests/protocols/keys/README.md:
--------------------------------------------------------------------------------
1 | ## keys
2 |
3 | the keys stored here especially `ci-private-key.pem` and `ci.crt` are used in integration tests to test template signing and verfication functionality introduced in nuclei v3
--------------------------------------------------------------------------------
/integration_tests/protocols/keys/ci-private-key.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PD NUCLEI USER PRIVATE KEY-----
2 | MHcCAQEEIEywlBGZ94ARrBT+1fTu/Ii7HGfJc4y7kK4aGYvDMYm5oAoGCCqGSM49
3 | AwEHoUQDQgAEnyVUkFKJx92/8doQ//VAPCrzB4dqvNgwLRZPC/oAieVpNG8HDGNw
4 | PJ7qB7ovIfGwDOW98vQwsRG4TmgFlZr0rQ==
5 | -----END PD NUCLEI USER PRIVATE KEY-----
6 |
--------------------------------------------------------------------------------
/integration_tests/protocols/keys/ci.crt:
--------------------------------------------------------------------------------
1 | -----BEGIN PD NUCLEI USER CERTIFICATE-----
2 | MIIBPzCB56ADAgECAgRlHGgmMAoGCCqGSM49BAMCMA0xCzAJBgNVBAMTAkNJMB4X
3 | DTIzMTAwMzE5MTQ0NloXDTI3MTAwMjE5MTQ0NlowDTELMAkGA1UEAxMCQ0kwWTAT
4 | BgcqhkjOPQIBBggqhkjOPQMBBwNCAASfJVSQUonH3b/x2hD/9UA8KvMHh2q82DAt
5 | Fk8L+gCJ5Wk0bwcMY3A8nuoHui8h8bAM5b3y9DCxEbhOaAWVmvStozUwMzAOBgNV
6 | HQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAK
7 | BggqhkjOPQQDAgNHADBEAiBgUdbAcSbDpkNNQscZog/pAuaRV4sk7fbOlTRcjZTL
8 | qQIgdtvG1w7l9VAtk6gx+HJa3BP9IFhSfT+a3UCuJy2p2iA=
9 | -----END PD NUCLEI USER CERTIFICATE-----
10 |
--------------------------------------------------------------------------------
/integration_tests/protocols/multi/dynamic-values.yaml:
--------------------------------------------------------------------------------
1 | id: dns-http-dynamic-values
2 |
3 | info:
4 | name: multi protocol request with dynamic values
5 | author: pdteam
6 | severity: info
7 |
8 | dns:
9 | - name: "{{FQDN}}" # DNS Request
10 | type: cname
11 |
12 | extractors:
13 | - type: dsl
14 | name: blogid
15 | dsl:
16 | - trim_suffix(cname,'.vercel-dns.com')
17 | internal: true
18 |
19 | http:
20 | - method: GET # http request
21 | path:
22 | - "{{BaseURL}}"
23 |
24 | matchers:
25 | - type: dsl
26 | dsl:
27 | - contains(body,'home') # check for http string
28 | - blogid == 'cname' # check for cname (extracted information from dns response)
29 | condition: and
--------------------------------------------------------------------------------
/integration_tests/protocols/multi/evaluate-variables.yaml:
--------------------------------------------------------------------------------
1 | id: dns-ssl-http-with-variables
2 |
3 | info:
4 | name: multi protocol request with dynamic values
5 | author: pdteam
6 | severity: info
7 |
8 |
9 | variables:
10 | cname_filtered: '{{trim_suffix(dns_cname,".vercel-dns.com")}}'
11 |
12 | dns:
13 | - name: "{{FQDN}}" # DNS Request
14 | type: cname
15 |
16 | ssl:
17 | - address: "{{Hostname}}" # ssl request
18 |
19 | http:
20 | - method: GET # http request
21 | path:
22 | - "{{BaseURL}}"
23 |
24 | matchers:
25 | - type: dsl
26 | dsl:
27 | - contains(http_body,'home') # check for http string
28 | - cname_filtered == 'cname' # check for cname (extracted information from dns response)
29 | - ssl_subject_cn == 'docs.projectdiscovery.io'
30 | condition: and
--------------------------------------------------------------------------------
/integration_tests/protocols/multi/exported-response-vars.yaml:
--------------------------------------------------------------------------------
1 | id: dns-ssl-http-proto-prefix
2 |
3 | info:
4 | name: multi protocol request with dynamic values
5 | author: pdteam
6 | severity: info
7 |
8 | dns:
9 | - name: "{{FQDN}}" # DNS Request
10 | type: cname
11 |
12 | ssl:
13 | - address: "{{Hostname}}" # ssl request
14 |
15 | http:
16 | - method: GET # http request
17 | path:
18 | - "{{BaseURL}}"
19 |
20 | matchers:
21 | - type: dsl
22 | dsl:
23 | - contains(http_body,'home') # check for http string
24 | - trim_suffix(dns_cname,'.vercel-dns.com') == 'cname' # check for cname (extracted information from dns response)
25 | - ssl_subject_cn == 'docs.projectdiscovery.io'
26 | condition: and
--------------------------------------------------------------------------------
/integration_tests/protocols/network/basic.yaml:
--------------------------------------------------------------------------------
1 | id: basic-network-request
2 |
3 | info:
4 | name: Basic Network Request
5 | author: pdteam
6 | severity: info
7 |
8 | network:
9 | - host:
10 | - "{{Hostname}}"
11 | inputs:
12 | - data: "PING\r\n"
13 | read-size: 4
14 | matchers:
15 | - type: word
16 | part: data
17 | words:
18 | - "PONG"
--------------------------------------------------------------------------------
/integration_tests/protocols/network/hex.yaml:
--------------------------------------------------------------------------------
1 | id: hex-network-request
2 |
3 | info:
4 | name: Hex Input Network Request
5 | author: pdteam
6 | severity: info
7 |
8 | network:
9 | - host:
10 | - "{{Hostname}}"
11 | inputs:
12 | - data: "50494e47"
13 | type: hex
14 | - data: "\r\n"
15 |
16 | read-size: 4
17 | matchers:
18 | - type: word
19 | part: data
20 | encoding: hex
21 | words:
22 | - "504f4e47"
--------------------------------------------------------------------------------
/integration_tests/protocols/network/multi-step.yaml:
--------------------------------------------------------------------------------
1 | id: multi-step
2 |
3 | info:
4 | name: Multi-Step Network Template
5 | author: pd-team
6 | severity: info
7 |
8 | network:
9 | - inputs:
10 | - data: "FIRST"
11 | read: 4
12 | name: first
13 | - data: "SECOND"
14 | read: 4
15 | name: second
16 | host:
17 | - "{{Hostname}}"
18 | read-size: 6
19 | matchers:
20 | - type: word
21 | part: first
22 | words:
23 | - "PING"
24 | - type: word
25 | part: second
26 | words:
27 | - "PONG"
28 | - type: word
29 | part: data
30 | words:
31 | - "NUCLEI"
32 | matchers-condition: and
--------------------------------------------------------------------------------
/integration_tests/protocols/network/net-https.yaml:
--------------------------------------------------------------------------------
1 | id: net-https
2 |
3 | info:
4 | name: Example Network template to send HTTPS request
5 | author: pdteam
6 | severity: high
7 | description: Example Network template to send HTTPS request
8 |
9 |
10 | tcp:
11 | - host:
12 | - "tls://{{Hostname}}"
13 | port: 443
14 | inputs:
15 | - data: "GET / HTTP/1.1\r\nHost: {{Hostname}}\r\nConnection: close\r\n\r\n"
16 | read-all: true
17 | extractors:
18 | - type: dsl
19 | dsl:
20 | - "len(data)"
--------------------------------------------------------------------------------
/integration_tests/protocols/network/network-port.yaml:
--------------------------------------------------------------------------------
1 | id: network-port-example
2 |
3 | info:
4 | name: Example Template with Network Port
5 | author: pdteam
6 | severity: high
7 | description: This is an updated description for the network port example.
8 | reference: https://updated-reference-link
9 |
10 | tcp:
11 | - host:
12 | - "{{Hostname}}"
13 | port: 23846
14 | inputs:
15 | - data: "PING\r\n"
16 | read-size: 4
17 | matchers:
18 | - type: word
19 | part: data
20 | words:
21 | - "PONG"
22 |
--------------------------------------------------------------------------------
/integration_tests/protocols/network/same-address.yaml:
--------------------------------------------------------------------------------
1 | id: same-target
2 |
3 | info:
4 | name: same-target
5 | author: pdteam
6 | severity: info
7 | description: Riak is a distributed NoSQL key-value data store that offers high availability, fault tolerance, operational simplicity, and scalability.
8 |
9 | network:
10 | - host:
11 | - "{{Hostname}}"
12 | - "{{Hostname}}"
13 | - "{{Hostname}}"
14 | - "{{Hostname}}"
15 | - "{{Hostname}}"
16 | - "{{Hostname}}"
17 | - "{{Hostname}}"
18 | - "{{Hostname}}"
19 | - "{{Hostname}}"
20 | - "{{Hostname}}"
21 | - "{{Hostname}}"
22 | inputs:
23 | - data: "PING\r\n"
24 | read-size: 4
25 | matchers:
26 | - type: word
27 | part: data
28 | words:
29 | - "PONG"
30 |
--------------------------------------------------------------------------------
/integration_tests/protocols/network/self-contained.yaml:
--------------------------------------------------------------------------------
1 | id: example-self-contained-input
2 |
3 | info:
4 | name: example-self-contained
5 | author: pd-team
6 | severity: info
7 |
8 | self-contained: true
9 | network:
10 | - host:
11 | - "127.0.0.1:5431"
12 |
13 | matchers:
14 | - type: word
15 | words:
16 | - "Authentication successful"
--------------------------------------------------------------------------------
/integration_tests/protocols/network/variables.yaml:
--------------------------------------------------------------------------------
1 | id: variables-example
2 |
3 | info:
4 | name: Variables Example
5 | author: pdteam
6 | severity: info
7 |
8 | variables:
9 | a1: "PING"
10 | a2: "{{base64('hello')}}"
11 |
12 | network:
13 | - host:
14 | - "{{Hostname}}"
15 | inputs:
16 | - data: "{{a1}}"
17 | read-size: 8
18 | matchers:
19 | - type: word
20 | part: data
21 | words:
22 | - "{{a2}}"
--------------------------------------------------------------------------------
/integration_tests/protocols/offlinehttp/data/req-resp-with-http-keywords.txt:
--------------------------------------------------------------------------------
1 | GET / HTTP/1.1
2 | Host: pastebin.com
3 | User-Agent: curl/7.79.1
4 | Accept: */*
5 | Connection: close
6 |
7 | HTTP/1.1 200 OK
8 | Date: Tue, 21 Jun 2022 09:32:01 GMT
9 | Content-Type: text/plain; charset=utf-8
10 | Connection: close
11 | x-frame-options: DENY
12 | x-content-type-options: nosniff
13 | x-xss-protection: 1;mode=block
14 | cache-control: public, max-age=1801
15 | CF-Cache-Status: HIT
16 | Age: 1585
17 | Last-Modified: Tue, 21 Jun 2022 09:05:36 GMT
18 | Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
19 | Server: cloudflare
20 | CF-RAY: 71ebbc0a7ea83b8b-CDG
21 |
22 | 54
23 | line1
24 | this is a line containing HTTP/1.1 FOO BAR
25 | line3
26 | 0
--------------------------------------------------------------------------------
/integration_tests/protocols/offlinehttp/offline-allowed-paths.yaml:
--------------------------------------------------------------------------------
1 | id: offline-allowed-paths
2 |
3 | info:
4 | name: offline-allowed-paths
5 | author: pdteam
6 | severity: info
7 | description: offline-allowed-paths
8 |
9 | http:
10 | - path:
11 | - "{{BaseURL}}"
12 | - "{{BaseURL}}/"
13 | - "/"
14 |
15 | matchers:
16 | - type: status
17 | status:
18 | - 200
--------------------------------------------------------------------------------
/integration_tests/protocols/offlinehttp/offline-raw.yaml:
--------------------------------------------------------------------------------
1 | id: offline-raw
2 | info:
3 | name: Test Offline raw Template
4 | author: pdteam
5 | severity: info
6 |
7 | http:
8 | - raw:
9 | - |
10 | GET / HTTP/1.1
11 | Host: {{Hostname}}
12 |
13 | matchers:
14 | - type: status
15 | status:
16 | - 200
--------------------------------------------------------------------------------
/integration_tests/protocols/offlinehttp/rfc-req-resp.yaml:
--------------------------------------------------------------------------------
1 | id: rfc-req-resp
2 |
3 | info:
4 | name: Basic GET Request
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}"
12 | matchers:
13 | - type: word
14 | words:
15 | - "this is a line containing HTTP/1.1 FOO BAR"
--------------------------------------------------------------------------------
/integration_tests/protocols/ssl/basic-ztls.yaml:
--------------------------------------------------------------------------------
1 | id: basic-ssl-tls
2 |
3 | info:
4 | name: Basic SSL Request with ztls
5 | author: pdteam
6 | severity: info
7 |
8 | ssl:
9 | - address: "{{Host}}:{{Port}}"
10 |
11 | min_version: ssl30
12 | max_version: tls12
13 |
14 | matchers:
15 | - type: dsl
16 | dsl:
17 | - "tls_connection == 'ztls'"
18 |
--------------------------------------------------------------------------------
/integration_tests/protocols/ssl/basic.yaml:
--------------------------------------------------------------------------------
1 | id: basic-ssl
2 |
3 | info:
4 | name: Basic SSL Request
5 | author: pdteam
6 | severity: info
7 |
8 | ssl:
9 | - address: "{{Host}}:{{Port}}"
10 |
11 | matchers:
12 | - type: dsl
13 | dsl:
14 | - "probe_status == true"
15 |
--------------------------------------------------------------------------------
/integration_tests/protocols/ssl/custom-cipher.yaml:
--------------------------------------------------------------------------------
1 | id: custom-cipher
2 |
3 | info:
4 | name: Basic SSL Request
5 | author: pdteam
6 | severity: info
7 |
8 | ssl:
9 | - address: "{{Host}}:{{Port}}"
10 |
11 | cipher_suites:
12 | - TLS_AES_128_GCM_SHA256
13 |
14 | matchers:
15 | - type: word
16 | part: response
17 | words:
18 | - "TLS_AES_128_GCM_SHA256"
19 |
--------------------------------------------------------------------------------
/integration_tests/protocols/ssl/custom-version.yaml:
--------------------------------------------------------------------------------
1 | id: custom-version
2 |
3 | info:
4 | name: Basic SSL Request
5 | author: pdteam
6 | severity: info
7 |
8 | ssl:
9 | - address: "{{Host}}:{{Port}}"
10 |
11 | min_version: tls12
12 | max_version: tls12
13 |
14 | matchers:
15 | - type: word
16 | part: response
17 | words:
18 | - 'tls12'
19 |
--------------------------------------------------------------------------------
/integration_tests/protocols/ssl/multi-req.yaml:
--------------------------------------------------------------------------------
1 | id: multi-req
2 |
3 | info:
4 | name: Multi-Request
5 | author: pdteam
6 | severity: info
7 |
8 | ssl:
9 | - address: "{{Host}}:{{Port}}"
10 | min_version: ssl30
11 | max_version: ssl30
12 |
13 | extractors:
14 | - type: json
15 | json:
16 | - " .tls_version"
17 |
18 | - address: "{{Host}}:{{Port}}"
19 | min_version: tls10
20 | max_version: tls10
21 |
22 | extractors:
23 | - type: json
24 | json:
25 | - " .tls_version"
26 |
27 | - address: "{{Host}}:{{Port}}"
28 | min_version: tls11
29 | max_version: tls11
30 |
31 | extractors:
32 | - type: json
33 | json:
34 | - " .tls_version"
--------------------------------------------------------------------------------
/integration_tests/protocols/ssl/ssl-with-vars.yaml:
--------------------------------------------------------------------------------
1 | id: ssl-with-vars
2 |
3 | info:
4 | name: SSL with variables
5 | author: pdteam
6 | severity: info
7 | tags: ssl
8 |
9 | ssl:
10 | - address: "{{Host}}:{{Port}}"
11 | matchers:
12 | - type: dsl
13 | dsl:
14 | - "print_debug(test)"
15 |
--------------------------------------------------------------------------------
/integration_tests/protocols/websocket/basic.yaml:
--------------------------------------------------------------------------------
1 | id: basic-request
2 |
3 | info:
4 | name: Basic Request
5 | author: pdteam
6 | severity: info
7 |
8 | websocket:
9 | - address: '{{Scheme}}://{{Hostname}}'
10 | inputs:
11 | - data: hello
12 | matchers:
13 | - type: word
14 | words:
15 | - world
16 | part: response
--------------------------------------------------------------------------------
/integration_tests/protocols/websocket/cswsh.yaml:
--------------------------------------------------------------------------------
1 | id: basic-cswsh-request
2 |
3 | info:
4 | name: Basic cswsh Request
5 | author: pdteam
6 | severity: info
7 |
8 | websocket:
9 | - address: '{{Scheme}}://{{Hostname}}'
10 | headers:
11 | Origin: 'http://evil.com'
12 | matchers:
13 | - type: word
14 | words:
15 | - true
16 | part: success
--------------------------------------------------------------------------------
/integration_tests/protocols/websocket/no-cswsh.yaml:
--------------------------------------------------------------------------------
1 | id: basic-nocswsh-request
2 |
3 | info:
4 | name: Basic Non-Vulnerable cswsh Request
5 | author: pdteam
6 | severity: info
7 |
8 | websocket:
9 | - address: '{{Scheme}}://{{Hostname}}'
10 | headers:
11 | Origin: 'http://evil.com'
12 | matchers:
13 | - type: word
14 | words:
15 | - true
16 | part: success
--------------------------------------------------------------------------------
/integration_tests/protocols/websocket/path.yaml:
--------------------------------------------------------------------------------
1 | id: basic-request-path
2 |
3 | info:
4 | name: Basic Request Path
5 | author: pdteam
6 | severity: info
7 |
8 | websocket:
9 | - address: '{{Scheme}}://{{Hostname}}'
10 | inputs:
11 | - data: hello
12 | matchers:
13 | - type: word
14 | words:
15 | - world
16 | part: response
--------------------------------------------------------------------------------
/integration_tests/protocols/whois/basic.yaml:
--------------------------------------------------------------------------------
1 | id: basic-whois-example
2 |
3 | info:
4 | name: test template for WHOIS
5 | author: pdteam
6 | severity: info
7 |
8 | whois:
9 | - query: "{{Host}}"
10 | extractors:
11 | - type: kval
12 | kval:
13 | - "expiration date"
14 | - "registrar"
--------------------------------------------------------------------------------
/integration_tests/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | echo "::group::Build nuclei"
4 | rm integration-test fuzzplayground nuclei 2>/dev/null
5 | cd ../cmd/nuclei
6 | go build -race .
7 | mv nuclei ../../integration_tests/nuclei
8 | echo "::endgroup::"
9 |
10 | echo "::group::Build nuclei integration-test"
11 | cd ../integration-test
12 | go build
13 | mv integration-test ../../integration_tests/integration-test
14 | cd ../../integration_tests
15 | echo "::endgroup::"
16 |
17 | echo "::group::Installing nuclei templates"
18 | ./nuclei -update-templates
19 | echo "::endgroup::"
20 |
21 | ./integration-test
22 | if [ $? -eq 0 ]
23 | then
24 | exit 0
25 | else
26 | exit 1
27 | fi
28 |
--------------------------------------------------------------------------------
/integration_tests/subdomains.txt:
--------------------------------------------------------------------------------
1 | one
2 | docs
3 | drive
4 | play
5 |
6 |
--------------------------------------------------------------------------------
/integration_tests/workflow/basic.yaml:
--------------------------------------------------------------------------------
1 | id: workflow-example
2 |
3 | info:
4 | name: Test Workflow Template
5 | author: pdteam
6 | severity: info
7 |
8 | workflows:
9 | - template: workflow/match-1.yaml
10 | - template: workflow/match-2.yaml
--------------------------------------------------------------------------------
/integration_tests/workflow/code-template-1.yaml:
--------------------------------------------------------------------------------
1 | id: code-template-1
2 |
3 | info:
4 | name: code-template-1
5 | author: tovask
6 | severity: info
7 | tags: code
8 |
9 | code:
10 | - engine:
11 | - py
12 | - python3
13 | - python
14 | source: |
15 | print("hello from first")
16 | extractors:
17 | - type: regex
18 | name: extracted
19 | regex:
20 | - 'hello from (.*)'
21 | group: 1
22 | # digest: 490a0046304402206b3648e8d393ac4df82c7d59b1a6ee3731c66c249dbd4d9bf31f0b7f176b37ec02203184d36373e516757c7d708b5799bc16edb1cebc0a64f3442d13ded4b33c42fb:4a3eb6b4988d95847d4203be25ed1d46
--------------------------------------------------------------------------------
/integration_tests/workflow/code-template-2.yaml:
--------------------------------------------------------------------------------
1 | id: code-template-2
2 |
3 | info:
4 | name: code-template-2
5 | author: tovask
6 | severity: info
7 | tags: code
8 |
9 | code:
10 | - engine:
11 | - py
12 | - python3
13 | - python
14 | source: |
15 | import os
16 | print("hello from " + os.getenv("extracted"))
17 | matchers:
18 | - type: word
19 | words:
20 | - "hello from first"
21 | # digest: 490a0046304402204cbb1bdf8370e49bb930b17460fb35e15f285a3b48b165736ac0e7ba2f9bc0fb022067c134790c4a2cf646b195aa4488e2c222266436e6bda47931908a28807bdb81:4a3eb6b4988d95847d4203be25ed1d46
--------------------------------------------------------------------------------
/integration_tests/workflow/code-value-share-workflow.yaml:
--------------------------------------------------------------------------------
1 | id: code-value-sharing-workflow
2 |
3 | info:
4 | name: Code Value Sharing Workflow
5 | author: tovask
6 | severity: info
7 | tags: code
8 |
9 | workflows:
10 | - template: workflow/code-template-1.yaml
11 | subtemplates:
12 | - template: workflow/code-template-2.yaml
13 |
--------------------------------------------------------------------------------
/integration_tests/workflow/complex-conditions.yaml:
--------------------------------------------------------------------------------
1 | id: complex-conditions-workflow
2 |
3 | info:
4 | name: Complex Conditions Workflow
5 | author: tovask
6 | severity: info
7 | description: Workflow to test a complex scenario, e.g. race conditions when evaluating the results of the templates
8 |
9 | workflows:
10 | - template: workflow/match-1.yaml
11 | subtemplates:
12 | - template: workflow/nomatch-1.yaml
13 | subtemplates:
14 | - template: workflow/match-2.yaml
15 | - template: workflow/match-3.yaml
16 | - template: workflow/match-2.yaml
17 | matchers:
18 | - name: test-matcher
19 | subtemplates:
20 | - template: workflow/nomatch-1.yaml
21 | subtemplates:
22 | - template: workflow/match-1.yaml
23 | - template: workflow/match-3.yaml
24 |
--------------------------------------------------------------------------------
/integration_tests/workflow/condition-matched.yaml:
--------------------------------------------------------------------------------
1 | id: condition-matched-workflow
2 |
3 | info:
4 | name: Condition Matched Workflow
5 | author: pdteam
6 | severity: info
7 |
8 | workflows:
9 | - template: workflow/match-1.yaml
10 | subtemplates:
11 | - template: workflow/match-2.yaml
--------------------------------------------------------------------------------
/integration_tests/workflow/condition-unmatched.yaml:
--------------------------------------------------------------------------------
1 | id: condition-unmatched-workflow
2 |
3 | info:
4 | name: Condition UnMatched Workflow
5 | author: pdteam
6 | severity: info
7 |
8 | workflows:
9 | - template: workflow/nomatch-1.yaml
10 | subtemplates:
11 | - template: workflow/match-2.yaml
--------------------------------------------------------------------------------
/integration_tests/workflow/dns-value-share-template-1.yaml:
--------------------------------------------------------------------------------
1 | id: dns-value-sharing-template1
2 |
3 | info:
4 | name: dns-value-sharing-template1
5 | author: pdteam
6 | severity: info
7 |
8 | dns:
9 | - name: "{{FQDN}}"
10 | type: A
11 |
12 | extractors:
13 | - type: regex
14 | name: extracted
15 | group: 1
16 | regex:
17 | - "IN\tA\t(.+)"
--------------------------------------------------------------------------------
/integration_tests/workflow/dns-value-share-template-2.yaml:
--------------------------------------------------------------------------------
1 | id: dns-value-sharing-template2
2 |
3 | info:
4 | name: dns-value-sharing-template2
5 | author: pdteam
6 | severity: info
7 |
8 | dns:
9 | - name: "{{extracted}}"
10 | type: PTR
--------------------------------------------------------------------------------
/integration_tests/workflow/dns-value-share-template-3.yaml:
--------------------------------------------------------------------------------
1 | id: value-sharing-template2
2 |
3 | info:
4 | name: value-sharing-template2
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - raw:
10 | - |
11 | GET / HTTP/1.1
12 | Host: {{Hostname}}
13 |
14 | {{extracted}}
15 |
16 | matchers:
17 | - type: word
18 | words:
19 | - "ok"
--------------------------------------------------------------------------------
/integration_tests/workflow/dns-value-share-workflow.yaml:
--------------------------------------------------------------------------------
1 | id: dns-value-sharing-workflow
2 | info:
3 | name: DNS Value Sharing Test
4 | author: pdteam
5 | severity: info
6 |
7 | workflows:
8 | - template: workflow/dns-value-share-template-1.yaml
9 | subtemplates:
10 | - template: workflow/dns-value-share-template-2.yaml
11 | - template: workflow/dns-value-share-template-3.yaml
--------------------------------------------------------------------------------
/integration_tests/workflow/headless-1.yaml:
--------------------------------------------------------------------------------
1 | id: headless-1
2 | info:
3 | name: Headless 1
4 | author: pdteam
5 | severity: info
6 | tags: headless
7 |
8 | headless:
9 | - steps:
10 | - action: navigate
11 | args:
12 | url: "{{BaseURL}}/headless1"
13 |
14 | - action: waitload
15 |
--------------------------------------------------------------------------------
/integration_tests/workflow/http-1.yaml:
--------------------------------------------------------------------------------
1 | id: http1
2 |
3 | info:
4 | name: http1
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}/http1"
--------------------------------------------------------------------------------
/integration_tests/workflow/http-2.yaml:
--------------------------------------------------------------------------------
1 | id: http2
2 |
3 | info:
4 | name: http2
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}/http2"
--------------------------------------------------------------------------------
/integration_tests/workflow/http-3.yaml:
--------------------------------------------------------------------------------
1 | id: http3
2 |
3 | info:
4 | name: http3
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}/http3"
--------------------------------------------------------------------------------
/integration_tests/workflow/http-value-share-template-1.yaml:
--------------------------------------------------------------------------------
1 | id: value-sharing-template1
2 |
3 | info:
4 | name: value-sharing-template1
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - path:
10 | - "{{BaseURL}}/path1"
11 | extractors:
12 | - type: regex
13 | part: body
14 | name: extracted
15 | regex:
16 | - 'href="(.*)"'
17 | group: 1
--------------------------------------------------------------------------------
/integration_tests/workflow/http-value-share-template-2.yaml:
--------------------------------------------------------------------------------
1 | id: value-sharing-template2
2 |
3 | info:
4 | name: value-sharing-template2
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - raw:
10 | - |
11 | GET /path2 HTTP/1.1
12 | Host: {{Hostname}}
13 |
14 | {{extracted}}
15 |
16 | matchers:
17 | - type: word
18 | words:
19 | - "test-value"
--------------------------------------------------------------------------------
/integration_tests/workflow/http-value-share-workflow.yaml:
--------------------------------------------------------------------------------
1 | id: http-value-sharing-workflow
2 | info:
3 | name: HTTP Value Sharing Test
4 | author: pdteam
5 | severity: info
6 |
7 | workflows:
8 | - template: workflow/http-value-share-template-1.yaml
9 | subtemplates:
10 | - template: workflow/http-value-share-template-2.yaml
--------------------------------------------------------------------------------
/integration_tests/workflow/match-1.yaml:
--------------------------------------------------------------------------------
1 | id: basic-get
2 |
3 | info:
4 | name: Basic GET Request
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}"
12 | matchers:
13 | - type: word
14 | words:
15 | - "This is test matcher text"
--------------------------------------------------------------------------------
/integration_tests/workflow/match-2.yaml:
--------------------------------------------------------------------------------
1 | id: basic-get-another
2 |
3 | info:
4 | name: Basic Another GET Request
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}"
12 | matchers:
13 | - type: word
14 | name: test-matcher
15 | words:
16 | - "This is test matcher text"
--------------------------------------------------------------------------------
/integration_tests/workflow/match-3.yaml:
--------------------------------------------------------------------------------
1 | id: basic-get-third
2 |
3 | info:
4 | name: Basic 3rd GET Request
5 | author: tovask
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}"
12 | matchers:
13 | - type: word
14 | name: test-matcher-3
15 | words:
16 | - "This is test matcher text"
17 |
--------------------------------------------------------------------------------
/integration_tests/workflow/matcher-name.yaml:
--------------------------------------------------------------------------------
1 | id: matcher-name-workflow
2 |
3 | info:
4 | name: Matcher Name Workflow
5 | author: pdteam
6 | severity: info
7 |
8 | workflows:
9 | - template: workflow/match-2.yaml
10 | matchers:
11 | - name: test-matcher
12 | subtemplates:
13 | - template: workflow/match-1.yaml
--------------------------------------------------------------------------------
/integration_tests/workflow/multimatch-value-share-template.yaml:
--------------------------------------------------------------------------------
1 | id: multimatch-value-share-template
2 |
3 | info:
4 | name: MultiMatch Value Share Template
5 | author: tovask
6 | severity: info
7 |
8 | http:
9 | - path:
10 | - "{{BaseURL}}/path1?v=1"
11 | - "{{BaseURL}}/path1?v=2"
12 | matchers:
13 | - type: word
14 | name: test-matcher
15 | words:
16 | - "href"
17 | extractors:
18 | - type: regex
19 | part: body
20 | name: extracted
21 | regex:
22 | - 'href="(.*)"'
23 | group: 1
24 |
--------------------------------------------------------------------------------
/integration_tests/workflow/multimatch-value-share-workflow.yaml:
--------------------------------------------------------------------------------
1 | id: multimatch-value-share-workflow
2 |
3 | info:
4 | name: MultiMatch Value Share Workflow
5 | author: tovask
6 | severity: info
7 | description: Workflow to test value sharing when multiple matches occur in the extractor template
8 |
9 | workflows:
10 | - template: workflow/multimatch-value-share-template.yaml
11 | subtemplates:
12 | - template: workflow/match-1.yaml
13 | subtemplates:
14 | - template: workflow/http-value-share-template-2.yaml
15 | - template: workflow/multimatch-value-share-template.yaml
16 | matchers:
17 | - name: test-matcher
18 | subtemplates:
19 | - template: workflow/match-1.yaml
20 | subtemplates:
21 | - template: workflow/http-value-share-template-2.yaml
22 |
--------------------------------------------------------------------------------
/integration_tests/workflow/multiprotocol-value-share-template.yaml:
--------------------------------------------------------------------------------
1 | id: multiprotocol-value-sharing-template
2 |
3 | info:
4 | name: MultiProtocol Value Sharing Template
5 | author: tovask
6 | severity: info
7 |
8 | dns:
9 | - name: "{{extracted}}"
10 | type: PTR
11 | matchers:
12 | - type: word
13 | words:
14 | - "blog.projectdiscovery.io"
15 |
16 | http:
17 | - path:
18 | - "{{BaseURL}}/path2?extracted={{extracted}}"
19 | matchers:
20 | - type: word
21 | words:
22 | - "blog.projectdiscovery.io"
23 |
--------------------------------------------------------------------------------
/integration_tests/workflow/multiprotocol-value-share-workflow.yaml:
--------------------------------------------------------------------------------
1 | id: multiprotocol-value-sharing-workflow
2 |
3 | info:
4 | name: MultiProtocol Value Sharing Workflow
5 | author: tovask
6 | severity: info
7 |
8 | workflows:
9 | - template: workflow/http-value-share-template-1.yaml
10 | subtemplates:
11 | - template: workflow/multiprotocol-value-share-template.yaml
12 |
--------------------------------------------------------------------------------
/integration_tests/workflow/nomatch-1.yaml:
--------------------------------------------------------------------------------
1 | id: basic-get-nomatch
2 |
3 | info:
4 | name: Basic GET Request NoMatch
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}"
12 | matchers:
13 | - type: word
14 | words:
15 | - "Random"
--------------------------------------------------------------------------------
/integration_tests/workflow/shared-cookie.yaml:
--------------------------------------------------------------------------------
1 | id: workflow-shared-cookies
2 |
3 | info:
4 | name: Test Workflow Shared Cookies
5 | author: pdteam
6 | severity: info
7 |
8 | workflows:
9 | # store cookies to standard http client cookie-jar
10 | - template: workflow/http-1.yaml
11 | - template: workflow/http-2.yaml
12 | # store cookie in native browser context
13 | - template: workflow/headless-1.yaml
14 | # retrieve 2 standard library cookies + headless cookie
15 | - template: workflow/http-3.yaml
--------------------------------------------------------------------------------
/internal/pdcp/utils.go:
--------------------------------------------------------------------------------
1 | package pdcp
2 |
3 | import (
4 | pdcpauth "github.com/projectdiscovery/utils/auth/pdcp"
5 | urlutil "github.com/projectdiscovery/utils/url"
6 | )
7 |
8 | func getScanDashBoardURL(id string, teamID string) string {
9 | ux, _ := urlutil.Parse(pdcpauth.DashBoardURL)
10 | ux.Path = "/scans/" + id
11 | if ux.Params == nil {
12 | ux.Params = urlutil.NewOrderedParams()
13 | }
14 | if teamID != "" {
15 | ux.Params.Add("team_id", teamID)
16 | } else {
17 | ux.Params.Add("team_id", NoneTeamID)
18 | }
19 | ux.Update()
20 | return ux.String()
21 | }
22 |
23 | type uploadResponse struct {
24 | ID string `json:"id"`
25 | Message string `json:"message"`
26 | }
27 |
--------------------------------------------------------------------------------
/pkg/authprovider/authx/basic_auth.go:
--------------------------------------------------------------------------------
1 | package authx
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/projectdiscovery/retryablehttp-go"
7 | )
8 |
9 | var (
10 | _ AuthStrategy = &BasicAuthStrategy{}
11 | )
12 |
13 | // BasicAuthStrategy is a strategy for basic auth
14 | type BasicAuthStrategy struct {
15 | Data *Secret
16 | }
17 |
18 | // NewBasicAuthStrategy creates a new basic auth strategy
19 | func NewBasicAuthStrategy(data *Secret) *BasicAuthStrategy {
20 | return &BasicAuthStrategy{Data: data}
21 | }
22 |
23 | // Apply applies the basic auth strategy to the request
24 | func (s *BasicAuthStrategy) Apply(req *http.Request) {
25 | req.SetBasicAuth(s.Data.Username, s.Data.Password)
26 | }
27 |
28 | // ApplyOnRR applies the basic auth strategy to the retryable request
29 | func (s *BasicAuthStrategy) ApplyOnRR(req *retryablehttp.Request) {
30 | req.SetBasicAuth(s.Data.Username, s.Data.Password)
31 | }
32 |
--------------------------------------------------------------------------------
/pkg/authprovider/authx/file_test.go:
--------------------------------------------------------------------------------
1 | package authx
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/require"
7 | )
8 |
9 | func TestSecretsUnmarshal(t *testing.T) {
10 | loc := "testData/example-auth.yaml"
11 | data, err := GetAuthDataFromFile(loc)
12 | require.Nil(t, err, "could not read secrets file")
13 | require.NotNil(t, data, "could not read secrets file")
14 | for _, s := range data.Secrets {
15 | require.Nil(t, s.Validate(), "could not validate secret")
16 | }
17 | for _, d := range data.Dynamic {
18 | require.Nil(t, d.Validate(), "could not validate dynamic")
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/pkg/catalog/config/ignorefile.go:
--------------------------------------------------------------------------------
1 | package config
2 |
3 | import (
4 | "os"
5 |
6 | "github.com/projectdiscovery/gologger"
7 | "gopkg.in/yaml.v2"
8 | )
9 |
10 | // IgnoreFile is an internal nuclei template blocking configuration file
11 | type IgnoreFile struct {
12 | Tags []string `yaml:"tags"`
13 | Files []string `yaml:"files"`
14 | }
15 |
16 | // ReadIgnoreFile reads the nuclei ignore file returning blocked tags and paths
17 | func ReadIgnoreFile() IgnoreFile {
18 | file, err := os.Open(DefaultConfig.GetIgnoreFilePath())
19 | if err != nil {
20 | gologger.Error().Msgf("Could not read nuclei-ignore file: %s\n", err)
21 | return IgnoreFile{}
22 | }
23 | defer file.Close()
24 |
25 | ignore := IgnoreFile{}
26 | if err := yaml.NewDecoder(file).Decode(&ignore); err != nil {
27 | gologger.Error().Msgf("Could not parse nuclei-ignore file: %s\n", err)
28 | return IgnoreFile{}
29 | }
30 | return ignore
31 | }
32 |
--------------------------------------------------------------------------------
/pkg/catalog/disk/known-files.go:
--------------------------------------------------------------------------------
1 | package disk
2 |
3 | var knownConfigFiles = []string{"cves.json", "contributors.json", "TEMPLATES-STATS.json"}
4 |
--------------------------------------------------------------------------------
/pkg/core/engine_test.go:
--------------------------------------------------------------------------------
1 | package core
2 |
--------------------------------------------------------------------------------
/pkg/fuzz/dataformat/raw.go:
--------------------------------------------------------------------------------
1 | package dataformat
2 |
3 | type Raw struct{}
4 |
5 | var (
6 | _ DataFormat = &Raw{}
7 | )
8 |
9 | // NewRaw returns a new Raw encoder
10 | func NewRaw() *Raw {
11 | return &Raw{}
12 | }
13 |
14 | // IsType returns true if the data is Raw encoded
15 | func (r *Raw) IsType(data string) bool {
16 | return false
17 | }
18 |
19 | // Encode encodes the data into Raw format
20 | func (r *Raw) Encode(data KV) (string, error) {
21 | return data.Get("value").(string), nil
22 | }
23 |
24 | // Decode decodes the data from Raw format
25 | func (r *Raw) Decode(data string) (KV, error) {
26 | return KVMap(map[string]interface{}{
27 | "value": data,
28 | }), nil
29 | }
30 |
31 | // Name returns the name of the encoder
32 | func (r *Raw) Name() string {
33 | return RawDataFormat
34 | }
35 |
--------------------------------------------------------------------------------
/pkg/fuzz/doc.go:
--------------------------------------------------------------------------------
1 | // Package fuzz contains the fuzzing functionality for dynamic
2 | // fuzzing of HTTP requests and its respective implementation.
3 | package fuzz
4 |
--------------------------------------------------------------------------------
/pkg/fuzz/parts_test.go:
--------------------------------------------------------------------------------
1 | // TODO: Write tests
2 | package fuzz
3 |
--------------------------------------------------------------------------------
/pkg/fuzz/stats/db.go:
--------------------------------------------------------------------------------
1 | package stats
2 |
3 | import (
4 | _ "embed"
5 |
6 | _ "github.com/mattn/go-sqlite3"
7 | )
8 |
9 | type StatsDatabase interface {
10 | Close()
11 |
12 | InsertComponent(event ComponentEvent) error
13 | InsertMatchedRecord(event FuzzingEvent) error
14 | InsertError(event ErrorEvent) error
15 | }
16 |
--------------------------------------------------------------------------------
/pkg/fuzz/stats/db_test.go:
--------------------------------------------------------------------------------
1 | package stats
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/require"
7 | )
8 |
9 | func Test_NewStatsDatabase(t *testing.T) {
10 | db, err := NewSimpleStats()
11 | require.NoError(t, err)
12 |
13 | err = db.InsertMatchedRecord(FuzzingEvent{
14 | URL: "http://localhost:8080/login",
15 | TemplateID: "apache-struts2-001",
16 | ComponentType: "path",
17 | ComponentName: "/login",
18 | PayloadSent: "/login'\"><",
19 | StatusCode: 401,
20 | })
21 | require.NoError(t, err)
22 |
23 | //os.Remove("test.stats.db")
24 | }
25 |
--------------------------------------------------------------------------------
/pkg/input/provider/list/utils.go:
--------------------------------------------------------------------------------
1 | package list
2 |
3 | type ipOptions struct {
4 | ScanAllIPs bool
5 | IPV4 bool
6 | IPV6 bool
7 | }
8 |
--------------------------------------------------------------------------------
/pkg/input/types/probe.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | // InputLivenessProbe is an interface for probing the liveness of an input
4 | type InputLivenessProbe interface {
5 | // ProbeURL probes the scheme for a URL. first HTTPS is tried
6 | ProbeURL(input string) (string, error)
7 | // Close closes the liveness probe
8 | Close() error
9 | }
10 |
--------------------------------------------------------------------------------
/pkg/installer/doc.go:
--------------------------------------------------------------------------------
1 | package installer
2 |
3 | // package install provides helper functions for all download and installation of following tasks:
4 | // 1. downloading and install nuclei templates
5 | // 2. download and update nuclei binary (i.e self update)
6 | // 3. version check for nuclei binary & templates
7 |
--------------------------------------------------------------------------------
/pkg/installer/versioncheck_test.go:
--------------------------------------------------------------------------------
1 | package installer
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/projectdiscovery/nuclei/v3/pkg/catalog/config"
7 | "github.com/projectdiscovery/utils/generic"
8 | "github.com/stretchr/testify/require"
9 | )
10 |
11 | func TestVersionCheck(t *testing.T) {
12 | err := NucleiVersionCheck()
13 | require.Nil(t, err)
14 | cfg := config.DefaultConfig
15 | if generic.EqualsAny("", cfg.LatestNucleiIgnoreHash, cfg.LatestNucleiVersion, cfg.LatestNucleiTemplatesVersion) {
16 | // all above values cannot be empty
17 | t.Errorf("something went wrong got empty response nuclei-version=%v templates-version=%v ignore-hash=%v", cfg.LatestNucleiVersion, cfg.LatestNucleiTemplatesVersion, cfg.LatestNucleiIgnoreHash)
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/pkg/js/THANKS.md:
--------------------------------------------------------------------------------
1 | # THANKS
2 |
3 | - https://github.com/dop251/goja - Pure Go Javascript VM used by nuclei JS layer.
4 | - https://github.com/gogap/gojs-tool - Inspiration for code generation used in JS Libraries addition.
5 | - https://github.com/ropnop/kerbrute - Kerberos Module of JS layer
6 | - https://github.com/praetorian-inc/fingerprintx - A lot of Network Protocol fingerprinting functionality is used from `fingerprintx` package.
7 | - https://github.com/zmap/zgrab2 - Used for SMB and SSH protocol handshake Metadata gathering.
8 |
9 | A lot of other Go based libraries are used in the javascript layer. Thanks goes to the creators and maintainers.
--------------------------------------------------------------------------------
/pkg/js/compiler/init.go:
--------------------------------------------------------------------------------
1 | package compiler
2 |
3 | import (
4 | "github.com/projectdiscovery/nuclei/v3/pkg/types"
5 | )
6 |
7 | // jsprotocolInit
8 |
9 | var (
10 | PoolingJsVmConcurrency = 100
11 | NonPoolingVMConcurrency = 20
12 | )
13 |
14 | // Init initializes the javascript protocol
15 | func Init(opts *types.Options) error {
16 |
17 | if opts.JsConcurrency < 100 {
18 | // 100 is reasonable default
19 | opts.JsConcurrency = 100
20 | }
21 | PoolingJsVmConcurrency = opts.JsConcurrency
22 | PoolingJsVmConcurrency -= NonPoolingVMConcurrency
23 | return nil
24 | }
25 |
--------------------------------------------------------------------------------
/pkg/js/compiler/non-pool.go:
--------------------------------------------------------------------------------
1 | package compiler
2 |
3 | import (
4 | "sync"
5 |
6 | "github.com/dop251/goja"
7 | syncutil "github.com/projectdiscovery/utils/sync"
8 | )
9 |
10 | var (
11 | ephemeraljsc *syncutil.AdaptiveWaitGroup
12 | lazyFixedSgInit = sync.OnceFunc(func() {
13 | ephemeraljsc, _ = syncutil.New(syncutil.WithSize(NonPoolingVMConcurrency))
14 | })
15 | )
16 |
17 | func executeWithoutPooling(p *goja.Program, args *ExecuteArgs, opts *ExecuteOptions) (result goja.Value, err error) {
18 | lazyFixedSgInit()
19 | ephemeraljsc.Add()
20 | defer ephemeraljsc.Done()
21 | runtime := createNewRuntime()
22 | return executeWithRuntime(runtime, p, args, opts)
23 | }
24 |
--------------------------------------------------------------------------------
/pkg/js/devtools/bindgen/INSTALL.md:
--------------------------------------------------------------------------------
1 | # INSTALL
2 |
3 | 1. Requires `js-beautify` node plugin installed in `$PATH`.
4 | 2. Requires `gofmt` installed in `$PATH`.
5 |
--------------------------------------------------------------------------------
/pkg/js/devtools/bindgen/README.md:
--------------------------------------------------------------------------------
1 | ## bindgen (aka bindings generator)
2 |
3 | bindgen is a tool that automatically generated bindings for native go packages with 'goja'
4 |
5 | Native Go packages are available [here](../../libs/)
6 |
7 | Generated Output is available [here](../../generated/)
8 |
9 | bindgen generates 3 different types of outputs
10 |
11 | - `go` => this directory contains corresponding goja bindings (actual bindings code) ex: [kerberos.go](../../generated/go/libkerberos/kerberos.go)
12 | - `js` => this is more of a javascript **representation** of all exposed functions and types etc in javascript ex: [kerberos.js](../../generated/js/libkerberos/kerberos.js) and does not server any functional purpose other than reference
13 | - `markdown` => autogenerated markdown documentation for each library / package ex: [kerberos.md](../../generated/markdown/libkerberos/kerberos.md)
14 |
15 |
--------------------------------------------------------------------------------
/pkg/js/devtools/tsgen/README.md:
--------------------------------------------------------------------------------
1 | # tsgen
2 |
3 | tsgen is devtool to generate dummy typescript code for goja node modules written in golang. These generated typescript code can be compiled to generate .d.ts files to provide intellisense to editors like vscode and documentation for the node modules.
--------------------------------------------------------------------------------
/pkg/js/generated/README.md:
--------------------------------------------------------------------------------
1 | ## generated
2 |
3 | !! Warning !! This is generated code, do not edit manually !!
4 |
5 | To make any changes to this code, please refer to [bindgen](../devtools/bindgen/README.md)
--------------------------------------------------------------------------------
/pkg/js/generated/go/libbytes/bytes.go:
--------------------------------------------------------------------------------
1 | package bytes
2 |
3 | import (
4 | lib_bytes "github.com/projectdiscovery/nuclei/v3/pkg/js/libs/bytes"
5 |
6 | "github.com/dop251/goja"
7 | "github.com/projectdiscovery/nuclei/v3/pkg/js/gojs"
8 | )
9 |
10 | var (
11 | module = gojs.NewGojaModule("nuclei/bytes")
12 | )
13 |
14 | func init() {
15 | module.Set(
16 | gojs.Objects{
17 | // Functions
18 | "NewBuffer": lib_bytes.NewBuffer,
19 |
20 | // Var and consts
21 |
22 | // Objects / Classes
23 | "Buffer": lib_bytes.NewBuffer,
24 | },
25 | ).Register()
26 | }
27 |
28 | func Enable(runtime *goja.Runtime) {
29 | module.Enable(runtime)
30 | }
31 |
--------------------------------------------------------------------------------
/pkg/js/generated/go/libfs/fs.go:
--------------------------------------------------------------------------------
1 | package fs
2 |
3 | import (
4 | lib_fs "github.com/projectdiscovery/nuclei/v3/pkg/js/libs/fs"
5 |
6 | "github.com/dop251/goja"
7 | "github.com/projectdiscovery/nuclei/v3/pkg/js/gojs"
8 | )
9 |
10 | var (
11 | module = gojs.NewGojaModule("nuclei/fs")
12 | )
13 |
14 | func init() {
15 | module.Set(
16 | gojs.Objects{
17 | // Functions
18 | "ListDir": lib_fs.ListDir,
19 | "ReadFile": lib_fs.ReadFile,
20 | "ReadFileAsString": lib_fs.ReadFileAsString,
21 | "ReadFilesFromDir": lib_fs.ReadFilesFromDir,
22 |
23 | // Var and consts
24 |
25 | // Objects / Classes
26 |
27 | },
28 | ).Register()
29 | }
30 |
31 | func Enable(runtime *goja.Runtime) {
32 | module.Enable(runtime)
33 | }
34 |
--------------------------------------------------------------------------------
/pkg/js/generated/go/libgoconsole/goconsole.go:
--------------------------------------------------------------------------------
1 | package goconsole
2 |
3 | import (
4 | lib_goconsole "github.com/projectdiscovery/nuclei/v3/pkg/js/libs/goconsole"
5 |
6 | "github.com/dop251/goja"
7 | "github.com/projectdiscovery/nuclei/v3/pkg/js/gojs"
8 | )
9 |
10 | var (
11 | module = gojs.NewGojaModule("nuclei/goconsole")
12 | )
13 |
14 | func init() {
15 | module.Set(
16 | gojs.Objects{
17 | // Functions
18 | "NewGoConsolePrinter": lib_goconsole.NewGoConsolePrinter,
19 |
20 | // Var and consts
21 |
22 | // Objects / Classes
23 | "GoConsolePrinter": gojs.GetClassConstructor[lib_goconsole.GoConsolePrinter](&lib_goconsole.GoConsolePrinter{}),
24 | },
25 | ).Register()
26 | }
27 |
28 | func Enable(runtime *goja.Runtime) {
29 | module.Enable(runtime)
30 | }
31 |
--------------------------------------------------------------------------------
/pkg/js/generated/go/libmssql/mssql.go:
--------------------------------------------------------------------------------
1 | package mssql
2 |
3 | import (
4 | lib_mssql "github.com/projectdiscovery/nuclei/v3/pkg/js/libs/mssql"
5 |
6 | "github.com/dop251/goja"
7 | "github.com/projectdiscovery/nuclei/v3/pkg/js/gojs"
8 | )
9 |
10 | var (
11 | module = gojs.NewGojaModule("nuclei/mssql")
12 | )
13 |
14 | func init() {
15 | module.Set(
16 | gojs.Objects{
17 | // Functions
18 |
19 | // Var and consts
20 |
21 | // Objects / Classes
22 | "MSSQLClient": gojs.GetClassConstructor[lib_mssql.MSSQLClient](&lib_mssql.MSSQLClient{}),
23 | },
24 | ).Register()
25 | }
26 |
27 | func Enable(runtime *goja.Runtime) {
28 | module.Enable(runtime)
29 | }
30 |
--------------------------------------------------------------------------------
/pkg/js/generated/go/libmysql/mysql.go:
--------------------------------------------------------------------------------
1 | package mysql
2 |
3 | import (
4 | lib_mysql "github.com/projectdiscovery/nuclei/v3/pkg/js/libs/mysql"
5 |
6 | "github.com/dop251/goja"
7 | "github.com/projectdiscovery/nuclei/v3/pkg/js/gojs"
8 | )
9 |
10 | var (
11 | module = gojs.NewGojaModule("nuclei/mysql")
12 | )
13 |
14 | func init() {
15 | module.Set(
16 | gojs.Objects{
17 | // Functions
18 | "BuildDSN": lib_mysql.BuildDSN,
19 |
20 | // Var and consts
21 |
22 | // Objects / Classes
23 | "MySQLClient": gojs.GetClassConstructor[lib_mysql.MySQLClient](&lib_mysql.MySQLClient{}),
24 | "MySQLInfo": gojs.GetClassConstructor[lib_mysql.MySQLInfo](&lib_mysql.MySQLInfo{}),
25 | "MySQLOptions": gojs.GetClassConstructor[lib_mysql.MySQLOptions](&lib_mysql.MySQLOptions{}),
26 | },
27 | ).Register()
28 | }
29 |
30 | func Enable(runtime *goja.Runtime) {
31 | module.Enable(runtime)
32 | }
33 |
--------------------------------------------------------------------------------
/pkg/js/generated/go/libnet/net.go:
--------------------------------------------------------------------------------
1 | package net
2 |
3 | import (
4 | lib_net "github.com/projectdiscovery/nuclei/v3/pkg/js/libs/net"
5 |
6 | "github.com/dop251/goja"
7 | "github.com/projectdiscovery/nuclei/v3/pkg/js/gojs"
8 | )
9 |
10 | var (
11 | module = gojs.NewGojaModule("nuclei/net")
12 | )
13 |
14 | func init() {
15 | module.Set(
16 | gojs.Objects{
17 | // Functions
18 | "Open": lib_net.Open,
19 | "OpenTLS": lib_net.OpenTLS,
20 |
21 | // Var and consts
22 |
23 | // Objects / Classes
24 | "NetConn": gojs.GetClassConstructor[lib_net.NetConn](&lib_net.NetConn{}),
25 | },
26 | ).Register()
27 | }
28 |
29 | func Enable(runtime *goja.Runtime) {
30 | module.Enable(runtime)
31 | }
32 |
--------------------------------------------------------------------------------
/pkg/js/generated/go/liboracle/oracle.go:
--------------------------------------------------------------------------------
1 | package oracle
2 |
3 | import (
4 | lib_oracle "github.com/projectdiscovery/nuclei/v3/pkg/js/libs/oracle"
5 |
6 | "github.com/dop251/goja"
7 | "github.com/projectdiscovery/nuclei/v3/pkg/js/gojs"
8 | )
9 |
10 | var (
11 | module = gojs.NewGojaModule("nuclei/oracle")
12 | )
13 |
14 | func init() {
15 | module.Set(
16 | gojs.Objects{
17 | // Functions
18 | "IsOracle": lib_oracle.IsOracle,
19 |
20 | // Var and consts
21 |
22 | // Objects / Classes
23 | "IsOracleResponse": gojs.GetClassConstructor[lib_oracle.IsOracleResponse](&lib_oracle.IsOracleResponse{}),
24 | },
25 | ).Register()
26 | }
27 |
28 | func Enable(runtime *goja.Runtime) {
29 | module.Enable(runtime)
30 | }
31 |
--------------------------------------------------------------------------------
/pkg/js/generated/go/libpop3/pop3.go:
--------------------------------------------------------------------------------
1 | package pop3
2 |
3 | import (
4 | lib_pop3 "github.com/projectdiscovery/nuclei/v3/pkg/js/libs/pop3"
5 |
6 | "github.com/dop251/goja"
7 | "github.com/projectdiscovery/nuclei/v3/pkg/js/gojs"
8 | )
9 |
10 | var (
11 | module = gojs.NewGojaModule("nuclei/pop3")
12 | )
13 |
14 | func init() {
15 | module.Set(
16 | gojs.Objects{
17 | // Functions
18 | "IsPOP3": lib_pop3.IsPOP3,
19 |
20 | // Var and consts
21 |
22 | // Objects / Classes
23 | "IsPOP3Response": gojs.GetClassConstructor[lib_pop3.IsPOP3Response](&lib_pop3.IsPOP3Response{}),
24 | },
25 | ).Register()
26 | }
27 |
28 | func Enable(runtime *goja.Runtime) {
29 | module.Enable(runtime)
30 | }
31 |
--------------------------------------------------------------------------------
/pkg/js/generated/go/libpostgres/postgres.go:
--------------------------------------------------------------------------------
1 | package postgres
2 |
3 | import (
4 | lib_postgres "github.com/projectdiscovery/nuclei/v3/pkg/js/libs/postgres"
5 |
6 | "github.com/dop251/goja"
7 | "github.com/projectdiscovery/nuclei/v3/pkg/js/gojs"
8 | )
9 |
10 | var (
11 | module = gojs.NewGojaModule("nuclei/postgres")
12 | )
13 |
14 | func init() {
15 | module.Set(
16 | gojs.Objects{
17 | // Functions
18 |
19 | // Var and consts
20 |
21 | // Objects / Classes
22 | "PGClient": gojs.GetClassConstructor[lib_postgres.PGClient](&lib_postgres.PGClient{}),
23 | },
24 | ).Register()
25 | }
26 |
27 | func Enable(runtime *goja.Runtime) {
28 | module.Enable(runtime)
29 | }
30 |
--------------------------------------------------------------------------------
/pkg/js/generated/go/librdp/rdp.go:
--------------------------------------------------------------------------------
1 | package rdp
2 |
3 | import (
4 | lib_rdp "github.com/projectdiscovery/nuclei/v3/pkg/js/libs/rdp"
5 |
6 | "github.com/dop251/goja"
7 | "github.com/projectdiscovery/nuclei/v3/pkg/js/gojs"
8 | )
9 |
10 | var (
11 | module = gojs.NewGojaModule("nuclei/rdp")
12 | )
13 |
14 | func init() {
15 | module.Set(
16 | gojs.Objects{
17 | // Functions
18 | "CheckRDPAuth": lib_rdp.CheckRDPAuth,
19 | "IsRDP": lib_rdp.IsRDP,
20 |
21 | // Var and consts
22 |
23 | // Objects / Classes
24 | "CheckRDPAuthResponse": gojs.GetClassConstructor[lib_rdp.CheckRDPAuthResponse](&lib_rdp.CheckRDPAuthResponse{}),
25 | "IsRDPResponse": gojs.GetClassConstructor[lib_rdp.IsRDPResponse](&lib_rdp.IsRDPResponse{}),
26 | },
27 | ).Register()
28 | }
29 |
30 | func Enable(runtime *goja.Runtime) {
31 | module.Enable(runtime)
32 | }
33 |
--------------------------------------------------------------------------------
/pkg/js/generated/go/libredis/redis.go:
--------------------------------------------------------------------------------
1 | package redis
2 |
3 | import (
4 | lib_redis "github.com/projectdiscovery/nuclei/v3/pkg/js/libs/redis"
5 |
6 | "github.com/dop251/goja"
7 | "github.com/projectdiscovery/nuclei/v3/pkg/js/gojs"
8 | )
9 |
10 | var (
11 | module = gojs.NewGojaModule("nuclei/redis")
12 | )
13 |
14 | func init() {
15 | module.Set(
16 | gojs.Objects{
17 | // Functions
18 | "Connect": lib_redis.Connect,
19 | "GetServerInfo": lib_redis.GetServerInfo,
20 | "GetServerInfoAuth": lib_redis.GetServerInfoAuth,
21 | "IsAuthenticated": lib_redis.IsAuthenticated,
22 | "RunLuaScript": lib_redis.RunLuaScript,
23 |
24 | // Var and consts
25 |
26 | // Objects / Classes
27 |
28 | },
29 | ).Register()
30 | }
31 |
32 | func Enable(runtime *goja.Runtime) {
33 | module.Enable(runtime)
34 | }
35 |
--------------------------------------------------------------------------------
/pkg/js/generated/go/librsync/rsync.go:
--------------------------------------------------------------------------------
1 | package rsync
2 |
3 | import (
4 | lib_rsync "github.com/projectdiscovery/nuclei/v3/pkg/js/libs/rsync"
5 |
6 | "github.com/dop251/goja"
7 | "github.com/projectdiscovery/nuclei/v3/pkg/js/gojs"
8 | )
9 |
10 | var (
11 | module = gojs.NewGojaModule("nuclei/rsync")
12 | )
13 |
14 | func init() {
15 | module.Set(
16 | gojs.Objects{
17 | // Functions
18 | "IsRsync": lib_rsync.IsRsync,
19 |
20 | // Var and consts
21 |
22 | // Objects / Classes
23 | "IsRsyncResponse": gojs.GetClassConstructor[lib_rsync.IsRsyncResponse](&lib_rsync.IsRsyncResponse{}),
24 | },
25 | ).Register()
26 | }
27 |
28 | func Enable(runtime *goja.Runtime) {
29 | module.Enable(runtime)
30 | }
31 |
--------------------------------------------------------------------------------
/pkg/js/generated/go/libsmb/smb.go:
--------------------------------------------------------------------------------
1 | package smb
2 |
3 | import (
4 | lib_smb "github.com/projectdiscovery/nuclei/v3/pkg/js/libs/smb"
5 |
6 | "github.com/dop251/goja"
7 | "github.com/projectdiscovery/nuclei/v3/pkg/js/gojs"
8 | )
9 |
10 | var (
11 | module = gojs.NewGojaModule("nuclei/smb")
12 | )
13 |
14 | func init() {
15 | module.Set(
16 | gojs.Objects{
17 | // Functions
18 |
19 | // Var and consts
20 |
21 | // Objects / Classes
22 | "SMBClient": gojs.GetClassConstructor[lib_smb.SMBClient](&lib_smb.SMBClient{}),
23 | },
24 | ).Register()
25 | }
26 |
27 | func Enable(runtime *goja.Runtime) {
28 | module.Enable(runtime)
29 | }
30 |
--------------------------------------------------------------------------------
/pkg/js/generated/go/libsmtp/smtp.go:
--------------------------------------------------------------------------------
1 | package smtp
2 |
3 | import (
4 | lib_smtp "github.com/projectdiscovery/nuclei/v3/pkg/js/libs/smtp"
5 |
6 | "github.com/dop251/goja"
7 | "github.com/projectdiscovery/nuclei/v3/pkg/js/gojs"
8 | )
9 |
10 | var (
11 | module = gojs.NewGojaModule("nuclei/smtp")
12 | )
13 |
14 | func init() {
15 | module.Set(
16 | gojs.Objects{
17 | // Functions
18 | "NewSMTPClient": lib_smtp.NewSMTPClient,
19 |
20 | // Var and consts
21 |
22 | // Objects / Classes
23 | "Client": lib_smtp.NewSMTPClient,
24 | "SMTPMessage": gojs.GetClassConstructor[lib_smtp.SMTPMessage](&lib_smtp.SMTPMessage{}),
25 | "SMTPResponse": gojs.GetClassConstructor[lib_smtp.SMTPResponse](&lib_smtp.SMTPResponse{}),
26 | },
27 | ).Register()
28 | }
29 |
30 | func Enable(runtime *goja.Runtime) {
31 | module.Enable(runtime)
32 | }
33 |
--------------------------------------------------------------------------------
/pkg/js/generated/go/libssh/ssh.go:
--------------------------------------------------------------------------------
1 | package ssh
2 |
3 | import (
4 | lib_ssh "github.com/projectdiscovery/nuclei/v3/pkg/js/libs/ssh"
5 |
6 | "github.com/dop251/goja"
7 | "github.com/projectdiscovery/nuclei/v3/pkg/js/gojs"
8 | )
9 |
10 | var (
11 | module = gojs.NewGojaModule("nuclei/ssh")
12 | )
13 |
14 | func init() {
15 | module.Set(
16 | gojs.Objects{
17 | // Functions
18 |
19 | // Var and consts
20 |
21 | // Objects / Classes
22 | "SSHClient": gojs.GetClassConstructor[lib_ssh.SSHClient](&lib_ssh.SSHClient{}),
23 | },
24 | ).Register()
25 | }
26 |
27 | func Enable(runtime *goja.Runtime) {
28 | module.Enable(runtime)
29 | }
30 |
--------------------------------------------------------------------------------
/pkg/js/generated/go/libstructs/structs.go:
--------------------------------------------------------------------------------
1 | package structs
2 |
3 | import (
4 | lib_structs "github.com/projectdiscovery/nuclei/v3/pkg/js/libs/structs"
5 |
6 | "github.com/dop251/goja"
7 | "github.com/projectdiscovery/nuclei/v3/pkg/js/gojs"
8 | )
9 |
10 | var (
11 | module = gojs.NewGojaModule("nuclei/structs")
12 | )
13 |
14 | func init() {
15 | module.Set(
16 | gojs.Objects{
17 | // Functions
18 | "Pack": lib_structs.Pack,
19 | "StructsCalcSize": lib_structs.StructsCalcSize,
20 | "Unpack": lib_structs.Unpack,
21 |
22 | // Var and consts
23 |
24 | // Objects / Classes
25 |
26 | },
27 | ).Register()
28 | }
29 |
30 | func Enable(runtime *goja.Runtime) {
31 | module.Enable(runtime)
32 | }
33 |
--------------------------------------------------------------------------------
/pkg/js/generated/go/libtelnet/telnet.go:
--------------------------------------------------------------------------------
1 | package telnet
2 |
3 | import (
4 | lib_telnet "github.com/projectdiscovery/nuclei/v3/pkg/js/libs/telnet"
5 |
6 | "github.com/dop251/goja"
7 | "github.com/projectdiscovery/nuclei/v3/pkg/js/gojs"
8 | )
9 |
10 | var (
11 | module = gojs.NewGojaModule("nuclei/telnet")
12 | )
13 |
14 | func init() {
15 | module.Set(
16 | gojs.Objects{
17 | // Functions
18 | "IsTelnet": lib_telnet.IsTelnet,
19 |
20 | // Var and consts
21 |
22 | // Objects / Classes
23 | "IsTelnetResponse": gojs.GetClassConstructor[lib_telnet.IsTelnetResponse](&lib_telnet.IsTelnetResponse{}),
24 | },
25 | ).Register()
26 | }
27 |
28 | func Enable(runtime *goja.Runtime) {
29 | module.Enable(runtime)
30 | }
31 |
--------------------------------------------------------------------------------
/pkg/js/generated/go/libvnc/vnc.go:
--------------------------------------------------------------------------------
1 | package vnc
2 |
3 | import (
4 | lib_vnc "github.com/projectdiscovery/nuclei/v3/pkg/js/libs/vnc"
5 |
6 | "github.com/dop251/goja"
7 | "github.com/projectdiscovery/nuclei/v3/pkg/js/gojs"
8 | )
9 |
10 | var (
11 | module = gojs.NewGojaModule("nuclei/vnc")
12 | )
13 |
14 | func init() {
15 | module.Set(
16 | gojs.Objects{
17 | // Functions
18 | "IsVNC": lib_vnc.IsVNC,
19 |
20 | // Var and consts
21 |
22 | // Objects / Classes
23 | "IsVNCResponse": gojs.GetClassConstructor[lib_vnc.IsVNCResponse](&lib_vnc.IsVNCResponse{}),
24 | },
25 | ).Register()
26 | }
27 |
28 | func Enable(runtime *goja.Runtime) {
29 | module.Enable(runtime)
30 | }
31 |
--------------------------------------------------------------------------------
/pkg/js/generated/ts/goconsole.ts:
--------------------------------------------------------------------------------
1 |
2 |
3 | /**
4 | * NewGoConsolePrinter Function
5 | */
6 | export function NewGoConsolePrinter(): GoConsolePrinter {
7 | return new GoConsolePrinter();
8 | }
9 |
10 |
11 |
12 | /**
13 | */
14 | export class GoConsolePrinter {
15 |
16 |
17 | // Constructor of GoConsolePrinter
18 | constructor() {}
19 | /**
20 | * Log Method
21 | */
22 | public Log(msg: string): void {
23 | return;
24 | }
25 |
26 |
27 | /**
28 | * Warn Method
29 | */
30 | public Warn(msg: string): void {
31 | return;
32 | }
33 |
34 |
35 | /**
36 | * Error Method
37 | */
38 | public Error(msg: string): void {
39 | return;
40 | }
41 |
42 |
43 | }
44 |
45 |
--------------------------------------------------------------------------------
/pkg/js/generated/ts/index.ts:
--------------------------------------------------------------------------------
1 | export * as bytes from './bytes';
2 | export * as fs from './fs';
3 | export * as goconsole from './goconsole';
4 | export * as ikev2 from './ikev2';
5 | export * as kerberos from './kerberos';
6 | export * as ldap from './ldap';
7 | export * as mssql from './mssql';
8 | export * as mysql from './mysql';
9 | export * as net from './net';
10 | export * as oracle from './oracle';
11 | export * as pop3 from './pop3';
12 | export * as postgres from './postgres';
13 | export * as rdp from './rdp';
14 | export * as redis from './redis';
15 | export * as rsync from './rsync';
16 | export * as smb from './smb';
17 | export * as smtp from './smtp';
18 | export * as ssh from './ssh';
19 | export * as structs from './structs';
20 | export * as telnet from './telnet';
21 | export * as vnc from './vnc';
22 |
--------------------------------------------------------------------------------
/pkg/js/generated/ts/oracle.ts:
--------------------------------------------------------------------------------
1 |
2 |
3 | /**
4 | * IsOracle checks if a host is running an Oracle server
5 | * @example
6 | * ```javascript
7 | * const oracle = require('nuclei/oracle');
8 | * const isOracle = oracle.IsOracle('acme.com', 1521);
9 | * log(toJSON(isOracle));
10 | * ```
11 | */
12 | export function IsOracle(host: string, port: number): IsOracleResponse | null {
13 | return null;
14 | }
15 |
16 |
17 |
18 | /**
19 | * IsOracleResponse is the response from the IsOracle function.
20 | * this is returned by IsOracle function.
21 | * @example
22 | * ```javascript
23 | * const oracle = require('nuclei/oracle');
24 | * const isOracle = oracle.IsOracle('acme.com', 1521);
25 | * ```
26 | */
27 | export interface IsOracleResponse {
28 |
29 | IsOracle?: boolean,
30 |
31 | Banner?: string,
32 | }
33 |
34 |
--------------------------------------------------------------------------------
/pkg/js/generated/ts/pop3.ts:
--------------------------------------------------------------------------------
1 |
2 |
3 | /**
4 | * IsPOP3 checks if a host is running a POP3 server.
5 | * @example
6 | * ```javascript
7 | * const pop3 = require('nuclei/pop3');
8 | * const isPOP3 = pop3.IsPOP3('acme.com', 110);
9 | * log(toJSON(isPOP3));
10 | * ```
11 | */
12 | export function IsPOP3(host: string, port: number): IsPOP3Response | null {
13 | return null;
14 | }
15 |
16 |
17 |
18 | /**
19 | * IsPOP3Response is the response from the IsPOP3 function.
20 | * this is returned by IsPOP3 function.
21 | * @example
22 | * ```javascript
23 | * const pop3 = require('nuclei/pop3');
24 | * const isPOP3 = pop3.IsPOP3('acme.com', 110);
25 | * log(toJSON(isPOP3));
26 | * ```
27 | */
28 | export interface IsPOP3Response {
29 |
30 | IsPOP3?: boolean,
31 |
32 | Banner?: string,
33 | }
34 |
35 |
--------------------------------------------------------------------------------
/pkg/js/generated/ts/rsync.ts:
--------------------------------------------------------------------------------
1 |
2 |
3 | /**
4 | * IsRsync checks if a host is running a Rsync server.
5 | * @example
6 | * ```javascript
7 | * const rsync = require('nuclei/rsync');
8 | * const isRsync = rsync.IsRsync('acme.com', 873);
9 | * log(toJSON(isRsync));
10 | * ```
11 | */
12 | export function IsRsync(host: string, port: number): IsRsyncResponse | null {
13 | return null;
14 | }
15 |
16 |
17 |
18 | /**
19 | * IsRsyncResponse is the response from the IsRsync function.
20 | * this is returned by IsRsync function.
21 | * @example
22 | * ```javascript
23 | * const rsync = require('nuclei/rsync');
24 | * const isRsync = rsync.IsRsync('acme.com', 873);
25 | * log(toJSON(isRsync));
26 | * ```
27 | */
28 | export interface IsRsyncResponse {
29 |
30 | IsRsync?: boolean,
31 |
32 | Banner?: string,
33 | }
34 |
35 |
--------------------------------------------------------------------------------
/pkg/js/generated/ts/telnet.ts:
--------------------------------------------------------------------------------
1 |
2 |
3 | /**
4 | * IsTelnet checks if a host is running a Telnet server.
5 | * @example
6 | * ```javascript
7 | * const telnet = require('nuclei/telnet');
8 | * const isTelnet = telnet.IsTelnet('acme.com', 23);
9 | * log(toJSON(isTelnet));
10 | * ```
11 | */
12 | export function IsTelnet(host: string, port: number): IsTelnetResponse | null {
13 | return null;
14 | }
15 |
16 |
17 |
18 | /**
19 | * IsTelnetResponse is the response from the IsTelnet function.
20 | * this is returned by IsTelnet function.
21 | * @example
22 | * ```javascript
23 | * const telnet = require('nuclei/telnet');
24 | * const isTelnet = telnet.IsTelnet('acme.com', 23);
25 | * log(toJSON(isTelnet));
26 | * ```
27 | */
28 | export interface IsTelnetResponse {
29 |
30 | IsTelnet?: boolean,
31 |
32 | Banner?: string,
33 | }
34 |
35 |
--------------------------------------------------------------------------------
/pkg/js/generated/ts/vnc.ts:
--------------------------------------------------------------------------------
1 |
2 |
3 | /**
4 | * IsVNC checks if a host is running a VNC server.
5 | * It returns a boolean indicating if the host is running a VNC server
6 | * and the banner of the VNC server.
7 | * @example
8 | * ```javascript
9 | * const vnc = require('nuclei/vnc');
10 | * const isVNC = vnc.IsVNC('acme.com', 5900);
11 | * log(toJSON(isVNC));
12 | * ```
13 | */
14 | export function IsVNC(host: string, port: number): IsVNCResponse | null {
15 | return null;
16 | }
17 |
18 |
19 |
20 | /**
21 | * IsVNCResponse is the response from the IsVNC function.
22 | * @example
23 | * ```javascript
24 | * const vnc = require('nuclei/vnc');
25 | * const isVNC = vnc.IsVNC('acme.com', 5900);
26 | * log(toJSON(isVNC));
27 | * ```
28 | */
29 | export interface IsVNCResponse {
30 |
31 | IsVNC?: boolean,
32 |
33 | Banner?: string,
34 | }
35 |
36 |
--------------------------------------------------------------------------------
/pkg/js/global/exports.js:
--------------------------------------------------------------------------------
1 | exports = {
2 | // General
3 | dump_json: dump_json,
4 | to_json: to_json,
5 | to_array: to_array,
6 | hex_to_ascii: hex_to_ascii,
7 |
8 | // Active Directory
9 | getDomainControllerName: getDomainControllerName,
10 | };
11 |
--------------------------------------------------------------------------------
/pkg/js/global/js/dump.js:
--------------------------------------------------------------------------------
1 | // dump_json dumps the data as JSON to the console.
2 | // It returns beautified JSON.
3 | function dump_json(data) {
4 | console.log(JSON.stringify(data, null, 2));
5 | }
6 |
7 | // to_json returns beautified JSON.
8 | function to_json(data) {
9 | return JSON.stringify(data, null, 2);
10 | }
11 |
12 | // to_array sets object type as array
13 | function to_array(data) {
14 | return Object.setPrototypeOf(data, Array.prototype);
15 | }
16 |
17 | // hex_to_ascii converts a hex string to ascii.
18 | function hex_to_ascii(str1) {
19 | var hex = str1.toString();
20 | var str = "";
21 | for (var n = 0; n < hex.length; n += 2) {
22 | str += String.fromCharCode(parseInt(hex.substr(n, 2), 16));
23 | }
24 | return str;
25 | }
26 |
--------------------------------------------------------------------------------
/pkg/js/global/scripts_test.go:
--------------------------------------------------------------------------------
1 | package global
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/dop251/goja"
7 | "github.com/dop251/goja_nodejs/console"
8 | "github.com/dop251/goja_nodejs/require"
9 | )
10 |
11 | func TestScriptsRuntime(t *testing.T) {
12 | defaultImports = ""
13 | runtime := goja.New()
14 |
15 | registry := new(require.Registry)
16 | registry.Enable(runtime)
17 | console.Enable(runtime)
18 |
19 | err := RegisterNativeScripts(runtime)
20 | if err != nil {
21 | t.Fatal(err)
22 | }
23 | value, err := runtime.RunString("dump_json({a: 1, b: 2})")
24 | if err != nil {
25 | t.Fatal(err)
26 | }
27 | _ = value
28 | }
29 |
--------------------------------------------------------------------------------
/pkg/js/libs/goconsole/log.go:
--------------------------------------------------------------------------------
1 | package goconsole
2 |
3 | import (
4 | "github.com/dop251/goja_nodejs/console"
5 | "github.com/projectdiscovery/gologger"
6 | )
7 |
8 | var _ console.Printer = &GoConsolePrinter{}
9 |
10 | // GoConsolePrinter is a console printer for nuclei using gologger
11 | type GoConsolePrinter struct {
12 | logger *gologger.Logger
13 | }
14 |
15 | func NewGoConsolePrinter() *GoConsolePrinter {
16 | return &GoConsolePrinter{
17 | logger: gologger.DefaultLogger,
18 | }
19 | }
20 |
21 | func (p *GoConsolePrinter) Log(msg string) {
22 | p.logger.Info().Msg(msg)
23 | }
24 |
25 | func (p *GoConsolePrinter) Warn(msg string) {
26 | p.logger.Warning().Msg(msg)
27 | }
28 |
29 | func (p *GoConsolePrinter) Error(msg string) {
30 | p.logger.Error().Msg(msg)
31 | }
32 |
--------------------------------------------------------------------------------
/pkg/js/libs/mysql/memo.mysql_private.go:
--------------------------------------------------------------------------------
1 | // Warning - This is generated code
2 | package mysql
3 |
4 | import (
5 | "errors"
6 | "fmt"
7 |
8 | "github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
9 | )
10 |
11 | func memoizedconnectWithDSN(dsn string) (bool, error) {
12 | hash := "connectWithDSN" + ":" + fmt.Sprint(dsn)
13 |
14 | v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
15 | return connectWithDSN(dsn)
16 | })
17 | if err != nil {
18 | return false, err
19 | }
20 | if value, ok := v.(bool); ok {
21 | return value, nil
22 | }
23 |
24 | return false, errors.New("could not convert cached result")
25 | }
26 |
--------------------------------------------------------------------------------
/pkg/js/libs/oracle/memo.oracle.go:
--------------------------------------------------------------------------------
1 | // Warning - This is generated code
2 | package oracle
3 |
4 | import (
5 | "errors"
6 | "fmt"
7 |
8 | "github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
9 | )
10 |
11 | func memoizedisOracle(host string, port int) (IsOracleResponse, error) {
12 | hash := "isOracle" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
13 |
14 | v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
15 | return isOracle(host, port)
16 | })
17 | if err != nil {
18 | return IsOracleResponse{}, err
19 | }
20 | if value, ok := v.(IsOracleResponse); ok {
21 | return value, nil
22 | }
23 |
24 | return IsOracleResponse{}, errors.New("could not convert cached result")
25 | }
26 |
--------------------------------------------------------------------------------
/pkg/js/libs/pop3/memo.pop3.go:
--------------------------------------------------------------------------------
1 | // Warning - This is generated code
2 | package pop3
3 |
4 | import (
5 | "errors"
6 | "fmt"
7 |
8 | "github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
9 | )
10 |
11 | func memoizedisPoP3(host string, port int) (IsPOP3Response, error) {
12 | hash := "isPoP3" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
13 |
14 | v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
15 | return isPoP3(host, port)
16 | })
17 | if err != nil {
18 | return IsPOP3Response{}, err
19 | }
20 | if value, ok := v.(IsPOP3Response); ok {
21 | return value, nil
22 | }
23 |
24 | return IsPOP3Response{}, errors.New("could not convert cached result")
25 | }
26 |
--------------------------------------------------------------------------------
/pkg/js/libs/rsync/memo.rsync.go:
--------------------------------------------------------------------------------
1 | // Warning - This is generated code
2 | package rsync
3 |
4 | import (
5 | "errors"
6 | "fmt"
7 |
8 | "github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
9 | )
10 |
11 | func memoizedisRsync(host string, port int) (IsRsyncResponse, error) {
12 | hash := "isRsync" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
13 |
14 | v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
15 | return isRsync(host, port)
16 | })
17 | if err != nil {
18 | return IsRsyncResponse{}, err
19 | }
20 | if value, ok := v.(IsRsyncResponse); ok {
21 | return value, nil
22 | }
23 |
24 | return IsRsyncResponse{}, errors.New("could not convert cached result")
25 | }
26 |
--------------------------------------------------------------------------------
/pkg/js/libs/smb/memo.smb_private.go:
--------------------------------------------------------------------------------
1 | // Warning - This is generated code
2 | package smb
3 |
4 | import (
5 | "errors"
6 | "fmt"
7 |
8 | "time"
9 |
10 | "github.com/praetorian-inc/fingerprintx/pkg/plugins"
11 |
12 | "github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
13 | )
14 |
15 | func memoizedcollectSMBv2Metadata(host string, port int, timeout time.Duration) (*plugins.ServiceSMB, error) {
16 | hash := "collectSMBv2Metadata" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port) + ":" + fmt.Sprint(timeout)
17 |
18 | v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
19 | return collectSMBv2Metadata(host, port, timeout)
20 | })
21 | if err != nil {
22 | return nil, err
23 | }
24 | if value, ok := v.(*plugins.ServiceSMB); ok {
25 | return value, nil
26 | }
27 |
28 | return nil, errors.New("could not convert cached result")
29 | }
30 |
--------------------------------------------------------------------------------
/pkg/js/libs/smb/memo.smbghost.go:
--------------------------------------------------------------------------------
1 | // Warning - This is generated code
2 | package smb
3 |
4 | import (
5 | "errors"
6 | "fmt"
7 |
8 | "github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
9 | )
10 |
11 | func memoizeddetectSMBGhost(host string, port int) (bool, error) {
12 | hash := "detectSMBGhost" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
13 |
14 | v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
15 | return detectSMBGhost(host, port)
16 | })
17 | if err != nil {
18 | return false, err
19 | }
20 | if value, ok := v.(bool); ok {
21 | return value, nil
22 | }
23 |
24 | return false, errors.New("could not convert cached result")
25 | }
26 |
--------------------------------------------------------------------------------
/pkg/js/libs/ssh/memo.ssh.go:
--------------------------------------------------------------------------------
1 | // Warning - This is generated code
2 | package ssh
3 |
4 | import (
5 | "errors"
6 | "fmt"
7 |
8 | "github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
9 |
10 | "github.com/zmap/zgrab2/lib/ssh"
11 | )
12 |
13 | func memoizedconnectSSHInfoMode(opts *connectOptions) (*ssh.HandshakeLog, error) {
14 | hash := "connectSSHInfoMode" + ":" + fmt.Sprint(opts)
15 |
16 | v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
17 | return connectSSHInfoMode(opts)
18 | })
19 | if err != nil {
20 | return nil, err
21 | }
22 | if value, ok := v.(*ssh.HandshakeLog); ok {
23 | return value, nil
24 | }
25 |
26 | return nil, errors.New("could not convert cached result")
27 | }
28 |
--------------------------------------------------------------------------------
/pkg/js/libs/telnet/memo.telnet.go:
--------------------------------------------------------------------------------
1 | // Warning - This is generated code
2 | package telnet
3 |
4 | import (
5 | "errors"
6 | "fmt"
7 |
8 | "github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
9 | )
10 |
11 | func memoizedisTelnet(host string, port int) (IsTelnetResponse, error) {
12 | hash := "isTelnet" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
13 |
14 | v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
15 | return isTelnet(host, port)
16 | })
17 | if err != nil {
18 | return IsTelnetResponse{}, err
19 | }
20 | if value, ok := v.(IsTelnetResponse); ok {
21 | return value, nil
22 | }
23 |
24 | return IsTelnetResponse{}, errors.New("could not convert cached result")
25 | }
26 |
--------------------------------------------------------------------------------
/pkg/js/libs/vnc/memo.vnc.go:
--------------------------------------------------------------------------------
1 | // Warning - This is generated code
2 | package vnc
3 |
4 | import (
5 | "errors"
6 | "fmt"
7 |
8 | "github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
9 | )
10 |
11 | func memoizedisVNC(host string, port int) (IsVNCResponse, error) {
12 | hash := "isVNC" + ":" + fmt.Sprint(host) + ":" + fmt.Sprint(port)
13 |
14 | v, err, _ := protocolstate.Memoizer.Do(hash, func() (interface{}, error) {
15 | return isVNC(host, port)
16 | })
17 | if err != nil {
18 | return IsVNCResponse{}, err
19 | }
20 | if value, ok := v.(IsVNCResponse); ok {
21 | return value, nil
22 | }
23 |
24 | return IsVNCResponse{}, errors.New("could not convert cached result")
25 | }
26 |
--------------------------------------------------------------------------------
/pkg/keys/key.go:
--------------------------------------------------------------------------------
1 | // keys package contains the public key for verifying digital signature of templates
2 | package keys
3 |
4 | import _ "embed"
5 |
6 | const PDVerifier = "projectdiscovery/nuclei-templates"
7 |
8 | //go:embed nuclei.crt
9 | var NucleiCert []byte // public key for verifying digital signature of templates
10 |
--------------------------------------------------------------------------------
/pkg/keys/nuclei.crt:
--------------------------------------------------------------------------------
1 | -----BEGIN PD NUCLEI USER CERTIFICATE-----
2 | MIIBgDCCASWgAwIBAgIEZSUZ3jAKBggqhkjOPQQDAjAsMSowKAYDVQQDEyFwcm9q
3 | ZWN0ZGlzY292ZXJ5L251Y2xlaS10ZW1wbGF0ZXMwHhcNMjMxMDEwMDkzMTEwWhcN
4 | MjcxMDA5MDkzMTEwWjAsMSowKAYDVQQDEyFwcm9qZWN0ZGlzY292ZXJ5L251Y2xl
5 | aS10ZW1wbGF0ZXMwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASTaiE41H7LWudF
6 | SMCfnqguQMwEte7dz/FRfK2lmezE02w+I2VwcS3j5cPwNaqYRAJkQhk6+7li0GpG
7 | 9fb11Fs2ozUwMzAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwEw
8 | DAYDVR0TAQH/BAIwADAKBggqhkjOPQQDAgNJADBGAiEAhFsWwLDcWks3RUv3ujCs
9 | 4V1reu6KL+kELrCCQWu5FiUCIQDZbtqL30GPGYaPSpVmd6BKrZDBOfUVBsoCS7pS
10 | q3JLHQ==
11 | -----END PD NUCLEI USER CERTIFICATE-----
--------------------------------------------------------------------------------
/pkg/loader/parser/parser.go:
--------------------------------------------------------------------------------
1 | package parser
2 |
3 | import (
4 | "github.com/projectdiscovery/nuclei/v3/pkg/catalog"
5 | )
6 |
7 | type Parser interface {
8 | LoadTemplate(templatePath string, tagFilter any, extraTags []string, catalog catalog.Catalog) (bool, error)
9 | ParseTemplate(templatePath string, catalog catalog.Catalog) (any, error)
10 | LoadWorkflow(templatePath string, catalog catalog.Catalog) (bool, error)
11 | }
12 |
--------------------------------------------------------------------------------
/pkg/model/types/stringslice/stringslice_raw.go:
--------------------------------------------------------------------------------
1 | package stringslice
2 |
3 | type RawStringSlice struct {
4 | StringSlice
5 | }
6 |
7 | func NewRawStringSlice(value interface{}) *RawStringSlice {
8 | return &RawStringSlice{StringSlice: StringSlice{Value: value}}
9 | }
10 |
11 | func (rawStringSlice *RawStringSlice) Normalize(value string) string {
12 | return value
13 | }
14 |
15 | func (rawStringSlice *RawStringSlice) UnmarshalYAML(unmarshal func(interface{}) error) error {
16 | marshalledSlice, err := marshalStringToSlice(unmarshal)
17 | if err != nil {
18 | return err
19 | }
20 | rawStringSlice.Value = marshalledSlice
21 | return nil
22 | }
23 |
24 | func (rawStringSlice RawStringSlice) JSONSchemaAlias() any {
25 | return StringOrSlice("")
26 | }
27 |
--------------------------------------------------------------------------------
/pkg/model/worflow_loader.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | // TODO shouldn't this rather be TemplateLoader?
4 |
5 | // WorkflowLoader is a loader interface required for workflow initialization.
6 | type WorkflowLoader interface {
7 | // GetTemplatePathsByTags returns a list of template paths based on the provided tags from the templates directory
8 | GetTemplatePathsByTags(tags []string) []string
9 |
10 | // GetTemplatePaths takes a list of templates and returns paths for them
11 | GetTemplatePaths(templatesList []string, noValidate bool) []string
12 | }
13 |
--------------------------------------------------------------------------------
/pkg/operators/extractors/doc.go:
--------------------------------------------------------------------------------
1 | // Package extractors implements extractors for http response
2 | // data retrieval.
3 | package extractors
4 |
--------------------------------------------------------------------------------
/pkg/operators/extractors/util.go:
--------------------------------------------------------------------------------
1 | package extractors
2 |
3 | // SupportsMap determines if the extractor type requires a map
4 | func SupportsMap(extractor *Extractor) bool {
5 | return extractor.Type.ExtractorType == KValExtractor || extractor.Type.ExtractorType == DSLExtractor
6 | }
7 |
--------------------------------------------------------------------------------
/pkg/operators/matchers/doc.go:
--------------------------------------------------------------------------------
1 | // Package matchers implements matchers for http response
2 | // matching with templates.
3 | package matchers
4 |
--------------------------------------------------------------------------------
/pkg/output/doc.go:
--------------------------------------------------------------------------------
1 | // Package output implements output writing interfaces for nuclei.
2 | package output
3 |
--------------------------------------------------------------------------------
/pkg/output/format_json.go:
--------------------------------------------------------------------------------
1 | package output
2 |
3 | import (
4 | jsoniter "github.com/json-iterator/go"
5 | )
6 |
7 | // formatJSON formats the output for json based formatting
8 | func (w *StandardWriter) formatJSON(output *ResultEvent) ([]byte, error) {
9 | if !w.jsonReqResp { // don't show request-response in json if not asked
10 | output.Request = ""
11 | output.Response = ""
12 | }
13 | return jsoniter.Marshal(output)
14 | }
15 |
--------------------------------------------------------------------------------
/pkg/progress/doc.go:
--------------------------------------------------------------------------------
1 | // Package progress implements progress display mechanism with very
2 | // simple command line statistics printing on runtime.
3 | package progress
4 |
--------------------------------------------------------------------------------
/pkg/protocols/common/automaticscan/automaticscan_test.go:
--------------------------------------------------------------------------------
1 | package automaticscan
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/require"
7 | )
8 |
9 | func TestNormalizeAppName(t *testing.T) {
10 | appName := normalizeAppName("JBoss")
11 | require.Equal(t, "jboss", appName, "could not get normalized name")
12 |
13 | appName = normalizeAppName("JBoss:2.3.5")
14 | require.Equal(t, "jboss", appName, "could not get normalized name")
15 | }
16 |
--------------------------------------------------------------------------------
/pkg/protocols/common/automaticscan/doc.go:
--------------------------------------------------------------------------------
1 | // Package automaticscan implements automatic technology based template
2 | // execution for a nuclei instance.
3 | //
4 | // First wappalyzer based technology detection is performed and templates
5 | // are executed based on the results found. The results of wappalyzer
6 | // technology detection are lowercased and split on space characters in the name,
7 | // which are then used as tags for the execution of the templates.
8 | //
9 | // Example -
10 | //
11 | // "Amazon Web Services,Jenkins,Atlassian Jira" -> "amazon,web,services,jenkins,atlassian,jira".
12 | //
13 | // Wappalyzergo (https://github.com/projectdiscovery/wappalyzergo) is used for wappalyzer tech
14 | // detection.
15 | //
16 | // The logic is very simple and can be further improved to increase the coverage of
17 | // this mode of nuclei execution.
18 | package automaticscan
19 |
--------------------------------------------------------------------------------
/pkg/protocols/common/contextargs/doc.go:
--------------------------------------------------------------------------------
1 | // Package contextargs implements a generic entity for shared context within workflows
2 | //
3 | // All templates within a workflow shares the same cookiejar and a key-value store with shared items
4 | package contextargs
5 |
--------------------------------------------------------------------------------
/pkg/protocols/common/contextargs/variables.go:
--------------------------------------------------------------------------------
1 | package contextargs
2 |
3 | // GenerateVariables from context args
4 | func GenerateVariables(ctx *Context) map[string]interface{} {
5 | vars := map[string]interface{}{
6 | "ip": ctx.MetaInput.CustomIP,
7 | }
8 | return vars
9 | }
10 |
--------------------------------------------------------------------------------
/pkg/protocols/common/expressions/variables_test.go:
--------------------------------------------------------------------------------
1 | package expressions
2 |
3 | import (
4 | "errors"
5 | "testing"
6 |
7 | "github.com/stretchr/testify/require"
8 | )
9 |
10 | func TestUnresolvedVariablesCheck(t *testing.T) {
11 | tests := []struct {
12 | data string
13 | err error
14 | }{
15 | {"{{test}}", errors.New("unresolved variables found: test")},
16 | {"{{test}}/{{another}}", errors.New("unresolved variables found: test,another")},
17 | {"test", nil},
18 | {"%7b%7btest%7d%7d", errors.New("unresolved variables found: test")},
19 | {"%7B%7Bfirst%2Asecond%7D%7D", errors.New("unresolved variables found: first%2Asecond")},
20 | {"{{7*7}}", nil},
21 | {"{{'a'+'b'}}", nil},
22 | {"{{'a'}}", nil},
23 | }
24 | for _, test := range tests {
25 | err := ContainsUnresolvedVariables(test.data)
26 | require.Equal(t, test.err, err, "could not get unresolved variables")
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/pkg/protocols/common/generators/env.go:
--------------------------------------------------------------------------------
1 | package generators
2 |
3 | import (
4 | "os"
5 |
6 | stringsutil "github.com/projectdiscovery/utils/strings"
7 | )
8 |
9 | var envVars map[string]interface{}
10 |
11 | func parseEnvVars() map[string]interface{} {
12 | sliceEnvVars := os.Environ()
13 | parsedEnvVars := make(map[string]interface{}, len(sliceEnvVars))
14 | for _, envVar := range sliceEnvVars {
15 | key, _ := stringsutil.Before(envVar, "=")
16 | val, _ := stringsutil.After(envVar, "=")
17 | parsedEnvVars[key] = val
18 | }
19 | return parsedEnvVars
20 | }
21 |
22 | // EnvVars returns a map with all environment variables into a map
23 | func EnvVars() map[string]interface{} {
24 | if envVars == nil {
25 | envVars = parseEnvVars()
26 | }
27 |
28 | return envVars
29 | }
30 |
--------------------------------------------------------------------------------
/pkg/protocols/common/generators/maps_test.go:
--------------------------------------------------------------------------------
1 | package generators
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/require"
7 | )
8 |
9 | func TestMergeMapsMany(t *testing.T) {
10 | got := MergeMapsMany(map[string]interface{}{"a": []string{"1", "2"}, "c": "5"}, map[string][]string{"b": {"3", "4"}})
11 | require.Equal(t, map[string][]string{
12 | "a": {"1", "2"},
13 | "b": {"3", "4"},
14 | "c": {"5"},
15 | }, got, "could not get correct merged map")
16 | }
17 |
--------------------------------------------------------------------------------
/pkg/protocols/common/generators/options.go:
--------------------------------------------------------------------------------
1 | package generators
2 |
3 | import (
4 | "github.com/projectdiscovery/nuclei/v3/pkg/types"
5 | )
6 |
7 | // BuildPayloadFromOptions returns a map with the payloads provided via CLI
8 | func BuildPayloadFromOptions(options *types.Options) map[string]interface{} {
9 | m := make(map[string]interface{})
10 | // merge with vars
11 | if !options.Vars.IsEmpty() {
12 | m = MergeMaps(m, options.Vars.AsMap())
13 | }
14 |
15 | // merge with env vars
16 | if options.EnvironmentVariables {
17 | m = MergeMaps(EnvVars(), m)
18 | }
19 | return m
20 | }
21 |
--------------------------------------------------------------------------------
/pkg/protocols/common/generators/slice.go:
--------------------------------------------------------------------------------
1 | package generators
2 |
3 | import stringsutil "github.com/projectdiscovery/utils/strings"
4 |
5 | // SliceToMap converts a slice of strings to map of string splitting each item at sep as "key sep value"
6 | func SliceToMap(s []string, sep string) map[string]interface{} {
7 | m := make(map[string]interface{})
8 | for _, sliceItem := range s {
9 | key, _ := stringsutil.Before(sliceItem, sep)
10 | value, _ := stringsutil.After(sliceItem, sep)
11 | if key != "" {
12 | m[key] = value
13 | }
14 | }
15 | return m
16 | }
17 |
--------------------------------------------------------------------------------
/pkg/protocols/common/helpers/deserialization/deserialization.go:
--------------------------------------------------------------------------------
1 | // Package deserialization implements helpers for deserialization issues in nuclei.
2 | package deserialization
3 |
--------------------------------------------------------------------------------
/pkg/protocols/common/helpers/deserialization/helpers.go:
--------------------------------------------------------------------------------
1 | package deserialization
2 |
3 | import "bytes"
4 |
5 | func InsertInto(s string, interval int, sep rune) string {
6 | var buffer bytes.Buffer
7 | before := interval - 1
8 | last := len(s) - 1
9 | for i, char := range s {
10 | buffer.WriteRune(char)
11 | if i%interval == before && i != last {
12 | buffer.WriteRune(sep)
13 | }
14 | }
15 | buffer.WriteRune(sep)
16 | return buffer.String()
17 | }
18 |
--------------------------------------------------------------------------------
/pkg/protocols/common/helpers/deserialization/testdata/Deserialize.java:
--------------------------------------------------------------------------------
1 | import java.io.*;
2 |
3 | class Deserialize {
4 | public static void main(String args[]) {
5 | FileInputStream fileIn = null;
6 | ObjectInputStream in = null;
7 | ValueObject vo2 = null;
8 |
9 | try {
10 | fileIn = new FileInputStream("ValueObject2.ser");
11 | }
12 | catch(FileNotFoundException e) {
13 | e.printStackTrace();
14 | }
15 |
16 | try {
17 | in = new ObjectInputStream(fileIn);
18 | }
19 | catch(IOException e) {
20 | e.printStackTrace();
21 | }
22 | try {
23 | vo2 = (ValueObject) in.readObject();
24 | }
25 | catch(Exception e) {
26 | e.printStackTrace();
27 | }
28 | System.out.println(vo2);
29 | }
30 | }
--------------------------------------------------------------------------------
/pkg/protocols/common/helpers/deserialization/testdata/README.md:
--------------------------------------------------------------------------------
1 | # testdata
2 |
3 | ### Test Unsafe Java Deserialization
4 |
5 | ```
6 | javac Deserialize.java ValueObject.java
7 | # generate payload and write to ValueObject2.ser
8 | java Deserialize
9 | ```
10 |
11 | Modified From: https://snyk.io/blog/serialization-and-deserialization-in-java/
--------------------------------------------------------------------------------
/pkg/protocols/common/helpers/deserialization/testdata/ValueObject.java:
--------------------------------------------------------------------------------
1 | import java.io.*;
2 |
3 | public class ValueObject implements Serializable {
4 | private String value;
5 | private String sideEffect;
6 |
7 | public ValueObject() {
8 | this("empty");
9 | }
10 |
11 | public ValueObject(String value) {
12 | this.value = value;
13 | this.sideEffect = java.time.LocalTime.now().toString();
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/pkg/protocols/common/interactsh/const.go:
--------------------------------------------------------------------------------
1 | package interactsh
2 |
3 | import (
4 | "errors"
5 | "regexp"
6 | "time"
7 | )
8 |
9 | var (
10 | defaultInteractionDuration = 60 * time.Second
11 | interactshURLMarkerRegex = regexp.MustCompile(`(%7[B|b]|\{){2}(interactsh-url(?:_[0-9]+){0,3})(%7[D|d]|\}){2}`)
12 |
13 | ErrInteractshClientNotInitialized = errors.New("interactsh client not initialized")
14 | )
15 |
16 | const (
17 | stopAtFirstMatchAttribute = "stop-at-first-match"
18 | templateIdAttribute = "template-id"
19 |
20 | defaultMaxInteractionsCount = 5000
21 | )
22 |
--------------------------------------------------------------------------------
/pkg/protocols/common/marker/marker.go:
--------------------------------------------------------------------------------
1 | package marker
2 |
3 | const (
4 | // General marker (open/close)
5 | General = "§"
6 | // ParenthesisOpen marker - begin of a placeholder
7 | ParenthesisOpen = "{{"
8 | // ParenthesisClose marker - end of a placeholder
9 | ParenthesisClose = "}}"
10 | )
11 |
--------------------------------------------------------------------------------
/pkg/protocols/common/protocolstate/js.go:
--------------------------------------------------------------------------------
1 | package protocolstate
2 |
3 | import (
4 | "github.com/dop251/goja"
5 | "github.com/dop251/goja/parser"
6 | "github.com/projectdiscovery/gologger"
7 | )
8 |
9 | // NewJSRuntime returns a new javascript runtime
10 | // with defaults set
11 | // i.e sourcemap parsing is disabled by default
12 | func NewJSRuntime() *goja.Runtime {
13 | vm := goja.New()
14 | vm.SetParserOptions(parser.WithDisableSourceMaps)
15 | // disable eval by default
16 | if err := vm.Set("eval", "undefined"); err != nil {
17 | gologger.Error().Msgf("could not set eval to undefined: %s", err)
18 | }
19 | return vm
20 | }
21 |
--------------------------------------------------------------------------------
/pkg/protocols/common/protocolstate/memoizer.go:
--------------------------------------------------------------------------------
1 | package protocolstate
2 |
3 | import (
4 | "github.com/projectdiscovery/utils/memoize"
5 | )
6 |
7 | var Memoizer *memoize.Memoizer
8 |
9 | func init() {
10 | var err error
11 | Memoizer, err = memoize.New(memoize.WithMaxSize(1500))
12 | if err != nil {
13 | panic(err)
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/pkg/protocols/common/utils/excludematchers/excludematchers_test.go:
--------------------------------------------------------------------------------
1 | package excludematchers
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/require"
7 | )
8 |
9 | func TestExcludeMatchers(t *testing.T) {
10 | em := New([]string{"test-template:test-matcher", "new-template:*", "*:new-matcher", "only-template-id"})
11 |
12 | require.True(t, em.Match("test-template", "test-matcher"), "could not get template-matcher value")
13 | require.False(t, em.Match("test-template", "random-matcher"), "could get template-matcher value")
14 |
15 | require.True(t, em.Match("new-template", "random-matcher"), "could not get template-matcher value wildcard")
16 | require.True(t, em.Match("random-template", "new-matcher"), "could not get template-matcher value wildcard")
17 |
18 | require.True(t, em.Match("only-template-id", "test"), "could not get only template id match value")
19 | }
20 |
--------------------------------------------------------------------------------
/pkg/protocols/common/utils/vardump/vars.go:
--------------------------------------------------------------------------------
1 | package vardump
2 |
3 | var (
4 | // EnableVarDump enables var dump for debugging optionally
5 | EnableVarDump bool
6 | // Limit is the maximum characters to be dumped
7 | Limit int = 255
8 | )
9 |
--------------------------------------------------------------------------------
/pkg/protocols/dns/cluster.go:
--------------------------------------------------------------------------------
1 | package dns
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/cespare/xxhash"
7 | )
8 |
9 |
10 | // TmplClusterKey generates a unique key for the request
11 | // to be used in the clustering process.
12 | func (request *Request) TmplClusterKey() uint64 {
13 | recursion := ""
14 | if request.Recursion != nil {
15 | recursion = fmt.Sprintf("%t", *request.Recursion)
16 | }
17 | inp := fmt.Sprintf("%s-%d-%d-%d-%s", request.Name, request.class, request.Retries, request.question, recursion)
18 | return xxhash.Sum64String(inp)
19 | }
20 |
21 | // IsClusterable returns true if the request is eligible to be clustered.
22 | func (request *Request) IsClusterable() bool {
23 | return !(len(request.Resolvers) > 0 || request.Trace || request.ID != "")
24 | }
25 |
--------------------------------------------------------------------------------
/pkg/protocols/headless/engine/util.go:
--------------------------------------------------------------------------------
1 | package engine
2 |
3 | import (
4 | "github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/expressions"
5 | "github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/marker"
6 | "github.com/valyala/fasttemplate"
7 | )
8 |
9 | // replaceWithValues replaces the template markers with the values
10 | //
11 | // Deprecated: Not used anymore.
12 | // nolint: unused
13 | func replaceWithValues(data string, values map[string]interface{}) string {
14 | return fasttemplate.ExecuteStringStd(data, marker.ParenthesisOpen, marker.ParenthesisClose, values)
15 | }
16 |
17 | func getExpressions(data string, values map[string]interface{}) []string {
18 | return expressions.FindExpressions(data, marker.ParenthesisOpen, marker.ParenthesisClose, values)
19 | }
20 |
--------------------------------------------------------------------------------
/pkg/protocols/headless/operators_test.go:
--------------------------------------------------------------------------------
1 | package headless
2 |
--------------------------------------------------------------------------------
/pkg/protocols/http/cluster.go:
--------------------------------------------------------------------------------
1 | package http
2 |
3 | import (
4 | "fmt"
5 | "strings"
6 |
7 | "github.com/cespare/xxhash"
8 | "github.com/projectdiscovery/nuclei/v3/pkg/utils"
9 | )
10 |
11 | // TmplClusterKey generates a unique key for the request
12 | // to be used in the clustering process.
13 | func (request *Request) TmplClusterKey() uint64 {
14 | inp := fmt.Sprintf("%s-%d-%t-%t-%s-%d", request.Method.String(), request.MaxRedirects, request.DisableCookie, request.Redirects, strings.Join(request.Path, "-"), utils.MapHash(request.Headers))
15 | return xxhash.Sum64String(inp)
16 | }
17 |
18 | // IsClusterable returns true if the request is eligible to be clustered.
19 | func (request *Request) IsClusterable() bool {
20 | return !(len(request.Payloads) > 0 || len(request.Fuzzing) > 0 || len(request.Raw) > 0 || len(request.Body) > 0 || request.Unsafe || request.NeedsRequestCondition() || request.Name != "")
21 | }
22 |
--------------------------------------------------------------------------------
/pkg/protocols/http/cluster_test.go:
--------------------------------------------------------------------------------
1 | package http
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/require"
7 | )
8 |
9 | func TestCanCluster(t *testing.T) {
10 | req := &Request{Unsafe: true}
11 | require.False(t, req.IsClusterable(), "could cluster unsafe request")
12 |
13 | req = &Request{Path: []string{"{{BaseURL}}"}, Method: HTTPMethodTypeHolder{MethodType: HTTPGet}}
14 | newReq := &Request{Path: []string{"{{BaseURL}}"}, Method: HTTPMethodTypeHolder{MethodType: HTTPGet}}
15 | require.True(t, req.IsClusterable(), "could not cluster GET request")
16 | require.True(t, req.IsClusterable(), "could not cluster GET request")
17 | require.Equal(t, req.TmplClusterKey(), newReq.TmplClusterKey(), "cluster keys should be equal")
18 | }
19 |
--------------------------------------------------------------------------------
/pkg/protocols/http/httpclientpool/errors.go:
--------------------------------------------------------------------------------
1 | package httpclientpool
2 |
3 | import "errors"
4 |
5 | var (
6 | ErrRebuildURL = errors.New("could not rebuild request URL")
7 | )
8 |
--------------------------------------------------------------------------------
/pkg/protocols/http/httputils/misc.go:
--------------------------------------------------------------------------------
1 | package httputils
2 |
3 | import (
4 | "strings"
5 |
6 | "github.com/projectdiscovery/nuclei/v3/pkg/types"
7 | mapsutil "github.com/projectdiscovery/utils/maps"
8 | )
9 |
10 | // if template contains more than 1 request and matchers require requestcondition from
11 | // both requests , then we need to request for event from interactsh even if current request
12 | // doesnot use interactsh url in it
13 | func GetInteractshURLSFromEvent(event map[string]interface{}) []string {
14 | interactshUrls := map[string]struct{}{}
15 | for k, v := range event {
16 | if strings.HasPrefix(k, "interactsh-url") {
17 | interactshUrls[types.ToString(v)] = struct{}{}
18 | }
19 | }
20 | return mapsutil.GetKeys(interactshUrls)
21 | }
22 |
--------------------------------------------------------------------------------
/pkg/protocols/http/raw/doc.go:
--------------------------------------------------------------------------------
1 | // Package raw provides raw http request parsing abilities for nuclei.
2 | package raw
3 |
--------------------------------------------------------------------------------
/pkg/protocols/http/validate.go:
--------------------------------------------------------------------------------
1 | package http
2 |
3 | import "github.com/pkg/errors"
4 |
5 | func (request *Request) validate() error {
6 | if request.Race && request.NeedsRequestCondition() {
7 | return errors.New("'race' and 'req-condition' can't be used together")
8 | }
9 |
10 | if request.Redirects && request.HostRedirects {
11 | return errors.New("'redirects' and 'host-redirects' can't be used together")
12 | }
13 |
14 | return nil
15 | }
16 |
--------------------------------------------------------------------------------
/pkg/protocols/javascript/testcases/ms-sql-detect.yaml:
--------------------------------------------------------------------------------
1 | id: ms-sql-detect
2 |
3 | info:
4 | name: microsoft sql server(mssql) detection
5 | author: Ice3man543,tarunKoyalwar
6 | severity: info
7 | description: |
8 | ms sql detection template
9 | metadata:
10 | shodan-query: "port:1433"
11 |
12 | javascript:
13 | - code: |
14 | var m = require("nuclei/mssql");
15 | var c = m.MSSQLClient();
16 | c.IsMssql(Host, Port);
17 |
18 | args:
19 | Host: "{{Host}}"
20 | Port: "1433"
21 |
22 | matchers:
23 | - type: dsl
24 | dsl:
25 | - "response == true"
26 | - "success == true"
27 | condition: and
28 |
29 |
30 |
--------------------------------------------------------------------------------
/pkg/protocols/javascript/testcases/ssh-server-fingerprint.yaml:
--------------------------------------------------------------------------------
1 | id: ssh-server-fingerprint
2 |
3 | info:
4 | name: Fingerprint SSH Server Software
5 | author: Ice3man543,tarunKoyalwar
6 | severity: info
7 |
8 |
9 | javascript:
10 | - code: |
11 | var m = require("nuclei/ssh");
12 | var c = m.SSHClient();
13 | var response = c.ConnectSSHInfoMode(Host, Port);
14 | to_json(response);
15 | args:
16 | Host: "{{Host}}"
17 | Port: "22"
18 |
19 | extractors:
20 | - type: json
21 | name: server
22 | json:
23 | - '.ServerID.Raw'
24 | part: response
25 |
--------------------------------------------------------------------------------
/pkg/protocols/utils/utils_test.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/require"
7 | )
8 |
9 | func TestCalculateContentLength(t *testing.T) {
10 | tests := []struct {
11 | name string
12 | expected int64
13 | contentLengthHeader int64
14 | bodyLength int64
15 | }{
16 | {"content-length-header", 10, 10, 10},
17 | {"content-length-header-with-body-length", 10, 10, 1000},
18 | {"no-content-length-header-with-body-length", 1000, -1, 1000},
19 | {"content-length-header-without-body-length", 10, 10, -1},
20 | }
21 | for _, test := range tests {
22 | t.Run(test.name, func(t *testing.T) {
23 | got := CalculateContentLength(test.contentLengthHeader, test.bodyLength)
24 | require.Equal(t, test.expected, got)
25 | })
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/pkg/reporting/client.go:
--------------------------------------------------------------------------------
1 | package reporting
2 |
3 | import (
4 | "github.com/projectdiscovery/nuclei/v3/pkg/output"
5 | )
6 |
7 | // Client is a client for nuclei issue tracking module
8 | type Client interface {
9 | RegisterTracker(tracker Tracker)
10 | RegisterExporter(exporter Exporter)
11 | Close()
12 | Clear()
13 | CreateIssue(event *output.ResultEvent) error
14 | CloseIssue(event *output.ResultEvent) error
15 | GetReportingOptions() *Options
16 | }
17 |
--------------------------------------------------------------------------------
/pkg/reporting/format/format.go:
--------------------------------------------------------------------------------
1 | package format
2 |
3 | type ResultFormatter interface {
4 | MakeBold(text string) string
5 | CreateCodeBlock(title string, content string, language string) string
6 | CreateTable(headers []string, rows [][]string) (string, error)
7 | CreateLink(title string, url string) string
8 | CreateHorizontalLine() string
9 | }
10 |
--------------------------------------------------------------------------------
/pkg/scan/events/scan_noop.go:
--------------------------------------------------------------------------------
1 | //go:build !stats
2 | // +build !stats
3 |
4 | package events
5 |
6 | // AddScanEvent is a no-op function
7 | func AddScanEvent(event ScanEvent) {
8 | }
9 |
10 | func InitWithConfig(config *ScanConfig, statsDirectory string) {
11 | }
12 |
13 | func Close() {
14 | }
15 |
--------------------------------------------------------------------------------
/pkg/templates/cache_test.go:
--------------------------------------------------------------------------------
1 | package templates
2 |
3 | import (
4 | "errors"
5 | "testing"
6 |
7 | "github.com/stretchr/testify/require"
8 | )
9 |
10 | func TestCache(t *testing.T) {
11 | templates := NewCache()
12 | testErr := errors.New("test error")
13 |
14 | data, _, err := templates.Has("test")
15 | require.Nil(t, err, "invalid value for err")
16 | require.Nil(t, data, "invalid value for data")
17 |
18 | item := &Template{}
19 |
20 | templates.Store("test", item, nil, testErr)
21 | data, _, err = templates.Has("test")
22 | require.Equal(t, testErr, err, "invalid value for err")
23 | require.Equal(t, item, data, "invalid value for data")
24 | }
25 |
--------------------------------------------------------------------------------
/pkg/templates/doc.go:
--------------------------------------------------------------------------------
1 | // Package templates contains the parser for a template for the engine.
2 | package templates
3 |
--------------------------------------------------------------------------------
/pkg/templates/extensions/extensions.go:
--------------------------------------------------------------------------------
1 | package extensions
2 |
3 | const (
4 | JSON = ".json"
5 | YAML = ".yaml"
6 | YML = ".yml"
7 | )
8 |
--------------------------------------------------------------------------------
/pkg/templates/log_test.go:
--------------------------------------------------------------------------------
1 | package templates
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/require"
7 | )
8 |
9 | func Test_appendAtSignToAuthors(t *testing.T) {
10 | result := appendAtSignToAuthors([]string{"user1", "user2", "user3"})
11 | require.Equal(t, result, "@user1,@user2,@user3")
12 | }
13 |
14 | func Test_appendAtSignToMissingAuthors(t *testing.T) {
15 | result := appendAtSignToAuthors([]string{})
16 | require.Equal(t, result, "@none")
17 |
18 | result = appendAtSignToAuthors(nil)
19 | require.Equal(t, result, "@none")
20 | }
21 |
22 | func Test_appendAtSignToOneAuthor(t *testing.T) {
23 | result := appendAtSignToAuthors([]string{"user1"})
24 | require.Equal(t, result, "@user1")
25 | }
26 |
--------------------------------------------------------------------------------
/pkg/templates/parser_config.go:
--------------------------------------------------------------------------------
1 | package templates
2 |
3 | import "regexp"
4 |
5 | var (
6 | ReTemplateID = regexp.MustCompile(`^([a-zA-Z0-9]+[-_])*[a-zA-Z0-9]+$`)
7 | )
8 |
--------------------------------------------------------------------------------
/pkg/templates/parser_error.go:
--------------------------------------------------------------------------------
1 | package templates
2 |
3 | import (
4 | errorutil "github.com/projectdiscovery/utils/errors"
5 | )
6 |
7 | var (
8 | ErrMandatoryFieldMissingFmt = errorutil.NewWithFmt("mandatory '%s' field is missing")
9 | ErrInvalidField = errorutil.NewWithFmt("invalid field format for '%s' (allowed format is %s)")
10 | ErrWarningFieldMissing = errorutil.NewWithFmt("field '%s' is missing")
11 | ErrCouldNotLoadTemplate = errorutil.NewWithFmt("Could not load template %s: %s")
12 | ErrLoadedWithWarnings = errorutil.NewWithFmt("Loaded template %s: with syntax warning : %s")
13 | )
14 |
--------------------------------------------------------------------------------
/pkg/templates/parser_stats.go:
--------------------------------------------------------------------------------
1 | package templates
2 |
3 | const (
4 | SyntaxWarningStats = "syntax-warnings"
5 | SyntaxErrorStats = "syntax-errors"
6 | RuntimeWarningsStats = "runtime-warnings"
7 | SkippedCodeTmplTamperedStats = "unsigned-warnings"
8 | ExcludedHeadlessTmplStats = "headless-flag-missing-warnings"
9 | TemplatesExcludedStats = "templates-executed"
10 | ExcludedCodeTmplStats = "code-flag-missing-warnings"
11 | ExludedDastTmplStats = "fuzz-flag-missing-warnings"
12 | SkippedUnsignedStats = "skipped-unsigned-stats" // tracks loading of unsigned templates
13 | ExcludedSelfContainedStats = "excluded-self-contained-stats"
14 | ExcludedFileStats = "excluded-file-stats"
15 | SkippedRequestSignatureStats = "skipped-request-signature-stats"
16 | )
17 |
--------------------------------------------------------------------------------
/pkg/templates/signer/.nuclei-config/nuclei/.templates-config.json:
--------------------------------------------------------------------------------
1 | {"nuclei-templates-directory":"/Users/tarun/nuclei-templates","custom-s3-templates-directory":"/Users/tarun/nuclei-templates/s3","custom-github-templates-directory":"/Users/tarun/nuclei-templates/github","custom-gitlab-templates-directory":"/Users/tarun/nuclei-templates/gitlab","custom-azure-templates-directory":"/Users/tarun/nuclei-templates/azure","nuclei-latest-version":"","nuclei-templates-latest-version":""}
--------------------------------------------------------------------------------
/pkg/templates/tests/json-template.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "go-integration-test",
3 | "info": {
4 | "name": "Basic Go Integration Test",
5 | "author": "pdteam",
6 | "severity": "info"
7 | },
8 | "requests": [
9 | {
10 | "method": "GET",
11 | "path": [
12 | "{{BaseURL}}"
13 | ],
14 | "headers": {
15 | "test": "nuclei"
16 | },
17 | "matchers": [
18 | {
19 | "type": "word",
20 | "words": [
21 | "This is test headers matcher text"
22 | ]
23 | }
24 | ]
25 | }
26 | ]
27 | }
--------------------------------------------------------------------------------
/pkg/templates/tests/match-1.yaml:
--------------------------------------------------------------------------------
1 | id: basic-get
2 |
3 | info:
4 | name: Basic GET Request
5 | author: pdteam
6 | severity: info
7 |
8 | requests:
9 | - method: GET
10 | path:
11 | - "{{BaseURL}}"
12 | matchers:
13 | - type: word
14 | words:
15 | - "This is test matcher text"
16 |
--------------------------------------------------------------------------------
/pkg/templates/tests/multiproto.yaml:
--------------------------------------------------------------------------------
1 | id: nuclei-multi-protocol
2 |
3 | info:
4 | name: multi protocol support
5 | author: pdteam
6 | severity: info
7 |
8 | dns:
9 | - name: "{{FQDN}}" # dns request
10 | type: cname
11 |
12 | ssl:
13 | - address: "{{Hostname}}" # ssl request
14 |
15 | http:
16 | - method: GET
17 | path:
18 | - "{{BaseURL}}" # http request
19 |
20 | headers:
21 | Host: "{{ssl_subject_cn}}" # host extracted from ssl request
22 | Metadata: "{{ssl_cipher}}"
23 |
24 | matchers:
25 | - type: dsl
26 | dsl:
27 | # - contains(http_body,'File not found') # check for http string
28 | - http_status_code == 404
29 | - contains(dns_cname, 'github.io') # check for cname
30 | condition: and
--------------------------------------------------------------------------------
/pkg/templates/tests/no-author.yaml:
--------------------------------------------------------------------------------
1 | id: basic-get
2 |
3 | info:
4 | name: Basic GET Request
5 | severity: info
6 |
7 | requests:
8 | - method: GET
9 | path:
10 | - "{{BaseURL}}"
11 | matchers:
12 | - type: word
13 | words:
14 | - "This is test matcher text"
15 |
--------------------------------------------------------------------------------
/pkg/templates/tests/no-req.yaml:
--------------------------------------------------------------------------------
1 | id: basic-get
2 |
3 | info:
4 | name: Basic GET Request
5 | author: pdteam
6 | severity: info
7 |
8 | requests:
9 |
10 |
--------------------------------------------------------------------------------
/pkg/templates/tests/workflow-invalid.yaml:
--------------------------------------------------------------------------------
1 | id: workflow-example
2 |
3 | info:
4 | name: Test Invalid Workflow Template
5 | author: pdteam
6 | severity: info
7 |
8 | http:
9 | - raw:
10 | - |
11 | POST /re HTTP/1.1
12 | Host: {{Hostname}}
13 |
14 | {{code_response}}
15 |
16 | workflows:
17 | - template: tests/match-1.yaml
18 | - template: tests/match-1.yaml
19 |
--------------------------------------------------------------------------------
/pkg/templates/tests/workflow.yaml:
--------------------------------------------------------------------------------
1 | id: workflow-example
2 |
3 | info:
4 | name: Test Workflow Template
5 | author: pdteam
6 | severity: info
7 |
8 | workflows:
9 | - template: tests/match-1.yaml
10 | - template: tests/match-1.yaml
11 |
--------------------------------------------------------------------------------
/pkg/testutils/testheadless/headless_local.go:
--------------------------------------------------------------------------------
1 | //go:build headless_local
2 |
3 | package testheadless
4 |
5 | // HeadlessLocal determines if local headless chrome should be used in tests
6 | const HeadlessLocal = true
7 |
--------------------------------------------------------------------------------
/pkg/testutils/testheadless/headless_runtime.go:
--------------------------------------------------------------------------------
1 | //go:build !headless_local
2 |
3 | package testheadless
4 |
5 | // HeadlessLocal determines if local headless chrome should be used in tests
6 | const HeadlessLocal = false
7 |
--------------------------------------------------------------------------------
/pkg/tmplexec/doc.go:
--------------------------------------------------------------------------------
1 | package tmplexec
2 |
3 | // tmplexec is package that provides
4 | // template executors it is one level higher than protocols
5 | // and deals with execution of entire template
6 |
--------------------------------------------------------------------------------
/pkg/tmplexec/flow/doc.go:
--------------------------------------------------------------------------------
1 | package flow
2 |
--------------------------------------------------------------------------------
/pkg/tmplexec/flow/testcases/condition-flow-extractors.yaml:
--------------------------------------------------------------------------------
1 | id: condition-flow-extractors
2 | info:
3 | name: Condition Flow Extractors
4 | author: pdteam
5 | severity: info
6 |
7 | flow: dns() && http()
8 |
9 | dns:
10 | - name: "{{FQDN}}"
11 | type: A
12 |
13 | extractors:
14 | - type: dsl
15 | name: a
16 | internal: true
17 | dsl:
18 | - a
19 |
20 | http:
21 | - method: GET
22 | path:
23 | - "{{BaseURL}}/?ref={{a}}"
24 |
25 | matchers:
26 | - type: word
27 | words:
28 | - "ok"
--------------------------------------------------------------------------------
/pkg/tmplexec/flow/testcases/condition-flow-no-operators.yaml:
--------------------------------------------------------------------------------
1 | id: condition-flow-no-operators
2 | info:
3 | name: Condition Flow No Operators
4 | author: pdteam
5 | severity: info
6 |
7 | flow: dns() && http()
8 |
9 | dns:
10 | - name: "{{FQDN}}"
11 | type: CNAME
12 |
13 | http:
14 | - method: GET
15 | path:
16 | - "{{BaseURL}}/?ref={{dns_cname}}"
17 |
18 | matchers:
19 | - type: word
20 | words:
21 | - "html>"
--------------------------------------------------------------------------------
/pkg/tmplexec/flow/testcases/condition-flow.yaml:
--------------------------------------------------------------------------------
1 | id: vercel-hosted-detection
2 | info:
3 | name: Vercel-hosted detection
4 | author: pdteam
5 | severity: info
6 |
7 |
8 | flow: dns() && http()
9 |
10 | dns:
11 | - name: "{{FQDN}}"
12 | type: CNAME
13 |
14 | matchers:
15 | - type: word
16 | words:
17 | - "vercel-dns"
18 |
19 | http:
20 | - method: GET
21 | path:
22 | - "{{dns_cname}}"
23 |
24 | matchers:
25 | - type: word
26 | words:
27 | - "DEPLOYMENT_NOT_FOUND"
--------------------------------------------------------------------------------
/pkg/tmplexec/flow/testcases/nuclei-flow-dns.yaml:
--------------------------------------------------------------------------------
1 | id: nuclei-flow-dns
2 |
3 | info:
4 | name: Nuclei flow dns
5 | author: pdteam
6 | severity: info
7 | description: Description of the Template
8 | reference: https://example-reference-link
9 |
10 | flow: |
11 | dns(1);
12 | template["nameservers"].forEach(nameserver => {
13 | set("nameserver",nameserver);
14 | dns(2);
15 | });
16 |
17 | dns:
18 | - name: "{{FQDN}}"
19 | type: NS
20 | matchers:
21 | - type: word
22 | words:
23 | - "IN\tNS"
24 | extractors:
25 | - type: regex
26 | internal: true
27 | name: "nameservers"
28 | group: 1
29 | regex:
30 | - "IN\tNS\t(.+)"
31 |
32 | - name: "{{nameserver}}"
33 | type: A
34 | class: inet
35 | retries: 3
36 | recursion: true
37 | extractors:
38 | - type: dsl
39 | dsl:
40 | - "a"
--------------------------------------------------------------------------------
/pkg/tmplexec/flow/util.go:
--------------------------------------------------------------------------------
1 | package flow
2 |
3 | import "github.com/projectdiscovery/nuclei/v3/pkg/operators"
4 |
5 | // Checks if template has matchers
6 | func hasMatchers(all []*operators.Operators) bool {
7 | for _, operator := range all {
8 | if len(operator.Matchers) > 0 {
9 | return true
10 | }
11 | }
12 | return false
13 | }
14 |
15 | // hasOperators checks if template has operators (i.e matchers/extractors)
16 | func hasOperators(all []*operators.Operators) bool {
17 | for _, operator := range all {
18 | if operator != nil {
19 | return true
20 | }
21 | }
22 | return false
23 | }
24 |
25 | func flatten(v interface{}) interface{} {
26 | switch v := v.(type) {
27 | case []interface{}:
28 | if len(v) == 1 {
29 | return v[0]
30 | }
31 | return v
32 | case []string:
33 | if len(v) == 1 {
34 | return v[0]
35 | }
36 | return v
37 | default:
38 | return v
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/pkg/tmplexec/multiproto/doc.go:
--------------------------------------------------------------------------------
1 | package multiproto
2 |
3 | // multiproto is a template executer engine that executes multiple protocols
4 | // with shared logic in between
5 |
--------------------------------------------------------------------------------
/pkg/tmplexec/multiproto/testcases/multiprotodynamic.yaml:
--------------------------------------------------------------------------------
1 | id: dns-http-dynamic-values
2 |
3 | info:
4 | name: multi protocol request with dynamic values
5 | author: pdteam
6 | severity: info
7 |
8 | dns:
9 | - name: "{{FQDN}}" # DNS Request
10 | type: a
11 |
12 | http:
13 | - method: GET # http request
14 | path:
15 | - "{{BaseURL}}"
16 |
17 | matchers:
18 | - type: dsl
19 | dsl:
20 | - body == "ok"
21 | - dns_a == '128.199.158.128' # check for A record (extracted information from dns response)
22 | condition: and
--------------------------------------------------------------------------------
/pkg/tmplexec/multiproto/testcases/multiprotowithprefix.yaml:
--------------------------------------------------------------------------------
1 | id: dns-http-proto-prefix
2 |
3 | info:
4 | name: multi protocol request with dynamic values
5 | author: pdteam
6 | severity: info
7 |
8 | dns:
9 | - name: "{{FQDN}}" # DNS Request
10 | type: cname
11 |
12 | ssl:
13 | - address: "{{Hostname}}" # ssl request
14 |
15 | http:
16 | - method: GET # http request
17 | path:
18 | - "{{BaseURL}}"
19 |
20 | matchers:
21 | - type: dsl
22 | dsl:
23 | - contains(http_body, 'ProjectDiscovery') # check for http string
24 | - dns_cname == 'cname.vercel-dns.com' # check for cname (extracted information from dns response)
25 | - ssl_subject_cn == 'cloud.projectdiscovery.io'
26 | condition: and
--------------------------------------------------------------------------------
/pkg/types/scanstrategy/scan_strategy.go:
--------------------------------------------------------------------------------
1 | package scanstrategy
2 |
3 | import (
4 | mapsutil "github.com/projectdiscovery/utils/maps"
5 | )
6 |
7 | // ScanStrategy supported
8 | type ScanStrategy uint8
9 |
10 | const (
11 | Auto ScanStrategy = iota
12 | HostSpray
13 | TemplateSpray
14 | )
15 |
16 | var strategies mapsutil.Map[ScanStrategy, string]
17 |
18 | func init() {
19 | strategies = make(mapsutil.Map[ScanStrategy, string])
20 | strategies[Auto] = "auto"
21 | strategies[HostSpray] = "host-spray"
22 | strategies[TemplateSpray] = "template-spray"
23 | }
24 |
25 | // String representation of the scan strategy
26 | func (s ScanStrategy) String() string {
27 | return strategies[s]
28 | }
29 |
--------------------------------------------------------------------------------
/pkg/utils/expand/expand.go:
--------------------------------------------------------------------------------
1 | package expand
2 |
3 | import (
4 | "github.com/projectdiscovery/mapcidr"
5 | "github.com/projectdiscovery/mapcidr/asn"
6 | )
7 |
8 | // Expands CIDR to IPs
9 | func CIDR(value string) []string {
10 | var ips []string
11 | ipsCh, _ := mapcidr.IPAddressesAsStream(value)
12 | for ip := range ipsCh {
13 | ips = append(ips, ip)
14 | }
15 | return ips
16 | }
17 |
18 | // Expand ASN to IPs
19 | func ASN(value string) []string {
20 | var ips []string
21 | cidrs, _ := asn.GetCIDRsForASNNum(value)
22 | for _, cidr := range cidrs {
23 | ips = append(ips, CIDR(cidr.String())...)
24 | }
25 | return ips
26 | }
27 |
--------------------------------------------------------------------------------
/pkg/utils/index.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | // TransformIndex transforms user given index (start from 1) to array index (start from 0)
4 | // in safe way without panic i.e negative index or index out of range
5 | func TransformIndex[T any](arr []T, index int) int {
6 | if index <= 1 {
7 | // negative index
8 | return 0
9 | }
10 | if index >= len(arr) {
11 | // index out of range
12 | return len(arr) - 1
13 | }
14 | // valid index
15 | return index - 1
16 | }
17 |
--------------------------------------------------------------------------------
/pkg/utils/insertion_ordered_map_test.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/require"
7 | "gopkg.in/yaml.v2"
8 | )
9 |
10 | func TestUnmarshalInsertionOrderedMapYAML(t *testing.T) {
11 | var data = `a1: test
12 | a2: value
13 | a3: new`
14 |
15 | var value InsertionOrderedStringMap
16 | err := yaml.Unmarshal([]byte(data), &value)
17 | require.NoError(t, err, "could not unmarshal map")
18 |
19 | var items []string
20 | value.ForEach(func(key string, value interface{}) {
21 | items = append(items, key)
22 | })
23 | require.Equal(t, []string{"a1", "a2", "a3"}, items, "could not get ordered keys")
24 | }
25 |
--------------------------------------------------------------------------------
/pkg/utils/json/json.go:
--------------------------------------------------------------------------------
1 | //go:build !go1.24 && (linux || darwin || windows) && (amd64 || arm64)
2 | // +build !go1.24
3 | // +build linux darwin windows
4 | // +build amd64 arm64
5 |
6 | package json
7 |
8 | import "github.com/bytedance/sonic"
9 |
10 | var api = sonic.ConfigStd
11 |
12 | // Exported functions from the [sonic.API].
13 | var (
14 | Marshal = api.Marshal
15 | Unmarshal = api.Unmarshal
16 | MarshalIndent = api.MarshalIndent
17 | NewDecoder = api.NewDecoder
18 | NewEncoder = api.NewEncoder
19 | )
20 |
21 | // Encoder is a JSON encoder.
22 | type Encoder = sonic.Encoder
23 |
24 | // Decoder is a JSON decoder.
25 | type Decoder = sonic.Decoder
26 |
27 | // SetConfig sets the configuration for the JSON package.
28 | func SetConfig(config *sonic.Config) {
29 | api = config.Froze()
30 | }
31 |
--------------------------------------------------------------------------------
/pkg/utils/json/json_fallback.go:
--------------------------------------------------------------------------------
1 | //go:build go1.24 || !(linux || darwin || windows) || !(amd64 || arm64)
2 | // +build go1.24 !linux,!darwin,!windows !amd64,!arm64
3 |
4 | package json
5 |
6 | import "github.com/goccy/go-json"
7 |
8 | // Exported functions from the [json] package.
9 | var (
10 | Marshal = json.Marshal
11 | Unmarshal = json.Unmarshal
12 | MarshalIndent = json.MarshalIndent
13 | NewDecoder = json.NewDecoder
14 | NewEncoder = json.NewEncoder
15 | )
16 |
17 | // Encoder is a JSON encoder.
18 | type Encoder = json.Encoder
19 |
20 | // Decoder is a JSON decoder.
21 | type Decoder = json.Decoder
22 |
--------------------------------------------------------------------------------
/pkg/utils/monitor/monitor_test.go:
--------------------------------------------------------------------------------
1 | package monitor
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/require"
7 | )
8 |
9 | func TestMonitorCompareStringSliceEqual(t *testing.T) {
10 | value := compareStringSliceEqual([]string{"a", "b"}, []string{"b", "a"})
11 | require.True(t, value, "could not get correct value")
12 |
13 | value = compareStringSliceEqual([]string{"a", "c"}, []string{"b", "a"})
14 | require.False(t, value, "could get incorrect value")
15 | }
16 |
--------------------------------------------------------------------------------
/pkg/utils/stats/doc.go:
--------------------------------------------------------------------------------
1 | // Package stats provides a storage mechanism for storing
2 | // and display vital statistics of the engine at various durations.
3 | package stats
4 |
--------------------------------------------------------------------------------
/pkg/utils/template_path.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import (
4 | "strings"
5 |
6 | "github.com/projectdiscovery/nuclei/v3/pkg/catalog/config"
7 | "github.com/projectdiscovery/nuclei/v3/pkg/keys"
8 | )
9 |
10 | const (
11 | // TemplatesRepoURL is the URL for files in nuclei-templates repository
12 | TemplatesRepoURL = "https://cloud.projectdiscovery.io/public/"
13 | )
14 |
15 | // TemplatePathURL returns the Path and URL for the provided template
16 | func TemplatePathURL(fullPath, templateId, templateVerifier string) (path string, url string) {
17 | configData := config.DefaultConfig
18 | if configData.TemplatesDirectory != "" && strings.HasPrefix(fullPath, configData.TemplatesDirectory) {
19 | path = strings.TrimPrefix(strings.TrimPrefix(fullPath, configData.TemplatesDirectory), "/")
20 | }
21 | if templateVerifier == keys.PDVerifier {
22 | url = TemplatesRepoURL + templateId
23 | }
24 | return
25 | }
26 |
--------------------------------------------------------------------------------
/pkg/utils/utils_test.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import (
4 | "fmt"
5 | "testing"
6 |
7 | "github.com/stretchr/testify/require"
8 | )
9 |
10 | func TestUnwrapError(t *testing.T) {
11 | require.Equal(t, nil, UnwrapError(nil))
12 |
13 | errOne := fmt.Errorf("error one")
14 | require.Equal(t, errOne, UnwrapError(errOne))
15 |
16 | errTwo := fmt.Errorf("error with error: %w", errOne)
17 | require.Equal(t, errOne, UnwrapError(errTwo))
18 |
19 | errThree := fmt.Errorf("error with error: %w", errTwo)
20 | require.Equal(t, errOne, UnwrapError(errThree))
21 | }
22 |
--------------------------------------------------------------------------------
/pkg/workflows/doc.go:
--------------------------------------------------------------------------------
1 | // Package workflows contains the workflows
2 | package workflows
3 |
--------------------------------------------------------------------------------
/static/Join-Discord.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/projectdiscovery/nuclei/a4859df5e9c9e5476a8cd5f2e2d2e96566df2524/static/Join-Discord.png
--------------------------------------------------------------------------------
/static/check-nuclei-documentation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/projectdiscovery/nuclei/a4859df5e9c9e5476a8cd5f2e2d2e96566df2524/static/check-nuclei-documentation.png
--------------------------------------------------------------------------------
/static/learn-more-button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/projectdiscovery/nuclei/a4859df5e9c9e5476a8cd5f2e2d2e96566df2524/static/learn-more-button.png
--------------------------------------------------------------------------------
/static/nuclei-cover-image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/projectdiscovery/nuclei/a4859df5e9c9e5476a8cd5f2e2d2e96566df2524/static/nuclei-cover-image.png
--------------------------------------------------------------------------------
/static/nuclei-cover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/projectdiscovery/nuclei/a4859df5e9c9e5476a8cd5f2e2d2e96566df2524/static/nuclei-cover.png
--------------------------------------------------------------------------------
/static/nuclei-flow.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/projectdiscovery/nuclei/a4859df5e9c9e5476a8cd5f2e2d2e96566df2524/static/nuclei-flow.jpg
--------------------------------------------------------------------------------
/static/nuclei-getting-started.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/projectdiscovery/nuclei/a4859df5e9c9e5476a8cd5f2e2d2e96566df2524/static/nuclei-getting-started.png
--------------------------------------------------------------------------------
/static/nuclei-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/projectdiscovery/nuclei/a4859df5e9c9e5476a8cd5f2e2d2e96566df2524/static/nuclei-logo.png
--------------------------------------------------------------------------------
/static/nuclei-template-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/projectdiscovery/nuclei/a4859df5e9c9e5476a8cd5f2e2d2e96566df2524/static/nuclei-template-example.png
--------------------------------------------------------------------------------
/static/nuclei-templates-teamcity-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/projectdiscovery/nuclei/a4859df5e9c9e5476a8cd5f2e2d2e96566df2524/static/nuclei-templates-teamcity-example.png
--------------------------------------------------------------------------------
/static/nuclei-templates-teamcity.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/projectdiscovery/nuclei/a4859df5e9c9e5476a8cd5f2e2d2e96566df2524/static/nuclei-templates-teamcity.png
--------------------------------------------------------------------------------
/static/nuclei-write-your-first-template.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/projectdiscovery/nuclei/a4859df5e9c9e5476a8cd5f2e2d2e96566df2524/static/nuclei-write-your-first-template.png
--------------------------------------------------------------------------------
/static/projectdiscovery-browse-results.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/projectdiscovery/nuclei/a4859df5e9c9e5476a8cd5f2e2d2e96566df2524/static/projectdiscovery-browse-results.gif
--------------------------------------------------------------------------------
/static/regression-cycle.md:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/static/regression-with-nuclei.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/projectdiscovery/nuclei/a4859df5e9c9e5476a8cd5f2e2d2e96566df2524/static/regression-with-nuclei.jpg
--------------------------------------------------------------------------------
/static/teamcity-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/projectdiscovery/nuclei/a4859df5e9c9e5476a8cd5f2e2d2e96566df2524/static/teamcity-example.png
--------------------------------------------------------------------------------