Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
projectdiscovery
GitHub Repository: projectdiscovery/nuclei
Path: blob/dev/pkg/operators/matchers/matchers.go
2070 views
1
package matchers
2
3
import (
4
"regexp"
5
6
"github.com/Knetic/govaluate"
7
)
8
9
// Matcher is used to match a part in the output from a protocol.
10
type Matcher struct {
11
// description: |
12
// Type is the type of the matcher.
13
Type MatcherTypeHolder `yaml:"type" json:"type" jsonschema:"title=type of matcher,description=Type of the matcher,enum=status,enum=size,enum=word,enum=regex,enum=binary,enum=dsl"`
14
// description: |
15
// Condition is the optional condition between two matcher variables. By default,
16
// the condition is assumed to be OR.
17
// values:
18
// - "and"
19
// - "or"
20
Condition string `yaml:"condition,omitempty" json:"condition,omitempty" jsonschema:"title=condition between matcher variables,description=Condition between the matcher variables,enum=and,enum=or"`
21
22
// description: |
23
// Part is the part of the request response to match data from.
24
//
25
// Each protocol exposes a lot of different parts which are well
26
// documented in docs for each request type.
27
// examples:
28
// - value: "\"body\""
29
// - value: "\"raw\""
30
Part string `yaml:"part,omitempty" json:"part,omitempty" jsonschema:"title=part of response to match,description=Part of response to match data from"`
31
32
// description: |
33
// Negative specifies if the match should be reversed
34
// It will only match if the condition is not true.
35
Negative bool `yaml:"negative,omitempty" json:"negative,omitempty" jsonschema:"title=negative specifies if match reversed,description=Negative specifies if the match should be reversed. It will only match if the condition is not true"`
36
37
// description: |
38
// Name of the matcher. Name should be lowercase and must not contain
39
// spaces or underscores (_).
40
// examples:
41
// - value: "\"cookie-matcher\""
42
Name string `yaml:"name,omitempty" json:"name,omitempty" jsonschema:"title=name of the matcher,description=Name of the matcher"`
43
// description: |
44
// Status are the acceptable status codes for the response.
45
// examples:
46
// - value: >
47
// []int{200, 302}
48
Status []int `yaml:"status,omitempty" json:"status,omitempty" jsonschema:"title=status to match,description=Status to match for the response"`
49
// description: |
50
// Size is the acceptable size for the response
51
// examples:
52
// - value: >
53
// []int{3029, 2042}
54
Size []int `yaml:"size,omitempty" json:"size,omitempty" jsonschema:"title=acceptable size for response,description=Size is the acceptable size for the response"`
55
// description: |
56
// Words contains word patterns required to be present in the response part.
57
// examples:
58
// - name: Match for Outlook mail protection domain
59
// value: >
60
// []string{"mail.protection.outlook.com"}
61
// - name: Match for application/json in response headers
62
// value: >
63
// []string{"application/json"}
64
Words []string `yaml:"words,omitempty" json:"words,omitempty" jsonschema:"title=words to match in response,description= Words contains word patterns required to be present in the response part"`
65
// description: |
66
// Regex contains Regular Expression patterns required to be present in the response part.
67
// examples:
68
// - name: Match for Linkerd Service via Regex
69
// value: >
70
// []string{`(?mi)^Via\\s*?:.*?linkerd.*$`}
71
// - name: Match for Open Redirect via Location header
72
// value: >
73
// []string{`(?m)^(?:Location\\s*?:\\s*?)(?:https?://|//)?(?:[a-zA-Z0-9\\-_\\.@]*)example\\.com.*$`}
74
Regex []string `yaml:"regex,omitempty" json:"regex,omitempty" jsonschema:"title=regex to match in response,description=Regex contains regex patterns required to be present in the response part"`
75
// description: |
76
// Binary are the binary patterns required to be present in the response part.
77
// examples:
78
// - name: Match for Springboot Heapdump Actuator "JAVA PROFILE", "HPROF", "Gunzip magic byte"
79
// value: >
80
// []string{"4a4156412050524f46494c45", "4850524f46", "1f8b080000000000"}
81
// - name: Match for 7zip files
82
// value: >
83
// []string{"377ABCAF271C"}
84
Binary []string `yaml:"binary,omitempty" json:"binary,omitempty" jsonschema:"title=binary patterns to match in response,description=Binary are the binary patterns required to be present in the response part"`
85
// description: |
86
// DSL are the dsl expressions that will be evaluated as part of nuclei matching rules.
87
// A list of these helper functions are available [here](https://nuclei.projectdiscovery.io/templating-guide/helper-functions/).
88
// examples:
89
// - name: DSL Matcher for package.json file
90
// value: >
91
// []string{"contains(body, 'packages') && contains(tolower(all_headers), 'application/octet-stream') && status_code == 200"}
92
// - name: DSL Matcher for missing strict transport security header
93
// value: >
94
// []string{"!contains(tolower(all_headers), ''strict-transport-security'')"}
95
DSL []string `yaml:"dsl,omitempty" json:"dsl,omitempty" jsonschema:"title=dsl expressions to match in response,description=DSL are the dsl expressions that will be evaluated as part of nuclei matching rules"`
96
// description: |
97
// XPath are the xpath queries expressions that will be evaluated against the response part.
98
// examples:
99
// - name: XPath Matcher to check a title
100
// value: >
101
// []string{"/html/head/title[contains(text(), 'How to Find XPath')]"}
102
// - name: XPath Matcher for finding links with target="_blank"
103
// value: >
104
// []string{"//a[@target=\"_blank\"]"}
105
XPath []string `yaml:"xpath,omitempty" json:"xpath,omitempty" jsonschema:"title=xpath queries to match in response,description=xpath are the XPath queries that will be evaluated against the response part of nuclei matching rules"`
106
// description: |
107
// Encoding specifies the encoding for the words field if any.
108
// values:
109
// - "hex"
110
Encoding string `yaml:"encoding,omitempty" json:"encoding,omitempty" jsonschema:"title=encoding for word field,description=Optional encoding for the word fields,enum=hex"`
111
// description: |
112
// CaseInsensitive enables case-insensitive matches. Default is false.
113
// values:
114
// - false
115
// - true
116
CaseInsensitive bool `yaml:"case-insensitive,omitempty" json:"case-insensitive,omitempty" jsonschema:"title=use case insensitive match,description=use case insensitive match"`
117
// description: |
118
// MatchAll enables matching for all matcher values. Default is false.
119
// values:
120
// - false
121
// - true
122
MatchAll bool `yaml:"match-all,omitempty" json:"match-all,omitempty" jsonschema:"title=match all values,description=match all matcher values ignoring condition"`
123
// description: |
124
// Internal when true hides the matcher from output. Default is false.
125
// It is meant to be used in multiprotocol / flow templates to create internal matcher condition without printing it in output.
126
// or other similar use cases.
127
// values:
128
// - false
129
// - true
130
Internal bool `yaml:"internal,omitempty" json:"internal,omitempty" jsonschema:"title=hide matcher from output,description=hide matcher from output"`
131
132
// cached data for the compiled matcher
133
condition ConditionType // todo: this field should be the one used for overridden marshal ops
134
matcherType MatcherType
135
binaryDecoded []string
136
regexCompiled []*regexp.Regexp
137
dslCompiled []*govaluate.EvaluableExpression
138
}
139
140
// ConditionType is the type of condition for matcher
141
type ConditionType int
142
143
const (
144
// ANDCondition matches responses with AND condition in arguments.
145
ANDCondition ConditionType = iota + 1
146
// ORCondition matches responses with AND condition in arguments.
147
ORCondition
148
)
149
150
// ConditionTypes is a table for conversion of condition type from string.
151
var ConditionTypes = map[string]ConditionType{
152
"and": ANDCondition,
153
"or": ORCondition,
154
}
155
156
// Result reverts the results of the match if the matcher is of type negative.
157
func (matcher *Matcher) Result(data bool) bool {
158
if matcher.Negative {
159
return !data
160
}
161
return data
162
}
163
164
// ResultWithMatchedSnippet returns true and the matched snippet, or false and an empty string
165
func (matcher *Matcher) ResultWithMatchedSnippet(data bool, matchedSnippet []string) (bool, []string) {
166
if matcher.Negative {
167
return !data, []string{}
168
}
169
return data, matchedSnippet
170
}
171
172