From 74dee426ed2f5c00c1d06003f05ee481aa96082f Mon Sep 17 00:00:00 2001 From: Tarun Koyalwar <45962551+tarunKoyalwar@users.noreply.github.com> Date: Tue, 9 Apr 2024 00:58:35 +0530 Subject: [PATCH] fuzz: fix missing expression evaluation before use (#5019) --- pkg/fuzz/execute.go | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/pkg/fuzz/execute.go b/pkg/fuzz/execute.go index 6e1a7a6a..c8054bf8 100644 --- a/pkg/fuzz/execute.go +++ b/pkg/fuzz/execute.go @@ -11,6 +11,7 @@ import ( "github.com/projectdiscovery/nuclei/v3/pkg/fuzz/component" "github.com/projectdiscovery/nuclei/v3/pkg/protocols" "github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/contextargs" + "github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/expressions" "github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/generators" "github.com/projectdiscovery/retryablehttp-go" errorutil "github.com/projectdiscovery/utils/errors" @@ -100,8 +101,11 @@ func (rule *Rule) Execute(input *ExecuteRuleInput) (err error) { baseValues := input.Values if rule.generator == nil { for _, component := range finalComponentList { + // get vars from variables while replacing interactsh urls evaluatedValues, interactURLs := rule.options.Variables.EvaluateWithInteractsh(baseValues, rule.options.Interactsh) - input.Values = generators.MergeMaps(evaluatedValues, baseValues, rule.options.Constants) + input.Values = generators.MergeMaps(evaluatedValues, baseValues, rule.options.Options.Vars.AsMap(), rule.options.Constants) + // evaluate all vars with interactsh + input.Values, interactURLs = rule.evaluateVarsWithInteractsh(input.Values, interactURLs) input.InteractURLs = interactURLs err := rule.executeRuleValues(input, component) if err != nil { @@ -118,9 +122,12 @@ mainLoop: if !next { continue mainLoop } + // get vars from variables while replacing interactsh urls evaluatedValues, interactURLs := rule.options.Variables.EvaluateWithInteractsh(generators.MergeMaps(values, baseValues), rule.options.Interactsh) + input.Values = generators.MergeMaps(values, evaluatedValues, baseValues, rule.options.Options.Vars.AsMap(), rule.options.Constants) + // evaluate all vars with interactsh + input.Values, interactURLs = rule.evaluateVarsWithInteractsh(input.Values, interactURLs) input.InteractURLs = interactURLs - input.Values = generators.MergeMaps(values, evaluatedValues, baseValues, rule.options.Constants) if err := rule.executeRuleValues(input, component); err != nil { if err == io.EOF { @@ -134,6 +141,33 @@ mainLoop: return nil } +// evaluateVarsWithInteractsh evaluates the variables with Interactsh URLs and updates them accordingly. +func (rule *Rule) evaluateVarsWithInteractsh(data map[string]interface{}, interactshUrls []string) (map[string]interface{}, []string) { + // Check if Interactsh options are configured + if rule.options.Interactsh != nil { + // Iterate through the data to replace and evaluate variables with Interactsh URLs + for k, v := range data { + // Replace variables with Interactsh URLs and collect new URLs + got, oastUrls := rule.options.Interactsh.Replace(fmt.Sprint(v), interactshUrls) + + // Append new OAST URLs if any + if len(oastUrls) > 0 { + interactshUrls = append(interactshUrls, oastUrls...) + } + // Evaluate the replaced data + evaluatedData, err := expressions.Evaluate(got, data) + if err == nil { + // Update the data if there is a change after evaluation + if evaluatedData != got { + data[k] = evaluatedData + } + } + } + } + // Return the updated data and Interactsh URLs without any error + return data, interactshUrls +} + // isInputURLValid returns true if url is valid after parsing it func (rule *Rule) isInputURLValid(input *contextargs.Context) bool { if input == nil || input.MetaInput == nil || input.MetaInput.Input == "" {