mirror of
https://github.com/projectdiscovery/nuclei.git
synced 2025-12-18 23:15:27 +00:00
adds scan strategy (#3075)
This commit is contained in:
parent
af2aaacbc9
commit
ff17d12ced
@ -246,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.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.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.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.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.BoolVarP(&options.DisableHTTPProbe, "no-httpx", "nh", false, "disable httpx probing for non-url input"),
|
||||||
flagSet.BoolVar(&options.DisableStdin, "no-stdin", false, "disable stdin processing"),
|
flagSet.BoolVar(&options.DisableStdin, "no-stdin", false, "disable stdin processing"),
|
||||||
|
|||||||
@ -627,7 +627,7 @@ func (r *Runner) executeTemplatesInput(store *loader.Store, engine *core.Engine)
|
|||||||
// tracks global progress and captures stdout/stderr until p.Wait finishes
|
// tracks global progress and captures stdout/stderr until p.Wait finishes
|
||||||
r.progress.Init(r.hmapInputProvider.Count(), templateCount, totalRequests)
|
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
|
return results, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import (
|
|||||||
"go.uber.org/atomic"
|
"go.uber.org/atomic"
|
||||||
|
|
||||||
"github.com/projectdiscovery/gologger"
|
"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/output"
|
||||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/contextargs"
|
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/contextargs"
|
||||||
"github.com/projectdiscovery/nuclei/v2/pkg/templates"
|
"github.com/projectdiscovery/nuclei/v2/pkg/templates"
|
||||||
@ -18,20 +19,13 @@ import (
|
|||||||
// All the execution logic for the templates/workflows happens in this part
|
// All the execution logic for the templates/workflows happens in this part
|
||||||
// of the engine.
|
// of the engine.
|
||||||
func (e *Engine) Execute(templates []*templates.Template, target InputProvider) *atomic.Bool {
|
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
|
// executeTemplateSpray executes scan using template spray strategy where targets are iterated over each template
|
||||||
func (e *Engine) ExecuteWithOpts(templatesList []*templates.Template, target InputProvider, noCluster bool) *atomic.Bool {
|
func (e *Engine) executeTemplateSpray(templatesList []*templates.Template, target InputProvider) *atomic.Bool {
|
||||||
var finalTemplates []*templates.Template
|
|
||||||
if !noCluster {
|
|
||||||
finalTemplates, _ = templates.ClusterTemplates(templatesList, e.executerOpts)
|
|
||||||
} else {
|
|
||||||
finalTemplates = templatesList
|
|
||||||
}
|
|
||||||
|
|
||||||
results := &atomic.Bool{}
|
results := &atomic.Bool{}
|
||||||
for _, template := range finalTemplates {
|
for _, template := range templatesList {
|
||||||
templateType := template.Type()
|
templateType := template.Type()
|
||||||
|
|
||||||
var wg *sizedwaitgroup.SizedWaitGroup
|
var wg *sizedwaitgroup.SizedWaitGroup
|
||||||
@ -59,6 +53,53 @@ func (e *Engine) ExecuteWithOpts(templatesList []*templates.Template, target Inp
|
|||||||
return results
|
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.
|
// processSelfContainedTemplates execute a self-contained template.
|
||||||
func (e *Engine) executeSelfContainedTemplateWithInput(template *templates.Template, results *atomic.Bool) {
|
func (e *Engine) executeSelfContainedTemplateWithInput(template *templates.Template, results *atomic.Bool) {
|
||||||
match, err := template.Executer.Execute(contextargs.New())
|
match, err := template.Executer.Execute(contextargs.New())
|
||||||
|
|||||||
@ -336,6 +336,8 @@ type Options struct {
|
|||||||
AwsBucketName string
|
AwsBucketName string
|
||||||
// AWS Region name where aws s3 bucket is located
|
// AWS Region name where aws s3 bucket is located
|
||||||
AwsRegion string
|
AwsRegion string
|
||||||
|
// Scan Strategy (auto,hosts-spray,templates-spray)
|
||||||
|
ScanStrategy string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (options *Options) AddVarPayload(key string, value interface{}) {
|
func (options *Options) AddVarPayload(key string, value interface{}) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user