Tarun Koyalwar e1d3f474a4
support for dynamic variables in template context (multi protocol execution) (#3672)
* multi proto request genesis

* adds template context dynamic vars

* feat: proto level resp variables

* remove proto prefix hacky logic

* implement template ctx args

* remove old var name logic

* improve AddTemplateVars func

* add multi proto comments+docs

* vardump with sorted keys

* fix race condition in ctx args

* default initialize ctx args

* use generic map

* index variables with multiple values

* fix nil cookies

* use synclock map

* fix build failure

* fix lint error

* resolve merge conflicts

* multi proto: add unit+ integration tests

* fix unit tests

* Issue 3339 headless fuzz (#3790)

* Basic headless fuzzing

* Remove debug statements

* Add integration tests

* Update template

* Fix recognize payload value in matcher

* Update tempalte

* use req.SetURL()

---------

Co-authored-by: Tarun Koyalwar <tarun@projectdiscovery.io>

* Auto Generate Syntax Docs + JSONSchema [Fri Jun  9 00:23:32 UTC 2023] 🤖

* Add headless header and status matchers (#3794)

* add headless header and status matchers

* rename headers as header

* add integration test for header+status

* fix typo

---------

Co-authored-by: Shubham Rasal <shubham@projectdiscovery.io>
Co-authored-by: GitHub Action <action@github.com>
Co-authored-by: Dogan Can Bakir <65292895+dogancanbakir@users.noreply.github.com>
2023-06-09 19:52:56 +05:30

145 lines
4.3 KiB
Go

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"
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"`
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"
Part string `yaml:"part,omitempty" json:"part,omitempty" jsonschema:"title=part of rule,description=Part of request rule to fuzz,enum=query"`
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"
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
// description: |
// Keys is the optional list of key named parameters to fuzz.
// examples:
// - name: Examples of keys
// value: >
// []string{"url", "file", "host"}
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{}
// description: |
// KeysRegex is the optional list of regex key parameters to fuzz.
// examples:
// - name: Examples of key regex
// value: >
// []string{"url.*"}
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
// description: |
// Values is the optional list of regex value parameters to fuzz.
// examples:
// - name: Examples of value regex
// value: >
// []string{"https?://.*"}
ValuesRegex []string `yaml:"values,omitempty" json:"values,omitempty" jsonschema:"title=values regex to fuzz,description=Regex of parameter values to fuzz"`
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"}
Fuzz []string `yaml:"fuzz,omitempty" json:"fuzz,omitempty" jsonschema:"title=payloads of fuzz rule,description=Payloads to perform fuzzing substitutions with"`
options *protocols.ExecutorOptions
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
}