Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
projectdiscovery
GitHub Repository: projectdiscovery/nuclei
Path: blob/dev/pkg/workflows/workflows.go
2070 views
1
package workflows
2
3
import (
4
"fmt"
5
6
"github.com/projectdiscovery/nuclei/v3/pkg/model/types/stringslice"
7
"github.com/projectdiscovery/nuclei/v3/pkg/operators"
8
"github.com/projectdiscovery/nuclei/v3/pkg/protocols"
9
templateTypes "github.com/projectdiscovery/nuclei/v3/pkg/templates/types"
10
)
11
12
// Workflow is a workflow to execute with chained requests, etc.
13
type Workflow struct {
14
// description: |
15
// Workflows is a list of workflows to execute for a template.
16
Workflows []*WorkflowTemplate `yaml:"workflows,omitempty" json:"workflows,omitempty" jsonschema:"title=list of workflows to execute,description=List of workflows to execute for template"`
17
18
Options *protocols.ExecutorOptions `yaml:"-" json:"-"`
19
}
20
21
// WorkflowTemplate is a template to be run as part of a workflow
22
type WorkflowTemplate struct {
23
// description: |
24
// Template is a single template or directory to execute as part of workflow.
25
// examples:
26
// - name: A single template
27
// value: "\"dns/worksites-detection.yaml\""
28
// - name: A template directory
29
// value: "\"misconfigurations/aem\""
30
Template string `yaml:"template,omitempty" json:"template,omitempty" jsonschema:"title=template/directory to execute,description=Template or directory to execute as part of workflow"`
31
// description: |
32
// Tags to run templates based on.
33
Tags stringslice.StringSlice `yaml:"tags,omitempty" json:"tags,omitempty" jsonschema:"title=tags to execute,description=Tags to run template based on"`
34
// description: |
35
// Matchers perform name based matching to run subtemplates for a workflow.
36
Matchers []*Matcher `yaml:"matchers,omitempty" json:"matchers,omitempty" jsonschema:"title=name based template result matchers,description=Matchers perform name based matching to run subtemplates for a workflow"`
37
// description: |
38
// Subtemplates are run if the `template` field Template matches.
39
Subtemplates []*WorkflowTemplate `yaml:"subtemplates,omitempty" json:"subtemplates,omitempty" jsonschema:"title=subtemplate based result matchers,description=Subtemplates are ran if the template field Template matches"`
40
// Executers perform the actual execution for the workflow template
41
Executers []*ProtocolExecuterPair `yaml:"-" json:"-"`
42
}
43
44
// ProtocolExecuterPair is a pair of protocol executer and its options
45
type ProtocolExecuterPair struct {
46
Executer protocols.Executer
47
Options *protocols.ExecutorOptions
48
TemplateType templateTypes.ProtocolType
49
}
50
51
// Matcher performs conditional matching on the workflow template results.
52
type Matcher struct {
53
// description: |
54
// Name is the name of the items to match.
55
Name stringslice.StringSlice `yaml:"name,omitempty" json:"name,omitempty" jsonschema:"title=name of items to match,description=Name of items to match"`
56
// description: |
57
// Condition is the optional condition between names. By default,
58
// the condition is assumed to be OR.
59
// values:
60
// - "and"
61
// - "or"
62
Condition string `yaml:"condition,omitempty" json:"condition,omitempty" jsonschema:"title=condition between names,description=Condition between the names,enum=and,enum=or"`
63
// description: |
64
// Subtemplates are run if the name of matcher matches.
65
Subtemplates []*WorkflowTemplate `yaml:"subtemplates,omitempty" json:"subtemplates,omitempty" jsonschema:"title=templates to run after match,description=Templates to run after match"`
66
67
condition ConditionType
68
}
69
70
// ConditionType is the type of condition for matcher
71
type ConditionType int
72
73
const (
74
// ANDCondition matches responses with AND condition in arguments.
75
ANDCondition ConditionType = iota + 1
76
// ORCondition matches responses with AND condition in arguments.
77
ORCondition
78
)
79
80
// ConditionTypes is a table for conversion of condition type from string.
81
var ConditionTypes = map[string]ConditionType{
82
"and": ANDCondition,
83
"or": ORCondition,
84
}
85
86
// Compile compiles the matcher for workflow
87
func (matcher *Matcher) Compile() error {
88
var ok bool
89
if matcher.Condition != "" {
90
matcher.condition, ok = ConditionTypes[matcher.Condition]
91
if !ok {
92
return fmt.Errorf("unknown condition specified: %s", matcher.Condition)
93
}
94
} else {
95
matcher.condition = ORCondition
96
}
97
return nil
98
}
99
100
// Match matches a name for matcher names or name
101
func (matcher *Matcher) Match(result *operators.Result) bool {
102
names := matcher.Name.ToSlice()
103
if len(names) == 0 {
104
return false
105
}
106
107
for i, name := range names {
108
matchOK := result.HasMatch(name)
109
extractOK := result.HasExtract(name)
110
111
if !matchOK && !extractOK {
112
if matcher.condition == ANDCondition {
113
return false
114
}
115
continue
116
}
117
if matcher.condition == ORCondition {
118
return true
119
} else if len(names)-1 == i {
120
return true
121
}
122
}
123
return false
124
}
125
126