github.com/projectdiscovery/nuclei/v2@v2.9.15/pkg/protocols/common/fuzz/fuzz.go (about)

     1  package fuzz
     2  
     3  import (
     4  	"regexp"
     5  	"strings"
     6  
     7  	"github.com/projectdiscovery/nuclei/v2/pkg/protocols"
     8  	"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/generators"
     9  )
    10  
    11  // Rule is a single rule which describes how to fuzz the request
    12  type Rule struct {
    13  	// description: |
    14  	//   Type is the type of fuzzing rule to perform.
    15  	//
    16  	//   replace replaces the values entirely. prefix prefixes the value. postfix postfixes the value
    17  	//   and infix places between the values.
    18  	// values:
    19  	//   - "replace"
    20  	//   - "prefix"
    21  	//   - "postfix"
    22  	//   - "infix"
    23  	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"`
    24  	ruleType ruleType
    25  	// description: |
    26  	//   Part is the part of request to fuzz.
    27  	//
    28  	//   query fuzzes the query part of url. More parts will be added later.
    29  	// values:
    30  	//   - "query"
    31  	Part     string `yaml:"part,omitempty" json:"part,omitempty" jsonschema:"title=part of rule,description=Part of request rule to fuzz,enum=query"`
    32  	partType partType
    33  	// description: |
    34  	//   Mode is the mode of fuzzing to perform.
    35  	//
    36  	//   single fuzzes one value at a time. multiple fuzzes all values at same time.
    37  	// values:
    38  	//   - "single"
    39  	//   - "multiple"
    40  	Mode     string `yaml:"mode,omitempty" json:"mode,omitempty" jsonschema:"title=mode of rule,description=Mode of request rule to fuzz,enum=single,enum=multiple"`
    41  	modeType modeType
    42  
    43  	// description: |
    44  	//   Keys is the optional list of key named parameters to fuzz.
    45  	// examples:
    46  	//   - name: Examples of keys
    47  	//     value: >
    48  	//       []string{"url", "file", "host"}
    49  	Keys    []string `yaml:"keys,omitempty" json:"keys,omitempty" jsonschema:"title=keys of parameters to fuzz,description=Keys of parameters to fuzz"`
    50  	keysMap map[string]struct{}
    51  	// description: |
    52  	//   KeysRegex is the optional list of regex key parameters to fuzz.
    53  	// examples:
    54  	//   - name: Examples of key regex
    55  	//     value: >
    56  	//       []string{"url.*"}
    57  	KeysRegex []string `yaml:"keys-regex,omitempty" json:"keys-regex,omitempty" jsonschema:"title=keys regex to fuzz,description=Regex of parameter keys to fuzz"`
    58  	keysRegex []*regexp.Regexp
    59  	// description: |
    60  	//   Values is the optional list of regex value parameters to fuzz.
    61  	// examples:
    62  	//   - name: Examples of value regex
    63  	//     value: >
    64  	//       []string{"https?://.*"}
    65  	ValuesRegex []string `yaml:"values,omitempty" json:"values,omitempty" jsonschema:"title=values regex to fuzz,description=Regex of parameter values to fuzz"`
    66  	valuesRegex []*regexp.Regexp
    67  
    68  	// description: |
    69  	//   Fuzz is the list of payloads to perform substitutions with.
    70  	// examples:
    71  	//   - name: Examples of fuzz
    72  	//     value: >
    73  	//       []string{"{{ssrf}}", "{{interactsh-url}}", "example-value"}
    74  	Fuzz []string `yaml:"fuzz,omitempty" json:"fuzz,omitempty" jsonschema:"title=payloads of fuzz rule,description=Payloads to perform fuzzing substitutions with"`
    75  
    76  	options   *protocols.ExecutorOptions
    77  	generator *generators.PayloadGenerator
    78  }
    79  
    80  // ruleType is the type of rule enum declaration
    81  type ruleType int
    82  
    83  const (
    84  	replaceRuleType ruleType = iota + 1
    85  	prefixRuleType
    86  	postfixRuleType
    87  	infixRuleType
    88  )
    89  
    90  var stringToRuleType = map[string]ruleType{
    91  	"replace": replaceRuleType,
    92  	"prefix":  prefixRuleType,
    93  	"postfix": postfixRuleType,
    94  	"infix":   infixRuleType,
    95  }
    96  
    97  // partType is the part of rule enum declaration
    98  type partType int
    99  
   100  const (
   101  	queryPartType partType = iota + 1
   102  )
   103  
   104  var stringToPartType = map[string]partType{
   105  	"query": queryPartType,
   106  }
   107  
   108  // modeType is the mode of rule enum declaration
   109  type modeType int
   110  
   111  const (
   112  	singleModeType modeType = iota + 1
   113  	multipleModeType
   114  )
   115  
   116  var stringToModeType = map[string]modeType{
   117  	"single":   singleModeType,
   118  	"multiple": multipleModeType,
   119  }
   120  
   121  // matchKeyOrValue matches key value parameters with rule parameters
   122  func (rule *Rule) matchKeyOrValue(key, value string) bool {
   123  	if len(rule.keysMap) == 0 && len(rule.valuesRegex) == 0 && len(rule.keysRegex) == 0 {
   124  		return true
   125  	}
   126  	if value != "" {
   127  		for _, regex := range rule.valuesRegex {
   128  			if regex.MatchString(value) {
   129  				return true
   130  			}
   131  		}
   132  	}
   133  	if (len(rule.keysMap) > 0 || len(rule.keysRegex) > 0) && key != "" {
   134  		if _, ok := rule.keysMap[strings.ToLower(key)]; ok {
   135  			return true
   136  		}
   137  		for _, regex := range rule.keysRegex {
   138  			if regex.MatchString(key) {
   139  				return true
   140  			}
   141  		}
   142  	}
   143  	return false
   144  }