2022-11-01 20:28:50 +05:30
package fuzz
import (
"regexp"
"strings"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/generators"
)
// Rule is a single rule which describes how to fuzz the request
type Rule struct {
// description: |
// Type is the type of fuzzing rule to perform.
//
// replace replaces the values entirely. prefix prefixes the value. postfix postfixes the value
// and infix places between the values.
// values:
// - "replace"
// - "prefix"
// - "postfix"
// - "infix"
2023-02-07 16:10:40 +08:00
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" `
2022-11-01 20:28:50 +05:30
ruleType ruleType
// description: |
// Part is the part of request to fuzz.
//
// query fuzzes the query part of url. More parts will be added later.
// values:
// - "query"
2023-02-07 16:10:40 +08:00
Part string ` yaml:"part,omitempty" json:"part,omitempty" jsonschema:"title=part of rule,description=Part of request rule to fuzz,enum=query" `
2022-11-01 20:28:50 +05:30
partType partType
// description: |
// Mode is the mode of fuzzing to perform.
//
// single fuzzes one value at a time. multiple fuzzes all values at same time.
// values:
// - "single"
// - "multiple"
2023-02-07 16:10:40 +08:00
Mode string ` yaml:"mode,omitempty" json:"mode,omitempty" jsonschema:"title=mode of rule,description=Mode of request rule to fuzz,enum=single,enum=multiple" `
2022-11-01 20:28:50 +05:30
modeType modeType
// description: |
// Keys is the optional list of key named parameters to fuzz.
// examples:
// - name: Examples of keys
// value: >
// []string{"url", "file", "host"}
2023-02-07 16:10:40 +08:00
Keys [ ] string ` yaml:"keys,omitempty" json:"keys,omitempty" jsonschema:"title=keys of parameters to fuzz,description=Keys of parameters to fuzz" `
2022-11-01 20:28:50 +05:30
keysMap map [ string ] struct { }
// description: |
// KeysRegex is the optional list of regex key parameters to fuzz.
// examples:
// - name: Examples of key regex
// value: >
// []string{"url.*"}
2023-02-07 16:10:40 +08:00
KeysRegex [ ] string ` yaml:"keys-regex,omitempty" json:"keys-regex,omitempty" jsonschema:"title=keys regex to fuzz,description=Regex of parameter keys to fuzz" `
2022-11-01 20:28:50 +05:30
keysRegex [ ] * regexp . Regexp
// description: |
// Values is the optional list of regex value parameters to fuzz.
// examples:
// - name: Examples of value regex
// value: >
// []string{"https?://.*"}
2023-02-07 16:10:40 +08:00
ValuesRegex [ ] string ` yaml:"values,omitempty" json:"values,omitempty" jsonschema:"title=values regex to fuzz,description=Regex of parameter values to fuzz" `
2022-11-01 20:28:50 +05:30
valuesRegex [ ] * regexp . Regexp
// description: |
// Fuzz is the list of payloads to perform substitutions with.
// examples:
// - name: Examples of fuzz
// value: >
// []string{"{{ssrf}}", "{{interactsh-url}}", "example-value"}
2023-02-07 16:10:40 +08:00
Fuzz [ ] string ` yaml:"fuzz,omitempty" json:"fuzz,omitempty" jsonschema:"title=payloads of fuzz rule,description=Payloads to perform fuzzing substitutions with" `
2022-11-01 20:28:50 +05:30
options * protocols . ExecuterOptions
generator * generators . PayloadGenerator
}
// ruleType is the type of rule enum declaration
type ruleType int
const (
replaceRuleType ruleType = iota + 1
prefixRuleType
postfixRuleType
infixRuleType
)
var stringToRuleType = map [ string ] ruleType {
"replace" : replaceRuleType ,
"prefix" : prefixRuleType ,
"postfix" : postfixRuleType ,
"infix" : infixRuleType ,
}
// partType is the part of rule enum declaration
type partType int
const (
queryPartType partType = iota + 1
)
var stringToPartType = map [ string ] partType {
"query" : queryPartType ,
}
// modeType is the mode of rule enum declaration
type modeType int
const (
singleModeType modeType = iota + 1
multipleModeType
)
var stringToModeType = map [ string ] modeType {
"single" : singleModeType ,
"multiple" : multipleModeType ,
}
// matchKeyOrValue matches key value parameters with rule parameters
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
}