Path: blob/dev/pkg/operators/matchers/matchers.go
2070 views
package matchers12import (3"regexp"45"github.com/Knetic/govaluate"6)78// Matcher is used to match a part in the output from a protocol.9type Matcher struct {10// description: |11// Type is the type of the matcher.12Type 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"`13// description: |14// Condition is the optional condition between two matcher variables. By default,15// the condition is assumed to be OR.16// values:17// - "and"18// - "or"19Condition string `yaml:"condition,omitempty" json:"condition,omitempty" jsonschema:"title=condition between matcher variables,description=Condition between the matcher variables,enum=and,enum=or"`2021// description: |22// Part is the part of the request response to match data from.23//24// Each protocol exposes a lot of different parts which are well25// documented in docs for each request type.26// examples:27// - value: "\"body\""28// - value: "\"raw\""29Part string `yaml:"part,omitempty" json:"part,omitempty" jsonschema:"title=part of response to match,description=Part of response to match data from"`3031// description: |32// Negative specifies if the match should be reversed33// It will only match if the condition is not true.34Negative 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"`3536// description: |37// Name of the matcher. Name should be lowercase and must not contain38// spaces or underscores (_).39// examples:40// - value: "\"cookie-matcher\""41Name string `yaml:"name,omitempty" json:"name,omitempty" jsonschema:"title=name of the matcher,description=Name of the matcher"`42// description: |43// Status are the acceptable status codes for the response.44// examples:45// - value: >46// []int{200, 302}47Status []int `yaml:"status,omitempty" json:"status,omitempty" jsonschema:"title=status to match,description=Status to match for the response"`48// description: |49// Size is the acceptable size for the response50// examples:51// - value: >52// []int{3029, 2042}53Size []int `yaml:"size,omitempty" json:"size,omitempty" jsonschema:"title=acceptable size for response,description=Size is the acceptable size for the response"`54// description: |55// Words contains word patterns required to be present in the response part.56// examples:57// - name: Match for Outlook mail protection domain58// value: >59// []string{"mail.protection.outlook.com"}60// - name: Match for application/json in response headers61// value: >62// []string{"application/json"}63Words []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"`64// description: |65// Regex contains Regular Expression patterns required to be present in the response part.66// examples:67// - name: Match for Linkerd Service via Regex68// value: >69// []string{`(?mi)^Via\\s*?:.*?linkerd.*$`}70// - name: Match for Open Redirect via Location header71// value: >72// []string{`(?m)^(?:Location\\s*?:\\s*?)(?:https?://|//)?(?:[a-zA-Z0-9\\-_\\.@]*)example\\.com.*$`}73Regex []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"`74// description: |75// Binary are the binary patterns required to be present in the response part.76// examples:77// - name: Match for Springboot Heapdump Actuator "JAVA PROFILE", "HPROF", "Gunzip magic byte"78// value: >79// []string{"4a4156412050524f46494c45", "4850524f46", "1f8b080000000000"}80// - name: Match for 7zip files81// value: >82// []string{"377ABCAF271C"}83Binary []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"`84// description: |85// DSL are the dsl expressions that will be evaluated as part of nuclei matching rules.86// A list of these helper functions are available [here](https://nuclei.projectdiscovery.io/templating-guide/helper-functions/).87// examples:88// - name: DSL Matcher for package.json file89// value: >90// []string{"contains(body, 'packages') && contains(tolower(all_headers), 'application/octet-stream') && status_code == 200"}91// - name: DSL Matcher for missing strict transport security header92// value: >93// []string{"!contains(tolower(all_headers), ''strict-transport-security'')"}94DSL []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"`95// description: |96// XPath are the xpath queries expressions that will be evaluated against the response part.97// examples:98// - name: XPath Matcher to check a title99// value: >100// []string{"/html/head/title[contains(text(), 'How to Find XPath')]"}101// - name: XPath Matcher for finding links with target="_blank"102// value: >103// []string{"//a[@target=\"_blank\"]"}104XPath []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"`105// description: |106// Encoding specifies the encoding for the words field if any.107// values:108// - "hex"109Encoding string `yaml:"encoding,omitempty" json:"encoding,omitempty" jsonschema:"title=encoding for word field,description=Optional encoding for the word fields,enum=hex"`110// description: |111// CaseInsensitive enables case-insensitive matches. Default is false.112// values:113// - false114// - true115CaseInsensitive bool `yaml:"case-insensitive,omitempty" json:"case-insensitive,omitempty" jsonschema:"title=use case insensitive match,description=use case insensitive match"`116// description: |117// MatchAll enables matching for all matcher values. Default is false.118// values:119// - false120// - true121MatchAll bool `yaml:"match-all,omitempty" json:"match-all,omitempty" jsonschema:"title=match all values,description=match all matcher values ignoring condition"`122// description: |123// Internal when true hides the matcher from output. Default is false.124// It is meant to be used in multiprotocol / flow templates to create internal matcher condition without printing it in output.125// or other similar use cases.126// values:127// - false128// - true129Internal bool `yaml:"internal,omitempty" json:"internal,omitempty" jsonschema:"title=hide matcher from output,description=hide matcher from output"`130131// cached data for the compiled matcher132condition ConditionType // todo: this field should be the one used for overridden marshal ops133matcherType MatcherType134binaryDecoded []string135regexCompiled []*regexp.Regexp136dslCompiled []*govaluate.EvaluableExpression137}138139// ConditionType is the type of condition for matcher140type ConditionType int141142const (143// ANDCondition matches responses with AND condition in arguments.144ANDCondition ConditionType = iota + 1145// ORCondition matches responses with AND condition in arguments.146ORCondition147)148149// ConditionTypes is a table for conversion of condition type from string.150var ConditionTypes = map[string]ConditionType{151"and": ANDCondition,152"or": ORCondition,153}154155// Result reverts the results of the match if the matcher is of type negative.156func (matcher *Matcher) Result(data bool) bool {157if matcher.Negative {158return !data159}160return data161}162163// ResultWithMatchedSnippet returns true and the matched snippet, or false and an empty string164func (matcher *Matcher) ResultWithMatchedSnippet(data bool, matchedSnippet []string) (bool, []string) {165if matcher.Negative {166return !data, []string{}167}168return data, matchedSnippet169}170171172