Merge pull request #2303 from projectdiscovery/dev

v2.7.4 Release
dev
Sandeep Singh 2022-07-18 13:43:20 +05:30 committed by GitHub
commit 0165822b49
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
62 changed files with 867 additions and 178 deletions

View File

@ -98,14 +98,16 @@ TARGET:
-resume string Resume scan using resume.cfg (clustering will be disabled)
TEMPLATES:
-nt, -new-templates run only new templates added in latest nuclei-templates release
-as, -automatic-scan automatic web scan using wappalyzer technology detection to tags mapping
-t, -templates string[] list of template or template directory to run (comma-separated, file)
-tu, -template-url string[] list of template urls to run (comma-separated, file)
-w, -workflows string[] list of workflow or workflow directory to run (comma-separated, file)
-wu, -workflow-url string[] list of workflow urls to run (comma-separated, file)
-validate validate the passed templates to nuclei
-tl list all available templates
-nt, -new-templates run only new templates added in latest nuclei-templates release
-ntv, -new-templates-version string[] run new templates added in specific version
-as, -automatic-scan automatic web scan using wappalyzer technology detection to tags mapping
-t, -templates string[] list of template or template directory to run (comma-separated, file)
-tu, -template-url string[] list of template urls to run (comma-separated, file)
-w, -workflows string[] list of workflow or workflow directory to run (comma-separated, file)
-wu, -workflow-url string[] list of workflow urls to run (comma-separated, file)
-validate validate the passed templates to nuclei
-nss, -no-strict-syntax Disable strict syntax check on templates
-tl list all available templates
FILTERING:
-a, -author string[] templates to run based on authors (comma-separated, file)
@ -116,6 +118,7 @@ FILTERING:
-eid, -exclude-id string[] templates to exclude based on template ids (comma-separated, file)
-it, -include-templates string[] templates to be executed even if they are excluded either by default or configuration
-et, -exclude-templates string[] template or template directory to exclude (comma-separated, file)
-em, -exclude-matchers string[] template matchers to exclude in result
-s, -severity value[] templates to run based on severity. Possible values: info, low, medium, high, critical, unknown
-es, -exclude-severity value[] templates to exclude based on severity. Possible values: info, low, medium, high, critical, unknown
-pt, -type value[] templates to run based on protocol type. Possible values: dns, file, http, headless, network, workflow, ssl, websocket, whois
@ -165,22 +168,24 @@ INTERACTSH:
-ni, -no-interactsh disable interactsh server for OAST testing, exclude OAST based templates
RATE-LIMIT:
-rl, -rate-limit int maximum number of requests to send per second (default 150)
-rlm, -rate-limit-minute int maximum number of requests to send per minute
-bs, -bulk-size int maximum number of hosts to be analyzed in parallel per template (default 25)
-c, -concurrency int maximum number of templates to be executed in parallel (default 25)
-hbs, -headless-bulk-size int maximum number of headless hosts to be analyzed in parallel per template (default 10)
-hc, -headless-concurrency int maximum number of headless templates to be executed in parallel (default 10)
-rl, -rate-limit int maximum number of requests to send per second (default 150)
-rlm, -rate-limit-minute int maximum number of requests to send per minute
-bs, -bulk-size int maximum number of hosts to be analyzed in parallel per template (default 25)
-c, -concurrency int maximum number of templates to be executed in parallel (default 25)
-hbs, -headless-bulk-size int maximum number of headless hosts to be analyzed in parallel per template (default 10)
-headc, -headless-concurrency int maximum number of headless templates to be executed in parallel (default 10)
OPTIMIZATIONS:
-timeout int time to wait in seconds before timeout (default 5)
-retries int number of times to retry a failed request (default 1)
-ldp, -leave-default-ports leave default HTTP/HTTPS ports (eg. host:80,host:443
-mhe, -max-host-error int max errors for a host before skipping from scan (default 30)
-project use a project folder to avoid sending same request multiple times
-project-path string set a specific project path
-spm, -stop-at-first-path stop processing HTTP requests after the first match (may break template/workflow logic)
-stream stream mode - start elaborating without sorting the input
-timeout int time to wait in seconds before timeout (default 5)
-retries int number of times to retry a failed request (default 1)
-ldp, -leave-default-ports leave default HTTP/HTTPS ports (eg. host:80,host:443
-mhe, -max-host-error int max errors for a host before skipping from scan (default 30)
-project use a project folder to avoid sending same request multiple times
-project-path string set a specific project path
-spm, -stop-at-first-path stop processing HTTP requests after the first match (may break template/workflow logic)
-stream stream mode - start elaborating without sorting the input
-irt, -input-read-timeout duration timeout on input read (default 3m0s)
-no-stdin Disable Stdin processing
HEADLESS:
-headless enable templates that require headless browser support (root user on linux will disable sandbox)
@ -202,6 +207,7 @@ DEBUG:
-vv display templates loaded for scan
-ep, -enable-pprof enable pprof debugging server
-tv, -templates-version shows the version of the installed nuclei-templates
-hc, -health-check run diagnostic check up
UPDATE:
-update update nuclei engine to the latest released version

View File

@ -96,6 +96,7 @@ Nuclei是一款注重于可配置性、可扩展性和易用性的基于模板
模板:
-t, -templates string[] 指定需要扫描的模板或者模板的路径
-nt, -new-templates 只扫描最新版本中添加的模板
-ntv -new-templates-version 运行在特定版本中添加的新模板
-w, -workflows string[] 指定扫描中的工作流或者工作流目录
-validate 验证通过的模板
-tl 列出所有可用的模板

View File

@ -101,6 +101,8 @@ requests:
status:
- 200
matchers-condition: and
templateid: ""
excludematchers: null
path:
- '{{BaseURL}}/.git/config'
method: GET
@ -133,6 +135,8 @@ dns:
- ec2-[-\d]+\.compute[-\d]*\.amazonaws\.com
- ec2-[-\d]+\.[\w\d\-]+\.compute[-\d]*\.amazonaws\.com
dsl: []
templateid: ""
excludematchers: null
name: '{{FQDN}}'
type: CNAME
class: inet
@ -166,6 +170,8 @@ file:
regex:
- amzn\.mws\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}
dsl: []
templateid: ""
excludematchers: null
extensions:
- all
archive: false
@ -203,6 +209,8 @@ network:
- type: word
words:
- zookeeper.version
templateid: ""
excludematchers: null
```
@ -792,6 +800,8 @@ matchers:
status:
- 200
matchers-condition: and
templateid: ""
excludematchers: null
path:
- '{{BaseURL}}/.git/config'
method: GET
@ -2295,6 +2305,8 @@ extractors:
- ec2-[-\d]+\.compute[-\d]*\.amazonaws\.com
- ec2-[-\d]+\.[\w\d\-]+\.compute[-\d]*\.amazonaws\.com
dsl: []
templateid: ""
excludematchers: null
name: '{{FQDN}}'
type: CNAME
class: inet
@ -2615,6 +2627,8 @@ extractors:
regex:
- amzn\.mws\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}
dsl: []
templateid: ""
excludematchers: null
extensions:
- all
archive: false
@ -2818,6 +2832,8 @@ matchers:
- type: word
words:
- zookeeper.version
templateid: ""
excludematchers: null
```
Part Definitions:

View File

@ -80,7 +80,8 @@ requests:
68: {{wait_for(1)}}
69: {{zlib("Hello")}}
70: {{zlib_decode(hex_decode("789cf248cdc9c907040000ffff058c01f5"))}}
71: {{hex_encode(aes_gcm("AES256Key-32Characters1234567890", "exampleplaintext"))}}
extractors:
- type: regex
name: results

View File

@ -0,0 +1,16 @@
id: excluded-template
info:
name: Basic Excluded Template
author: pdteam
severity: info
tags: fuzz
requests:
- method: GET
path:
- "{{BaseURL}}"
matchers:
- type: word
words:
- "This is test matcher text"

View File

@ -0,0 +1,26 @@
GET / HTTP/1.1
Host: pastebin.com
User-Agent: curl/7.79.1
Accept: */*
Connection: close
HTTP/1.1 200 OK
Date: Tue, 21 Jun 2022 09:32:01 GMT
Content-Type: text/plain; charset=utf-8
Connection: close
x-frame-options: DENY
x-content-type-options: nosniff
x-xss-protection: 1;mode=block
cache-control: public, max-age=1801
CF-Cache-Status: HIT
Age: 1585
Last-Modified: Tue, 21 Jun 2022 09:05:36 GMT
Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
Server: cloudflare
CF-RAY: 71ebbc0a7ea83b8b-CDG
54
line1
this is a line containing HTTP/1.1 FOO BAR
line3
0

View File

@ -0,0 +1,18 @@
id: offline-allowed-paths
info:
name: offline-allowed-paths
author: pdteam
severity: info
description: offline-allowed-paths
requests:
- path:
- "{{BaseURL}}"
- "{{BaseURL}}/"
- "/"
matchers:
- type: status
status:
- 200

View File

@ -0,0 +1,16 @@
id: offline-raw
info:
name: Test Offline raw Template
author: pdteam
severity: info
requests:
- raw:
- |
GET / HTTP/1.1
Host: {{Hostname}}
matchers:
- type: status
status:
- 200

View File

@ -0,0 +1,15 @@
id: rfc-req-resp
info:
name: Basic GET Request
author: pdteam
severity: info
requests:
- method: GET
path:
- "{{BaseURL}}"
matchers:
- type: word
words:
- "this is a line containing HTTP/1.1 FOO BAR"

View File

@ -352,6 +352,11 @@
"title": "type of the attack",
"description": "Type of the attack"
},
"excludematchers.ExcludeMatchers": {
"properties": {},
"additionalProperties": false,
"type": "object"
},
"variables.Variable": {
"properties": {},
"additionalProperties": false,
@ -375,6 +380,10 @@
"description": "Type is the type of DNS request to make"
},
"dns.Request": {
"required": [
"TemplateID",
"ExcludeMatchers"
],
"properties": {
"matchers": {
"items": {
@ -401,6 +410,12 @@
"title": "condition between the matchers",
"description": "Conditions between the matchers"
},
"TemplateID": {
"type": "string"
},
"ExcludeMatchers": {
"$ref": "#/definitions/excludematchers.ExcludeMatchers"
},
"id": {
"type": "string",
"title": "id of the dns request",
@ -464,6 +479,8 @@
},
"file.Request": {
"required": [
"TemplateID",
"ExcludeMatchers",
"Archive",
"MimeType"
],
@ -493,6 +510,12 @@
"title": "condition between the matchers",
"description": "Conditions between the matchers"
},
"TemplateID": {
"type": "string"
},
"ExcludeMatchers": {
"$ref": "#/definitions/excludematchers.ExcludeMatchers"
},
"extensions": {
"items": {
"type": "string"
@ -535,6 +558,10 @@
"type": "object"
},
"headless.Request": {
"required": [
"TemplateID",
"ExcludeMatchers"
],
"properties": {
"id": {
"type": "string",
@ -600,6 +627,12 @@
"type": "string",
"title": "condition between the matchers",
"description": "Conditions between the matchers"
},
"TemplateID": {
"type": "string"
},
"ExcludeMatchers": {
"$ref": "#/definitions/excludematchers.ExcludeMatchers"
}
},
"additionalProperties": false,
@ -688,6 +721,10 @@
"description": "Method is the HTTP Request Method"
},
"http.Request": {
"required": [
"TemplateID",
"ExcludeMatchers"
],
"properties": {
"matchers": {
"items": {
@ -716,6 +753,13 @@
"title": "condition between the matchers",
"description": "Conditions between the matchers"
},
"TemplateID": {
"type": "string"
},
"ExcludeMatchers": {
"$schema": "http://json-schema.org/draft-04/schema#",
"$ref": "#/definitions/excludematchers.ExcludeMatchers"
},
"path": {
"items": {
"type": "string"
@ -923,6 +967,10 @@
"description": "description=Type of input specified in data field"
},
"network.Request": {
"required": [
"TemplateID",
"ExcludeMatchers"
],
"properties": {
"id": {
"type": "string",
@ -995,12 +1043,22 @@
"type": "string",
"title": "condition between the matchers",
"description": "Conditions between the matchers"
},
"TemplateID": {
"type": "string"
},
"ExcludeMatchers": {
"$ref": "#/definitions/excludematchers.ExcludeMatchers"
}
},
"additionalProperties": false,
"type": "object"
},
"ssl.Request": {
"required": [
"TemplateID",
"ExcludeMatchers"
],
"properties": {
"matchers": {
"items": {
@ -1027,6 +1085,12 @@
"title": "condition between the matchers",
"description": "Conditions between the matchers"
},
"TemplateID": {
"type": "string"
},
"ExcludeMatchers": {
"$ref": "#/definitions/excludematchers.ExcludeMatchers"
},
"address": {
"type": "string",
"title": "address for the ssl request",
@ -1083,6 +1147,10 @@
"type": "object"
},
"websocket.Request": {
"required": [
"TemplateID",
"ExcludeMatchers"
],
"properties": {
"matchers": {
"items": {
@ -1109,6 +1177,12 @@
"title": "condition between the matchers",
"description": "Conditions between the matchers"
},
"TemplateID": {
"type": "string"
},
"ExcludeMatchers": {
"$ref": "#/definitions/excludematchers.ExcludeMatchers"
},
"address": {
"type": "string",
"title": "address for the websocket request",
@ -1153,6 +1227,10 @@
"type": "object"
},
"whois.Request": {
"required": [
"TemplateID",
"ExcludeMatchers"
],
"properties": {
"matchers": {
"items": {
@ -1179,6 +1257,12 @@
"title": "condition between the matchers",
"description": "Conditions between the matchers"
},
"TemplateID": {
"type": "string"
},
"ExcludeMatchers": {
"$ref": "#/definitions/excludematchers.ExcludeMatchers"
},
"query": {
"type": "string",
"title": "query for the WHOIS request",

View File

@ -74,12 +74,19 @@ var (
const maxReferenceCount = 5
// dead sites to skip for references
var badrefsRegexes = []*regexp.Regexp{
regexp.MustCompile(`(www\.|\/)secunia\.com\/`),
regexp.MustCompile(`(www\.|\/)osvdb\.org\/`),
regexp.MustCompile(`(www\.|\/)securityfocus\.com\/`),
regexp.MustCompile(`(www\.|\/)iss\.net\/`),
regexp.MustCompile(`\/archives\.neohapsis\.com\/`),
var badRefs = []string{
"osvdb.org/",
"securityfocus.com/",
"archives.neohapsis.com/",
"iss.net/",
"ntelbras.com/",
"andmp.com/",
"blacklanternsecurity.com/",
"pwnwiki.org/",
"0dayhack.net/",
"correkt.horse/",
"poc.wgpsec.org/",
"ctf-writeup.revers3c.com/",
}
func getCVEData(client *nvd.Client, filePath, data string) {
@ -165,16 +172,10 @@ func getCVEData(client *nvd.Client, filePath, data string) {
// skip sites that are no longer alive
for _, reference := range cveItem.CVE.References.ReferenceData {
skip := false
for _, badrefsRegex := range badrefsRegexes {
if badrefsRegex.MatchString(reference.URL) {
skip = true
break
}
}
if !skip {
referenceDataURLs = append(referenceDataURLs, reference.URL)
if stringsutil.ContainsAny(reference.URL, badRefs...) {
continue
}
referenceDataURLs = append(referenceDataURLs, reference.URL)
}
hasReferenceData := len(cveItem.CVE.References.ReferenceData) > 0
areCveReferencesContained := sliceutil.ContainsItems(infoBlock.Info.Reference, referenceDataURLs)

View File

@ -1,4 +1,5 @@
{{binary}}
{{binary}} -tags cve -ntv 8.8.8,8.8.9
{{binary}} -tags cve
{{binary}} -tags cve,exposure
{{binary}} -tags cve,exposure -tags token
@ -48,4 +49,4 @@
{{binary}} -w workflows
{{binary}} -w workflows -author geeknik,pdteam
{{binary}} -w workflows -severity high,critical
{{binary}} -w workflows -author geeknik,pdteam -severity high,critical
{{binary}} -w workflows -author geeknik,pdteam -severity high,critical

View File

@ -256,7 +256,7 @@ func (h *httpDSLFunctions) Execute(filePath string) error {
}
totalExtracted := strings.Split(submatch[1], ",")
numberOfDslFunctions := 70
numberOfDslFunctions := 71
if len(totalExtracted) != numberOfDslFunctions {
return errors.New("incorrect number of results")
}

View File

@ -32,6 +32,7 @@ var (
"templatesPath": templatesPathTestCases,
"templatesDir": templatesDirTestCases,
"file": fileTestcases,
"offlineHttp": offlineHttpTestcases,
}
)

View File

@ -16,6 +16,7 @@ import (
var loaderTestcases = map[string]testutils.TestCase{
"loader/template-list.yaml": &remoteTemplateList{},
"loader/workflow-list.yaml": &remoteWorkflowList{},
"loader/excluded-template.yaml": &excludedTemplate{},
"loader/nonexistent-template-list.yaml": &nonExistentTemplateList{},
"loader/nonexistent-workflow-list.yaml": &nonExistentWorkflowList{},
"loader/template-list-not-allowed.yaml": &remoteTemplateListNotAllowed{},
@ -62,6 +63,29 @@ func (h *remoteTemplateList) Execute(templateList string) error {
return expectResultsCount(results, 2)
}
type excludedTemplate struct{}
// Execute executes a test case and returns an error if occurred
func (h *excludedTemplate) Execute(templateList string) error {
router := httprouter.New()
router.GET("/", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
fmt.Fprintf(w, "This is test matcher text")
if strings.EqualFold(r.Header.Get("test"), "nuclei") {
fmt.Fprintf(w, "This is test headers matcher text")
}
})
ts := httptest.NewServer(router)
defer ts.Close()
results, err := testutils.RunNucleiBareArgsAndGetResults(debug, "-target", ts.URL, "-t", templateList, "-include-templates", templateList)
if err != nil {
return err
}
return expectResultsCount(results, 1)
}
type remoteTemplateListNotAllowed struct{}
// Execute executes a test case and returns an error if occurred

View File

@ -0,0 +1,48 @@
package main
import (
"fmt"
"github.com/projectdiscovery/nuclei/v2/pkg/testutils"
)
var offlineHttpTestcases = map[string]testutils.TestCase{
"offlinehttp/rfc-req-resp.yaml": &RfcRequestResponse{},
"offlinehttp/offline-allowed-paths.yaml": &RequestResponseWithAllowedPaths{},
"offlinehttp/offline-raw.yaml": &RawRequestResponse{},
}
type RfcRequestResponse struct{}
// Execute executes a test case and returns an error if occurred
func (h *RfcRequestResponse) Execute(filePath string) error {
results, err := testutils.RunNucleiTemplateAndGetResults(filePath, "offlinehttp/data/", debug, "-passive")
if err != nil {
return err
}
return expectResultsCount(results, 1)
}
type RequestResponseWithAllowedPaths struct{}
// Execute executes a test case and returns an error if occurred
func (h *RequestResponseWithAllowedPaths) Execute(filePath string) error {
results, err := testutils.RunNucleiTemplateAndGetResults(filePath, "offlinehttp/data/", debug, "-passive")
if err != nil {
return err
}
return expectResultsCount(results, 1)
}
type RawRequestResponse struct{}
// Execute executes a test case and returns an error if occurred
func (h *RawRequestResponse) Execute(filePath string) error {
_, err := testutils.RunNucleiTemplateAndGetResults(filePath, "offlinehttp/data/", debug, "-passive")
if err == nil {
return fmt.Errorf("incorrect result: no error (actual) vs error expected")
}
return nil
}

View File

@ -98,12 +98,14 @@ on extensive configurability, massive extensibility and ease of use.`)
flagSet.CreateGroup("templates", "Templates",
flagSet.BoolVarP(&options.NewTemplates, "new-templates", "nt", false, "run only new templates added in latest nuclei-templates release"),
flagSet.CommaSeparatedStringSliceVarP(&options.NewTemplatesWithVersion,"new-templates-version", "ntv", []string{}, "run new templates added in specific version"),
flagSet.BoolVarP(&options.AutomaticScan, "automatic-scan", "as", false, "automatic web scan using wappalyzer technology detection to tags mapping"),
flagSet.FileNormalizedOriginalStringSliceVarP(&options.Templates, "templates", "t", []string{}, "list of template or template directory to run (comma-separated, file)"),
flagSet.FileNormalizedOriginalStringSliceVarP(&options.TemplateURLs, "template-url", "tu", []string{}, "list of template urls to run (comma-separated, file)"),
flagSet.FileNormalizedOriginalStringSliceVarP(&options.Workflows, "workflows", "w", []string{}, "list of workflow or workflow directory to run (comma-separated, file)"),
flagSet.FileNormalizedOriginalStringSliceVarP(&options.WorkflowURLs, "workflow-url", "wu", []string{}, "list of workflow urls to run (comma-separated, file)"),
flagSet.BoolVar(&options.Validate, "validate", false, "validate the passed templates to nuclei"),
flagSet.BoolVarP(&options.NoStrictSyntax, "no-strict-syntax", "nss", false, "Disable strict syntax check on templates"),
flagSet.BoolVar(&options.TemplateList, "tl", false, "list all available templates"),
flagSet.StringSliceVarConfigOnly(&options.RemoteTemplateDomainList, "remote-template-domain", []string{"api.nuclei.sh"}, "allowed domain list to load remote templates from"),
)
@ -117,6 +119,7 @@ on extensive configurability, massive extensibility and ease of use.`)
flagSet.FileNormalizedStringSliceVarP(&options.ExcludeIds, "exclude-id", "eid", []string{}, "templates to exclude based on template ids (comma-separated, file)"),
flagSet.FileNormalizedOriginalStringSliceVarP(&options.IncludeTemplates, "include-templates", "it", []string{}, "templates to be executed even if they are excluded either by default or configuration"),
flagSet.FileNormalizedOriginalStringSliceVarP(&options.ExcludedTemplates, "exclude-templates", "et", []string{}, "template or template directory to exclude (comma-separated, file)"),
flagSet.FileCommaSeparatedStringSliceVarP(&options.ExcludeMatchers, "exclude-matchers", "em", []string{}, "template matchers to exclude in result"),
flagSet.VarP(&options.Severities, "severity", "s", fmt.Sprintf("templates to run based on severity. Possible values: %s", severity.GetSupportedSeverities().String())),
flagSet.VarP(&options.ExcludeSeverities, "exclude-severity", "es", fmt.Sprintf("templates to exclude based on severity. Possible values: %s", severity.GetSupportedSeverities().String())),
flagSet.VarP(&options.Protocols, "type", "pt", fmt.Sprintf("templates to run based on protocol type. Possible values: %s", templateTypes.GetSupportedProtocolTypes())),
@ -175,7 +178,7 @@ on extensive configurability, massive extensibility and ease of use.`)
flagSet.IntVarP(&options.BulkSize, "bulk-size", "bs", 25, "maximum number of hosts to be analyzed in parallel per template"),
flagSet.IntVarP(&options.TemplateThreads, "concurrency", "c", 25, "maximum number of templates to be executed in parallel"),
flagSet.IntVarP(&options.HeadlessBulkSize, "headless-bulk-size", "hbs", 10, "maximum number of headless hosts to be analyzed in parallel per template"),
flagSet.IntVarP(&options.HeadlessTemplateThreads, "headless-concurrency", "hc", 10, "maximum number of headless templates to be executed in parallel"),
flagSet.IntVarP(&options.HeadlessTemplateThreads, "headless-concurrency", "headc", 10, "maximum number of headless templates to be executed in parallel"),
)
flagSet.CreateGroup("optimization", "Optimizations",
@ -187,6 +190,8 @@ on extensive configurability, massive extensibility and ease of use.`)
flagSet.StringVar(&options.ProjectPath, "project-path", os.TempDir(), "set a specific project path"),
flagSet.BoolVarP(&options.StopAtFirstMatch, "stop-at-first-path", "spm", false, "stop processing HTTP requests after the first match (may break template/workflow logic)"),
flagSet.BoolVar(&options.Stream, "stream", false, "stream mode - start elaborating without sorting the input"),
flagSet.DurationVarP(&options.InputReadTimeout, "input-read-timeout", "irt", time.Duration(3*time.Minute), "timeout on input read"),
flagSet.BoolVar(&options.DisableStdin, "no-stdin", false, "Disable Stdin processing"),
)
flagSet.CreateGroup("headless", "Headless",
@ -210,7 +215,7 @@ on extensive configurability, massive extensibility and ease of use.`)
flagSet.BoolVar(&options.VerboseVerbose, "vv", false, "display templates loaded for scan"),
flagSet.BoolVarP(&options.EnablePprof, "enable-pprof", "ep", false, "enable pprof debugging server"),
flagSet.BoolVarP(&options.TemplatesVersion, "templates-version", "tv", false, "shows the version of the installed nuclei-templates"),
flagSet.BoolVar(&options.HealthCheck, "health-check", false, "run diagnostic check up"),
flagSet.BoolVarP(&options.HealthCheck, "health-check", "hc", false, "run diagnostic check up"),
)
flagSet.CreateGroup("update", "Update",

View File

@ -12,28 +12,27 @@ require (
github.com/bluele/gcache v0.0.2
github.com/corpix/uarand v0.2.0
github.com/go-playground/validator/v10 v10.11.0
github.com/go-rod/rod v0.107.1
github.com/go-rod/rod v0.108.1
github.com/gobwas/ws v1.1.0
github.com/google/go-github v17.0.0+incompatible
github.com/itchyny/gojq v0.12.8
github.com/json-iterator/go v1.1.12
github.com/julienschmidt/httprouter v1.3.0
github.com/karlseguin/ccache v2.0.3+incompatible
github.com/karrick/godirwalk v1.17.0 // indirect
github.com/logrusorgru/aurora v2.0.3+incompatible
github.com/miekg/dns v1.1.49
github.com/miekg/dns v1.1.50
github.com/olekukonko/tablewriter v0.0.5
github.com/owenrumney/go-sarif/v2 v2.1.1
github.com/owenrumney/go-sarif/v2 v2.1.2
github.com/pkg/errors v0.9.1
github.com/projectdiscovery/clistats v0.0.8
github.com/projectdiscovery/cryptoutil v1.0.0
github.com/projectdiscovery/fastdialer v0.0.16-0.20220609092737-7e3c7dcecf16
github.com/projectdiscovery/filekv v0.0.0-20210915124239-3467ef45dd08
github.com/projectdiscovery/fileutil v0.0.0-20220609150212-453ac591c36c
github.com/projectdiscovery/fileutil v0.0.0-20220626180823-b24f0847f8e6
github.com/projectdiscovery/goflags v0.0.8-0.20220610073650-5d31a8c159e3
github.com/projectdiscovery/gologger v1.1.4
github.com/projectdiscovery/hmap v0.0.2-0.20210917080408-0fd7bd286bfa
github.com/projectdiscovery/interactsh v1.0.4
github.com/projectdiscovery/interactsh v1.0.5
github.com/projectdiscovery/nuclei-updatecheck-api v0.0.0-20211006155443-c0a8d610a4df
github.com/projectdiscovery/rawhttp v0.0.8-0.20220526170355-03de6bb78f37
github.com/projectdiscovery/retryabledns v1.0.13
@ -43,16 +42,16 @@ require (
github.com/remeh/sizedwaitgroup v1.0.0
github.com/rs/xid v1.4.0
github.com/segmentio/ksuid v1.0.4
github.com/shirou/gopsutil/v3 v3.22.5
github.com/shirou/gopsutil/v3 v3.22.6
github.com/spaolacci/murmur3 v1.1.0
github.com/spf13/cast v1.5.0
github.com/syndtr/goleveldb v1.0.0
github.com/tj/go-update v2.2.5-0.20200519121640-62b4b798fd68+incompatible
github.com/valyala/fasttemplate v1.2.1
github.com/weppos/publicsuffix-go v0.15.1-0.20210928183822-5ee35905bd95
github.com/xanzy/go-gitlab v0.68.0
github.com/xanzy/go-gitlab v0.68.2
github.com/ysmood/gson v0.7.1 // indirect
github.com/ysmood/leakless v0.7.0 // indirect
github.com/ysmood/leakless v0.8.0 // indirect
go.uber.org/atomic v1.9.0
go.uber.org/multierr v1.8.0
go.uber.org/ratelimit v0.2.0
@ -63,7 +62,7 @@ require (
moul.io/http2curl v1.0.0
)
require github.com/aws/aws-sdk-go v1.44.37
require github.com/aws/aws-sdk-go v1.44.55
require github.com/projectdiscovery/folderutil v0.0.0-20220215113126-add60a1e8e08
@ -72,15 +71,16 @@ require (
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d
github.com/docker/go-units v0.4.0
github.com/h2non/filetype v1.1.3
github.com/hashicorp/go-version v1.5.0
github.com/hashicorp/go-version v1.6.0
github.com/mholt/archiver v3.1.1+incompatible
github.com/mitchellh/go-homedir v1.1.0
github.com/openrdap/rdap v0.9.1-0.20191017185644-af93e7ef17b7
github.com/projectdiscovery/iputil v0.0.0-20210804143329-3a30fcde43f3
github.com/projectdiscovery/iputil v0.0.0-20220620153941-036d511e4097
github.com/projectdiscovery/nvd v1.0.9-0.20220314070650-d4a214c1f87d
github.com/projectdiscovery/sliceutil v0.0.0-20220511171050-c7d9bc5cadd9
github.com/projectdiscovery/urlutil v0.0.0-20210525140139-b874f06ad921
github.com/projectdiscovery/wappalyzergo v0.0.47
github.com/stretchr/testify v1.7.2
github.com/projectdiscovery/wappalyzergo v0.0.50
github.com/stretchr/testify v1.7.5
github.com/zmap/zcrypto v0.0.0-20211005224000-2d0ffdec8a9b
gopkg.in/yaml.v3 v3.0.1
)
@ -121,12 +121,14 @@ require (
github.com/gorilla/css v1.0.0 // indirect
github.com/gosuri/uilive v0.0.4 // indirect
github.com/gosuri/uiprogress v0.0.1 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-retryablehttp v0.7.1 // indirect
github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0 // indirect
github.com/itchyny/timefmt-go v0.1.3 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/klauspost/compress v1.15.2 // indirect
github.com/klauspost/compress v1.15.6 // indirect
github.com/klauspost/cpuid/v2 v2.0.11 // indirect
github.com/klauspost/pgzip v1.2.5 // indirect
github.com/leodido/go-urn v1.2.1 // indirect
@ -137,7 +139,6 @@ require (
github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/mholt/acmez v1.0.2 // indirect
github.com/microcosm-cc/bluemonday v1.0.18 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/nwaples/rardecode v1.1.2 // indirect
@ -145,7 +146,7 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/projectdiscovery/blackrock v0.0.0-20210415162320-b38689ae3a2e // indirect
github.com/projectdiscovery/mapcidr v0.0.8 // indirect
github.com/projectdiscovery/mapcidr v1.0.0 // indirect
github.com/projectdiscovery/networkpolicy v0.0.1 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca // indirect

View File

@ -88,8 +88,8 @@ github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ=
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/aws/aws-sdk-go v1.20.6/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.44.37 h1:KvDxCX6dfJeEDC77U5GPGSP0ErecmNnhDHFxw+NIvlI=
github.com/aws/aws-sdk-go v1.44.37/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
github.com/aws/aws-sdk-go v1.44.55 h1:h+p61sPEsLOpnQ2mKnGPrIe1MFUKwwA0X5eQYAcjOMU=
github.com/aws/aws-sdk-go v1.44.55/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I=
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
@ -178,8 +178,8 @@ github.com/go-playground/validator/v10 v10.11.0 h1:0W+xRM511GY47Yy3bZUbJVitCNg2B
github.com/go-playground/validator/v10 v10.11.0/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
github.com/go-redis/redis v6.15.5+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
github.com/go-rod/rod v0.91.1/go.mod h1:/W4lcZiCALPD603MnJGIvhtywP3R6yRB9EDfFfsHiiI=
github.com/go-rod/rod v0.107.1 h1:wRxTTAXJ0JUnoSGcyGAOubpdrToWIKPCnLu3av8EDFY=
github.com/go-rod/rod v0.107.1/go.mod h1:Au6ufsz7KyXUJVnw6Ljs1nFpsopy+9AJ/lBwGauYBVg=
github.com/go-rod/rod v0.108.1 h1:2lKs+v/+B/2pbGKZgNIRbURhduTKNDZ3PXIvTRAV2Mg=
github.com/go-rod/rod v0.108.1/go.mod h1:yNvL687cwcjgebRuArQN9AStFdm8iS/e/rzImrS9Pzg=
github.com/goburrow/cache v0.1.4 h1:As4KzO3hgmzPlnaMniZU9+VmoNYseUhuELbxy9mRBfw=
github.com/goburrow/cache v0.1.4/go.mod h1:cDFesZDnIlrHoNlMYqqMpCRawuXulgx+y7mXU8HZ+/c=
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
@ -275,17 +275,21 @@ github.com/gosuri/uiprogress v0.0.1 h1:0kpv/XY/qTmFWl/SkaJykZXrBBzwwadmW8fRb7RJS
github.com/gosuri/uiprogress v0.0.1/go.mod h1:C1RTYn4Sc7iEyf6j8ft5dyoZ4212h8G1ol9QQluh5+0=
github.com/h2non/filetype v1.1.3 h1:FKkx9QbD7HR/zjK1Ia5XiBsq9zdLi5Kf3zGyFTAFkGg=
github.com/h2non/filetype v1.1.3/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI=
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/hashicorp/go-retryablehttp v0.6.8/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
github.com/hashicorp/go-retryablehttp v0.7.1 h1:sUiuQAnLlbvmExtFQs72iFW/HXeUn8Z1aJLQ4LJJbTQ=
github.com/hashicorp/go-retryablehttp v0.7.1/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.5.0 h1:O293SZ2Eg+AAYijkVK3jR786Am1bhDEh2GHT0tIVE5E=
github.com/hashicorp/go-version v1.5.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
@ -329,12 +333,10 @@ github.com/karlseguin/ccache/v2 v2.0.8/go.mod h1:2BDThcfQMf/c0jnZowt16eW405XIqZP
github.com/karlseguin/expect v1.0.2-0.20190806010014-778a5f0c6003 h1:vJ0Snvo+SLMY72r5J4sEfkuE7AFbixEP2qRbEcum/wA=
github.com/karlseguin/expect v1.0.2-0.20190806010014-778a5f0c6003/go.mod h1:zNBxMY8P21owkeogJELCLeHIt+voOSduHYTFUbwRAV8=
github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk=
github.com/karrick/godirwalk v1.17.0 h1:b4kY7nqDdioR/6qnbHQyDvmA17u5G1cZ6J+CZXwSWoI=
github.com/karrick/godirwalk v1.17.0/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.15.2 h1:3WH+AG7s2+T8o3nrM/8u2rdqUEcQhmga7smjrT41nAw=
github.com/klauspost/compress v1.15.2/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
github.com/klauspost/compress v1.15.6 h1:6D9PcO8QWu0JyaQ2zUMmu16T1T+zjjEpP91guRsvDfY=
github.com/klauspost/compress v1.15.6/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
github.com/klauspost/cpuid v1.2.0 h1:NMpwD2G9JSFOE1/TJjGSo5zG7Yb2bTe7eq1jH+irmeE=
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/cpuid/v2 v2.0.11 h1:i2lw1Pm7Yi/4O6XCSyJWqEHI2MDw2FzUK6o/D21xn2A=
@ -385,9 +387,8 @@ github.com/miekg/dns v1.1.29/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
github.com/miekg/dns v1.1.46/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
github.com/miekg/dns v1.1.48/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
github.com/miekg/dns v1.1.49 h1:qe0mQU3Z/XpFeE+AEBo2rqaS1IPBJ3anmqZ4XiZJVG8=
github.com/miekg/dns v1.1.49/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
github.com/minio/minio-go/v6 v6.0.46/go.mod h1:qD0lajrGW49lKZLtXKtCB4X/qkMf0a5tBvN2PaZg7Gg=
github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
@ -428,8 +429,8 @@ github.com/openrdap/rdap v0.9.1-0.20191017185644-af93e7ef17b7/go.mod h1:inRbqVxN
github.com/owenrumney/go-sarif v1.0.11/go.mod h1:hTBFbxU7GuVRUvwMx+eStp9M/Oun4xHCS3vqpPvket8=
github.com/owenrumney/go-sarif v1.1.1 h1:QNObu6YX1igyFKhdzd7vgzmw7XsWN3/6NMGuDzBgXmE=
github.com/owenrumney/go-sarif v1.1.1/go.mod h1:dNDiPlF04ESR/6fHlPyq7gHKmrM0sHUvAGjsoh8ZH0U=
github.com/owenrumney/go-sarif/v2 v2.1.1 h1:JVUO0cEhG8bvEWIxsRmURY4u7wBZUTgdh4zikkkiPM8=
github.com/owenrumney/go-sarif/v2 v2.1.1/go.mod h1:MSqMMx9WqlBSY7pXoOZWgEsVB4FDNfhcaXDA1j6Sr+w=
github.com/owenrumney/go-sarif/v2 v2.1.2 h1:PMDK7tXShJ9zsB7bfvlpADH5NEw1dfA9xwU8Xtdj73U=
github.com/owenrumney/go-sarif/v2 v2.1.2/go.mod h1:MSqMMx9WqlBSY7pXoOZWgEsVB4FDNfhcaXDA1j6Sr+w=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM=
github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
@ -456,15 +457,13 @@ github.com/projectdiscovery/filekv v0.0.0-20210915124239-3467ef45dd08/go.mod h1:
github.com/projectdiscovery/fileutil v0.0.0-20210914153648-31f843feaad4/go.mod h1:U+QCpQnX8o2N2w0VUGyAzjM3yBAe4BKedVElxiImsx0=
github.com/projectdiscovery/fileutil v0.0.0-20210926202739-6050d0acf73c/go.mod h1:U+QCpQnX8o2N2w0VUGyAzjM3yBAe4BKedVElxiImsx0=
github.com/projectdiscovery/fileutil v0.0.0-20210928100737-cab279c5d4b5/go.mod h1:U+QCpQnX8o2N2w0VUGyAzjM3yBAe4BKedVElxiImsx0=
github.com/projectdiscovery/fileutil v0.0.0-20220215113056-ba188a0c8abc/go.mod h1:Pm0f+MWgDFMSSI9NBedNh48LyYPs8gD3Jd8DXGmp4aQ=
github.com/projectdiscovery/fileutil v0.0.0-20220427234316-40b2541a84b8 h1:2j5ev2I0RESb1+sLpnbLDXzty83Kdz0/bO4OVKWMPfM=
github.com/projectdiscovery/fileutil v0.0.0-20220427234316-40b2541a84b8/go.mod h1:wjS/oBWbzlayJ/aTK0KW0oOHGO03G8oEYzuN6stI8Ho=
github.com/projectdiscovery/fileutil v0.0.0-20220609150212-453ac591c36c h1:/+xJK8e/Gj/zAmudWh5l2SzGJB+CkwYnraelCkBe7Aw=
github.com/projectdiscovery/fileutil v0.0.0-20220609150212-453ac591c36c/go.mod h1:g8wsrb0S5NtEN0JgVyyPeb3FQdArx+UMESmFX94bcGY=
github.com/projectdiscovery/fileutil v0.0.0-20220506114156-c4ab20801483/go.mod h1:wjS/oBWbzlayJ/aTK0KW0oOHGO03G8oEYzuN6stI8Ho=
github.com/projectdiscovery/fileutil v0.0.0-20220626180823-b24f0847f8e6 h1:5C3sxeSsGsrj2eDY+3SgYl/W1jUvciP71XzTGTQ511E=
github.com/projectdiscovery/fileutil v0.0.0-20220626180823-b24f0847f8e6/go.mod h1:DaY7wmLPMleyHDCD/14YApPCDtrARY4J8Eny2ZGsG/g=
github.com/projectdiscovery/folderutil v0.0.0-20220215113126-add60a1e8e08 h1:m1pgJisawU7zP9lKGktOEk6KNrNAR7e4Q07Kt3ox0NM=
github.com/projectdiscovery/folderutil v0.0.0-20220215113126-add60a1e8e08/go.mod h1:BMqXH4jNGByVdE2iLtKvc/6XStaiZRuCIaKv1vw9PnI=
github.com/projectdiscovery/goflags v0.0.7/go.mod h1:Jjwsf4eEBPXDSQI2Y+6fd3dBumJv/J1U0nmpM+hy2YY=
github.com/projectdiscovery/goflags v0.0.8-0.20220412061559-5119d6086323/go.mod h1:uN+pHMLsWQoiZHUg/l0tqf/VdbX3+ecKfYz/H7b/+NA=
github.com/projectdiscovery/goflags v0.0.8-0.20220426153734-2ffbfbff923c/go.mod h1:uN+pHMLsWQoiZHUg/l0tqf/VdbX3+ecKfYz/H7b/+NA=
github.com/projectdiscovery/goflags v0.0.8-0.20220610073650-5d31a8c159e3 h1:2cUSicd6wkd7A3P+tjjAYiPmD99FtWp4k2curJkcrJ0=
github.com/projectdiscovery/goflags v0.0.8-0.20220610073650-5d31a8c159e3/go.mod h1:Np0EwqmopHDDb1cY4/NEBaC4fornMIWc6dr5yL91kzM=
github.com/projectdiscovery/gologger v1.0.1/go.mod h1:Ok+axMqK53bWNwDSU1nTNwITLYMXMdZtRc8/y1c7sWE=
@ -475,18 +474,20 @@ github.com/projectdiscovery/hmap v0.0.2-0.20210616215655-7b78e7f33d1f/go.mod h1:
github.com/projectdiscovery/hmap v0.0.2-0.20210917080408-0fd7bd286bfa h1:9sZWFUAshIa/ea0RKjGRuuZiS5PzYXAFjTRUnSbezr0=
github.com/projectdiscovery/hmap v0.0.2-0.20210917080408-0fd7bd286bfa/go.mod h1:lV5f/PNPmCCjCN/dR317/chN9s7VG5h/xcbFfXOz8Fo=
github.com/projectdiscovery/interactsh v0.0.4/go.mod h1:PtJrddeBW1/LeOVgTvvnjUl3Hu/17jTkoIi8rXeEODE=
github.com/projectdiscovery/interactsh v1.0.4 h1:73HHOeqGduU1lkIqeYkuEfzdejXRqxQJFZCEbQ1uvkU=
github.com/projectdiscovery/interactsh v1.0.4/go.mod h1:57Xl3Q59aTb8VaFNGkCPO8pWTyTYhlM33p+HDhL8Ygw=
github.com/projectdiscovery/interactsh v1.0.5 h1:/hWP/0qGAzPa3quG8y87Ki4bFZkzXu1OXmyxEWrgnvk=
github.com/projectdiscovery/interactsh v1.0.5/go.mod h1:qEbFdjL3QWbLa5cvoHs9VSYBYCA7uDyViGkM+QqJCQk=
github.com/projectdiscovery/ipranger v0.0.2/go.mod h1:kcAIk/lo5rW+IzUrFkeYyXnFJ+dKwYooEOHGVPP/RWE=
github.com/projectdiscovery/iputil v0.0.0-20210414194613-4b4d2517acf0/go.mod h1:PQAqn5h5NXsQTF4ZA00ZTYLRzGCjOtcCq8llAqrsd1A=
github.com/projectdiscovery/iputil v0.0.0-20210429152401-c18a5408ca46/go.mod h1:PQAqn5h5NXsQTF4ZA00ZTYLRzGCjOtcCq8llAqrsd1A=
github.com/projectdiscovery/iputil v0.0.0-20210804143329-3a30fcde43f3 h1:VZ9H51A7tI7R/9I5W5l960Nkq7eMJqGd3y1wsuwzdjE=
github.com/projectdiscovery/iputil v0.0.0-20210804143329-3a30fcde43f3/go.mod h1:blmYJkS8lSrrx3QcmcgS2tZIxlojeVmoGeA9twslCBU=
github.com/projectdiscovery/iputil v0.0.0-20220620153941-036d511e4097 h1:hPFYljvvgbvH+oTPtixCTruvR8uecCBON4C74xOUMFY=
github.com/projectdiscovery/iputil v0.0.0-20220620153941-036d511e4097/go.mod h1:+27oPnef3nuy3NfYp6WGfUH/xcHYgSw0n0rlialTk+w=
github.com/projectdiscovery/mapcidr v0.0.4/go.mod h1:ALOIj6ptkWujNoX8RdQwB2mZ+kAmKuLJBq9T5gR5wG0=
github.com/projectdiscovery/mapcidr v0.0.6/go.mod h1:ZEBhMmBU3laUl3g9QGTrzJku1VJOzjdFwW01f/zVVzM=
github.com/projectdiscovery/mapcidr v0.0.7/go.mod h1:7CzdUdjuLVI0s33dQ33lWgjg3vPuLFw2rQzZ0RxkT00=
github.com/projectdiscovery/mapcidr v0.0.8 h1:16U05F2x3o/jSTsxSCY2hCuCs9xOSwVxjo2zlsL4L4E=
github.com/projectdiscovery/mapcidr v0.0.8/go.mod h1:7CzdUdjuLVI0s33dQ33lWgjg3vPuLFw2rQzZ0RxkT00=
github.com/projectdiscovery/mapcidr v1.0.0 h1:4ctYAgkxaLeky3o3c+qMgHoUjytYy6DME2fjbgiB1Ag=
github.com/projectdiscovery/mapcidr v1.0.0/go.mod h1:5QkKrV6rNQQurCZI3nNedFsAOYp04mRDkC5yht+znYA=
github.com/projectdiscovery/networkpolicy v0.0.1 h1:RGRuPlxE8WLFF9tdKSjTsYiTIKHNHW20Kl0nGGiRb1I=
github.com/projectdiscovery/networkpolicy v0.0.1/go.mod h1:asvdg5wMy3LPVMGALatebKeOYH5n5fV5RCTv6DbxpIs=
github.com/projectdiscovery/nuclei-updatecheck-api v0.0.0-20211006155443-c0a8d610a4df h1:CvTNAUD5JbLMqpMFoGNgfk2gOcN0NC57ICu0+oK84vs=
@ -512,15 +513,13 @@ github.com/projectdiscovery/stringsutil v0.0.0-20210524051937-51dabe3b72c0/go.mo
github.com/projectdiscovery/stringsutil v0.0.0-20210804142656-fd3c28dbaafe/go.mod h1:oTRc18WBv9t6BpaN9XBY+QmG28PUpsyDzRht56Qf49I=
github.com/projectdiscovery/stringsutil v0.0.0-20210823090203-2f5f137e8e1d/go.mod h1:oTRc18WBv9t6BpaN9XBY+QmG28PUpsyDzRht56Qf49I=
github.com/projectdiscovery/stringsutil v0.0.0-20210830151154-f567170afdd9/go.mod h1:oTRc18WBv9t6BpaN9XBY+QmG28PUpsyDzRht56Qf49I=
github.com/projectdiscovery/stringsutil v0.0.0-20220208075244-7c05502ca8e9/go.mod h1:oTRc18WBv9t6BpaN9XBY+QmG28PUpsyDzRht56Qf49I=
github.com/projectdiscovery/stringsutil v0.0.0-20220422150559-b54fb5dc6833 h1:yo7hCL47BOHl8X/aMmPeRQwiqUrH6TZ2WjgqItaSPcc=
github.com/projectdiscovery/stringsutil v0.0.0-20220422150559-b54fb5dc6833/go.mod h1:oTRc18WBv9t6BpaN9XBY+QmG28PUpsyDzRht56Qf49I=
github.com/projectdiscovery/stringsutil v0.0.0-20220612082425-0037ce9f89f3 h1:EbP+rVR7NPsFKfwhzshmXP2GMjqBpaMZurJzQ5PYvbY=
github.com/projectdiscovery/stringsutil v0.0.0-20220612082425-0037ce9f89f3/go.mod h1:mF5sh4jTghoGWwgUb9qWi5waTFklClDbtrqtJU93awc=
github.com/projectdiscovery/urlutil v0.0.0-20210525140139-b874f06ad921 h1:EgaxpJm7+lKppfAHkFHs+S+II0lodp4Gu3leZCCkWlc=
github.com/projectdiscovery/urlutil v0.0.0-20210525140139-b874f06ad921/go.mod h1:oXLErqOpqEAp/ueQlknysFxHO3CUNoSiDNnkiHG+Jpo=
github.com/projectdiscovery/wappalyzergo v0.0.47 h1:xFTk1MLhLuXX8Ll5i5pJoO7Z0Nbgr8KCvCSid/odRD8=
github.com/projectdiscovery/wappalyzergo v0.0.47/go.mod h1:vS+npIOANv7eKsEtODsyRQt2n1v8VofCwj2gjmq72EM=
github.com/projectdiscovery/wappalyzergo v0.0.50 h1:mV0RwGnzyyfKscXnDCgzb2INy1BTJX8dT8Zurl+WCuY=
github.com/projectdiscovery/wappalyzergo v0.0.50/go.mod h1:1LQBGQVW47tMHxGTxmBK+pAwfsWKSLQMXt/egxGlljo=
github.com/projectdiscovery/yamldoc-go v1.0.2/go.mod h1:7uSxfMXaBmzvw8m5EhOEjB6nhz0rK/H9sUjq1ciZu24=
github.com/projectdiscovery/yamldoc-go v1.0.3-0.20211126104922-00d2c6bb43b6 h1:DvWRQpw7Ib2CRL3ogYm/BWM+X0UGPfz1n9Ix9YKgFM8=
github.com/projectdiscovery/yamldoc-go v1.0.3-0.20211126104922-00d2c6bb43b6/go.mod h1:8OfZj8p/axkUM/TJoS/O9LDjj/S8u17rxRbqluE9CU4=
@ -546,8 +545,8 @@ github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c
github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shirou/gopsutil/v3 v3.21.7/go.mod h1:RGl11Y7XMTQPmHh8F0ayC6haKNBgH4PXMJuTAcMOlz4=
github.com/shirou/gopsutil/v3 v3.22.5 h1:atX36I/IXgFiB81687vSiBI5zrMsxcIBkP9cQMJQoJA=
github.com/shirou/gopsutil/v3 v3.22.5/go.mod h1:so9G9VzeHt/hsd0YwqprnjHnfARAUktauykSbr+y2gA=
github.com/shirou/gopsutil/v3 v3.22.6 h1:FnHOFOh+cYAM0C30P+zysPISzlknLC5Z1G4EAElznfQ=
github.com/shirou/gopsutil/v3 v3.22.6/go.mod h1:EdIubSnZhbAvBS1yJ7Xi+AShB/hxwLHOMz4MCYz7yMs=
github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
@ -571,6 +570,7 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
@ -579,8 +579,11 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/stretchr/testify v1.7.3/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.7.5 h1:s5PTfem8p8EbKQOctVV53k6jCJt3UX4IEJzwh+C324Q=
github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
github.com/tj/assert v0.0.0-20171129193455-018094318fb0/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0=
@ -617,8 +620,8 @@ github.com/weppos/publicsuffix-go v0.15.1-0.20210928183822-5ee35905bd95/go.mod h
github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0 h1:3UeQBvD0TFrlVjOeLOBz+CPAI8dnbqNSVwUwRrkp7vQ=
github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0/go.mod h1:IXCdmsXIht47RaVFLEdVnh1t+pgYtTAhQGj73kz+2DM=
github.com/xanzy/go-gitlab v0.50.3/go.mod h1:Q+hQhV508bDPoBijv7YjK/Lvlb4PhVhJdKqXVQrUoAE=
github.com/xanzy/go-gitlab v0.68.0 h1:b2iMQHgZ1V+NyRqLRJVv6RFfr4xnd/AASeS/PETYL0Y=
github.com/xanzy/go-gitlab v0.68.0/go.mod h1:o4yExCtdaqlM8YGdDJWuZoBmfxBsmA9TPEjs9mx1UO4=
github.com/xanzy/go-gitlab v0.68.2 h1:bRVpa+czzpR2j2UV9oeJRU3SO40ieOHlgKlVwW0LRBw=
github.com/xanzy/go-gitlab v0.68.2/go.mod h1:o4yExCtdaqlM8YGdDJWuZoBmfxBsmA9TPEjs9mx1UO4=
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
@ -629,8 +632,8 @@ github.com/ysmood/goob v0.4.0 h1:HsxXhyLBeGzWXnqVKtmT9qM7EuVs/XOgkX7T6r1o1AQ=
github.com/ysmood/goob v0.4.0/go.mod h1:u6yx7ZhS4Exf2MwciFr6nIM8knHQIE22lFpWHnfql18=
github.com/ysmood/got v0.9.3/go.mod h1:pE1l4LOwOBhQg6A/8IAatkGp7uZjnalzrZolnlhhMgY=
github.com/ysmood/got v0.14.1/go.mod h1:pE1l4LOwOBhQg6A/8IAatkGp7uZjnalzrZolnlhhMgY=
github.com/ysmood/got v0.29.5 h1:+wMnm8UjoyYFMfeAsr57a1bahWTkloysc0Hxsu2gmnM=
github.com/ysmood/got v0.29.5/go.mod h1:pE1l4LOwOBhQg6A/8IAatkGp7uZjnalzrZolnlhhMgY=
github.com/ysmood/got v0.31.2 h1:+aNBkkXrVqZ0UJfeiOfuGbKq3kiJarjNl371Nxz6zLA=
github.com/ysmood/got v0.31.2/go.mod h1:pE1l4LOwOBhQg6A/8IAatkGp7uZjnalzrZolnlhhMgY=
github.com/ysmood/gotrace v0.2.0/go.mod h1:TzhIG7nHDry5//eYZDYcTzuJLYQIkykJzCRIo4/dzQM=
github.com/ysmood/gotrace v0.2.2/go.mod h1:TzhIG7nHDry5//eYZDYcTzuJLYQIkykJzCRIo4/dzQM=
github.com/ysmood/gotrace v0.6.0 h1:SyI1d4jclswLhg7SWTL6os3L1WOKeNn/ZtzVQF8QmdY=
@ -640,8 +643,9 @@ github.com/ysmood/gson v0.6.4/go.mod h1:3Kzs5zDl21g5F/BlLTNcuAGAYLKt2lV5G8D1zF3R
github.com/ysmood/gson v0.7.1 h1:zKL2MTGtynxdBdlZjyGsvEOZ7dkxaY5TH6QhAbTgz0Q=
github.com/ysmood/gson v0.7.1/go.mod h1:3Kzs5zDl21g5F/BlLTNcuAGAYLKt2lV5G8D1zF3RNmg=
github.com/ysmood/leakless v0.6.12/go.mod h1:R8iAXPRaG97QJwqxs74RdwzcRHT1SWCGTNqY8q0JvMQ=
github.com/ysmood/leakless v0.7.0 h1:XCGdaPExyoreoQd+H5qgxM3ReNbSPFsEXpSKwbXbwQw=
github.com/ysmood/leakless v0.7.0/go.mod h1:R8iAXPRaG97QJwqxs74RdwzcRHT1SWCGTNqY8q0JvMQ=
github.com/ysmood/leakless v0.8.0 h1:BzLrVoiwxikpgEQR0Lk8NyBN5Cit2b1z+u0mgL4ZJak=
github.com/ysmood/leakless v0.8.0/go.mod h1:R8iAXPRaG97QJwqxs74RdwzcRHT1SWCGTNqY8q0JvMQ=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@ -779,7 +783,6 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2 h1:NWy5+hlRbC7HK+PmcXVUmW1IMyFce7to56IUvhUFm7Y=
golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220615171555-694bf12d69de h1:ogOG2+P6LjO2j55AkRScrkB2BFpd+Z8TY2wcM0Z3MGo=
golang.org/x/net v0.0.0-20220615171555-694bf12d69de/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=

View File

@ -3,11 +3,11 @@ package runner
import (
"fmt"
"net"
"os"
"path/filepath"
"runtime"
"strings"
"github.com/mitchellh/go-homedir"
"github.com/projectdiscovery/fileutil"
"github.com/projectdiscovery/goflags"
"github.com/projectdiscovery/nuclei/v2/pkg/catalog/config"
@ -29,7 +29,7 @@ func DoHealthCheck(options *types.Options) string {
var testResult string
nucleiIgnorePath := filepath.Join(cfgFileFolder, ".nuclei-ignore")
homedir, _ := os.UserHomeDir()
homedir, _ := homedir.Dir()
nucleiTemplatePath := filepath.Join(homedir, "nuclei-templates/.checksum")
for _, filename := range []string{cfgFilePath, nucleiIgnorePath, nucleiTemplatePath} {
ok, err := fileutil.IsReadable(filename)

View File

@ -34,7 +34,7 @@ func ConfigureOptions() error {
// ParseOptions parses the command line flags provided by a user
func ParseOptions(options *types.Options) {
// Check if stdin pipe was given
options.Stdin = hasStdin()
options.Stdin = !options.DisableStdin && fileutil.HasStdin()
// Read the inputs and configure the logging
configureOutput(options)
@ -84,18 +84,6 @@ func ParseOptions(options *types.Options) {
}
}
// hasStdin returns true if we have stdin input
func hasStdin() bool {
fi, err := os.Stdin.Stat()
if err != nil {
return false
}
if fi.Mode()&os.ModeNamedPipe == 0 {
return false
}
return true
}
// validateOptions validates the configuration options passed
func validateOptions(options *types.Options) error {
validate := validator.New()

View File

@ -2,8 +2,11 @@ package runner
import (
"bufio"
"bytes"
"context"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
_ "net/http/pprof"
"os"
@ -11,6 +14,7 @@ import (
"strings"
"time"
"github.com/blang/semver"
"github.com/logrusorgru/aurora"
"github.com/pkg/errors"
"go.uber.org/atomic"
@ -32,6 +36,7 @@ import (
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/hosterrorscache"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/interactsh"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/protocolinit"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/utils/excludematchers"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/headless/engine"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/http/httpclientpool"
"github.com/projectdiscovery/nuclei/v2/pkg/reporting"
@ -89,6 +94,8 @@ func New(options *types.Options) (*Runner, error) {
// Does not update the templates when validate flag is used
options.NoUpdateTemplates = true
}
parsers.NoStrictSyntax = options.NoStrictSyntax
if err := runner.updateTemplates(); err != nil {
gologger.Error().Msgf("Could not update templates: %s\n", err)
}
@ -306,6 +313,30 @@ func (r *Runner) RunEnumeration() error {
}
r.options.Templates = append(r.options.Templates, templatesLoaded...)
}
if len(r.options.NewTemplatesWithVersion) > 0 {
minVersion, err := semver.Parse("8.8.4")
if err != nil {
return errors.Wrap(err, "could not parse minimum version")
}
latestVersion, err := semver.Parse(r.templatesConfig.NucleiTemplatesLatestVersion)
if err != nil {
return errors.Wrap(err, "could not get latest version")
}
for _, version := range r.options.NewTemplatesWithVersion {
current, err := semver.Parse(strings.Trim(version, "v"))
if err != nil {
return errors.Wrap(err, "could not parse current version")
}
if !(current.GT(minVersion) && current.LTE(latestVersion)) {
return fmt.Errorf("version should be greater than %s and less than %s", minVersion, latestVersion)
}
templatesLoaded, err := r.readNewTemplatesWithVersionFile(fmt.Sprintf("v%s", current))
if err != nil {
return errors.Wrap(err, "could not get newly added templates for "+current.String())
}
r.options.Templates = append(r.options.Templates, templatesLoaded...)
}
}
// Exclude ignored file for validation
if !r.options.Validate {
ignoreFile := config.ReadIgnoreFile()
@ -333,6 +364,7 @@ func (r *Runner) RunEnumeration() error {
HostErrorsCache: cache,
Colorizer: r.colorizer,
ResumeCfg: r.resumeCfg,
ExcludeMatchers: excludematchers.New(r.options.ExcludeMatchers),
}
engine := core.New(r.options)
engine.SetExecuterOptions(executerOpts)
@ -514,6 +546,31 @@ func (r *Runner) displayExecutionInfo(store *loader.Store) {
gologger.Info().Msgf("Workflows loaded for scan: %d", len(store.Workflows()))
}
}
func (r *Runner) readNewTemplatesWithVersionFile(version string) ([]string, error) {
resp, err := http.DefaultClient.Get(fmt.Sprintf("https://raw.githubusercontent.com/projectdiscovery/nuclei-templates/%s/.new-additions", version))
if err != nil {
return nil, err
}
if resp.StatusCode != http.StatusOK {
return nil, errors.New("version not found")
}
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
templatesList := []string{}
scanner := bufio.NewScanner(bytes.NewReader(data))
for scanner.Scan() {
text := scanner.Text()
if text == "" {
continue
}
if isTemplate(text) {
templatesList = append(templatesList, text)
}
}
return templatesList, nil
}
// readNewTemplatesFile reads newly added templates from directory if it exists
func (r *Runner) readNewTemplatesFile() ([]string, error) {
@ -524,7 +581,7 @@ func (r *Runner) readNewTemplatesFile() ([]string, error) {
file, err := os.Open(additionsFile)
if err != nil {
return nil, err
}
}
defer file.Close()
templatesList := []string{}

View File

@ -73,10 +73,10 @@ func (r *Runner) updateTemplates() error { // TODO this method does more than ju
TemplatesDirectory: defaultTemplatesDirectory,
NucleiVersion: config.Version,
}
r.templatesConfig = currentConfig
if writeErr := config.WriteConfiguration(currentConfig); writeErr != nil {
return errors.Wrap(writeErr, "could not write template configuration")
}
r.templatesConfig = currentConfig
}
if r.options.TemplatesDirectory == "" {
if r.templatesConfig.TemplatesDirectory != "" {

View File

@ -5,6 +5,7 @@ import (
"path/filepath"
jsoniter "github.com/json-iterator/go"
"github.com/mitchellh/go-homedir"
"github.com/pkg/errors"
"gopkg.in/yaml.v2"
@ -27,7 +28,7 @@ type Config struct {
const nucleiConfigFilename = ".templates-config.json"
// Version is the current version of nuclei
const Version = `2.7.3`
const Version = `2.7.4`
func getConfigDetails() (string, error) {
configDir, err := GetConfigDir()
@ -41,7 +42,7 @@ func getConfigDetails() (string, error) {
// GetConfigDir returns the nuclei configuration directory
func GetConfigDir() (string, error) {
home, err := os.UserHomeDir()
home, err := homedir.Dir()
if err != nil {
return "", err
}

View File

@ -43,3 +43,9 @@ func (p *PathFilter) Match(templates []string) map[string]struct{} {
}
return templatesMap
}
// MatchIncluded returns true if the template was included explicitly
func (p *PathFilter) MatchIncluded(template string) bool {
_, found := p.alwaysIncludedTemplatesMap[template]
return found
}

View File

@ -261,10 +261,7 @@ func (store *Store) LoadTemplates(templatesList []string) []*templates.Template
loadedTemplates := make([]*templates.Template, 0, len(templatePathMap))
for templatePath := range templatePathMap {
loaded, err := parsers.LoadTemplate(templatePath, store.tagFilter, nil)
if err != nil {
gologger.Warning().Msgf("Could not load template %s: %s\n", templatePath, err)
}
if loaded {
if loaded || store.pathFilter.MatchIncluded(templatePath) {
parsed, err := templates.Parse(templatePath, store.preprocessor, store.config.ExecutorOptions)
if err != nil {
stats.Increment(parsers.RuntimeWarningsStats)
@ -272,6 +269,8 @@ func (store *Store) LoadTemplates(templatesList []string) []*templates.Template
} else if parsed != nil {
loadedTemplates = append(loadedTemplates, parsed)
}
} else if err != nil {
gologger.Warning().Msgf("Could not load template %s: %s\n", templatePath, err)
}
}
return loadedTemplates
@ -309,10 +308,7 @@ func (store *Store) LoadTemplatesWithTags(templatesList, tags []string) []*templ
loadedTemplates := make([]*templates.Template, 0, len(templatePathMap))
for templatePath := range templatePathMap {
loaded, err := parsers.LoadTemplate(templatePath, store.tagFilter, tags)
if err != nil {
gologger.Warning().Msgf("Could not load template %s: %s\n", templatePath, err)
}
if loaded {
if loaded || store.pathFilter.MatchIncluded(templatePath) {
parsed, err := templates.Parse(templatePath, store.preprocessor, store.config.ExecutorOptions)
if err != nil {
stats.Increment(parsers.RuntimeWarningsStats)
@ -320,6 +316,8 @@ func (store *Store) LoadTemplatesWithTags(templatesList, tags []string) []*templ
} else if parsed != nil {
loadedTemplates = append(loadedTemplates, parsed)
}
} else if err != nil {
gologger.Warning().Msgf("Could not load template %s: %s\n", templatePath, err)
}
}
return loadedTemplates

View File

@ -7,6 +7,7 @@ import (
"io"
"os"
"strings"
"time"
"github.com/pkg/errors"
@ -73,7 +74,7 @@ func (i *Input) initializeInputSources(options *types.Options) error {
// Handle stdin
if options.Stdin {
i.scanInputFromReader(os.Stdin)
i.scanInputFromReader(fileutil.TimeoutReader{Reader: os.Stdin, Timeout: time.Duration(options.InputReadTimeout)})
}
// Handle target file

View File

@ -4,8 +4,11 @@ import (
"bytes"
"compress/gzip"
"compress/zlib"
"crypto/aes"
"crypto/cipher"
"crypto/hmac"
"crypto/md5"
crand "crypto/rand"
"crypto/sha1"
"crypto/sha256"
"encoding/base64"
@ -505,6 +508,26 @@ func init() {
}
return nil, fmt.Errorf("invalid number: %T", args[0])
}),
"aes_gcm": makeDslFunction(2, func(args ...interface{}) (interface{}, error) {
key := args[0].(string)
value := args[1].(string)
c, err := aes.NewCipher([]byte(key))
if nil != err {
return "", err
}
gcm, err := cipher.NewGCM(c)
if nil != err {
return "", err
}
nonce := make([]byte, gcm.NonceSize())
if _, err = io.ReadFull(crand.Reader, nonce); err != nil {
return "", err
}
data := gcm.Seal(nonce, nonce, []byte(value), nil)
return data, nil
}),
}
dslFunctions = make(map[string]dslFunction, len(tempDslFunctions))

View File

@ -133,7 +133,8 @@ func createSignatureError(signature string) string {
}
func TestGetPrintableDslFunctionSignatures(t *testing.T) {
expected := ` base64(arg1 interface{}) interface{}
expected := ` aes_gcm(arg1, arg2 interface{}) interface{}
base64(arg1 interface{}) interface{}
base64_decode(arg1 interface{}) interface{}
base64_py(arg1 interface{}) interface{}
compare_versions(firstVersion, constraints ...string) bool

View File

@ -31,6 +31,12 @@ func (matcher *Matcher) CompileMatchers() error {
}
matcher.matcherType = computedType
// Validate the matcher structure
if err := matcher.Validate(); err != nil {
return err
}
// By default, match on body if user hasn't provided any specific items
if matcher.Part == "" {
matcher.Part = "body"

View File

@ -0,0 +1,76 @@
package matchers
import (
"errors"
"fmt"
"reflect"
"strings"
"github.com/projectdiscovery/sliceutil"
"gopkg.in/yaml.v3"
)
var commonExpectedFields = []string{"Type", "Condition", "Name", "MatchAll", "Negative"}
// Validate perform initial validation on the matcher structure
func (matcher *Matcher) Validate() error {
// uses yaml marshaling to convert the struct to map[string]interface to have same field names
matcherMap := make(map[string]interface{})
marshaledMatcher, err := yaml.Marshal(matcher)
if err != nil {
return err
}
if err := yaml.Unmarshal(marshaledMatcher, &matcherMap); err != nil {
return err
}
var expectedFields []string
switch matcher.matcherType {
case DSLMatcher:
expectedFields = append(commonExpectedFields, "DSL")
case StatusMatcher:
expectedFields = append(commonExpectedFields, "Status", "Part")
case SizeMatcher:
expectedFields = append(commonExpectedFields, "Size", "Part")
case WordsMatcher:
expectedFields = append(commonExpectedFields, "Words", "Part", "Encoding", "CaseInsensitive")
case BinaryMatcher:
expectedFields = append(commonExpectedFields, "Binary", "Part", "Encoding", "CaseInsensitive")
case RegexMatcher:
expectedFields = append(commonExpectedFields, "Regex", "Part", "Encoding", "CaseInsensitive")
}
return checkFields(matcher, matcherMap, expectedFields...)
}
func checkFields(m *Matcher, matcherMap map[string]interface{}, expectedFields ...string) error {
var foundUnexpectedFields []string
for marshaledFieldName := range matcherMap {
// revert back the marshaled name to the original field
structFieldName, err := getFieldNameFromYamlTag(marshaledFieldName, *m)
if err != nil {
return err
}
if !sliceutil.Contains(expectedFields, structFieldName) {
foundUnexpectedFields = append(foundUnexpectedFields, structFieldName)
}
}
if len(foundUnexpectedFields) > 0 {
return fmt.Errorf("matcher %s has unexpected fields: %s", m.matcherType, strings.Join(foundUnexpectedFields, ","))
}
return nil
}
func getFieldNameFromYamlTag(tagName string, object interface{}) (string, error) {
reflectType := reflect.TypeOf(object)
if reflectType.Kind() != reflect.Struct {
return "", errors.New("the object must be a struct")
}
for idx := 0; idx < reflectType.NumField(); idx++ {
field := reflectType.Field(idx)
tagParts := strings.Split(field.Tag.Get("yaml"), ",")
if len(tagParts) > 0 && tagParts[0] == tagName {
return field.Name, nil
}
}
return "", fmt.Errorf("field %s not found", tagName)
}

View File

@ -0,0 +1,18 @@
package matchers
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestValidate(t *testing.T) {
m := &Matcher{matcherType: DSLMatcher, DSL: []string{"anything"}}
err := m.Validate()
require.Nil(t, err, "Could not validate correct template")
m = &Matcher{matcherType: DSLMatcher, Part: "test"}
err = m.Validate()
require.NotNil(t, err, "Invalid template was correctly validated")
}

View File

@ -9,6 +9,7 @@ import (
"github.com/projectdiscovery/nuclei/v2/pkg/operators/extractors"
"github.com/projectdiscovery/nuclei/v2/pkg/operators/matchers"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/generators"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/utils/excludematchers"
"github.com/projectdiscovery/sliceutil"
)
@ -34,6 +35,11 @@ type Operators struct {
MatchersCondition string `yaml:"matchers-condition,omitempty" jsonschema:"title=condition between the matchers,description=Conditions between the matchers,enum=and,enum=or"`
// cached variables that may be used along with request.
matchersCondition matchers.ConditionType
// TemplateID is the ID of the template for matcher
TemplateID string
// ExcludeMatchers is a list of excludeMatchers items
ExcludeMatchers *excludematchers.ExcludeMatchers
}
// Compile compiles the operators as well as their corresponding matchers and extractors
@ -238,6 +244,12 @@ func (operators *Operators) Execute(data map[string]interface{}, match MatchFunc
}
for matcherIndex, matcher := range operators.Matchers {
// Skip matchers that are in the blocklist
if operators.ExcludeMatchers != nil {
if operators.ExcludeMatchers.Match(operators.TemplateID, matcher.Name) {
continue
}
}
if isMatch, matched := match(data, matcher); isMatch {
if isDebug { // matchers without an explicit name or with AND condition should only be made visible if debug is enabled
matcherName := getMatcherName(matcher, matcherIndex)

View File

@ -103,6 +103,7 @@ func validateTemplateFields(template *templates.Template) error {
var (
parsedTemplatesCache *cache.Templates
ShouldValidate bool
NoStrictSyntax bool
fieldErrorRegexp = regexp.MustCompile(`not found in`)
templateIDRegexp = regexp.MustCompile(`^([a-zA-Z0-9]+[-_])*[a-zA-Z0-9]+$`)
)
@ -133,7 +134,12 @@ func ParseTemplate(templatePath string) (*templates.Template, error) {
}
template := &templates.Template{}
if err := yaml.UnmarshalStrict(data, template); err != nil {
if NoStrictSyntax {
err = yaml.Unmarshal(data, template)
} else {
err = yaml.UnmarshalStrict(data, template)
}
if err != nil {
errString := err.Error()
if !fieldErrorRegexp.MatchString(errString) {
stats.Increment(SyntaxErrorStats)

View File

@ -87,6 +87,10 @@ func (e *Executer) Execute(input string) (bool, error) {
} else {
if writer.WriteResult(event, e.options.Output, e.options.Progress, e.options.IssuesClient) {
results = true
} else {
if err := e.options.Output.WriteFailure(event.InternalEvent); err != nil {
gologger.Warning().Msgf("Could not write failure event to output: %s\n", err)
}
}
}
})

View File

@ -0,0 +1,67 @@
package excludematchers
import (
"strings"
)
// ExcludeMatchers is an instance for excluding matchers with template IDs
type ExcludeMatchers struct {
values map[string]struct{}
templateIDs map[string]struct{}
matcherNames map[string]struct{}
}
// New returns a new exclude matchers instance
//
// Wildcard and non-wildcard values are supported.
// <template-id>:<matcher-name> is the syntax. Wildcards can be specified
// using * character for either value.
//
// Ex- http-missing-security-headers:* skips all http-missing-security-header templates
func New(values []string) *ExcludeMatchers {
excludeMatchers := &ExcludeMatchers{
values: make(map[string]struct{}),
templateIDs: make(map[string]struct{}),
matcherNames: make(map[string]struct{}),
}
for _, value := range values {
partValues := strings.SplitN(value, ":", 2)
if len(partValues) < 2 {
// If there is no matcher name, consider it as template ID
if _, ok := excludeMatchers.templateIDs[value]; !ok {
excludeMatchers.templateIDs[value] = struct{}{}
}
continue
}
templateID, matcherName := partValues[0], partValues[1]
// Handle wildcards
if templateID == "*" {
if _, ok := excludeMatchers.matcherNames[matcherName]; !ok {
excludeMatchers.matcherNames[matcherName] = struct{}{}
}
} else if matcherName == "*" {
if _, ok := excludeMatchers.templateIDs[templateID]; !ok {
excludeMatchers.templateIDs[templateID] = struct{}{}
}
} else {
if _, ok := excludeMatchers.values[value]; !ok {
excludeMatchers.values[value] = struct{}{}
}
}
}
return excludeMatchers
}
// Match returns true if templateID and matcherName matches the blocklist
func (e *ExcludeMatchers) Match(templateID, matcherName string) bool {
if _, ok := e.templateIDs[templateID]; ok {
return true
}
if _, ok := e.matcherNames[matcherName]; ok {
return true
}
matchName := strings.Join([]string{templateID, matcherName}, ":")
_, found := e.values[matchName]
return found
}

View File

@ -0,0 +1,19 @@
package excludematchers
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestExcludeMatchers(t *testing.T) {
em := New([]string{"test-template:test-matcher", "new-template:*", "*:new-matcher", "only-template-id"})
require.True(t, em.Match("test-template", "test-matcher"), "could not get template-matcher value")
require.False(t, em.Match("test-template", "random-matcher"), "could get template-matcher value")
require.True(t, em.Match("new-template", "random-matcher"), "could not get template-matcher value wildcard")
require.True(t, em.Match("random-template", "new-matcher"), "could not get template-matcher value wildcard")
require.True(t, em.Match("only-template-id", "test"), "could not get only template id match value")
}

View File

@ -1,9 +1,12 @@
package variables
import (
"strings"
"github.com/alecthomas/jsonschema"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/expressions"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/generators"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/interactsh"
"github.com/projectdiscovery/nuclei/v2/pkg/types"
"github.com/projectdiscovery/nuclei/v2/pkg/utils"
)
@ -44,6 +47,21 @@ func (variables *Variable) Evaluate(values map[string]interface{}) map[string]in
return result
}
// EvaluateWithInteractsh returns evaluation results of variables with interactsh
func (variables *Variable) EvaluateWithInteractsh(values map[string]interface{}, interact *interactsh.Client) (map[string]interface{}, []string) {
result := make(map[string]interface{}, variables.Len())
var interactURLs []string
variables.ForEach(func(key string, value interface{}) {
valueString := types.ToString(value)
if strings.Contains(valueString, "interactsh-url") {
valueString, interactURLs = interact.ReplaceMarkers(valueString, interactURLs)
}
result[key] = evaluateVariableValue(valueString, values, result)
})
return result, interactURLs
}
// evaluateVariableValue expression and returns final value
func evaluateVariableValue(expression string, values, processing map[string]interface{}) string {
finalMap := generators.MergeMaps(values, processing)

View File

@ -9,8 +9,7 @@ import (
)
func TestVariablesEvaluate(t *testing.T) {
data := `a1: "{{rand_base(5)}}"
a2: "{{md5(a1)}}"
data := `a2: "{{md5('test')}}"
a3: "this_is_random_text"
a4: "{{date_time('%Y-%M-%D')}}"
a5: "{{reverse(hostname)}}"
@ -22,5 +21,5 @@ a6: "123456"`
result := variables.Evaluate(map[string]interface{}{"hostname": "google.com"})
a4 := time.Now().Format("2006-01-02")
require.Equal(t, map[string]interface{}{"a1": "BpLnf", "a2": "531403a4c6a4133e42d0499b5a6ee60f", "a3": "this_is_random_text", "a4": a4, "a5": "moc.elgoog", "a6": "123456"}, result, "could not get correct elements")
require.Equal(t, map[string]interface{}{"a2": "098f6bcd4621d373cade4e832627b4f6", "a3": "this_is_random_text", "a4": a4, "a5": "moc.elgoog", "a6": "123456"}, result, "could not get correct elements")
}

View File

@ -130,6 +130,8 @@ func (request *Request) Compile(options *protocols.ExecuterOptions) error {
if len(request.Matchers) > 0 || len(request.Extractors) > 0 {
compiled := &request.Operators
compiled.ExcludeMatchers = options.ExcludeMatchers
compiled.TemplateID = options.TemplateID
if err := compiled.Compile(); err != nil {
return errors.Wrap(err, "could not compile operators")
}

View File

@ -226,6 +226,10 @@ func TestDNSMakeResult(t *testing.T) {
recursion := false
testutils.Init(options)
templateID := "testing-dns"
executerOpts := testutils.NewMockExecuterOptions(options, &testutils.TemplateInfo{
ID: templateID,
Info: model.Info{SeverityHolder: severity.Holder{Severity: severity.Low}, Name: "test"},
})
request := &Request{
RequestType: DNSRequestTypeHolder{DNSRequestType: A},
Class: "INET",
@ -246,11 +250,8 @@ func TestDNSMakeResult(t *testing.T) {
Regex: []string{"[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+"},
}},
},
options: executerOpts,
}
executerOpts := testutils.NewMockExecuterOptions(options, &testutils.TemplateInfo{
ID: templateID,
Info: model.Info{SeverityHolder: severity.Holder{Severity: severity.Low}, Name: "test"},
})
err := request.Compile(executerOpts)
require.Nil(t, err, "could not compile dns request")

View File

@ -20,6 +20,10 @@ func TestDNSExecuteWithResults(t *testing.T) {
recursion := false
testutils.Init(options)
templateID := "testing-dns"
executerOpts := testutils.NewMockExecuterOptions(options, &testutils.TemplateInfo{
ID: templateID,
Info: model.Info{SeverityHolder: severity.Holder{Severity: severity.Low}, Name: "test"},
})
request := &Request{
RequestType: DNSRequestTypeHolder{DNSRequestType: A},
Class: "INET",
@ -40,11 +44,8 @@ func TestDNSExecuteWithResults(t *testing.T) {
Regex: []string{"[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+"},
}},
},
options: executerOpts,
}
executerOpts := testutils.NewMockExecuterOptions(options, &testutils.TemplateInfo{
ID: templateID,
Info: model.Info{SeverityHolder: severity.Holder{Severity: severity.Low}, Name: "test"},
})
err := request.Compile(executerOpts)
require.Nil(t, err, "could not compile dns request")

View File

@ -101,6 +101,8 @@ func (request *Request) GetID() string {
func (request *Request) Compile(options *protocols.ExecuterOptions) error {
if len(request.Matchers) > 0 || len(request.Extractors) > 0 {
compiled := &request.Operators
compiled.ExcludeMatchers = options.ExcludeMatchers
compiled.TemplateID = options.TemplateID
if err := compiled.Compile(); err != nil {
return errors.Wrap(err, "could not compile operators")
}

View File

@ -239,6 +239,10 @@ func testFileMakeResult(t *testing.T, matchers []*matchers.Matcher, matcherCondi
testutils.Init(options)
templateID := "testing-file"
executerOpts := testutils.NewMockExecuterOptions(options, &testutils.TemplateInfo{
ID: templateID,
Info: model.Info{SeverityHolder: severity.Holder{Severity: severity.Low}, Name: "test"},
})
request := &Request{
ID: templateID,
MaxSize: "1Gb",
@ -254,11 +258,8 @@ func testFileMakeResult(t *testing.T, matchers []*matchers.Matcher, matcherCondi
Regex: []string{"[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+"},
}},
},
options: executerOpts,
}
executerOpts := testutils.NewMockExecuterOptions(options, &testutils.TemplateInfo{
ID: templateID,
Info: model.Info{SeverityHolder: severity.Holder{Severity: severity.Low}, Name: "test"},
})
err := request.Compile(executerOpts)
require.Nil(t, err, "could not compile file request")

View File

@ -22,6 +22,10 @@ func TestFileExecuteWithResults(t *testing.T) {
testutils.Init(options)
templateID := "testing-file"
executerOpts := testutils.NewMockExecuterOptions(options, &testutils.TemplateInfo{
ID: templateID,
Info: model.Info{SeverityHolder: severity.Holder{Severity: severity.Low}, Name: "test"},
})
request := &Request{
ID: templateID,
MaxSize: "1Gb",
@ -41,11 +45,8 @@ func TestFileExecuteWithResults(t *testing.T) {
Regex: []string{"[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+"},
}},
},
options: executerOpts,
}
executerOpts := testutils.NewMockExecuterOptions(options, &testutils.TemplateInfo{
ID: templateID,
Info: model.Info{SeverityHolder: severity.Holder{Severity: severity.Low}, Name: "test"},
})
err := request.Compile(executerOpts)
require.Nil(t, err, "could not compile file request")

View File

@ -46,7 +46,7 @@ func TestActionScript(t *testing.T) {
<script>window.test = 'some-data';</script>
</html>`
timeout := 15 * time.Second
timeout := 180 * time.Second
t.Run("run-and-results", func(t *testing.T) {
actions := []*Action{

View File

@ -118,6 +118,8 @@ func (request *Request) Compile(options *protocols.ExecuterOptions) error {
if len(request.Matchers) > 0 || len(request.Extractors) > 0 {
compiled := &request.Operators
compiled.ExcludeMatchers = options.ExcludeMatchers
compiled.TemplateID = options.TemplateID
if err := compiled.Compile(); err != nil {
return errors.Wrap(err, "could not compile operators")
}

View File

@ -290,7 +290,7 @@ func (r *requestGenerator) handleRawWithPayloads(ctx context.Context, rawRequest
return nil, err
}
if reqWithAnnotations, hasAnnotations := parseAnnotations(rawRequest, req); hasAnnotations {
if reqWithAnnotations, hasAnnotations := r.request.parseAnnotations(rawRequest, req); hasAnnotations {
req = reqWithAnnotations
request = request.WithContext(req.Context())
}

View File

@ -120,12 +120,13 @@ type Request struct {
CompiledOperators *operators.Operators `yaml:"-"`
options *protocols.ExecuterOptions
totalRequests int
customHeaders map[string]string
generator *generators.PayloadGenerator // optional, only enabled when using payloads
httpClient *retryablehttp.Client
rawhttpClient *rawhttp.Client
options *protocols.ExecuterOptions
connConfiguration *httpclientpool.Configuration
totalRequests int
customHeaders map[string]string
generator *generators.PayloadGenerator // optional, only enabled when using payloads
httpClient *retryablehttp.Client
rawhttpClient *rawhttp.Client
// description: |
// SelfContained specifies if the request is self-contained.
@ -233,9 +234,17 @@ func (request *Request) Compile(options *protocols.ExecuterOptions) error {
connectionConfiguration := &httpclientpool.Configuration{
Threads: request.Threads,
MaxRedirects: request.MaxRedirects,
NoTimeout: false,
FollowRedirects: request.Redirects,
CookieReuse: request.CookieReuse,
}
// If we have request level timeout, ignore http client timeouts
for _, req := range request.Raw {
if reTimeoutAnnotation.MatchString(req) {
connectionConfiguration.NoTimeout = true
}
}
request.connConfiguration = connectionConfiguration
// if the headers contain "Connection" we need to disable the automatic keep alive of the standard library
if _, hasConnectionHeader := request.Headers["Connection"]; hasConnectionHeader {
@ -270,6 +279,8 @@ func (request *Request) Compile(options *protocols.ExecuterOptions) error {
}
if len(request.Matchers) > 0 || len(request.Extractors) > 0 {
compiled := &request.Operators
compiled.ExcludeMatchers = options.ExcludeMatchers
compiled.TemplateID = options.TemplateID
if compileErr := compiled.Compile(); compileErr != nil {
return errors.Wrap(compileErr, "could not compile operators")
}

View File

@ -69,6 +69,8 @@ type Configuration struct {
Threads int
// MaxRedirects is the maximum number of redirects to follow
MaxRedirects int
// NoTimeout disables http request timeout for context based usage
NoTimeout bool
// CookieReuse enables cookie reuse for the http client (cookiejar impl)
CookieReuse bool
// FollowRedirects specifies whether to follow redirects
@ -85,6 +87,8 @@ func (c *Configuration) Hash() string {
builder.WriteString(strconv.Itoa(c.Threads))
builder.WriteString("m")
builder.WriteString(strconv.Itoa(c.MaxRedirects))
builder.WriteString("n")
builder.WriteString(strconv.FormatBool(c.NoTimeout))
builder.WriteString("f")
builder.WriteString(strconv.FormatBool(c.FollowRedirects))
builder.WriteString("r")
@ -97,7 +101,7 @@ func (c *Configuration) Hash() string {
// HasStandardOptions checks whether the configuration requires custom settings
func (c *Configuration) HasStandardOptions() bool {
return c.Threads == 0 && c.MaxRedirects == 0 && !c.FollowRedirects && !c.CookieReuse && c.Connection == nil
return c.Threads == 0 && c.MaxRedirects == 0 && !c.FollowRedirects && !c.CookieReuse && c.Connection == nil && !c.NoTimeout
}
// GetRawHTTP returns the rawhttp request client
@ -217,6 +221,14 @@ func wrappedGet(options *types.Options, configuration *Configuration) (*retryabl
})
if proxyErr == nil {
transport.DialContext = dc.DialContext
transport.DialTLSContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
// upgrade proxy connection to tls
conn, err := dc.DialContext(ctx, network, addr)
if err != nil {
return nil, err
}
return tls.Client(conn, tlsConfig), nil
}
}
}
@ -227,11 +239,14 @@ func wrappedGet(options *types.Options, configuration *Configuration) (*retryabl
}
}
client := retryablehttp.NewWithHTTPClient(&http.Client{
httpclient := &http.Client{
Transport: transport,
Timeout: time.Duration(options.Timeout) * time.Second,
CheckRedirect: makeCheckRedirectFunc(followRedirects, maxRedirects),
}, retryableHttpOptions)
}
if !configuration.NoTimeout {
httpclient.Timeout = time.Duration(options.Timeout) * time.Second
}
client := retryablehttp.NewWithHTTPClient(httpclient, retryableHttpOptions)
if jar != nil {
client.HTTPClient.Jar = jar
}

View File

@ -222,6 +222,10 @@ func (request *Request) executeTurboHTTP(reqURL string, dynamicValues, previous
// ExecuteWithResults executes the final request on a URL
func (request *Request) ExecuteWithResults(reqURL string, dynamicValues, previous output.InternalEvent, callback protocols.OutputEventCallback) error {
if request.Pipeline || request.Race && request.RaceNumberRequests > 0 || request.Threads > 0 {
variablesMap := request.options.Variables.Evaluate(generators.MergeMaps(dynamicValues, previous))
dynamicValues = generators.MergeMaps(variablesMap, dynamicValues)
}
// verify if pipeline was requested
if request.Pipeline {
return request.executeTurboHTTP(reqURL, dynamicValues, previous, callback)
@ -229,7 +233,7 @@ func (request *Request) ExecuteWithResults(reqURL string, dynamicValues, previou
// verify if a basic race condition was requested
if request.Race && request.RaceNumberRequests > 0 {
return request.executeRaceRequest(reqURL, previous, callback)
return request.executeRaceRequest(reqURL, dynamicValues, callback)
}
// verify if parallel elaboration was requested
@ -245,7 +249,7 @@ func (request *Request) ExecuteWithResults(reqURL string, dynamicValues, previou
// returns two values, error and skip, which skips the execution for the request instance.
executeFunc := func(data string, payloads, dynamicValue map[string]interface{}) (bool, error) {
hasInteractMatchers := interactsh.HasMatchers(request.CompiledOperators)
variablesMap := request.options.Variables.Evaluate(generators.MergeMaps(dynamicValues, payloads))
variablesMap, interactURLs := request.options.Variables.EvaluateWithInteractsh(generators.MergeMaps(dynamicValues, payloads), request.options.Interactsh)
dynamicValue = generators.MergeMaps(variablesMap, dynamicValue)
generatedHttpRequest, err := generator.Make(reqURL, data, payloads, dynamicValue)
@ -256,6 +260,10 @@ func (request *Request) ExecuteWithResults(reqURL string, dynamicValues, previou
request.options.Progress.IncrementFailedRequestsBy(int64(generator.Total()))
return true, err
}
// If the variables contain interactsh urls, use them
if len(interactURLs) > 0 {
generatedHttpRequest.interactshURLs = append(generatedHttpRequest.interactshURLs, interactURLs...)
}
hasInteractMarkers := interactsh.HasMarkers(data) || len(generatedHttpRequest.interactshURLs) > 0
if reqURL == "" {
reqURL = generatedHttpRequest.URL()

View File

@ -6,6 +6,7 @@ import (
"net/http"
"regexp"
"strings"
"time"
"github.com/projectdiscovery/fastdialer/fastdialer"
"github.com/projectdiscovery/iputil"
@ -21,10 +22,12 @@ var (
// request.host: takes the value from the host header
// target: overiddes with the specific value
reSniAnnotation = regexp.MustCompile(`(?m)^@tls-sni:\s*(.+)\s*$`)
// @timeout:duration overrides the input timout with a custom duration
reTimeoutAnnotation = regexp.MustCompile(`(?m)^@timeout:\s*(.+)\s*$`)
)
// parseAnnotations and override requests settings
func parseAnnotations(rawRequest string, request *http.Request) (*http.Request, bool) {
func (r *Request) parseAnnotations(rawRequest string, request *http.Request) (*http.Request, bool) {
// parse request for known ovverride annotations
var modified bool
// @Host:target
@ -68,6 +71,25 @@ func parseAnnotations(rawRequest string, request *http.Request) (*http.Request,
request = request.Clone(ctx)
modified = true
}
// @timeout:duration
if r.connConfiguration.NoTimeout {
modified = true
if duration := reTimeoutAnnotation.FindStringSubmatch(rawRequest); len(duration) > 0 {
value := strings.TrimSpace(duration[1])
if parsed, err := time.ParseDuration(value); err == nil {
//nolint:govet // cancelled automatically by withTimeout
ctx, _ := context.WithTimeout(request.Context(), parsed)
request = request.Clone(ctx)
}
} else {
//nolint:govet // cancelled automatically by withTimeout
ctx, _ := context.WithTimeout(request.Context(), time.Duration(r.options.Options.Timeout)*time.Second)
request = request.Clone(ctx)
}
}
return request, modified
}

View File

@ -199,6 +199,8 @@ func (request *Request) Compile(options *protocols.ExecuterOptions) error {
if len(request.Matchers) > 0 || len(request.Extractors) > 0 {
compiled := &request.Operators
compiled.ExcludeMatchers = options.ExcludeMatchers
compiled.TemplateID = options.TemplateID
if err := compiled.Compile(); err != nil {
return errors.Wrap(err, "could not compile operators")
}

View File

@ -12,8 +12,16 @@ var noMinor = regexp.MustCompile(`HTTP/([0-9]) `)
// readResponseFromString reads a raw http response from a string.
func readResponseFromString(data string) (*http.Response, error) {
var final string
// Check if "data" contains RFC compatible Request followed by a response
br := bufio.NewReader(strings.NewReader(data))
if req, err := http.ReadRequest(br); err == nil {
if resp, err := http.ReadResponse(br, req); err == nil {
return resp, nil
}
}
// otherwise tries to patch known cases such as http minor version
var final string
if strings.HasPrefix(data, "HTTP/") {
final = addMinorVersionToHTTP(data)
} else {

View File

@ -15,6 +15,7 @@ import (
"github.com/projectdiscovery/nuclei/v2/pkg/projectfile"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/hosterrorscache"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/interactsh"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/utils/excludematchers"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/variables"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/headless/engine"
"github.com/projectdiscovery/nuclei/v2/pkg/reporting"
@ -66,6 +67,8 @@ type ExecuterOptions struct {
StopAtFirstMatch bool
// Variables is a list of variables from template
Variables variables.Variable
// ExcludeMatchers is the list of matchers to exclude
ExcludeMatchers *excludematchers.ExcludeMatchers
Operators []*operators.Operators // only used by offlinehttp module

View File

@ -86,6 +86,8 @@ func (request *Request) Compile(options *protocols.ExecuterOptions) error {
if len(request.Matchers) > 0 || len(request.Extractors) > 0 {
compiled := &request.Operators
compiled.ExcludeMatchers = options.ExcludeMatchers
compiled.TemplateID = options.TemplateID
if err := compiled.Compile(); err != nil {
return errors.Wrap(err, "could not compile operators")
}

View File

@ -110,6 +110,8 @@ func (request *Request) Compile(options *protocols.ExecuterOptions) error {
if len(request.Matchers) > 0 || len(request.Extractors) > 0 {
compiled := &request.Operators
compiled.ExcludeMatchers = options.ExcludeMatchers
compiled.TemplateID = options.TemplateID
if err := compiled.Compile(); err != nil {
return errors.Wrap(err, "could not compile operators")
}

View File

@ -64,6 +64,8 @@ func (request *Request) Compile(options *protocols.ExecuterOptions) error {
if len(request.Matchers) > 0 || len(request.Extractors) > 0 {
compiled := &request.Operators
compiled.ExcludeMatchers = options.ExcludeMatchers
compiled.TemplateID = options.TemplateID
if err := compiled.Compile(); err != nil {
return errors.Wrap(err, "could not compile operators")
}

View File

@ -112,7 +112,7 @@ func ClusterTemplates(templatesList []*Template, options protocols.ExecuterOptio
finalTemplatesList = append(finalTemplatesList, &Template{
ID: clusterID,
RequestsHTTP: cluster[0].RequestsHTTP,
Executer: NewExecuter(cluster, &executerOpts),
Executer: NewClusterExecuter(cluster, &executerOpts),
TotalRequests: len(cluster[0].RequestsHTTP),
})
clusterCount += len(cluster)
@ -123,12 +123,12 @@ func ClusterTemplates(templatesList []*Template, options protocols.ExecuterOptio
return finalTemplatesList, clusterCount
}
// Executer executes a group of requests for a protocol for a clustered
// ClusterExecuter executes a group of requests for a protocol for a clustered
// request. It is different from normal executers since the original
// operators are all combined and post processed after making the request.
//
// TODO: We only cluster http requests as of now.
type Executer struct {
type ClusterExecuter struct {
requests *http.Request
operators []*clusteredOperator
options *protocols.ExecuterOptions
@ -141,21 +141,25 @@ type clusteredOperator struct {
operator *operators.Operators
}
var _ protocols.Executer = &Executer{}
var _ protocols.Executer = &ClusterExecuter{}
// NewExecuter creates a new request executer for list of requests
func NewExecuter(requests []*Template, options *protocols.ExecuterOptions) *Executer {
executer := &Executer{
// NewClusterExecuter creates a new request executer for list of requests
func NewClusterExecuter(requests []*Template, options *protocols.ExecuterOptions) *ClusterExecuter {
executer := &ClusterExecuter{
options: options,
requests: requests[0].RequestsHTTP[0],
}
for _, req := range requests {
if req.RequestsHTTP[0].CompiledOperators != nil {
operator := req.RequestsHTTP[0].CompiledOperators
operator.TemplateID = req.ID
operator.ExcludeMatchers = options.ExcludeMatchers
executer.operators = append(executer.operators, &clusteredOperator{
operator: operator,
templateID: req.ID,
templateInfo: req.Info,
templatePath: req.Path,
operator: req.RequestsHTTP[0].CompiledOperators,
})
}
}
@ -163,19 +167,19 @@ func NewExecuter(requests []*Template, options *protocols.ExecuterOptions) *Exec
}
// Compile compiles the execution generators preparing any requests possible.
func (e *Executer) Compile() error {
func (e *ClusterExecuter) Compile() error {
return e.requests.Compile(e.options)
}
// Requests returns the total number of requests the rule will perform
func (e *Executer) Requests() int {
func (e *ClusterExecuter) Requests() int {
var count int
count += e.requests.Requests()
return count
}
// Execute executes the protocol group and returns true or false if results were found.
func (e *Executer) Execute(input string) (bool, error) {
func (e *ClusterExecuter) Execute(input string) (bool, error) {
var results bool
previous := make(map[string]interface{})
@ -209,7 +213,7 @@ func (e *Executer) Execute(input string) (bool, error) {
}
// ExecuteWithResults executes the protocol requests and returns results instead of writing them.
func (e *Executer) ExecuteWithResults(input string, callback protocols.OutputEventCallback) error {
func (e *ClusterExecuter) ExecuteWithResults(input string, callback protocols.OutputEventCallback) error {
dynamicValues := make(map[string]interface{})
err := e.requests.ExecuteWithResults(input, dynamicValues, nil, func(event *output.InternalWrappedEvent) {
for _, operator := range e.operators {

View File

@ -3,7 +3,6 @@ package templates
import (
"fmt"
"reflect"
"strings"
"github.com/pkg/errors"
"gopkg.in/yaml.v2"
@ -14,6 +13,7 @@ import (
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/offlinehttp"
"github.com/projectdiscovery/nuclei/v2/pkg/templates/cache"
"github.com/projectdiscovery/nuclei/v2/pkg/utils"
"github.com/projectdiscovery/stringsutil"
)
var (
@ -203,8 +203,13 @@ func (template *Template) compileOfflineHTTPRequest(options protocols.ExecuterOp
mainLoop:
for _, req := range template.RequestsHTTP {
hasPaths := len(req.Path) > 0
if !hasPaths {
break mainLoop
}
for _, path := range req.Path {
if !(strings.EqualFold(path, "{{BaseURL}}") || strings.EqualFold(path, "{{BaseURL}}/")) {
pathIsBaseURL := stringsutil.EqualFoldAny(path, "{{BaseURL}}", "{{BaseURL}}/", "/")
if !pathIsBaseURL {
break mainLoop
}
}

View File

@ -1,6 +1,8 @@
package types
import (
"time"
"github.com/projectdiscovery/fileutil"
"github.com/projectdiscovery/goflags"
"github.com/projectdiscovery/nuclei/v2/pkg/model/types/severity"
@ -27,6 +29,8 @@ type Options struct {
RemoteTemplateDomainList goflags.StringSlice
// ExcludedTemplates specifies the template/templates to exclude
ExcludedTemplates goflags.FileOriginalNormalizedStringSlice
// ExcludeMatchers is a list of matchers to exclude processing
ExcludeMatchers goflags.FileCommaSeparatedStringSlice
// CustomHeaders is the list of custom global headers to send with each request.
CustomHeaders goflags.FileStringSlice
// Vars is the list of custom global vars
@ -157,6 +161,8 @@ type Options struct {
Version bool
// Validate validates the templates passed to nuclei.
Validate bool
// NoStrictSyntax disables strict syntax check on nuclei templates (allows custom key-value pairs).
NoStrictSyntax bool
// Verbose flag indicates whether to show verbose output or not
Verbose bool
VerboseVerbose bool
@ -190,6 +196,8 @@ type Options struct {
Project bool
// NewTemplates only runs newly added templates from the repository
NewTemplates bool
// NewTemplatesWithVersion runs new templates added in specific version
NewTemplatesWithVersion goflags.CommaSeparatedStringSlice
// NoInteractsh disables use of interactsh server for interaction polling
NoInteractsh bool
// UpdateNuclei checks for an update for the nuclei engine
@ -222,6 +230,10 @@ type Options struct {
SNI string
// Health Check
HealthCheck bool
// Time to wait between each input read operation before closing the stream
InputReadTimeout time.Duration
// Disable stdin for input processing
DisableStdin bool
}
func (options *Options) AddVarPayload(key string, value interface{}) {

View File

@ -1,10 +1,10 @@
package utils
import (
"os"
"path/filepath"
"strings"
"github.com/mitchellh/go-homedir"
"github.com/projectdiscovery/nuclei/v2/pkg/catalog/config"
)
@ -35,7 +35,7 @@ func TemplatePathURL(fullPath string) (string, string) {
// GetDefaultTemplatePath on default settings
func GetDefaultTemplatePath() (string, error) {
home, err := os.UserHomeDir()
home, err := homedir.Dir()
if err != nil {
return "", err
}