172 lines
5.3 KiB
Go
Raw Normal View History

2020-04-04 00:16:27 +05:30
package matchers
import (
"regexp"
2020-04-26 23:32:58 +02:00
"github.com/Knetic/govaluate"
2020-04-04 00:16:27 +05:30
)
// Matcher is used to match a part in the output from a protocol.
2020-04-04 00:16:27 +05:30
type Matcher struct {
2021-07-27 16:03:56 +05:30
// description: |
// Type is the type of the matcher.
// values:
// - "status"
// - "size"
// - "word"
// - "regex"
// - "binary"
// - "dsl"
2020-04-04 00:16:27 +05:30
Type string `yaml:"type"`
2021-07-27 16:03:56 +05:30
// description: |
// Condition is the optional condition between two matcher variables. By default,
// the condition is assumed to be OR.
// values:
// - "and"
// - "or"
Condition string `yaml:"condition,omitempty"`
2021-07-27 16:03:56 +05:30
// description: |
// Part is the part of the request response to match data from.
//
// Each protocol exposes a lot of different parts which are well
// documented in docs for each request type.
// examples:
// - value: "\"body\""
// - value: "\"raw\""
Part string `yaml:"part,omitempty"`
2021-07-27 16:03:56 +05:30
// description: |
// Negative specifies if the match should be reversed
// It will only match if the condition is not true.
Negative bool `yaml:"negative,omitempty"`
2020-04-04 00:16:27 +05:30
2021-07-27 16:03:56 +05:30
// description: |
// Name of the matcher. Name should be lowercase and must not contain
// spaces or dashes (-).
// examples:
// - value: "\"cookie-matcher\""
2020-04-24 06:54:46 +05:30
Name string `yaml:"name,omitempty"`
2021-07-27 16:03:56 +05:30
// description: |
// Status are the acceptable status codes for the response.
// examples:
// - value: >
// []int{200, 302}
2020-04-04 00:16:27 +05:30
Status []int `yaml:"status,omitempty"`
2021-07-27 16:03:56 +05:30
// description: |
// Size is the acceptable size for the response
// examples:
// - value: >
// []int{3029, 2042}
2020-04-04 00:16:27 +05:30
Size []int `yaml:"size,omitempty"`
2021-07-27 16:03:56 +05:30
// description: |
// Words contains word patterns required to be present in the response part.
// examples:
// - name: Match for outlook mail protection domain
// value: >
// []string{"mail.protection.outlook.com"}
// - name: Match for application/json in response headers
// value: >
// []string{"application/json"}
2020-04-04 00:16:27 +05:30
Words []string `yaml:"words,omitempty"`
2021-07-27 16:03:56 +05:30
// description: |
// Regex contains Regular Expression patterns required to be present in the response part.
// examples:
// - name: Match for Linkerd Service via Regex
// value: >
// []string{`(?mi)^Via\\s*?:.*?linkerd.*$`}
// - name: Match for Open Redirect via Location header
// value: >
// []string{`(?m)^(?:Location\\s*?:\\s*?)(?:https?://|//)?(?:[a-zA-Z0-9\\-_\\.@]*)example\\.com.*$`}
2020-04-04 00:16:27 +05:30
Regex []string `yaml:"regex,omitempty"`
2021-07-27 16:03:56 +05:30
// description: |
// Binary are the binary patterns required to be present in the response part.
// examples:
// - name: Match for Springboot Heapdump Actuator "JAVA PROFILE", "HPROF", "Gunzip magic byte"
// value: >
// []string{"4a4156412050524f46494c45", "4850524f46", "1f8b080000000000"}
// - name: Match for 7zip files
// value: >
// []string{"377ABCAF271C"}
2020-04-24 06:54:46 +05:30
Binary []string `yaml:"binary,omitempty"`
2021-07-27 16:03:56 +05:30
// description: |
// DSL are the dsl expressions that will be evaluated as part of nuclei matching rules.
// A list of these helper functions are available [here](https://nuclei.projectdiscovery.io/templating-guide/helper-functions/).
// examples:
// - name: DSL Matcher for package.json file
// value: >
// []string{"contains(body, 'packages') && contains(tolower(all_headers), 'application/octet-stream') && status_code == 200"}
// - name: DSL Matcher for missing strict transport security header
// value: >
// []string{"!contains(tolower(all_headers), ''strict-transport-security'')"}
2020-04-26 23:32:58 +02:00
DSL []string `yaml:"dsl,omitempty"`
2021-07-27 16:03:56 +05:30
// description: |
// Encoding specifies the encoding for the words field if any.
// values:
// - "hex"
2021-02-24 11:23:22 +05:30
Encoding string `yaml:"encoding,omitempty"`
2020-04-04 00:16:27 +05:30
// cached data for the compiled matcher
condition ConditionType
matcherType MatcherType
regexCompiled []*regexp.Regexp
dslCompiled []*govaluate.EvaluableExpression
2020-04-04 00:16:27 +05:30
}
// MatcherType is the type of the matcher specified
type MatcherType = int
const (
// WordsMatcher matches responses with words
WordsMatcher MatcherType = iota + 1
// RegexMatcher matches responses with regexes
RegexMatcher
// BinaryMatcher matches responses with words
2020-04-24 06:54:46 +05:30
BinaryMatcher
2020-04-04 00:16:27 +05:30
// StatusMatcher matches responses with status codes
StatusMatcher
// SizeMatcher matches responses with response size
SizeMatcher
2020-04-26 23:32:58 +02:00
// DSLMatcher matches based upon dsl syntax
DSLMatcher
2020-04-04 00:16:27 +05:30
)
// MatcherTypes is an table for conversion of matcher type from string.
var MatcherTypes = map[string]MatcherType{
"status": StatusMatcher,
"size": SizeMatcher,
"word": WordsMatcher,
"regex": RegexMatcher,
"binary": BinaryMatcher,
2020-04-26 23:32:58 +02:00
"dsl": DSLMatcher,
2020-04-04 00:16:27 +05:30
}
// ConditionType is the type of condition for matcher
type ConditionType int
const (
// ANDCondition matches responses with AND condition in arguments.
ANDCondition ConditionType = iota + 1
// ORCondition matches responses with AND condition in arguments.
ORCondition
)
// ConditionTypes is an table for conversion of condition type from string.
var ConditionTypes = map[string]ConditionType{
"and": ANDCondition,
"or": ORCondition,
}
2020-12-24 20:47:41 +05:30
// Result reverts the results of the match if the matcher is of type negative.
func (m *Matcher) Result(data bool) bool {
2020-08-23 22:55:11 +05:30
if m.Negative {
return !data
}
return data
}
2020-12-24 20:47:41 +05:30
// GetType returns the type of the matcher
func (m *Matcher) GetType() MatcherType {
return m.matcherType
}