mirror of
https://github.com/projectdiscovery/nuclei.git
synced 2025-12-17 22:35:27 +00:00
code: fix variables merge order (#4623)
* fix variables merge order * format screen: quote and trim extracted result * code: interpret env vars in debug mode * update integration test
This commit is contained in:
parent
70452efec1
commit
a8cdd21120
@ -113,7 +113,7 @@ func (h *headlessExtractValues) Execute(filePath string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return expectResultsCount(results, 3)
|
return expectResultsCount(results, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
type headlessPayloads struct{}
|
type headlessPayloads struct{}
|
||||||
|
|||||||
@ -368,6 +368,7 @@ func (h *httpDSLFunctions) Execute(filePath string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, header := range extracted {
|
for _, header := range extracted {
|
||||||
|
header = strings.Trim(header, `"`)
|
||||||
parts := strings.Split(header, ": ")
|
parts := strings.Split(header, ": ")
|
||||||
index, err := strconv.Atoi(parts[0])
|
index, err := strconv.Atoi(parts[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package output
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/projectdiscovery/nuclei/v3/pkg/types"
|
"github.com/projectdiscovery/nuclei/v3/pkg/types"
|
||||||
mapsutil "github.com/projectdiscovery/utils/maps"
|
mapsutil "github.com/projectdiscovery/utils/maps"
|
||||||
@ -57,6 +58,9 @@ func (w *StandardWriter) formatScreen(output *ResultEvent) []byte {
|
|||||||
builder.WriteString(" [")
|
builder.WriteString(" [")
|
||||||
|
|
||||||
for i, item := range output.ExtractedResults {
|
for i, item := range output.ExtractedResults {
|
||||||
|
// trim trailing space
|
||||||
|
item = strings.TrimSpace(item)
|
||||||
|
item = strconv.QuoteToASCII(item)
|
||||||
builder.WriteString(w.aurora.BrightCyan(item).String())
|
builder.WriteString(w.aurora.BrightCyan(item).String())
|
||||||
|
|
||||||
if i != len(output.ExtractedResults)-1 {
|
if i != len(output.ExtractedResults)-1 {
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package code
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -28,6 +29,14 @@ import (
|
|||||||
errorutil "github.com/projectdiscovery/utils/errors"
|
errorutil "github.com/projectdiscovery/utils/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
pythonEnvRegex = `os\.getenv\(['"]([^'"]+)['"]\)`
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
pythonEnvRegexCompiled = regexp.MustCompile(pythonEnvRegex)
|
||||||
|
)
|
||||||
|
|
||||||
// Request is a request for the SSL protocol
|
// Request is a request for the SSL protocol
|
||||||
type Request struct {
|
type Request struct {
|
||||||
// Operators for the current request go here.
|
// Operators for the current request go here.
|
||||||
@ -125,17 +134,20 @@ func (request *Request) ExecuteWithResults(input *contextargs.Context, dynamicVa
|
|||||||
|
|
||||||
var interactshURLs []string
|
var interactshURLs []string
|
||||||
|
|
||||||
// inject all template context values as gozero env variables
|
// inject all template context values as gozero env allvars
|
||||||
variables := protocolutils.GenerateVariables(input.MetaInput.Input, false, nil)
|
allvars := protocolutils.GenerateVariables(input.MetaInput.Input, false, nil)
|
||||||
// add template context values
|
// 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 are vars passed from CLI or env variables
|
||||||
optionVars := generators.BuildPayloadFromOptions(request.options.Options)
|
optionVars := generators.BuildPayloadFromOptions(request.options.Options)
|
||||||
variablesMap := request.options.Variables.Evaluate(variables)
|
variablesMap := request.options.Variables.Evaluate(allvars)
|
||||||
variables = generators.MergeMaps(variablesMap, variables, optionVars, request.options.Constants)
|
// since we evaluate variables using allvars, give precedence to variablesMap
|
||||||
for name, value := range variables {
|
allvars = generators.MergeMaps(allvars, variablesMap, optionVars, request.options.Constants)
|
||||||
|
for name, value := range allvars {
|
||||||
v := fmt.Sprint(value)
|
v := fmt.Sprint(value)
|
||||||
v, interactshURLs = request.options.Interactsh.Replace(v, interactshURLs)
|
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})
|
metaSrc.AddVariable(gozerotypes.Variable{Name: name, Value: v})
|
||||||
}
|
}
|
||||||
gOutput, err := request.gozero.Eval(context.Background(), request.src, metaSrc)
|
gOutput, err := request.gozero.Eval(context.Background(), request.src, metaSrc)
|
||||||
@ -145,11 +157,11 @@ func (request *Request) ExecuteWithResults(input *contextargs.Context, dynamicVa
|
|||||||
gologger.Verbose().Msgf("[%s] Executed code on local machine %v", request.options.TemplateID, input.MetaInput.Input)
|
gologger.Verbose().Msgf("[%s] Executed code on local machine %v", request.options.TemplateID, input.MetaInput.Input)
|
||||||
|
|
||||||
if vardump.EnableVarDump {
|
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 {
|
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())
|
dataOutputString := fmtStdout(gOutput.Stdout.String())
|
||||||
@ -272,3 +284,24 @@ func (request *Request) MakeResultEventItem(wrapped *output.InternalWrappedEvent
|
|||||||
func fmtStdout(data string) string {
|
func fmtStdout(data string) string {
|
||||||
return strings.Trim(data, " \n\r\t")
|
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
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user