Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
projectdiscovery
GitHub Repository: projectdiscovery/nuclei
Path: blob/dev/pkg/protocols/common/automaticscan/util.go
2851 views
1
package automaticscan
2
3
import (
4
"fmt"
5
6
"github.com/pkg/errors"
7
"github.com/projectdiscovery/nuclei/v3/pkg/catalog/config"
8
"github.com/projectdiscovery/nuclei/v3/pkg/catalog/disk"
9
"github.com/projectdiscovery/nuclei/v3/pkg/templates"
10
"github.com/projectdiscovery/nuclei/v3/pkg/types"
11
sliceutil "github.com/projectdiscovery/utils/slice"
12
)
13
14
// getTemplateDirs returns template directories for given input
15
// by default it returns default template directory
16
func getTemplateDirs(opts Options) ([]string, error) {
17
defaultTemplatesDirectories := []string{config.DefaultConfig.GetTemplateDir()}
18
// adding custom template path if available
19
if len(opts.ExecuterOpts.Options.Templates) > 0 {
20
defaultTemplatesDirectories = append(defaultTemplatesDirectories, opts.ExecuterOpts.Options.Templates...)
21
}
22
// Collect path for default directories we want to look for templates in
23
var allTemplates []string
24
for _, directory := range defaultTemplatesDirectories {
25
templates, err := opts.ExecuterOpts.Catalog.GetTemplatePath(directory)
26
if err != nil {
27
return nil, errors.Wrap(err, "could not get templates in directory")
28
}
29
allTemplates = append(allTemplates, templates...)
30
}
31
allTemplates = sliceutil.Dedupe(allTemplates)
32
if len(allTemplates) == 0 {
33
return nil, fmt.Errorf("%w for given input", disk.ErrNoTemplatesFound)
34
}
35
return allTemplates, nil
36
}
37
38
// LoadTemplatesWithTags loads and returns templates with given tags
39
func LoadTemplatesWithTags(opts Options, templateDirs []string, tags []string, logInfo bool) ([]*templates.Template, error) {
40
finalTemplates := opts.Store.LoadTemplatesWithTags(templateDirs, tags)
41
if len(finalTemplates) == 0 {
42
return nil, errors.New("could not find any templates with tech tag")
43
}
44
45
if !opts.ExecuterOpts.Options.DisableClustering {
46
// cluster and reduce requests
47
totalReqBeforeCluster := getRequestCount(finalTemplates) * int(opts.Target.Count())
48
finalTemplates, clusterCount := templates.ClusterTemplates(finalTemplates, opts.ExecuterOpts)
49
totalReqAfterClustering := getRequestCount(finalTemplates) * int(opts.Target.Count())
50
if totalReqAfterClustering < totalReqBeforeCluster && logInfo {
51
opts.ExecuterOpts.Logger.Info().Msgf("Automatic scan tech-detect: Templates clustered: %d (Reduced %d Requests)", clusterCount, totalReqBeforeCluster-totalReqAfterClustering)
52
}
53
}
54
55
// log template loaded if VerboseVerbose flag is set
56
if opts.ExecuterOpts.Options.VerboseVerbose {
57
for _, tpl := range finalTemplates {
58
opts.ExecuterOpts.Logger.Print().Msgf("%s\n", templates.TemplateLogMessage(tpl.ID,
59
types.ToString(tpl.Info.Name),
60
tpl.Info.Authors.ToSlice(),
61
tpl.Info.SeverityHolder.Severity))
62
}
63
64
}
65
return finalTemplates, nil
66
}
67
68
// returns total requests count
69
func getRequestCount(templates []*templates.Template) int {
70
count := 0
71
for _, template := range templates {
72
// ignore requests in workflows as total requests in workflow
73
// depends on what templates will be called in workflow
74
if len(template.Workflows) > 0 {
75
continue
76
}
77
count += template.TotalRequests
78
}
79
return count
80
}
81
82