From 8b722ca6fb24e9a8462c1729931416dee8b58cdc Mon Sep 17 00:00:00 2001 From: Tarun Koyalwar Date: Fri, 12 Jan 2024 01:31:41 +0530 Subject: [PATCH 1/4] fix variables merge order --- pkg/protocols/code/code.go | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/pkg/protocols/code/code.go b/pkg/protocols/code/code.go index 58526a0fb5..d33c1e5dc8 100644 --- a/pkg/protocols/code/code.go +++ b/pkg/protocols/code/code.go @@ -125,15 +125,16 @@ func (request *Request) ExecuteWithResults(input *contextargs.Context, dynamicVa var interactshURLs []string - // inject all template context values as gozero env variables - variables := protocolutils.GenerateVariables(input.MetaInput.Input, false, nil) + // inject all template context values as gozero env allvars + allvars := protocolutils.GenerateVariables(input.MetaInput.Input, false, nil) // add template context values - variables = generators.MergeMaps(variables, request.options.GetTemplateCtx(input.MetaInput).GetAll()) + allvars = generators.MergeMaps(allvars, request.options.GetTemplateCtx(input.MetaInput).GetAll()) // optionvars are vars passed from CLI or env variables optionVars := generators.BuildPayloadFromOptions(request.options.Options) - variablesMap := request.options.Variables.Evaluate(variables) - variables = generators.MergeMaps(variablesMap, variables, optionVars, request.options.Constants) - for name, value := range variables { + variablesMap := request.options.Variables.Evaluate(allvars) + // since we evaluate variables using allvars, give precedence to variablesMap + allvars = generators.MergeMaps(allvars, variablesMap, optionVars, request.options.Constants) + for name, value := range allvars { v := fmt.Sprint(value) v, interactshURLs = request.options.Interactsh.Replace(v, interactshURLs) metaSrc.AddVariable(gozerotypes.Variable{Name: name, Value: v}) @@ -145,7 +146,7 @@ func (request *Request) ExecuteWithResults(input *contextargs.Context, dynamicVa gologger.Verbose().Msgf("[%s] Executed code on local machine %v", request.options.TemplateID, input.MetaInput.Input) if vardump.EnableVarDump { - gologger.Debug().Msgf("Code Protocol request variables: \n%s\n", vardump.DumpVariables(variables)) + gologger.Debug().Msgf("Code Protocol request variables: \n%s\n", vardump.DumpVariables(allvars)) } if request.options.Options.Debug || request.options.Options.DebugRequests { From c763604668fb71f310eac228f448d7c8b6db9993 Mon Sep 17 00:00:00 2001 From: Tarun Koyalwar Date: Fri, 12 Jan 2024 01:38:17 +0530 Subject: [PATCH 2/4] format screen: quote and trim extracted result --- pkg/output/format_screen.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/output/format_screen.go b/pkg/output/format_screen.go index a02ba574ae..e902f942d1 100644 --- a/pkg/output/format_screen.go +++ b/pkg/output/format_screen.go @@ -3,6 +3,7 @@ package output import ( "bytes" "strconv" + "strings" "github.com/projectdiscovery/nuclei/v3/pkg/types" mapsutil "github.com/projectdiscovery/utils/maps" @@ -57,6 +58,9 @@ func (w *StandardWriter) formatScreen(output *ResultEvent) []byte { builder.WriteString(" [") for i, item := range output.ExtractedResults { + // trim trailing space + item = strings.TrimSpace(item) + item = strconv.QuoteToASCII(item) builder.WriteString(w.aurora.BrightCyan(item).String()) if i != len(output.ExtractedResults)-1 { From c31d57e6b531df4e2bc56cdcb28fd3ab4d037739 Mon Sep 17 00:00:00 2001 From: Tarun Koyalwar Date: Fri, 12 Jan 2024 01:57:44 +0530 Subject: [PATCH 3/4] code: interpret env vars in debug mode --- pkg/protocols/code/code.go | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/pkg/protocols/code/code.go b/pkg/protocols/code/code.go index d33c1e5dc8..e1d5483176 100644 --- a/pkg/protocols/code/code.go +++ b/pkg/protocols/code/code.go @@ -3,6 +3,7 @@ package code import ( "context" "fmt" + "regexp" "strings" "time" @@ -28,6 +29,14 @@ import ( errorutil "github.com/projectdiscovery/utils/errors" ) +const ( + pythonEnvRegex = `os\.getenv\(['"]([^'"]+)['"]\)` +) + +var ( + pythonEnvRegexCompiled = regexp.MustCompile(pythonEnvRegex) +) + // Request is a request for the SSL protocol type Request struct { // Operators for the current request go here. @@ -137,6 +146,8 @@ func (request *Request) ExecuteWithResults(input *contextargs.Context, dynamicVa for name, value := range allvars { v := fmt.Sprint(value) v, interactshURLs = request.options.Interactsh.Replace(v, interactshURLs) + // if value is updated by interactsh, update allvars to reflect the change downstream + allvars[name] = v metaSrc.AddVariable(gozerotypes.Variable{Name: name, Value: v}) } gOutput, err := request.gozero.Eval(context.Background(), request.src, metaSrc) @@ -150,7 +161,7 @@ func (request *Request) ExecuteWithResults(input *contextargs.Context, dynamicVa } if request.options.Options.Debug || request.options.Options.DebugRequests { - gologger.Debug().Msgf("[%s] Dumped Executed Source Code for %v\n\n%v\n", request.options.TemplateID, input.MetaInput.Input, request.Source) + gologger.Debug().Msgf("[%s] Dumped Executed Source Code for %v\n\n%v\n", request.options.TemplateID, input.MetaInput.Input, interpretEnvVars(request.Source, allvars)) } dataOutputString := fmtStdout(gOutput.Stdout.String()) @@ -273,3 +284,24 @@ func (request *Request) MakeResultEventItem(wrapped *output.InternalWrappedEvent func fmtStdout(data string) string { return strings.Trim(data, " \n\r\t") } + +// interpretEnvVars replaces environment variables in the input string +func interpretEnvVars(source string, vars map[string]interface{}) string { + // bash mode + if strings.Contains(source, "$") { + for k, v := range vars { + source = strings.ReplaceAll(source, "$"+k, fmt.Sprintf("'%s'", v)) + } + } + // python mode + if strings.Contains(source, "os.getenv") { + matches := pythonEnvRegexCompiled.FindAllStringSubmatch(source, -1) + for _, match := range matches { + if len(match) == 0 { + continue + } + source = strings.ReplaceAll(source, fmt.Sprintf("os.getenv('%s')", match), fmt.Sprintf("'%s'", vars[match[0]])) + } + } + return source +} From cafcd587555780b96be59d1a10335e45f92f2551 Mon Sep 17 00:00:00 2001 From: Tarun Koyalwar Date: Fri, 12 Jan 2024 02:04:18 +0530 Subject: [PATCH 4/4] update integration test --- cmd/integration-test/headless.go | 2 +- cmd/integration-test/http.go | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/integration-test/headless.go b/cmd/integration-test/headless.go index 1f24d262ef..627dac16a5 100644 --- a/cmd/integration-test/headless.go +++ b/cmd/integration-test/headless.go @@ -113,7 +113,7 @@ func (h *headlessExtractValues) Execute(filePath string) error { return err } - return expectResultsCount(results, 3) + return expectResultsCount(results, 1) } type headlessPayloads struct{} diff --git a/cmd/integration-test/http.go b/cmd/integration-test/http.go index 6b81d9a3b1..e1fddc04ad 100644 --- a/cmd/integration-test/http.go +++ b/cmd/integration-test/http.go @@ -368,6 +368,7 @@ func (h *httpDSLFunctions) Execute(filePath string) error { } for _, header := range extracted { + header = strings.Trim(header, `"`) parts := strings.Split(header, ": ") index, err := strconv.Atoi(parts[0]) if err != nil {