2022-11-01 20:28:50 +05:30
package fuzz
import (
"regexp"
"strings"
2023-10-17 17:44:13 +05:30
"github.com/projectdiscovery/nuclei/v3/pkg/protocols"
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/generators"
2022-11-01 20:28:50 +05:30
)
// 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"
2024-03-14 03:08:53 +05:30
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" `
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"
2024-03-14 03:08:53 +05:30
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" `
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"}
2024-03-14 03:08:53 +05:30
// or
// x-header: 1
// x-header: 2
Fuzz SliceOrMapSlice ` yaml:"fuzz,omitempty" json:"fuzz,omitempty" jsonschema:"title=payloads of fuzz rule,description=Payloads to perform fuzzing substitutions with" `
// description: |
// replace-regex is regex for regex-replace rule type
// it is only required for replace-regex rule type
// examples:
// - type: replace-regex
// replace-regex: "https?://.*"
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
2022-11-01 20:28:50 +05:30
}
// ruleType is the type of rule enum declaration
type ruleType int
const (
replaceRuleType ruleType = iota + 1
prefixRuleType
postfixRuleType
infixRuleType
2024-03-14 03:08:53 +05:30
replaceRegexRuleType
2022-11-01 20:28:50 +05:30
)
var stringToRuleType = map [ string ] ruleType {
2024-03-14 03:08:53 +05:30
"replace" : replaceRuleType ,
"prefix" : prefixRuleType ,
"postfix" : postfixRuleType ,
"infix" : infixRuleType ,
"replace-regex" : replaceRegexRuleType ,
2022-11-01 20:28:50 +05:30
}
// partType is the part of rule enum declaration
type partType int
const (
queryPartType partType = iota + 1
2023-09-18 21:31:32 +03:00
headersPartType
2024-03-14 03:08:53 +05:30
pathPartType
bodyPartType
cookiePartType
requestPartType
2022-11-01 20:28:50 +05:30
)
var stringToPartType = map [ string ] partType {
2023-09-18 21:31:32 +03:00
"query" : queryPartType ,
2024-03-14 03:08:53 +05:30
"header" : headersPartType ,
"path" : pathPartType ,
"body" : bodyPartType ,
"cookie" : cookiePartType ,
"request" : requestPartType , // request means all request parts
2022-11-01 20:28:50 +05:30
}
// 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
}