2021-02-04 01:09:29 +05:30
|
|
|
package http
|
|
|
|
|
|
2021-04-16 16:56:41 +05:30
|
|
|
import (
|
|
|
|
|
"github.com/projectdiscovery/nuclei/v2/pkg/protocols"
|
|
|
|
|
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/generators"
|
|
|
|
|
)
|
2021-02-04 01:09:29 +05:30
|
|
|
|
|
|
|
|
// requestGenerator generates requests sequentially based on various
|
|
|
|
|
// configurations for a http request template.
|
|
|
|
|
//
|
|
|
|
|
// If payload values are present, an iterator is created for the payload
|
|
|
|
|
// values. Paths and Raw requests are supported as base input, so
|
|
|
|
|
// it will automatically select between them based on the template.
|
|
|
|
|
type requestGenerator struct {
|
2022-05-17 11:52:00 +02:00
|
|
|
currentIndex int
|
|
|
|
|
currentPayloads map[string]interface{}
|
|
|
|
|
okCurrentPayload bool
|
|
|
|
|
request *Request
|
|
|
|
|
options *protocols.ExecuterOptions
|
|
|
|
|
payloadIterator *generators.Iterator
|
|
|
|
|
interactshURLs []string
|
2021-02-04 01:09:29 +05:30
|
|
|
}
|
|
|
|
|
|
2022-01-18 04:13:59 +05:30
|
|
|
// LeaveDefaultPorts skips normalization of default standard ports
|
|
|
|
|
var LeaveDefaultPorts = false
|
|
|
|
|
|
2021-02-04 01:09:29 +05:30
|
|
|
// newGenerator creates a new request generator instance
|
2021-10-01 14:30:04 +03:00
|
|
|
func (request *Request) newGenerator() *requestGenerator {
|
|
|
|
|
generator := &requestGenerator{request: request, options: request.options}
|
2021-02-04 01:09:29 +05:30
|
|
|
|
2021-10-01 14:30:04 +03:00
|
|
|
if len(request.Payloads) > 0 {
|
|
|
|
|
generator.payloadIterator = request.generator.NewIterator()
|
2021-02-04 01:09:29 +05:30
|
|
|
}
|
|
|
|
|
return generator
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// nextValue returns the next path or the next raw request depending on user input
|
|
|
|
|
// It returns false if all the inputs have been exhausted by the generator instance.
|
2021-02-26 13:13:11 +05:30
|
|
|
func (r *requestGenerator) nextValue() (value string, payloads map[string]interface{}, result bool) {
|
2022-05-17 11:52:00 +02:00
|
|
|
// Iterate each payload sequentially for each request path/raw
|
2021-08-13 19:40:10 +05:30
|
|
|
//
|
2022-05-17 11:52:00 +02:00
|
|
|
// If the sequence has finished for the current payload values
|
|
|
|
|
// then restart the sequence from the beginning and move on to the next payloads values
|
|
|
|
|
// otherwise use the last request.
|
|
|
|
|
var sequence []string
|
|
|
|
|
switch {
|
|
|
|
|
case len(r.request.Path) > 0:
|
|
|
|
|
sequence = r.request.Path
|
|
|
|
|
case len(r.request.Raw) > 0:
|
|
|
|
|
sequence = r.request.Raw
|
|
|
|
|
default:
|
|
|
|
|
return "", nil, false
|
2021-02-04 01:09:29 +05:30
|
|
|
}
|
|
|
|
|
|
2022-05-17 11:52:00 +02:00
|
|
|
hasPayloadIterator := r.payloadIterator != nil
|
|
|
|
|
hasInitializedPayloads := r.currentPayloads != nil
|
2021-02-04 01:09:29 +05:30
|
|
|
|
2022-05-17 11:52:00 +02:00
|
|
|
if r.currentIndex == 0 && hasPayloadIterator && !hasInitializedPayloads {
|
|
|
|
|
r.currentPayloads, r.okCurrentPayload = r.payloadIterator.Value()
|
|
|
|
|
}
|
|
|
|
|
if r.currentIndex < len(sequence) {
|
|
|
|
|
currentRequest := sequence[r.currentIndex]
|
|
|
|
|
r.currentIndex++
|
|
|
|
|
return currentRequest, r.currentPayloads, true
|
|
|
|
|
}
|
|
|
|
|
if r.currentIndex == len(sequence) {
|
|
|
|
|
if r.okCurrentPayload {
|
|
|
|
|
r.currentIndex = 0
|
|
|
|
|
currentRequest := sequence[r.currentIndex]
|
|
|
|
|
if hasPayloadIterator {
|
|
|
|
|
r.currentPayloads, r.okCurrentPayload = r.payloadIterator.Value()
|
|
|
|
|
if r.okCurrentPayload {
|
|
|
|
|
r.currentIndex++
|
|
|
|
|
return currentRequest, r.currentPayloads, true
|
2021-02-04 01:09:29 +05:30
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-05-17 11:52:00 +02:00
|
|
|
|
2021-02-04 01:09:29 +05:30
|
|
|
return "", nil, false
|
|
|
|
|
}
|