Work on operators package and generic protocol agnostic matching capabilities

dev
Ice3man543 2020-12-24 01:41:32 +05:30
parent ff4c61a0eb
commit 8a64578890
4 changed files with 20 additions and 60 deletions

View File

@ -17,6 +17,10 @@ func (m *Matcher) CompileMatchers() error {
if !ok { if !ok {
return fmt.Errorf("unknown matcher type specified: %s", m.Type) return fmt.Errorf("unknown matcher type specified: %s", m.Type)
} }
// By default, match on all if user hasn't provided any specific items
if m.Part == "" {
m.Part = "all"
}
// Compile the regexes // Compile the regexes
for _, regex := range m.Regex { for _, regex := range m.Regex {

View File

@ -2,75 +2,34 @@ package matchers
import ( import (
"encoding/hex" "encoding/hex"
"net/http"
"strings" "strings"
"time"
"github.com/miekg/dns"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/generators"
) )
// Match matches a http response again a given matcher // Match matches a generic data response again a given matcher
func (m *Matcher) Match(resp *http.Response, body, headers string, duration time.Duration) bool { func (m *Matcher) Match(data map[string]interface{}) bool {
switch m.matcherType { part, ok := data[m.Part]
case StatusMatcher: if !ok {
return m.isNegative(m.matchStatusCode(resp.StatusCode))
case SizeMatcher:
return m.isNegative(m.matchSizeCode(len(body)))
case WordsMatcher:
// Match the parts as required for word check
if m.Part == "body" {
return m.isNegative(m.matchWords(body))
} else if m.Part == "header" {
return m.isNegative(m.matchWords(headers))
} else {
return m.isNegative(m.matchWords(headers) || m.matchWords(body))
}
case RegexMatcher:
// Match the parts as required for regex check
if m.Part == "body" {
return m.isNegative(m.matchRegex(body))
} else if m.Part == "header" {
return m.isNegative(m.matchRegex(headers))
} else {
return m.isNegative(m.matchRegex(headers) || m.matchRegex(body))
}
case BinaryMatcher:
// Match the parts as required for binary characters check
if m.Part == "body" {
return m.isNegative(m.matchBinary(body))
} else if m.Part == "header" {
return m.isNegative(m.matchBinary(headers))
} else {
return m.isNegative(m.matchBinary(headers) || m.matchBinary(body))
}
case DSLMatcher:
// Match complex query
return m.isNegative(m.matchDSL(generators.MergeMaps(HTTPToMap(resp, body, headers, duration, ""), data)))
}
return false return false
} }
partString := part.(string)
// MatchDNS matches a dns response against a given matcher
func (m *Matcher) MatchDNS(msg *dns.Msg) bool {
switch m.matcherType { switch m.matcherType {
case StatusMatcher: case StatusMatcher:
return m.isNegative(m.matchStatusCode(msg.Rcode)) statusCode, ok := data["status_code"]
if !ok {
return false
}
return m.isNegative(m.matchStatusCode(statusCode.(int)))
case SizeMatcher: case SizeMatcher:
return m.matchSizeCode(msg.Len()) return m.isNegative(m.matchSizeCode(len(partString)))
case WordsMatcher: case WordsMatcher:
// Match for word check return m.isNegative(m.matchWords(partString))
return m.matchWords(msg.String())
case RegexMatcher: case RegexMatcher:
// Match regex check return m.isNegative(m.matchRegex(partString))
return m.matchRegex(msg.String())
case BinaryMatcher: case BinaryMatcher:
// Match binary characters check return m.isNegative(m.matchBinary(partString))
return m.matchBinary(msg.String())
case DSLMatcher: case DSLMatcher:
// Match complex query return m.isNegative(m.matchDSL(data))
return m.matchDSL(DNSToMap(msg, ""))
} }
return false return false
} }
@ -88,7 +47,6 @@ func (m *Matcher) matchStatusCode(statusCode int) bool {
// Return on the first match. // Return on the first match.
return true return true
} }
return false return false
} }

View File

@ -94,6 +94,5 @@ func (m *Matcher) isNegative(data bool) bool {
if m.Negative { if m.Negative {
return !data return !data
} }
return data return data
} }

View File

@ -16,7 +16,6 @@ type Operators struct {
// MatchersCondition is the condition of the matchers // MatchersCondition is the condition of the matchers
// whether to use AND or OR. Default is OR. // whether to use AND or OR. Default is OR.
MatchersCondition string `yaml:"matchers-condition"` MatchersCondition string `yaml:"matchers-condition"`
// cached variables that may be used along with request. // cached variables that may be used along with request.
matchersCondition matchers.ConditionType matchersCondition matchers.ConditionType
} }