diff --git a/v2/cmd/nuclei/main.go b/v2/cmd/nuclei/main.go index 0b8ccb1c1..e52b71331 100644 --- a/v2/cmd/nuclei/main.go +++ b/v2/cmd/nuclei/main.go @@ -79,6 +79,7 @@ based on templates offering massive extensibility and ease of use.`) set.StringVarP(&options.ReportingConfig, "report-config", "rc", "", "Nuclei Reporting Module configuration file") set.StringVarP(&options.ReportingDB, "report-db", "rdb", "", "Local Nuclei Reporting Database") set.StringSliceVar(&options.Tags, "tags", []string{}, "Tags to execute templates for") + set.StringSliceVar(&options.ExcludeTags, "exclude-tags", []string{}, "Exclude templates with the provided tags") set.StringVarP(&options.ResolversFile, "resolvers", "r", "", "File containing resolver list for nuclei") set.BoolVar(&options.Headless, "headless", false, "Enable headless browser based templates support") set.BoolVar(&options.ShowBrowser, "show-browser", false, "Show the browser on the screen") diff --git a/v2/internal/runner/runner.go b/v2/internal/runner/runner.go index d531fb27e..32cfd25e8 100644 --- a/v2/internal/runner/runner.go +++ b/v2/internal/runner/runner.go @@ -197,8 +197,8 @@ func (r *Runner) Close() { // RunEnumeration sets up the input layer for giving input nuclei. // binary and runs the actual enumeration func (r *Runner) RunEnumeration() { - // resolves input templates definitions and any optional exclusion - if len(r.options.Templates) == 0 && len(r.options.Tags) > 0 { + // If we have no templates, run on whole template directory with provided tags + if len(r.options.Templates) == 0 && len(r.options.Tags) > 0 || len(r.options.ExcludeTags) > 0 { r.options.Templates = append(r.options.Templates, r.options.TemplatesDirectory) } if r.options.NewTemplates { diff --git a/v2/pkg/templates/compile.go b/v2/pkg/templates/compile.go index 3fb25b6ae..15f498096 100644 --- a/v2/pkg/templates/compile.go +++ b/v2/pkg/templates/compile.go @@ -45,14 +45,21 @@ func Parse(filePath string, options protocols.ExecuterOptions) (*Template, error if _, ok := template.Info["author"]; !ok { return nil, errors.New("no template author field provided") } + templateTags, ok := template.Info["tags"] + if !ok { + templateTags = "" + } + matchWithTags := false if len(options.Options.Tags) > 0 { - templateTags, ok := template.Info["tags"] - if !ok { - templateTags = "" - } if err := matchTemplateWithTags(types.ToString(templateTags), types.ToString(template.Info["severity"]), options.Options); err != nil { return nil, nil } + matchWithTags = true + } + if len(options.Options.ExcludeTags) > 0 && !matchWithTags { + if err := matchTemplateWithTags(types.ToString(templateTags), types.ToString(template.Info["severity"]), options.Options); err == nil { + return nil, nil + } } // Setting up variables regarding template metadata diff --git a/v2/pkg/types/types.go b/v2/pkg/types/types.go index 507d4bec3..dec4a3b65 100644 --- a/v2/pkg/types/types.go +++ b/v2/pkg/types/types.go @@ -8,6 +8,8 @@ type Options struct { // can be specified with -l flag and -tags can be used in combination with // the -l flag. Tags goflags.StringSlice + // ExcludeTags is the list of tags to exclude + ExcludeTags goflags.StringSlice // Workflows specifies any workflows to run by nuclei Workflows goflags.StringSlice // Templates specifies the template/templates to use