package fuzz
import (
"regexp"
"strings"
"github.com/projectdiscovery/nuclei/v3/pkg/protocols"
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/generators"
)
type Rule struct {
Type string `yaml:"type,omitempty" json:"type,omitempty" jsonschema:"title=type of rule,description=Type of fuzzing rule to perform,enum=replace,enum=prefix,enum=postfix,enum=infix,enum=replace-regex"`
ruleType ruleType
Part string `yaml:"part,omitempty" json:"part,omitempty" jsonschema:"title=part of rule,description=Part of request rule to fuzz,enum=query,enum=header,enum=path,enum=body,enum=cookie,enum=request"`
partType partType
Parts []string `yaml:"parts,omitempty" json:"parts,omitempty" jsonschema:"title=parts of rule,description=Part of request rule to fuzz,enum=query,enum=header,enum=path,enum=body,enum=cookie,enum=request"`
Mode string `yaml:"mode,omitempty" json:"mode,omitempty" jsonschema:"title=mode of rule,description=Mode of request rule to fuzz,enum=single,enum=multiple"`
modeType modeType
Keys []string `yaml:"keys,omitempty" json:"keys,omitempty" jsonschema:"title=keys of parameters to fuzz,description=Keys of parameters to fuzz"`
keysMap map[string]struct{}
KeysRegex []string `yaml:"keys-regex,omitempty" json:"keys-regex,omitempty" jsonschema:"title=keys regex to fuzz,description=Regex of parameter keys to fuzz"`
keysRegex []*regexp.Regexp
ValuesRegex []string `yaml:"values,omitempty" json:"values,omitempty" jsonschema:"title=values regex to fuzz,description=Regex of parameter values to fuzz"`
valuesRegex []*regexp.Regexp
Fuzz SliceOrMapSlice `yaml:"fuzz,omitempty" json:"fuzz,omitempty" jsonschema:"title=payloads of fuzz rule,description=Payloads to perform fuzzing substitutions with"`
ReplaceRegex string `yaml:"replace-regex,omitempty" json:"replace-regex,omitempty" jsonschema:"title=replace regex of rule,description=Regex for regex-replace rule type"`
replaceRegex *regexp.Regexp `yaml:"-" json:"-"`
options *protocols.ExecutorOptions
generator *generators.PayloadGenerator
}
type ruleType int
const (
replaceRuleType ruleType = iota + 1
prefixRuleType
postfixRuleType
infixRuleType
replaceRegexRuleType
)
var stringToRuleType = map[string]ruleType{
"replace": replaceRuleType,
"prefix": prefixRuleType,
"postfix": postfixRuleType,
"infix": infixRuleType,
"replace-regex": replaceRegexRuleType,
}
type partType int
const (
queryPartType partType = iota + 1
headersPartType
pathPartType
bodyPartType
cookiePartType
requestPartType
)
var stringToPartType = map[string]partType{
"query": queryPartType,
"header": headersPartType,
"path": pathPartType,
"body": bodyPartType,
"cookie": cookiePartType,
"request": requestPartType,
}
type modeType int
const (
singleModeType modeType = iota + 1
multipleModeType
)
var stringToModeType = map[string]modeType{
"single": singleModeType,
"multiple": multipleModeType,
}
func (rule *Rule) matchKeyOrValue(key, value string) bool {
if len(rule.keysMap) == 0 && len(rule.valuesRegex) == 0 && len(rule.keysRegex) == 0 {
return true
}
if value != "" {
for _, regex := range rule.valuesRegex {
if regex.MatchString(value) {
return true
}
}
}
if (len(rule.keysMap) > 0 || len(rule.keysRegex) > 0) && key != "" {
if _, ok := rule.keysMap[strings.ToLower(key)]; ok {
return true
}
for _, regex := range rule.keysRegex {
if regex.MatchString(key) {
return true
}
}
}
return false
}