Path: blob/dev/pkg/protocols/common/automaticscan/util.go
2851 views
package automaticscan12import (3"fmt"45"github.com/pkg/errors"6"github.com/projectdiscovery/nuclei/v3/pkg/catalog/config"7"github.com/projectdiscovery/nuclei/v3/pkg/catalog/disk"8"github.com/projectdiscovery/nuclei/v3/pkg/templates"9"github.com/projectdiscovery/nuclei/v3/pkg/types"10sliceutil "github.com/projectdiscovery/utils/slice"11)1213// getTemplateDirs returns template directories for given input14// by default it returns default template directory15func getTemplateDirs(opts Options) ([]string, error) {16defaultTemplatesDirectories := []string{config.DefaultConfig.GetTemplateDir()}17// adding custom template path if available18if len(opts.ExecuterOpts.Options.Templates) > 0 {19defaultTemplatesDirectories = append(defaultTemplatesDirectories, opts.ExecuterOpts.Options.Templates...)20}21// Collect path for default directories we want to look for templates in22var allTemplates []string23for _, directory := range defaultTemplatesDirectories {24templates, err := opts.ExecuterOpts.Catalog.GetTemplatePath(directory)25if err != nil {26return nil, errors.Wrap(err, "could not get templates in directory")27}28allTemplates = append(allTemplates, templates...)29}30allTemplates = sliceutil.Dedupe(allTemplates)31if len(allTemplates) == 0 {32return nil, fmt.Errorf("%w for given input", disk.ErrNoTemplatesFound)33}34return allTemplates, nil35}3637// LoadTemplatesWithTags loads and returns templates with given tags38func LoadTemplatesWithTags(opts Options, templateDirs []string, tags []string, logInfo bool) ([]*templates.Template, error) {39finalTemplates := opts.Store.LoadTemplatesWithTags(templateDirs, tags)40if len(finalTemplates) == 0 {41return nil, errors.New("could not find any templates with tech tag")42}4344if !opts.ExecuterOpts.Options.DisableClustering {45// cluster and reduce requests46totalReqBeforeCluster := getRequestCount(finalTemplates) * int(opts.Target.Count())47finalTemplates, clusterCount := templates.ClusterTemplates(finalTemplates, opts.ExecuterOpts)48totalReqAfterClustering := getRequestCount(finalTemplates) * int(opts.Target.Count())49if totalReqAfterClustering < totalReqBeforeCluster && logInfo {50opts.ExecuterOpts.Logger.Info().Msgf("Automatic scan tech-detect: Templates clustered: %d (Reduced %d Requests)", clusterCount, totalReqBeforeCluster-totalReqAfterClustering)51}52}5354// log template loaded if VerboseVerbose flag is set55if opts.ExecuterOpts.Options.VerboseVerbose {56for _, tpl := range finalTemplates {57opts.ExecuterOpts.Logger.Print().Msgf("%s\n", templates.TemplateLogMessage(tpl.ID,58types.ToString(tpl.Info.Name),59tpl.Info.Authors.ToSlice(),60tpl.Info.SeverityHolder.Severity))61}6263}64return finalTemplates, nil65}6667// returns total requests count68func getRequestCount(templates []*templates.Template) int {69count := 070for _, template := range templates {71// ignore requests in workflows as total requests in workflow72// depends on what templates will be called in workflow73if len(template.Workflows) > 0 {74continue75}76count += template.TotalRequests77}78return count79}808182