forgedhallpass 4be6b3cc96 [feature] Add coloring to debug information #999 [WIP]
TODO:
* if there are multiple matchers, make sure the response is only displayed once, with all the matching values colored
* remove code duplication from the request.go files
2021-09-29 19:43:46 +03:00

174 lines
4.6 KiB
Go

package matchers
import (
"encoding/hex"
"strings"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/expressions"
)
// MatchStatusCode matches a status code check against a corpus
func (m *Matcher) MatchStatusCode(statusCode int) bool {
// Iterate over all the status codes accepted as valid
//
// Status codes don't support AND conditions.
for _, status := range m.Status {
// Continue if the status codes don't match
if statusCode != status {
continue
}
// Return on the first match.
return true
}
return false
}
// MatchSize matches a size check against a corpus
func (m *Matcher) MatchSize(length int) bool {
// Iterate over all the sizes accepted as valid
//
// Sizes codes don't support AND conditions.
for _, size := range m.Size {
// Continue if the size doesn't match
if length != size {
continue
}
// Return on the first match.
return true
}
return false
}
// MatchWords matches a word check against a corpus.
func (m *Matcher) MatchWords(corpus string, dynamicValues map[string]interface{}) (bool, []string) {
var matchedWords []string
// Iterate over all the words accepted as valid
for i, word := range m.Words {
if dynamicValues == nil {
dynamicValues = make(map[string]interface{})
}
var err error
word, err = expressions.Evaluate(word, dynamicValues)
if err != nil {
continue
}
// Continue if the word doesn't match
if !strings.Contains(corpus, word) {
// If we are in an AND request and a match failed,
// return false as the AND condition fails on any single mismatch.
if m.condition == ANDCondition {
return false, []string{}
}
// Continue with the flow since it's an OR Condition.
continue
}
// If the condition was an OR, return on the first match.
if m.condition == ORCondition {
return true, []string{word}
}
matchedWords = append(matchedWords, word)
// If we are at the end of the words, return with true
if len(m.Words)-1 == i {
return true, matchedWords
}
}
return false, []string{}
}
// MatchRegex matches a regex check against a corpus
func (m *Matcher) MatchRegex(corpus string) (bool, []string) {
// Iterate over all the regexes accepted as valid
for i, regex := range m.regexCompiled {
// Continue if the regex doesn't match
if !regex.MatchString(corpus) {
// If we are in an AND request and a match failed,
// return false as the AND condition fails on any single mismatch.
if m.condition == ANDCondition {
return false, []string{}
}
// Continue with the flow since it's an OR Condition.
continue
}
// If the condition was an OR, return on the first match.
if m.condition == ORCondition {
return true, regex.FindAllString(corpus, -1)
}
// If we are at the end of the regex, return with true
if len(m.regexCompiled)-1 == i {
return true, []string{corpus}
}
}
return false, []string{}
}
// MatchBinary matches a binary check against a corpus
func (m *Matcher) MatchBinary(corpus string) (bool, []string) {
// Iterate over all the words accepted as valid
for i, binary := range m.Binary {
// Continue if the word doesn't match
hexa, _ := hex.DecodeString(binary)
if !strings.Contains(corpus, string(hexa)) {
// If we are in an AND request and a match failed,
// return false as the AND condition fails on any single mismatch.
if m.condition == ANDCondition {
return false, []string{}
}
// Continue with the flow since it's an OR Condition.
continue
}
// If the condition was an OR, return on the first match.
if m.condition == ORCondition {
return true, []string{string(hexa)}
}
// If we are at the end of the words, return with true
if len(m.Binary)-1 == i {
return true, []string{string(hexa)}
}
}
return false, []string{}
}
// MatchDSL matches on a generic map result
func (m *Matcher) MatchDSL(data map[string]interface{}) bool {
// Iterate over all the expressions accepted as valid
for i, expression := range m.dslCompiled {
result, err := expression.Evaluate(data)
if err != nil {
continue
}
var bResult bool
bResult, ok := result.(bool)
// Continue if the regex doesn't match
if !ok || !bResult {
// If we are in an AND request and a match failed,
// return false as the AND condition fails on any single mismatch.
if m.condition == ANDCondition {
return false
}
// Continue with the flow since it's an OR Condition.
continue
}
// If the condition was an OR, return on the first match.
if m.condition == ORCondition {
return true
}
// If we are at the end of the dsl, return with true
if len(m.dslCompiled)-1 == i {
return true
}
}
return false
}