From b4ba7ca144ccac53d5eea261d63a5584158331a5 Mon Sep 17 00:00:00 2001 From: Sajad Parra Date: Fri, 13 Aug 2021 19:40:10 +0530 Subject: [PATCH 1/2] add payload, helper function support to all http requests --- v2/pkg/protocols/http/build_request.go | 22 +++++++++++---- v2/pkg/protocols/http/request_generator.go | 33 +++++++++++++++++----- 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/v2/pkg/protocols/http/build_request.go b/v2/pkg/protocols/http/build_request.go index a0fa13a1..d30f9815 100644 --- a/v2/pkg/protocols/http/build_request.go +++ b/v2/pkg/protocols/http/build_request.go @@ -77,7 +77,7 @@ func (r *requestGenerator) Make(baseURL string, dynamicValues map[string]interfa if isRawRequest { return r.makeHTTPRequestFromRaw(ctx, parsedString, data, values, payloads, interactURL) } - return r.makeHTTPRequestFromModel(ctx, data, values, interactURL) + return r.makeHTTPRequestFromModel(ctx, data, values, payloads, interactURL) } // Total returns the total number of requests for the generator @@ -106,14 +106,24 @@ func baseURLWithTemplatePrefs(data string, parsed *url.URL) (string, *url.URL) { } // MakeHTTPRequestFromModel creates a *http.Request from a request template -func (r *requestGenerator) makeHTTPRequestFromModel(ctx context.Context, data string, values map[string]interface{}, interactURL string) (*generatedRequest, error) { - final := replacer.Replace(data, values) +func (r *requestGenerator) makeHTTPRequestFromModel(ctx context.Context, data string, values, generatorValues map[string]interface{}, interactURL string) (*generatedRequest, error) { if interactURL != "" { - final = r.options.Interactsh.ReplaceMarkers(final, interactURL) + data = r.options.Interactsh.ReplaceMarkers(data, interactURL) + } + + // Combine the template payloads along with base + // request values. + finalValues := generators.MergeMaps(generatorValues, values) + + // Evaulate the expressions for the request if any. + var err error + data, err = expressions.Evaluate(data, finalValues) + if err != nil { + return nil, errors.Wrap(err, "could not evaluate helper expressions") } // Build a request on the specified URL - req, err := http.NewRequestWithContext(ctx, r.request.Method, final, nil) + req, err := http.NewRequestWithContext(ctx, r.request.Method, data, nil) if err != nil { return nil, err } @@ -122,7 +132,7 @@ func (r *requestGenerator) makeHTTPRequestFromModel(ctx context.Context, data st if err != nil { return nil, err } - return &generatedRequest{request: request, original: r.request}, nil + return &generatedRequest{request: request, meta: generatorValues, original: r.request}, nil } // makeHTTPRequestFromRaw creates a *http.Request from a raw request diff --git a/v2/pkg/protocols/http/request_generator.go b/v2/pkg/protocols/http/request_generator.go index d474792b..23622592 100644 --- a/v2/pkg/protocols/http/request_generator.go +++ b/v2/pkg/protocols/http/request_generator.go @@ -31,20 +31,39 @@ func (r *Request) newGenerator() *requestGenerator { // 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. func (r *requestGenerator) nextValue() (value string, payloads map[string]interface{}, result bool) { - // If we have paths, return the next path. + // For both raw/path requests, start with the request at current index. + // If we are not at the start, then check if the iterator for payloads + // has finished if there are any. + // + // If the iterator has finished for the current request + // then reset it and move on to the next value, otherwise use the last request. + if len(r.request.Path) > 0 && r.currentIndex < len(r.request.Path) { + if r.payloadIterator != nil { + payload, ok := r.payloadIterator.Value() + if !ok { + r.currentIndex++ + r.payloadIterator.Reset() + + // No more payloads request for us now. + if len(r.request.Path) == r.currentIndex { + return "", nil, false + } + if item := r.request.Path[r.currentIndex]; item != "" { + newPayload, ok := r.payloadIterator.Value() + return item, newPayload, ok + } + return "", nil, false + } + return r.request.Path[r.currentIndex], payload, true + } if value := r.request.Path[r.currentIndex]; value != "" { r.currentIndex++ return value, nil, true } } - // If we have raw requests, start with the request at current index. - // If we are not at the start, then check if the iterator for payloads - // has finished if there are any. - // - // If the iterator has finished for the current raw request - // then reset it and move on to the next value, otherwise use the last request. + if len(r.request.Raw) > 0 && r.currentIndex < len(r.request.Raw) { if r.payloadIterator != nil { payload, ok := r.payloadIterator.Value() From cef6459b7ec63eef7b5ddc53c0dd977674978b20 Mon Sep 17 00:00:00 2001 From: Sajad Parra Date: Mon, 16 Aug 2021 00:14:47 +0530 Subject: [PATCH 2/2] add payload/heelper support for http headers, body, method --- v2/pkg/protocols/http/build_request.go | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/v2/pkg/protocols/http/build_request.go b/v2/pkg/protocols/http/build_request.go index d30f9815..f1a2eb46 100644 --- a/v2/pkg/protocols/http/build_request.go +++ b/v2/pkg/protocols/http/build_request.go @@ -15,7 +15,6 @@ import ( "github.com/pkg/errors" "github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/expressions" "github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/generators" - "github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/replacer" "github.com/projectdiscovery/nuclei/v2/pkg/protocols/http/race" "github.com/projectdiscovery/nuclei/v2/pkg/protocols/http/raw" "github.com/projectdiscovery/rawhttp" @@ -122,13 +121,18 @@ func (r *requestGenerator) makeHTTPRequestFromModel(ctx context.Context, data st return nil, errors.Wrap(err, "could not evaluate helper expressions") } + method, err := expressions.Evaluate(r.request.Method, finalValues) + if err != nil { + return nil, errors.Wrap(err, "could not evaluate helper expressions") + } + // Build a request on the specified URL - req, err := http.NewRequestWithContext(ctx, r.request.Method, data, nil) + req, err := http.NewRequestWithContext(ctx, method, data, nil) if err != nil { return nil, err } - request, err := r.fillRequest(req, values, interactURL) + request, err := r.fillRequest(req, finalValues, interactURL) if err != nil { return nil, err } @@ -188,7 +192,7 @@ func (r *requestGenerator) handleRawWithPayloads(ctx context.Context, rawRequest req.Host = value } } - request, err := r.fillRequest(req, values, "") + request, err := r.fillRequest(req, finalValues, "") if err != nil { return nil, err } @@ -203,9 +207,13 @@ func (r *requestGenerator) fillRequest(req *http.Request, values map[string]inte if interactURL != "" { value = r.options.Interactsh.ReplaceMarkers(value, interactURL) } - req.Header[header] = []string{replacer.Replace(value, values)} + value, err := expressions.Evaluate(value, values) + if err != nil { + return nil, errors.Wrap(err, "could not evaluate helper expressions") + } + req.Header[header] = []string{value} if header == "Host" { - req.Host = replacer.Replace(value, values) + req.Host = value } } @@ -220,6 +228,10 @@ func (r *requestGenerator) fillRequest(req *http.Request, values map[string]inte if interactURL != "" { body = r.options.Interactsh.ReplaceMarkers(body, interactURL) } + body, err := expressions.Evaluate(body, values) + if err != nil { + return nil, errors.Wrap(err, "could not evaluate helper expressions") + } req.Body = ioutil.NopCloser(strings.NewReader(body)) } setHeader(req, "User-Agent", uarand.GetRandom())