mirror of https://github.com/daffainfo/nuclei.git
Merge branch 'dev' of https://github.com/projectdiscovery/nuclei into cloud-bug-fixes
commit
ded218a88a
|
@ -12,6 +12,8 @@ jobs:
|
|||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: "Set up Go"
|
||||
uses: actions/setup-go@v3
|
||||
|
@ -36,7 +38,6 @@ jobs:
|
|||
run: |
|
||||
git config --local user.email "action@github.com"
|
||||
git config --local user.name "GitHub Action"
|
||||
git pull
|
||||
git add SYNTAX-REFERENCE.md nuclei-jsonschema.json
|
||||
git commit -m "Auto Generate Syntax Docs + JSONSchema [$(date)] :robot:" -a
|
||||
|
||||
|
|
26
README.md
26
README.md
|
@ -59,6 +59,23 @@ Nuclei requires **go1.18** to install successfully. Run the following command to
|
|||
go install -v github.com/projectdiscovery/nuclei/v2/cmd/nuclei@latest
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Brew</summary>
|
||||
|
||||
```sh
|
||||
brew install nuclei
|
||||
```
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>Docker</summary>
|
||||
|
||||
```sh
|
||||
docker pull projectdiscovery/nuclei:latest
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
**More installation [methods can be found here](https://nuclei.projectdiscovery.io/nuclei/get-started/).**
|
||||
|
||||
<table>
|
||||
|
@ -369,6 +386,7 @@ import (
|
|||
"github.com/projectdiscovery/nuclei/v2/pkg/output"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/parsers"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/contextargs"
|
||||
"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"
|
||||
|
@ -439,7 +457,13 @@ func main() {
|
|||
}
|
||||
store.Load()
|
||||
|
||||
input := &inputs.SimpleInputProvider{Inputs: []string{"docs.hackerone.com"}}
|
||||
inputArgs := []*contextargs.MetaInput{
|
||||
&contextargs.MetaInput{
|
||||
Input: "docs.hackerone.com",
|
||||
},
|
||||
}
|
||||
|
||||
input := &inputs.SimpleInputProvider{Inputs: inputArgs}
|
||||
_ = engine.Execute(store.Templates(), input)
|
||||
engine.WorkPool().Wait() // Wait for the scan to finish
|
||||
}
|
||||
|
|
|
@ -3519,6 +3519,19 @@ description: |
|
|||
|
||||
<div class="dd">
|
||||
|
||||
<code>stop-at-first-match</code> <i>bool</i>
|
||||
|
||||
</div>
|
||||
<div class="dt">
|
||||
|
||||
StopAtFirstMatch stops the execution of the requests and template as soon as a match is found.
|
||||
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="dd">
|
||||
|
||||
<code>matchers</code> <i>[]<a href="#matchersmatcher">matchers.Matcher</a></i>
|
||||
|
||||
</div>
|
||||
|
|
|
@ -576,6 +576,11 @@
|
|||
"title": "custom user agent for the headless request",
|
||||
"description": "Custom user agent for the headless request"
|
||||
},
|
||||
"stop-at-first-match": {
|
||||
"type": "boolean",
|
||||
"title": "stop at first match",
|
||||
"description": "Stop the execution after a match is found"
|
||||
},
|
||||
"matchers": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/matchers.Matcher"
|
||||
|
|
|
@ -93,13 +93,15 @@ func executeNucleiAsCode(templatePath, templateURL string) ([]string, error) {
|
|||
|
||||
home, _ := os.UserHomeDir()
|
||||
catalog := disk.NewCatalog(path.Join(home, "nuclei-templates"))
|
||||
ratelimiter := ratelimit.New(context.Background(), 150, time.Second)
|
||||
defer ratelimiter.Stop()
|
||||
executerOpts := protocols.ExecuterOptions{
|
||||
Output: outputWriter,
|
||||
Options: defaultOpts,
|
||||
Progress: mockProgress,
|
||||
Catalog: catalog,
|
||||
IssuesClient: reportingClient,
|
||||
RateLimiter: ratelimit.New(context.Background(), 150, time.Second),
|
||||
RateLimiter: ratelimiter,
|
||||
Interactsh: interactClient,
|
||||
HostErrorsCache: cache,
|
||||
Colorizer: aurora.NewAurora(true),
|
||||
|
|
|
@ -82,6 +82,7 @@ func main() {
|
|||
// Setup graceful exits
|
||||
resumeFileName := types.DefaultResumeFilePath()
|
||||
c := make(chan os.Signal, 1)
|
||||
defer close(c)
|
||||
signal.Notify(c, os.Interrupt)
|
||||
go func() {
|
||||
for range c {
|
||||
|
@ -123,21 +124,21 @@ on extensive configurability, massive extensibility and ease of use.`)
|
|||
*/
|
||||
|
||||
flagSet.CreateGroup("input", "Target",
|
||||
flagSet.StringSliceVarP(&options.Targets, "target", "u", []string{}, "target URLs/hosts to scan", goflags.StringSliceOptions),
|
||||
flagSet.StringSliceVarP(&options.Targets, "target", "u", nil, "target URLs/hosts to scan", goflags.StringSliceOptions),
|
||||
flagSet.StringVarP(&options.TargetsFilePath, "list", "l", "", "path to file containing a list of target URLs/hosts to scan (one per line)"),
|
||||
flagSet.StringVar(&options.Resume, "resume", "", "resume scan using resume.cfg (clustering will be disabled)"),
|
||||
flagSet.BoolVarP(&options.ScanAllIPs, "scan-all-ips", "sa", false, "scan all the IP's associated with dns record"),
|
||||
flagSet.StringSliceVarP(&options.IPVersion, "ip-version", "iv", []string{""}, "IP version to scan of hostname (4,6) - (default 4)", goflags.CommaSeparatedStringSliceOptions),
|
||||
flagSet.StringSliceVarP(&options.IPVersion, "ip-version", "iv", nil, "IP version to scan of hostname (4,6) - (default 4)", goflags.CommaSeparatedStringSliceOptions),
|
||||
)
|
||||
|
||||
flagSet.CreateGroup("templates", "Templates",
|
||||
flagSet.BoolVarP(&options.NewTemplates, "new-templates", "nt", false, "run only new templates added in latest nuclei-templates release"),
|
||||
flagSet.StringSliceVarP(&options.NewTemplatesWithVersion, "new-templates-version", "ntv", []string{}, "run new templates added in specific version", goflags.CommaSeparatedStringSliceOptions),
|
||||
flagSet.StringSliceVarP(&options.NewTemplatesWithVersion, "new-templates-version", "ntv", nil, "run new templates added in specific version", goflags.CommaSeparatedStringSliceOptions),
|
||||
flagSet.BoolVarP(&options.AutomaticScan, "automatic-scan", "as", false, "automatic web scan using wappalyzer technology detection to tags mapping"),
|
||||
flagSet.StringSliceVarP(&options.Templates, "templates", "t", []string{}, "list of template or template directory to run (comma-separated, file)", goflags.FileCommaSeparatedStringSliceOptions),
|
||||
flagSet.StringSliceVarP(&options.TemplateURLs, "template-url", "tu", []string{}, "list of template urls to run (comma-separated, file)", goflags.FileCommaSeparatedStringSliceOptions),
|
||||
flagSet.StringSliceVarP(&options.Workflows, "workflows", "w", []string{}, "list of workflow or workflow directory to run (comma-separated, file)", goflags.FileCommaSeparatedStringSliceOptions),
|
||||
flagSet.StringSliceVarP(&options.WorkflowURLs, "workflow-url", "wu", []string{}, "list of workflow urls to run (comma-separated, file)", goflags.FileCommaSeparatedStringSliceOptions),
|
||||
flagSet.StringSliceVarP(&options.Templates, "templates", "t", nil, "list of template or template directory to run (comma-separated, file)", goflags.FileCommaSeparatedStringSliceOptions),
|
||||
flagSet.StringSliceVarP(&options.TemplateURLs, "template-url", "tu", nil, "list of template urls to run (comma-separated, file)", goflags.FileCommaSeparatedStringSliceOptions),
|
||||
flagSet.StringSliceVarP(&options.Workflows, "workflows", "w", nil, "list of workflow or workflow directory to run (comma-separated, file)", goflags.FileCommaSeparatedStringSliceOptions),
|
||||
flagSet.StringSliceVarP(&options.WorkflowURLs, "workflow-url", "wu", nil, "list of workflow urls to run (comma-separated, file)", goflags.FileCommaSeparatedStringSliceOptions),
|
||||
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.BoolVarP(&options.TemplateDisplay, "template-display", "td", false, "displays the templates content"),
|
||||
|
@ -146,15 +147,15 @@ on extensive configurability, massive extensibility and ease of use.`)
|
|||
)
|
||||
|
||||
flagSet.CreateGroup("filters", "Filtering",
|
||||
flagSet.StringSliceVarP(&options.Authors, "author", "a", []string{}, "templates to run based on authors (comma-separated, file)", goflags.FileNormalizedStringSliceOptions),
|
||||
flagSet.StringSliceVar(&options.Tags, "tags", []string{}, "templates to run based on tags (comma-separated, file)", goflags.FileNormalizedStringSliceOptions),
|
||||
flagSet.StringSliceVarP(&options.ExcludeTags, "exclude-tags", "etags", []string{}, "templates to exclude based on tags (comma-separated, file)", goflags.FileNormalizedStringSliceOptions),
|
||||
flagSet.StringSliceVarP(&options.IncludeTags, "include-tags", "itags", []string{}, "tags to be executed even if they are excluded either by default or configuration", goflags.FileNormalizedStringSliceOptions), // TODO show default deny list
|
||||
flagSet.StringSliceVarP(&options.IncludeIds, "template-id", "id", []string{}, "templates to run based on template ids (comma-separated, file)", goflags.FileNormalizedStringSliceOptions),
|
||||
flagSet.StringSliceVarP(&options.ExcludeIds, "exclude-id", "eid", []string{}, "templates to exclude based on template ids (comma-separated, file)", goflags.FileNormalizedStringSliceOptions),
|
||||
flagSet.StringSliceVarP(&options.IncludeTemplates, "include-templates", "it", []string{}, "templates to be executed even if they are excluded either by default or configuration", goflags.FileCommaSeparatedStringSliceOptions),
|
||||
flagSet.StringSliceVarP(&options.ExcludedTemplates, "exclude-templates", "et", []string{}, "template or template directory to exclude (comma-separated, file)", goflags.FileCommaSeparatedStringSliceOptions),
|
||||
flagSet.StringSliceVarP(&options.ExcludeMatchers, "exclude-matchers", "em", []string{}, "template matchers to exclude in result", goflags.FileCommaSeparatedStringSliceOptions),
|
||||
flagSet.StringSliceVarP(&options.Authors, "author", "a", nil, "templates to run based on authors (comma-separated, file)", goflags.FileNormalizedStringSliceOptions),
|
||||
flagSet.StringSliceVar(&options.Tags, "tags", nil, "templates to run based on tags (comma-separated, file)", goflags.FileNormalizedStringSliceOptions),
|
||||
flagSet.StringSliceVarP(&options.ExcludeTags, "exclude-tags", "etags", nil, "templates to exclude based on tags (comma-separated, file)", goflags.FileNormalizedStringSliceOptions),
|
||||
flagSet.StringSliceVarP(&options.IncludeTags, "include-tags", "itags", nil, "tags to be executed even if they are excluded either by default or configuration", goflags.FileNormalizedStringSliceOptions), // TODO show default deny list
|
||||
flagSet.StringSliceVarP(&options.IncludeIds, "template-id", "id", nil, "templates to run based on template ids (comma-separated, file)", goflags.FileNormalizedStringSliceOptions),
|
||||
flagSet.StringSliceVarP(&options.ExcludeIds, "exclude-id", "eid", nil, "templates to exclude based on template ids (comma-separated, file)", goflags.FileNormalizedStringSliceOptions),
|
||||
flagSet.StringSliceVarP(&options.IncludeTemplates, "include-templates", "it", nil, "templates to be executed even if they are excluded either by default or configuration", goflags.FileCommaSeparatedStringSliceOptions),
|
||||
flagSet.StringSliceVarP(&options.ExcludedTemplates, "exclude-templates", "et", nil, "template or template directory to exclude (comma-separated, file)", goflags.FileCommaSeparatedStringSliceOptions),
|
||||
flagSet.StringSliceVarP(&options.ExcludeMatchers, "exclude-matchers", "em", nil, "template matchers to exclude in result", goflags.FileCommaSeparatedStringSliceOptions),
|
||||
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())),
|
||||
|
@ -185,8 +186,8 @@ on extensive configurability, massive extensibility and ease of use.`)
|
|||
flagSet.IntVarP(&options.MaxRedirects, "max-redirects", "mr", 10, "max number of redirects to follow for http templates"),
|
||||
flagSet.BoolVarP(&options.DisableRedirects, "disable-redirects", "dr", false, "disable redirects for http templates"),
|
||||
flagSet.StringVarP(&options.ReportingConfig, "report-config", "rc", "", "nuclei reporting module configuration file"), // TODO merge into the config file or rename to issue-tracking
|
||||
flagSet.StringSliceVarP(&options.CustomHeaders, "header", "H", []string{}, "custom header/cookie to include in all http request in header:value format (cli, file)", goflags.FileStringSliceOptions),
|
||||
flagSet.RuntimeMapVarP(&options.Vars, "var", "V", []string{}, "custom vars in key=value format"),
|
||||
flagSet.StringSliceVarP(&options.CustomHeaders, "header", "H", nil, "custom header/cookie to include in all http request in header:value format (cli, file)", goflags.FileStringSliceOptions),
|
||||
flagSet.RuntimeMapVarP(&options.Vars, "var", "V", nil, "custom vars in key=value format"),
|
||||
flagSet.StringVarP(&options.ResolversFile, "resolvers", "r", "", "file containing resolver list for nuclei"),
|
||||
flagSet.BoolVarP(&options.SystemResolvers, "system-resolvers", "sr", false, "use system DNS resolving as error fallback"),
|
||||
flagSet.BoolVarP(&options.DisableClustering, "disable-clustering", "dc", false, "disable clustering of requests"),
|
||||
|
@ -220,8 +221,8 @@ on extensive configurability, massive extensibility and ease of use.`)
|
|||
|
||||
flagSet.CreateGroup("uncover", "Uncover",
|
||||
flagSet.BoolVarP(&options.Uncover, "uncover", "uc", false, "enable uncover engine"),
|
||||
flagSet.StringSliceVarP(&options.UncoverQuery, "uncover-query", "uq", []string{}, "uncover search query", goflags.FileStringSliceOptions),
|
||||
flagSet.StringSliceVarP(&options.UncoverEngine, "uncover-engine", "ue", []string{}, fmt.Sprintf("uncover search engine (%s) (default shodan)", uncover.GetUncoverSupportedAgents()), goflags.FileStringSliceOptions),
|
||||
flagSet.StringSliceVarP(&options.UncoverQuery, "uncover-query", "uq", nil, "uncover search query", goflags.FileStringSliceOptions),
|
||||
flagSet.StringSliceVarP(&options.UncoverEngine, "uncover-engine", "ue", nil, fmt.Sprintf("uncover search engine (%s) (default shodan)", uncover.GetUncoverSupportedAgents()), goflags.FileStringSliceOptions),
|
||||
flagSet.StringVarP(&options.UncoverField, "uncover-field", "uf", "ip:port", "uncover fields to return (ip,port,host)"),
|
||||
flagSet.IntVarP(&options.UncoverLimit, "uncover-limit", "ul", 100, "uncover results to return"),
|
||||
flagSet.IntVarP(&options.UncoverDelay, "uncover-delay", "ucd", 1, "delay between uncover query requests in seconds (0 to disable)"),
|
||||
|
@ -245,6 +246,11 @@ 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-match", "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.EnumVarP(&options.ScanStrategy, "scan-strategy", "ss", goflags.EnumVariable(0), "strategy to use while scanning(auto/host-spray/template-spray)", goflags.AllowdTypes{
|
||||
"auto": goflags.EnumVariable(0),
|
||||
"host-spray": goflags.EnumVariable(1),
|
||||
"template-spray": goflags.EnumVariable(2),
|
||||
}),
|
||||
flagSet.DurationVarP(&options.InputReadTimeout, "input-read-timeout", "irt", time.Duration(3*time.Minute), "timeout on input read"),
|
||||
flagSet.BoolVarP(&options.DisableHTTPProbe, "no-httpx", "nh", false, "disable httpx probing for non-url input"),
|
||||
flagSet.BoolVar(&options.DisableStdin, "no-stdin", false, "disable stdin processing"),
|
||||
|
@ -262,7 +268,7 @@ on extensive configurability, massive extensibility and ease of use.`)
|
|||
flagSet.BoolVar(&options.Debug, "debug", false, "show all requests and responses"),
|
||||
flagSet.BoolVarP(&options.DebugRequests, "debug-req", "dreq", false, "show all sent requests"),
|
||||
flagSet.BoolVarP(&options.DebugResponse, "debug-resp", "dresp", false, "show all received responses"),
|
||||
flagSet.StringSliceVarP(&options.Proxy, "proxy", "p", []string{}, "list of http/socks5 proxy to use (comma separated or file input)", goflags.FileCommaSeparatedStringSliceOptions),
|
||||
flagSet.StringSliceVarP(&options.Proxy, "proxy", "p", nil, "list of http/socks5 proxy to use (comma separated or file input)", goflags.FileCommaSeparatedStringSliceOptions),
|
||||
flagSet.BoolVarP(&options.ProxyInternal, "proxy-internal", "pi", false, "proxy all internal requests"),
|
||||
flagSet.BoolVarP(&options.ListDslSignatures, "list-dsl-function", "ldf", false, "list all supported DSL function signatures"),
|
||||
flagSet.StringVarP(&options.TraceLogFile, "trace-log", "tlog", "", "file to write sent requests trace log"),
|
||||
|
|
36
v2/go.mod
36
v2/go.mod
|
@ -45,7 +45,7 @@ require (
|
|||
github.com/weppos/publicsuffix-go v0.15.1-0.20220724114530-e087fba66a37
|
||||
github.com/xanzy/go-gitlab v0.77.0
|
||||
go.uber.org/atomic v1.10.0
|
||||
go.uber.org/multierr v1.8.0
|
||||
go.uber.org/multierr v1.9.0
|
||||
golang.org/x/net v0.4.0
|
||||
golang.org/x/oauth2 v0.0.0-20220722155238-128564f6959c
|
||||
golang.org/x/text v0.5.0
|
||||
|
@ -58,10 +58,10 @@ require (
|
|||
github.com/antchfx/xmlquery v1.3.13
|
||||
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d
|
||||
github.com/aws/aws-sdk-go-v2 v1.17.3
|
||||
github.com/aws/aws-sdk-go-v2/config v1.18.4
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.13.4
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.43
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.29.5
|
||||
github.com/aws/aws-sdk-go-v2/config v1.18.7
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.13.7
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.46
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.29.6
|
||||
github.com/docker/go-units v0.5.0
|
||||
github.com/fatih/structs v1.1.0
|
||||
github.com/go-git/go-git/v5 v5.5.1
|
||||
|
@ -74,13 +74,13 @@ require (
|
|||
github.com/projectdiscovery/fasttemplate v0.0.2
|
||||
github.com/projectdiscovery/goflags v0.1.6
|
||||
github.com/projectdiscovery/nvd v1.0.9
|
||||
github.com/projectdiscovery/ratelimit v0.0.3
|
||||
github.com/projectdiscovery/ratelimit v0.0.4-0.20221222024635-17151503fe59
|
||||
github.com/projectdiscovery/rdap v0.9.1-0.20221108103045-9865884d1917
|
||||
github.com/projectdiscovery/sarif v0.0.1
|
||||
github.com/projectdiscovery/tlsx v1.0.0
|
||||
github.com/projectdiscovery/uncover v1.0.1
|
||||
github.com/projectdiscovery/utils v0.0.4-0.20221214110533-9f95ee986a54
|
||||
github.com/projectdiscovery/wappalyzergo v0.0.74
|
||||
github.com/projectdiscovery/wappalyzergo v0.0.75
|
||||
github.com/stretchr/testify v1.8.1
|
||||
gopkg.in/src-d/go-git.v4 v4.13.1
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
|
@ -88,10 +88,10 @@ require (
|
|||
|
||||
require (
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.17 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.18 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.21 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.20 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.22 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.21 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bits-and-blooms/bitset v1.3.1 // indirect
|
||||
github.com/bits-and-blooms/bloom/v3 v3.3.1 // indirect
|
||||
|
@ -224,14 +224,14 @@ require (
|
|||
github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4 // indirect
|
||||
github.com/acomagu/bufpipe v1.0.3 // indirect
|
||||
github.com/alecthomas/chroma v0.10.0
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.20 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.26 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.20 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.27 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.20 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.11.26 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.9 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.17.6 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.21 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.27 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.21 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.28 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.21 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.11.28 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.11 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.17.7 // indirect
|
||||
github.com/aws/smithy-go v1.13.5 // indirect
|
||||
github.com/emirpasic/gods v1.18.1 // indirect
|
||||
github.com/go-git/gcfg v1.5.0 // indirect
|
||||
|
|
73
v2/go.sum
73
v2/go.sum
|
@ -101,43 +101,42 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkY
|
|||
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-v2 v1.17.2/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw=
|
||||
github.com/aws/aws-sdk-go-v2 v1.17.3 h1:shN7NlnVzvDUgPQ+1rLMSxY8OWRNDRYtiqe0p/PgrhY=
|
||||
github.com/aws/aws-sdk-go-v2 v1.17.3/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 h1:dK82zF6kkPeCo8J1e+tGx4JdvDIQzj7ygIoLg8WMuGs=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10/go.mod h1:VeTZetY5KRJLuD/7fkQXMU6Mw7H5m/KP2J5Iy9osMno=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.18.4 h1:VZKhr3uAADXHStS/Gf9xSYVmmaluTUfkc0dcbPiDsKE=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.18.4/go.mod h1:EZxMPLSdGAZ3eAmkqXfYbRppZJTzFTkv8VyEzJhKko4=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.13.4 h1:nEbHIyJy7mCvQ/kzGG7VWHSBpRB4H6sJy3bWierWUtg=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.13.4/go.mod h1:/Cj5w9LRsNTLSwexsohwDME32OzJ6U81Zs33zr2ZWOM=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.20 h1:tpNOglTZ8kg9T38NpcGBxudqfUAwUzyUnLQ4XSd0CHE=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.20/go.mod h1:d9xFpWd3qYwdIXM0fvu7deD08vvdRXyc/ueV+0SqaWE=
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.43 h1:+bkAMTd5OGyHu2nwNOangjEsP65fR0uhMbZJA52sZ64=
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.43/go.mod h1:sS2tu0VEspKuY5eM1vQgy7P/hpZX8F62o6qsghZExWc=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.26 h1:5WU31cY7m0tG+AiaXuXGoMzo2GBQ1IixtWa8Yywsgco=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.26/go.mod h1:2E0LdbJW6lbeU4uxjum99GZzI0ZjDpAb0CoSCM0oeEY=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.20 h1:WW0qSzDWoiWU2FS5DbKpxGilFVlCEJPwx4YtjdfI0Jw=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.20/go.mod h1:/+6lSiby8TBFpTVXZgKiN/rCfkYXEGvhlM4zCgPpt7w=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.27 h1:N2eKFw2S+JWRCtTt0IhIX7uoGGQciD4p6ba+SJv4WEU=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.27/go.mod h1:RdwFVc7PBYWY33fa2+8T1mSqQ7ZEK4ILpM0wfioDC3w=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.17 h1:5tXbMJ7Jq0iG65oiMg6tCLsHkSaO2xLXa2EmZ29vaTA=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.17/go.mod h1:twV0fKMQuqLY4klyFH56aXNq3AFiA5LO0/frTczEOFE=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.18.7 h1:V94lTcix6jouwmAsgQMAEBozVAGJMFhVj+6/++xfe3E=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.18.7/go.mod h1:OZYsyHFL5PB9UpyS78NElgKs11qI/B5KJau2XOJDXHA=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.13.7 h1:qUUcNS5Z1092XBFT66IJM7mYkMwgZ8fcC8YDIbEwXck=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.13.7/go.mod h1:AdCcbZXHQCjJh6NaH3pFaw8LUeBFn5+88BZGMVGuBT8=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.21 h1:j9wi1kQ8b+e0FBVHxCqCGo4kxDU175hoDHcWAi0sauU=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.21/go.mod h1:ugwW57Z5Z48bpvUyZuaPy4Kv+vEfJWnIrky7RmkBvJg=
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.46 h1:OCX1pQ4pcqhsDV7B92HzdLWjHWOQsILvjLinpaUWhcc=
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.46/go.mod h1:MxCBOcyNXGJRvfpPiH+L6n/BF9zbowthGSUZdDvQF/c=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.27 h1:I3cakv2Uy1vNmmhRQmFptYDxOvBnwCdNwyw63N0RaRU=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.27/go.mod h1:a1/UpzeyBBerajpnP5nGZa9mGzsBn5cOKxm6NWQsvoI=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.21 h1:5NbbMrIzmUn/TXFqAle6mgrH5m9cOvMLRGL7pnG8tRE=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.21/go.mod h1:+Gxn8jYn5k9ebfHEqlhrMirFjSW0v0C9fI+KN5vk2kE=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.28 h1:KeTxcGdNnQudb46oOl4d90f2I33DF/c6q3RnZAmvQdQ=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.28/go.mod h1:yRZVr/iT0AqyHeep00SZ4YfBAKojXz08w3XMBscdi0c=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.18 h1:H/mF2LNWwX00lD6FlYfKpLLZgUW7oIzCBkig78x4Xok=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.18/go.mod h1:T2Ku+STrYQ1zIkL1wMvj8P3wWQaaCMKNdz70MT2FLfE=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11 h1:y2+VQzC6Zh2ojtV2LoC0MNwHWc6qXv/j2vrQtlftkdA=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11/go.mod h1:iV4q2hsqtNECrfmlXyord9u4zyuFEJX9eLgLpSPzWA8=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.21 h1:77b1GfaSuIok5yB/3HYbG+ypWvOJDQ2rVdq943D17R4=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.21/go.mod h1:sPOz31BVdqeeurKEuUpLNSve4tdCNPluE+070HNcEHI=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.20 h1:jlgyHbkZQAgAc7VIxJDmtouH8eNjOk2REVAQfVhdaiQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.20/go.mod h1:Xs52xaLBqDEKRcAfX/hgjmD3YQ7c/W+BEyfamlO/W2E=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.20 h1:4K6dbmR0mlp3o4Bo78PnpvzHtYAqEeVMguvEenpMGsI=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.20/go.mod h1:1XpDcReIEOHsjwNToDKhIAO3qwLo1BnfbtSqWJa8j7g=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.29.5 h1:nRSEQj1JergKTVc8RGkhZvOEGgcvo4fWpDPwGDeg2ok=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.29.5/go.mod h1:wcaJTmjKFDW0s+Se55HBNIds6ghdAGoDDw+SGUdrfAk=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.11.26 h1:ActQgdTNQej/RuUJjB9uxYVLDOvRGtUreXF8L3c8wyg=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.11.26/go.mod h1:uB9tV79ULEZUXc6Ob18A46KSQ0JDlrplPni9XW6Ot60=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.9 h1:wihKuqYUlA2T/Rx+yu2s6NDAns8B9DgnRooB1PVhY+Q=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.9/go.mod h1:2E/3D/mB8/r2J7nK42daoKP/ooCwbf0q1PznNc+DZTU=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.17.6 h1:VQFOLQVL3BrKM/NLO/7FiS4vcp5bqK0mGMyk09xLoAY=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.17.6/go.mod h1:Az3OXXYGyfNwQNsK/31L4R75qFYnO641RZGAoV3uH1c=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.22 h1:kv5vRAl00tozRxSnI0IszPWGXsJOyA7hmEUHFYqsyvw=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.22/go.mod h1:Od+GU5+Yx41gryN/ZGZzAJMZ9R1yn6lgA0fD5Lo5SkQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.21 h1:5C6XgTViSb0bunmU57b3CT+MhxULqHH2721FVA+/kDM=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.21/go.mod h1:lRToEJsn+DRA9lW4O9L9+/3hjTkUzlzyzHqn8MTds5k=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.21 h1:vY5siRXvW5TrOKm2qKEf9tliBfdLxdfy0i02LOcmqUo=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.21/go.mod h1:WZvNXT1XuH8dnJM0HvOlvk+RNn7NbAPvA/ACO0QarSc=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.29.6 h1:W8pLcSn6Uy0eXgDBUUl8M8Kxv7JCoP68ZKTD04OXLEA=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.29.6/go.mod h1:L2l2/q76teehcW7YEsgsDjqdsDTERJeX3nOMIFlgGUE=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.11.28 h1:gItLq3zBYyRDPmqAClgzTH8PBjDQGeyptYGHIwtYYNA=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.11.28/go.mod h1:wo/B7uUm/7zw/dWhBJ4FXuw1sySU5lyIhVg1Bu2yL9A=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.11 h1:KCacyVSs/wlcPGx37hcbT3IGYO8P8Jx+TgSDhAXtQMY=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.11/go.mod h1:TZSH7xLO7+phDtViY/KUp9WGCJMQkLJ/VpgkTFd5gh8=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.17.7 h1:9Mtq1KM6nD8/+HStvWcvYnixJ5N85DX+P+OY3kI3W2k=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.17.7/go.mod h1:+lGbb3+1ugwKrNTWcf2RT05Xmp543B06zDFTwiTLp7I=
|
||||
github.com/aws/smithy-go v1.13.5 h1:hgz0X/DX0dGqTYpGALqXJoRKRj5oQ7150i5FdTePzO8=
|
||||
github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
|
||||
github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I=
|
||||
|
@ -629,8 +628,8 @@ github.com/projectdiscovery/networkpolicy v0.0.3 h1:OZFPkMVY6SJxc1ncuRXB2VlT6xlz
|
|||
github.com/projectdiscovery/networkpolicy v0.0.3/go.mod h1:DIXwKs3sQyfCoWHKRLQiRrEorSQW4Zrh4ftu7oDVK6w=
|
||||
github.com/projectdiscovery/nvd v1.0.9 h1:2DdMm7lu3GnCQsyYDEQiQ/LRYDmpEm654kvGQS6jzjE=
|
||||
github.com/projectdiscovery/nvd v1.0.9/go.mod h1:nGHAo7o6G4V4kscZlm488qKp/ZrZYiBoKqAQrn3X4Og=
|
||||
github.com/projectdiscovery/ratelimit v0.0.3 h1:6c8QKL3ivOdjXqbP+UA2jsTNHcH0OMHk+4AMkanOkUo=
|
||||
github.com/projectdiscovery/ratelimit v0.0.3/go.mod h1:WBz8N1P+CyxnfUoGfVCqah4NZ2SreSX7v9dY8wIlK70=
|
||||
github.com/projectdiscovery/ratelimit v0.0.4-0.20221222024635-17151503fe59 h1:XHi//FUJTo+RRKfLT9Mj6oqkQq9E65uNMhL2RVuG5zA=
|
||||
github.com/projectdiscovery/ratelimit v0.0.4-0.20221222024635-17151503fe59/go.mod h1:WBz8N1P+CyxnfUoGfVCqah4NZ2SreSX7v9dY8wIlK70=
|
||||
github.com/projectdiscovery/rawhttp v0.1.4 h1:zdOqU1DUY2dGoyCzBqzHnHVwPyv32j+Hke8KfLRUouI=
|
||||
github.com/projectdiscovery/rawhttp v0.1.4/go.mod h1:mhSXo96awUUr20VdReDYUKxldsvR5841FRgiaoaxDCY=
|
||||
github.com/projectdiscovery/rdap v0.9.1-0.20221108103045-9865884d1917 h1:m03X4gBVSorSzvmm0bFa7gDV4QNSOWPL/fgZ4kTXBxk=
|
||||
|
@ -651,8 +650,8 @@ github.com/projectdiscovery/uncover v1.0.1 h1:bhP+EW4d+e4cAizOWAEz7jeyKZGkDYYTsZ
|
|||
github.com/projectdiscovery/uncover v1.0.1/go.mod h1:/D9qxgN2iZ/C2M8eo+pNQMnTaMhTZUu40Vat/LgSIxU=
|
||||
github.com/projectdiscovery/utils v0.0.4-0.20221214110533-9f95ee986a54 h1:/fZvw6gT1fzdmMLMBBw75OrJ0Z6g7dulQrxM9FRp1qU=
|
||||
github.com/projectdiscovery/utils v0.0.4-0.20221214110533-9f95ee986a54/go.mod h1:PCwA5YuCYWPgHaGiZmr53/SA9iGQmAnw7DSHuhr8VPQ=
|
||||
github.com/projectdiscovery/wappalyzergo v0.0.74 h1:EHukHzfmcOSP8fTLDkXYEsXHQgtq3OlHT9OFr659sDY=
|
||||
github.com/projectdiscovery/wappalyzergo v0.0.74/go.mod h1:HvYuW0Be4JCjVds/+XAEaMSqRG9yrI97UmZq0TPk6A0=
|
||||
github.com/projectdiscovery/wappalyzergo v0.0.75 h1:IRiI4CtMpDfjMDa1FmWinEQsGOk4tqNkr+PLzhvXW18=
|
||||
github.com/projectdiscovery/wappalyzergo v0.0.75/go.mod h1:HvYuW0Be4JCjVds/+XAEaMSqRG9yrI97UmZq0TPk6A0=
|
||||
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=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
|
@ -866,8 +865,8 @@ go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0
|
|||
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
|
||||
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8=
|
||||
go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
|
||||
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
|
||||
go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
|
||||
go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
|
||||
go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY=
|
||||
go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY=
|
||||
|
|
|
@ -54,6 +54,7 @@ import (
|
|||
"github.com/projectdiscovery/nuclei/v2/pkg/types"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/utils"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/utils/stats"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/utils/yaml"
|
||||
yamlwrapper "github.com/projectdiscovery/nuclei/v2/pkg/utils/yaml"
|
||||
"github.com/projectdiscovery/retryablehttp-go"
|
||||
stringsutil "github.com/projectdiscovery/utils/strings"
|
||||
|
@ -109,7 +110,10 @@ func New(options *types.Options) (*Runner, error) {
|
|||
// Does not update the templates when validate flag is used
|
||||
options.NoUpdateTemplates = true
|
||||
}
|
||||
|
||||
// TODO: refactor to pass options reference globally without cycles
|
||||
parsers.NoStrictSyntax = options.NoStrictSyntax
|
||||
yaml.StrictSyntax = !options.NoStrictSyntax
|
||||
|
||||
// parse the runner.options.GithubTemplateRepo and store the valid repos in runner.customTemplateRepos
|
||||
runner.customTemplates = customtemplates.ParseCustomTemplates(runner.options)
|
||||
|
@ -332,6 +336,9 @@ func (r *Runner) Close() {
|
|||
if r.pprofServer != nil {
|
||||
_ = r.pprofServer.Shutdown(context.Background())
|
||||
}
|
||||
if r.ratelimiter != nil {
|
||||
r.ratelimiter.Stop()
|
||||
}
|
||||
}
|
||||
|
||||
// RunEnumeration sets up the input layer for giving input nuclei.
|
||||
|
@ -627,7 +634,7 @@ func (r *Runner) executeTemplatesInput(store *loader.Store, engine *core.Engine)
|
|||
// tracks global progress and captures stdout/stderr until p.Wait finishes
|
||||
r.progress.Init(r.hmapInputProvider.Count(), templateCount, totalRequests)
|
||||
|
||||
results := engine.ExecuteWithOpts(finalTemplates, r.hmapInputProvider, true)
|
||||
results := engine.ExecuteScanWithOpts(finalTemplates, r.hmapInputProvider, true)
|
||||
return results, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"go.uber.org/atomic"
|
||||
|
||||
"github.com/projectdiscovery/gologger"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/core/inputs"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/output"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/contextargs"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/templates"
|
||||
|
@ -18,20 +19,13 @@ import (
|
|||
// All the execution logic for the templates/workflows happens in this part
|
||||
// of the engine.
|
||||
func (e *Engine) Execute(templates []*templates.Template, target InputProvider) *atomic.Bool {
|
||||
return e.ExecuteWithOpts(templates, target, false)
|
||||
return e.ExecuteScanWithOpts(templates, target, false)
|
||||
}
|
||||
|
||||
// ExecuteWithOpts executes with the full options
|
||||
func (e *Engine) ExecuteWithOpts(templatesList []*templates.Template, target InputProvider, noCluster bool) *atomic.Bool {
|
||||
var finalTemplates []*templates.Template
|
||||
if !noCluster {
|
||||
finalTemplates, _ = templates.ClusterTemplates(templatesList, e.executerOpts)
|
||||
} else {
|
||||
finalTemplates = templatesList
|
||||
}
|
||||
|
||||
// executeTemplateSpray executes scan using template spray strategy where targets are iterated over each template
|
||||
func (e *Engine) executeTemplateSpray(templatesList []*templates.Template, target InputProvider) *atomic.Bool {
|
||||
results := &atomic.Bool{}
|
||||
for _, template := range finalTemplates {
|
||||
for _, template := range templatesList {
|
||||
templateType := template.Type()
|
||||
|
||||
var wg *sizedwaitgroup.SizedWaitGroup
|
||||
|
@ -59,6 +53,53 @@ func (e *Engine) ExecuteWithOpts(templatesList []*templates.Template, target Inp
|
|||
return results
|
||||
}
|
||||
|
||||
// executeHostSpray executes scan using host spray strategy where templates are iterated over each target
|
||||
func (e *Engine) executeHostSpray(templatesList []*templates.Template, target InputProvider) *atomic.Bool {
|
||||
results := &atomic.Bool{}
|
||||
hostwg := sizedwaitgroup.New(e.options.BulkSize)
|
||||
target.Scan(func(value *contextargs.MetaInput) bool {
|
||||
host := inputs.SimpleInputProvider{
|
||||
Inputs: []*contextargs.MetaInput{
|
||||
value,
|
||||
},
|
||||
}
|
||||
hostwg.Add()
|
||||
go func(result *atomic.Bool) {
|
||||
defer hostwg.Done()
|
||||
status := e.executeTemplateSpray(templatesList, &host)
|
||||
results.CompareAndSwap(false, status.Load())
|
||||
}(results)
|
||||
return true
|
||||
})
|
||||
hostwg.Wait()
|
||||
return results
|
||||
}
|
||||
|
||||
// ExecuteScanWithOpts executes scan with given scanStatergy
|
||||
func (e *Engine) ExecuteScanWithOpts(templatesList []*templates.Template, target InputProvider, noCluster bool) *atomic.Bool {
|
||||
var results *atomic.Bool
|
||||
|
||||
var finalTemplates []*templates.Template
|
||||
if !noCluster {
|
||||
finalTemplates, _ = templates.ClusterTemplates(templatesList, e.executerOpts)
|
||||
} else {
|
||||
finalTemplates = templatesList
|
||||
}
|
||||
|
||||
if e.options.ScanStrategy == "auto" {
|
||||
// TODO: this is only a placeholder, auto scan strategy should choose scan strategy
|
||||
// based on no of hosts , templates , stream and other optimization parameters
|
||||
e.options.ScanStrategy = "template-spray"
|
||||
}
|
||||
switch e.options.ScanStrategy {
|
||||
case "template-spray":
|
||||
results = e.executeTemplateSpray(finalTemplates, target)
|
||||
case "host-spray":
|
||||
results = e.executeHostSpray(finalTemplates, target)
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
// processSelfContainedTemplates execute a self-contained template.
|
||||
func (e *Engine) executeSelfContainedTemplateWithInput(template *templates.Template, results *atomic.Bool) {
|
||||
match, err := template.Executer.Execute(contextargs.New())
|
||||
|
|
|
@ -5,7 +5,7 @@ package hybrid
|
|||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"net/url"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
|
@ -22,6 +22,7 @@ import (
|
|||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/protocolstate"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/uncover"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/types"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/utils"
|
||||
fileutil "github.com/projectdiscovery/utils/file"
|
||||
iputil "github.com/projectdiscovery/utils/ip"
|
||||
readerutil "github.com/projectdiscovery/utils/reader"
|
||||
|
@ -169,39 +170,49 @@ func (i *Input) Set(value string) {
|
|||
if URL == "" {
|
||||
return
|
||||
}
|
||||
// actual hostname
|
||||
var host string
|
||||
// parse hostname if url is given
|
||||
parsedURL, err := url.Parse(value)
|
||||
if err == nil && parsedURL.Host != "" {
|
||||
host = parsedURL.Host
|
||||
host := utils.ParseHostname(value)
|
||||
if host == "" {
|
||||
// not a valid url hence scanallips is skipped
|
||||
gologger.Debug().Msgf("scanAllIps: failed to parse hostname of %v falling back to default", value)
|
||||
i.setItem(&contextargs.MetaInput{Input: value})
|
||||
return
|
||||
} else {
|
||||
parsedURL = nil
|
||||
host = value
|
||||
// case when hostname contains port
|
||||
hostwithoutport, _, erx := net.SplitHostPort(host)
|
||||
if erx == nil && hostwithoutport != "" {
|
||||
// given host contains port
|
||||
host = hostwithoutport
|
||||
}
|
||||
}
|
||||
|
||||
if i.ipOptions.ScanAllIPs {
|
||||
// scan all ips
|
||||
dnsData, err := protocolstate.Dialer.GetDNSData(host)
|
||||
if err == nil && (len(dnsData.A)+len(dnsData.AAAA)) > 0 {
|
||||
var ips []string
|
||||
if i.ipOptions.IPV4 {
|
||||
ips = append(ips, dnsData.A...)
|
||||
}
|
||||
if i.ipOptions.IPV6 {
|
||||
ips = append(ips, dnsData.AAAA...)
|
||||
}
|
||||
for _, ip := range ips {
|
||||
if ip == "" {
|
||||
continue
|
||||
if err == nil {
|
||||
if (len(dnsData.A) + len(dnsData.AAAA)) > 0 {
|
||||
var ips []string
|
||||
if i.ipOptions.IPV4 {
|
||||
ips = append(ips, dnsData.A...)
|
||||
}
|
||||
metaInput := &contextargs.MetaInput{Input: value, CustomIP: ip}
|
||||
i.setItem(metaInput)
|
||||
if i.ipOptions.IPV6 {
|
||||
ips = append(ips, dnsData.AAAA...)
|
||||
}
|
||||
for _, ip := range ips {
|
||||
if ip == "" {
|
||||
continue
|
||||
}
|
||||
metaInput := &contextargs.MetaInput{Input: value, CustomIP: ip}
|
||||
i.setItem(metaInput)
|
||||
}
|
||||
return
|
||||
} else {
|
||||
gologger.Debug().Msgf("scanAllIps: no ip's found reverting to default")
|
||||
}
|
||||
return
|
||||
} else {
|
||||
// failed to scanallips falling back to defaults
|
||||
gologger.Debug().Msgf("scanAllIps: dns resolution failed: %v", err)
|
||||
}
|
||||
// failed to scanallips falling back to defaults
|
||||
gologger.Error().Msgf("failed to scan all ips reverting to default %v", err)
|
||||
}
|
||||
|
||||
ips := []string{}
|
||||
|
@ -212,7 +223,7 @@ func (i *Input) Set(value string) {
|
|||
// pick/ prefer 1st
|
||||
ips = append(ips, dnsData.AAAA[0])
|
||||
} else {
|
||||
gologger.Warning().Msgf("target does not have ipv6 address falling back to ipv4 %s\n", err)
|
||||
gologger.Warning().Msgf("target does not have ipv6 address falling back to ipv4 %v\n", err)
|
||||
}
|
||||
}
|
||||
if i.ipOptions.IPV4 {
|
||||
|
|
|
@ -51,7 +51,7 @@ func Test_expandCIDRInputValue(t *testing.T) {
|
|||
|
||||
type mockDnsHandler struct{}
|
||||
|
||||
func (this *mockDnsHandler) ServeDNS(w dns.ResponseWriter, r *dns.Msg) {
|
||||
func (m *mockDnsHandler) ServeDNS(w dns.ResponseWriter, r *dns.Msg) {
|
||||
msg := dns.Msg{}
|
||||
msg.SetReply(r)
|
||||
switch r.Question[0].Qtype {
|
||||
|
@ -85,18 +85,14 @@ func Test_scanallips_normalizeStoreInputValue(t *testing.T) {
|
|||
defaultOpts := types.DefaultOptions()
|
||||
defaultOpts.InternalResolversList = []string{"127.0.0.1:61234"}
|
||||
_ = protocolstate.Init(defaultOpts)
|
||||
tests := []struct {
|
||||
type testcase struct {
|
||||
hostname string
|
||||
ipv4 bool
|
||||
ipv6 bool
|
||||
expected []string
|
||||
}{
|
||||
}
|
||||
tests := []testcase{
|
||||
{
|
||||
hostname: "scanme.sh",
|
||||
ipv4: true,
|
||||
ipv6: true,
|
||||
expected: []string{"128.199.158.128", "2400:6180:0:d0::91:1001"},
|
||||
}, {
|
||||
hostname: "scanme.sh",
|
||||
ipv4: true,
|
||||
expected: []string{"128.199.158.128"},
|
||||
|
@ -104,12 +100,27 @@ func Test_scanallips_normalizeStoreInputValue(t *testing.T) {
|
|||
hostname: "scanme.sh",
|
||||
ipv6: true,
|
||||
expected: []string{"2400:6180:0:d0::91:1001"},
|
||||
}, {
|
||||
hostname: "http://scanme.sh",
|
||||
},
|
||||
}
|
||||
// add extra edge cases
|
||||
urls := []string{
|
||||
"https://scanme.sh/",
|
||||
"http://scanme.sh",
|
||||
"https://scanme.sh:443/",
|
||||
"https://scanme.sh:443/somepath",
|
||||
"http://scanme.sh:80/?with=param",
|
||||
"scanme.sh/home",
|
||||
"scanme.sh",
|
||||
}
|
||||
resolvedIps := []string{"128.199.158.128", "2400:6180:0:d0::91:1001"}
|
||||
|
||||
for _, v := range urls {
|
||||
tests = append(tests, testcase{
|
||||
hostname: v,
|
||||
ipv4: true,
|
||||
ipv6: true,
|
||||
expected: []string{"128.199.158.128", "2400:6180:0:d0::91:1001"},
|
||||
},
|
||||
expected: resolvedIps,
|
||||
})
|
||||
}
|
||||
for _, tt := range tests {
|
||||
hm, err := hybrid.New(hybrid.DefaultDiskOptions)
|
||||
|
@ -134,7 +145,7 @@ func Test_scanallips_normalizeStoreInputValue(t *testing.T) {
|
|||
got = append(got, metainput.CustomIP)
|
||||
return nil
|
||||
})
|
||||
require.ElementsMatch(t, tt.expected, got, "could not get correct ips")
|
||||
require.ElementsMatchf(t, tt.expected, got, "could not get correct ips for hostname %v", tt.hostname)
|
||||
input.Close()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@ func (h *Helper) convertInputToType(input string, inputType inputType, defaultPo
|
|||
if hasHost {
|
||||
return host
|
||||
}
|
||||
if isURL {
|
||||
if isURL && uri != nil {
|
||||
return uri.Hostname()
|
||||
}
|
||||
return input
|
||||
|
|
|
@ -82,7 +82,7 @@ type ResultEvent struct {
|
|||
// TemplateID is the ID of the template for the result.
|
||||
TemplateID string `json:"template-id"`
|
||||
// TemplatePath is the path of template
|
||||
TemplatePath string `json:"-"`
|
||||
TemplatePath string `json:"template-path,omitempty"`
|
||||
// Info contains information block of the template for the result.
|
||||
Info model.Info `json:"info,inline"`
|
||||
// MatcherName is the name of the matcher matched if any.
|
||||
|
|
|
@ -261,6 +261,18 @@ func (c *Client) Close() bool {
|
|||
c.interactsh.StopPolling()
|
||||
c.interactsh.Close()
|
||||
}
|
||||
|
||||
closeCache := func(cc *ccache.Cache) {
|
||||
if cc != nil {
|
||||
cc.Clear()
|
||||
cc.Stop()
|
||||
}
|
||||
}
|
||||
closeCache(c.requests)
|
||||
closeCache(c.interactions)
|
||||
closeCache(c.matchedTemplates)
|
||||
closeCache(c.interactshURLs)
|
||||
|
||||
return c.matched
|
||||
}
|
||||
|
||||
|
|
|
@ -107,6 +107,9 @@ func getTargets(uncoverOptions *ucRunner.Options, field string) (chan string, er
|
|||
} else {
|
||||
rateLimiter = ratelimit.NewUnlimited(context.Background())
|
||||
}
|
||||
if rateLimiter != nil {
|
||||
defer rateLimiter.Stop()
|
||||
}
|
||||
var agents []uncover.Agent
|
||||
// declare clients
|
||||
for _, engine := range uncoverOptions.Engine {
|
||||
|
|
|
@ -2,6 +2,8 @@ package templates
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"reflect"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
@ -35,44 +37,25 @@ func Parse(filePath string, preprocessor Preprocessor, options protocols.Execute
|
|||
return value.(*Template), err
|
||||
}
|
||||
|
||||
template := &Template{}
|
||||
|
||||
data, err := utils.ReadFromPathOrURL(filePath, options.Catalog)
|
||||
var reader io.ReadCloser
|
||||
if utils.IsURL(filePath) {
|
||||
resp, err := http.Get(filePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
reader = resp.Body
|
||||
} else {
|
||||
var err error
|
||||
reader, err = options.Catalog.OpenFile(filePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
defer reader.Close()
|
||||
template, err := ParseTemplateFromReader(reader, preprocessor, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data = template.expandPreprocessors(data)
|
||||
if preprocessor != nil {
|
||||
data = preprocessor.Process(data)
|
||||
}
|
||||
|
||||
if err := yaml.Unmarshal(data, template); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if utils.IsBlank(template.Info.Name) {
|
||||
return nil, errors.New("no template name field provided")
|
||||
}
|
||||
if template.Info.Authors.IsEmpty() {
|
||||
return nil, errors.New("no template author field provided")
|
||||
}
|
||||
|
||||
// Setting up variables regarding template metadata
|
||||
options.TemplateID = template.ID
|
||||
options.TemplateInfo = template.Info
|
||||
options.TemplatePath = filePath
|
||||
options.StopAtFirstMatch = template.StopAtFirstMatch
|
||||
|
||||
if template.Variables.Len() > 0 {
|
||||
options.Variables = template.Variables
|
||||
}
|
||||
|
||||
// If no requests, and it is also not a workflow, return error.
|
||||
if template.Requests() == 0 {
|
||||
return nil, fmt.Errorf("no requests defined for %s", template.ID)
|
||||
}
|
||||
|
||||
// Compile the workflow request
|
||||
if len(template.Workflows) > 0 {
|
||||
compiled := &template.Workflow
|
||||
|
@ -81,24 +64,7 @@ func Parse(filePath string, preprocessor Preprocessor, options protocols.Execute
|
|||
template.CompiledWorkflow = compiled
|
||||
template.CompiledWorkflow.Options = &options
|
||||
}
|
||||
|
||||
if err := template.compileProtocolRequests(options); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if template.Executer != nil {
|
||||
if err := template.Executer.Compile(); err != nil {
|
||||
return nil, errors.Wrap(err, "could not compile request")
|
||||
}
|
||||
template.TotalRequests = template.Executer.Requests()
|
||||
}
|
||||
if template.Executer == nil && template.CompiledWorkflow == nil {
|
||||
return nil, ErrCreateTemplateExecutor
|
||||
}
|
||||
template.Path = filePath
|
||||
|
||||
template.parseSelfContainedRequests()
|
||||
|
||||
parsedTemplatesCache.Store(filePath, template, err)
|
||||
return template, nil
|
||||
}
|
||||
|
@ -221,3 +187,60 @@ mainLoop:
|
|||
template.Executer = executer.NewExecuter([]protocols.Request{&offlinehttp.Request{}}, &options)
|
||||
}
|
||||
}
|
||||
|
||||
// ParseTemplateFromReader reads the template from reader
|
||||
// returns the parsed template
|
||||
func ParseTemplateFromReader(reader io.Reader, preprocessor Preprocessor, options protocols.ExecuterOptions) (*Template, error) {
|
||||
template := &Template{}
|
||||
data, err := io.ReadAll(reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data = template.expandPreprocessors(data)
|
||||
if preprocessor != nil {
|
||||
data = preprocessor.Process(data)
|
||||
}
|
||||
|
||||
if err := yaml.Unmarshal(data, template); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if utils.IsBlank(template.Info.Name) {
|
||||
return nil, errors.New("no template name field provided")
|
||||
}
|
||||
if template.Info.Authors.IsEmpty() {
|
||||
return nil, errors.New("no template author field provided")
|
||||
}
|
||||
|
||||
// Setting up variables regarding template metadata
|
||||
options.TemplateID = template.ID
|
||||
options.TemplateInfo = template.Info
|
||||
options.StopAtFirstMatch = template.StopAtFirstMatch
|
||||
|
||||
if template.Variables.Len() > 0 {
|
||||
options.Variables = template.Variables
|
||||
}
|
||||
|
||||
// If no requests, and it is also not a workflow, return error.
|
||||
if template.Requests() == 0 {
|
||||
return nil, fmt.Errorf("no requests defined for %s", template.ID)
|
||||
}
|
||||
|
||||
if err := template.compileProtocolRequests(options); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if template.Executer != nil {
|
||||
if err := template.Executer.Compile(); err != nil {
|
||||
return nil, errors.Wrap(err, "could not compile request")
|
||||
}
|
||||
template.TotalRequests = template.Executer.Requests()
|
||||
}
|
||||
if template.Executer == nil && template.CompiledWorkflow == nil {
|
||||
return nil, ErrCreateTemplateExecutor
|
||||
}
|
||||
template.parseSelfContainedRequests()
|
||||
|
||||
return template, nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,184 @@
|
|||
package templates_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/catalog/disk"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/model"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/model/types/severity"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/model/types/stringslice"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/operators"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/operators/extractors"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/operators/matchers"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/parsers"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/progress"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/generators"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/variables"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/http"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/ssl"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/templates"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/testutils"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/workflows"
|
||||
"github.com/projectdiscovery/ratelimit"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var executerOpts protocols.ExecuterOptions
|
||||
|
||||
func setup() {
|
||||
options := testutils.DefaultOptions
|
||||
testutils.Init(options)
|
||||
progressImpl, _ := progress.NewStatsTicker(0, false, false, false, 0)
|
||||
|
||||
executerOpts = protocols.ExecuterOptions{
|
||||
Output: testutils.NewMockOutputWriter(),
|
||||
Options: options,
|
||||
Progress: progressImpl,
|
||||
ProjectFile: nil,
|
||||
IssuesClient: nil,
|
||||
Browser: nil,
|
||||
Catalog: disk.NewCatalog(options.TemplatesDirectory),
|
||||
RateLimiter: ratelimit.New(context.Background(), uint(options.RateLimit), time.Second),
|
||||
}
|
||||
workflowLoader, err := parsers.NewLoader(&executerOpts)
|
||||
if err != nil {
|
||||
log.Fatalf("Could not create workflow loader: %s\n", err)
|
||||
}
|
||||
executerOpts.WorkflowLoader = workflowLoader
|
||||
|
||||
}
|
||||
|
||||
func Test_ParseFromURL(t *testing.T) {
|
||||
filePath := "https://api.nuclei.sh/api/v1/templates/raw/ssl/tls-version.yaml"
|
||||
expectedTemplate := &templates.Template{
|
||||
ID: "tls-version",
|
||||
Info: model.Info{
|
||||
Authors: stringslice.StringSlice{Value: []string{"pdteam"}},
|
||||
SeverityHolder: severity.Holder{Severity: severity.Info},
|
||||
Name: "TLS Version",
|
||||
Tags: stringslice.StringSlice{Value: []string{"ssl"}},
|
||||
},
|
||||
RequestsSSL: []*ssl.Request{
|
||||
{
|
||||
Address: "{{Host}}:{{Port}}",
|
||||
Operators: operators.Operators{
|
||||
Extractors: []*extractors.Extractor{
|
||||
{
|
||||
Type: extractors.ExtractorTypeHolder{ExtractorType: extractors.JSONExtractor},
|
||||
JSON: []string{".tls_version"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}},
|
||||
TotalRequests: 1,
|
||||
Executer: nil,
|
||||
Path: "https://api.nuclei.sh/api/v1/templates/raw/ssl/tls-version.yaml",
|
||||
}
|
||||
setup()
|
||||
got, err := templates.Parse(filePath, nil, executerOpts)
|
||||
require.Nil(t, err, "could not parse template")
|
||||
require.Equal(t, expectedTemplate.ID, got.ID)
|
||||
require.Equal(t, expectedTemplate.Info, got.Info)
|
||||
require.Equal(t, expectedTemplate.TotalRequests, got.TotalRequests)
|
||||
require.Equal(t, expectedTemplate.Path, got.Path)
|
||||
require.Equal(t, expectedTemplate.RequestsSSL[0].Address, got.RequestsSSL[0].Address)
|
||||
require.Equal(t, expectedTemplate.RequestsSSL[0].Extractors[0].Type, got.RequestsSSL[0].Extractors[0].Type)
|
||||
require.Equal(t, expectedTemplate.RequestsSSL[0].Extractors[0].JSON, got.RequestsSSL[0].Extractors[0].JSON)
|
||||
require.Equal(t, len(expectedTemplate.RequestsSSL), len(got.RequestsSSL))
|
||||
}
|
||||
|
||||
func Test_ParseFromFile(t *testing.T) {
|
||||
filePath := "tests/match-1.yaml"
|
||||
expectedTemplate := &templates.Template{
|
||||
ID: "basic-get",
|
||||
Info: model.Info{
|
||||
Name: "Basic GET Request",
|
||||
Authors: stringslice.StringSlice{Value: []string{"pdteam"}},
|
||||
SeverityHolder: severity.Holder{Severity: severity.Info},
|
||||
},
|
||||
RequestsHTTP: []*http.Request{{
|
||||
Operators: operators.Operators{
|
||||
Matchers: []*matchers.Matcher{{
|
||||
Type: matchers.MatcherTypeHolder{
|
||||
MatcherType: matchers.WordsMatcher,
|
||||
},
|
||||
Words: []string{"This is test matcher text"},
|
||||
}},
|
||||
},
|
||||
Path: []string{"{{BaseURL}}"},
|
||||
AttackType: generators.AttackTypeHolder{},
|
||||
Method: http.HTTPMethodTypeHolder{
|
||||
MethodType: http.HTTPGet,
|
||||
},
|
||||
}},
|
||||
TotalRequests: 1,
|
||||
Executer: nil,
|
||||
Path: "tests/match-1.yaml",
|
||||
}
|
||||
setup()
|
||||
got, err := templates.Parse(filePath, nil, executerOpts)
|
||||
require.Nil(t, err, "could not parse template")
|
||||
require.Equal(t, expectedTemplate.ID, got.ID)
|
||||
require.Equal(t, expectedTemplate.Info, got.Info)
|
||||
require.Equal(t, expectedTemplate.TotalRequests, got.TotalRequests)
|
||||
require.Equal(t, expectedTemplate.Path, got.Path)
|
||||
require.Equal(t, expectedTemplate.RequestsHTTP[0].Path, got.RequestsHTTP[0].Path)
|
||||
require.Equal(t, expectedTemplate.RequestsHTTP[0].Operators.Matchers[0].Words, got.RequestsHTTP[0].Operators.Matchers[0].Words)
|
||||
require.Equal(t, len(expectedTemplate.RequestsHTTP), len(got.RequestsHTTP))
|
||||
|
||||
// Test cache
|
||||
got, err = templates.Parse(filePath, nil, executerOpts)
|
||||
require.Nil(t, err, "could not parse template")
|
||||
require.Equal(t, expectedTemplate.ID, got.ID)
|
||||
}
|
||||
|
||||
func Test_ParseWorkflow(t *testing.T) {
|
||||
filePath := "tests/workflow.yaml"
|
||||
expectedTemplate := &templates.Template{
|
||||
ID: "workflow-example",
|
||||
Info: model.Info{
|
||||
Name: "Test Workflow Template",
|
||||
Authors: stringslice.StringSlice{Value: []string{"pdteam"}},
|
||||
SeverityHolder: severity.Holder{Severity: severity.Info},
|
||||
},
|
||||
Workflow: workflows.Workflow{
|
||||
Workflows: []*workflows.WorkflowTemplate{{Template: "tests/match-1.yaml"}, {Template: "tests/match-1.yaml"}},
|
||||
Options: &protocols.ExecuterOptions{},
|
||||
},
|
||||
CompiledWorkflow: &workflows.Workflow{},
|
||||
SelfContained: false,
|
||||
StopAtFirstMatch: false,
|
||||
Signature: http.SignatureTypeHolder{},
|
||||
Variables: variables.Variable{},
|
||||
TotalRequests: 0,
|
||||
Executer: nil,
|
||||
Path: "tests/workflow.yaml",
|
||||
}
|
||||
setup()
|
||||
got, err := templates.Parse(filePath, nil, executerOpts)
|
||||
require.Nil(t, err, "could not parse template")
|
||||
require.Equal(t, expectedTemplate.ID, got.ID)
|
||||
require.Equal(t, expectedTemplate.Info, got.Info)
|
||||
require.Equal(t, expectedTemplate.TotalRequests, got.TotalRequests)
|
||||
require.Equal(t, expectedTemplate.Path, got.Path)
|
||||
require.Equal(t, expectedTemplate.Workflow.Workflows[0].Template, got.Workflow.Workflows[0].Template)
|
||||
require.Equal(t, len(expectedTemplate.Workflows), len(got.Workflows))
|
||||
}
|
||||
|
||||
func Test_WrongTemplate(t *testing.T) {
|
||||
setup()
|
||||
|
||||
filePath := "tests/no-author.yaml"
|
||||
got, err := templates.Parse(filePath, nil, executerOpts)
|
||||
require.Nil(t, got, "could not parse template")
|
||||
require.ErrorContains(t, err, "no template author field provided")
|
||||
|
||||
filePath = "tests/no-req.yaml"
|
||||
got, err = templates.Parse(filePath, nil, executerOpts)
|
||||
require.Nil(t, got, "could not parse template")
|
||||
require.ErrorContains(t, err, "no requests defined ")
|
||||
}
|
|
@ -1542,7 +1542,7 @@ func init() {
|
|||
Value: "Headless response received from client (default)",
|
||||
},
|
||||
}
|
||||
HEADLESSRequestDoc.Fields = make([]encoder.Doc, 9)
|
||||
HEADLESSRequestDoc.Fields = make([]encoder.Doc, 10)
|
||||
HEADLESSRequestDoc.Fields[0].Name = "id"
|
||||
HEADLESSRequestDoc.Fields[0].Type = "string"
|
||||
HEADLESSRequestDoc.Fields[0].Note = ""
|
||||
|
@ -1573,22 +1573,27 @@ func init() {
|
|||
HEADLESSRequestDoc.Fields[5].Note = ""
|
||||
HEADLESSRequestDoc.Fields[5].Description = "description: |\n If UserAgent is set to custom, customUserAgent is the custom user-agent to use for the request."
|
||||
HEADLESSRequestDoc.Fields[5].Comments[encoder.LineComment] = " description: |"
|
||||
HEADLESSRequestDoc.Fields[6].Name = "matchers"
|
||||
HEADLESSRequestDoc.Fields[6].Type = "[]matchers.Matcher"
|
||||
HEADLESSRequestDoc.Fields[6].Name = "stop-at-first-match"
|
||||
HEADLESSRequestDoc.Fields[6].Type = "bool"
|
||||
HEADLESSRequestDoc.Fields[6].Note = ""
|
||||
HEADLESSRequestDoc.Fields[6].Description = "Matchers contains the detection mechanism for the request to identify\nwhether the request was successful by doing pattern matching\non request/responses.\n\nMultiple matchers can be combined with `matcher-condition` flag\nwhich accepts either `and` or `or` as argument."
|
||||
HEADLESSRequestDoc.Fields[6].Comments[encoder.LineComment] = "Matchers contains the detection mechanism for the request to identify"
|
||||
HEADLESSRequestDoc.Fields[7].Name = "extractors"
|
||||
HEADLESSRequestDoc.Fields[7].Type = "[]extractors.Extractor"
|
||||
HEADLESSRequestDoc.Fields[6].Description = "StopAtFirstMatch stops the execution of the requests and template as soon as a match is found."
|
||||
HEADLESSRequestDoc.Fields[6].Comments[encoder.LineComment] = "StopAtFirstMatch stops the execution of the requests and template as soon as a match is found."
|
||||
HEADLESSRequestDoc.Fields[7].Name = "matchers"
|
||||
HEADLESSRequestDoc.Fields[7].Type = "[]matchers.Matcher"
|
||||
HEADLESSRequestDoc.Fields[7].Note = ""
|
||||
HEADLESSRequestDoc.Fields[7].Description = "Extractors contains the extraction mechanism for the request to identify\nand extract parts of the response."
|
||||
HEADLESSRequestDoc.Fields[7].Comments[encoder.LineComment] = "Extractors contains the extraction mechanism for the request to identify"
|
||||
HEADLESSRequestDoc.Fields[8].Name = "matchers-condition"
|
||||
HEADLESSRequestDoc.Fields[8].Type = "string"
|
||||
HEADLESSRequestDoc.Fields[7].Description = "Matchers contains the detection mechanism for the request to identify\nwhether the request was successful by doing pattern matching\non request/responses.\n\nMultiple matchers can be combined with `matcher-condition` flag\nwhich accepts either `and` or `or` as argument."
|
||||
HEADLESSRequestDoc.Fields[7].Comments[encoder.LineComment] = "Matchers contains the detection mechanism for the request to identify"
|
||||
HEADLESSRequestDoc.Fields[8].Name = "extractors"
|
||||
HEADLESSRequestDoc.Fields[8].Type = "[]extractors.Extractor"
|
||||
HEADLESSRequestDoc.Fields[8].Note = ""
|
||||
HEADLESSRequestDoc.Fields[8].Description = "MatchersCondition is the condition between the matchers. Default is OR."
|
||||
HEADLESSRequestDoc.Fields[8].Comments[encoder.LineComment] = "MatchersCondition is the condition between the matchers. Default is OR."
|
||||
HEADLESSRequestDoc.Fields[8].Values = []string{
|
||||
HEADLESSRequestDoc.Fields[8].Description = "Extractors contains the extraction mechanism for the request to identify\nand extract parts of the response."
|
||||
HEADLESSRequestDoc.Fields[8].Comments[encoder.LineComment] = "Extractors contains the extraction mechanism for the request to identify"
|
||||
HEADLESSRequestDoc.Fields[9].Name = "matchers-condition"
|
||||
HEADLESSRequestDoc.Fields[9].Type = "string"
|
||||
HEADLESSRequestDoc.Fields[9].Note = ""
|
||||
HEADLESSRequestDoc.Fields[9].Description = "MatchersCondition is the condition between the matchers. Default is OR."
|
||||
HEADLESSRequestDoc.Fields[9].Comments[encoder.LineComment] = "MatchersCondition is the condition between the matchers. Default is OR."
|
||||
HEADLESSRequestDoc.Fields[9].Values = []string{
|
||||
"and",
|
||||
"or",
|
||||
}
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
id: basic-get
|
||||
|
||||
info:
|
||||
name: Basic GET Request
|
||||
author: pdteam
|
||||
severity: info
|
||||
|
||||
requests:
|
||||
- method: GET
|
||||
path:
|
||||
- "{{BaseURL}}"
|
||||
matchers:
|
||||
- type: word
|
||||
words:
|
||||
- "This is test matcher text"
|
|
@ -0,0 +1,14 @@
|
|||
id: basic-get
|
||||
|
||||
info:
|
||||
name: Basic GET Request
|
||||
severity: info
|
||||
|
||||
requests:
|
||||
- method: GET
|
||||
path:
|
||||
- "{{BaseURL}}"
|
||||
matchers:
|
||||
- type: word
|
||||
words:
|
||||
- "This is test matcher text"
|
|
@ -0,0 +1,9 @@
|
|||
id: basic-get
|
||||
|
||||
info:
|
||||
name: Basic GET Request
|
||||
author: pdteam
|
||||
severity: info
|
||||
|
||||
requests:
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
id: workflow-example
|
||||
|
||||
info:
|
||||
name: Test Workflow Template
|
||||
author: pdteam
|
||||
severity: info
|
||||
|
||||
workflows:
|
||||
- template: tests/match-1.yaml
|
||||
- template: tests/match-1.yaml
|
|
@ -336,6 +336,8 @@ type Options struct {
|
|||
AwsBucketName string
|
||||
// AWS Region name where aws s3 bucket is located
|
||||
AwsRegion string
|
||||
// Scan Strategy (auto,hosts-spray,templates-spray)
|
||||
ScanStrategy string
|
||||
}
|
||||
|
||||
func (options *Options) AddVarPayload(key string, value interface{}) {
|
||||
|
|
|
@ -77,3 +77,24 @@ func StringSliceContains(slice []string, item string) bool {
|
|||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ParseHostname returns hostname
|
||||
func ParseHostname(inputURL string) string {
|
||||
/*
|
||||
currently if URL is scanme.sh/path or scanme.sh:443 i.e without protocol then
|
||||
url.Parse considers this as valid url but fails to parse hostname
|
||||
this can be handled by adding schema
|
||||
*/
|
||||
input, err := url.Parse(inputURL)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
if input.Host == "" {
|
||||
newinput, err := url.Parse("https://" + inputURL)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return newinput.Host
|
||||
}
|
||||
return input.Host
|
||||
}
|
||||
|
|
|
@ -19,3 +19,24 @@ func TestUnwrapError(t *testing.T) {
|
|||
errThree := fmt.Errorf("error with error: %w", errTwo)
|
||||
require.Equal(t, errOne, UnwrapError(errThree))
|
||||
}
|
||||
|
||||
func TestParseURL(t *testing.T) {
|
||||
testcases := []struct {
|
||||
URL string
|
||||
Hostname string
|
||||
}{
|
||||
{"https://scanme.sh:443", "scanme.sh:443"},
|
||||
{"http://scanme.sh/path", "scanme.sh"},
|
||||
{"scanme.sh:443/path", "scanme.sh:443"},
|
||||
{"scanme.sh/path", "scanme.sh"},
|
||||
}
|
||||
for _, v := range testcases {
|
||||
urlx := ParseHostname(v.URL)
|
||||
if urlx == "" {
|
||||
t.Errorf("failed to hostname of url %v", v)
|
||||
}
|
||||
if urlx != v.Hostname {
|
||||
t.Errorf("hostname mismatch expected scanme.sh got %v", urlx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package yaml
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
@ -12,10 +13,18 @@ import (
|
|||
|
||||
var reImportsPattern = regexp.MustCompile(`(?m)# !include:(.+.yaml)`)
|
||||
|
||||
// StrictSyntax determines if pre-processing directives should be observed
|
||||
var StrictSyntax bool
|
||||
|
||||
// PreProcess all include directives
|
||||
func PreProcess(data []byte) ([]byte, error) {
|
||||
// find all matches like !include:path\n
|
||||
importMatches := reImportsPattern.FindAllSubmatch(data, -1)
|
||||
hasImportDirectives := len(importMatches) > 0
|
||||
|
||||
if hasImportDirectives && StrictSyntax {
|
||||
return data, errors.New("include directive preprocessing is disabled")
|
||||
}
|
||||
|
||||
var replaceItems []string
|
||||
|
||||
|
|
Loading…
Reference in New Issue