mirror of
https://github.com/projectdiscovery/nuclei.git
synced 2025-12-18 04:45:27 +00:00
fix(multiproto): missing previous InternalEvents output when ExecuteWithResults (#5967)
Signed-off-by: Dwi Siswanto <git@dw1.io>
This commit is contained in:
parent
a7f7616db9
commit
2450ecb503
@ -2,6 +2,7 @@ package multiproto
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/output"
|
||||
@ -9,6 +10,7 @@ import (
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/generators"
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/scan"
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/templates/types"
|
||||
mapsutil "github.com/projectdiscovery/utils/maps"
|
||||
stringsutil "github.com/projectdiscovery/utils/strings"
|
||||
)
|
||||
|
||||
@ -60,41 +62,7 @@ func (m *MultiProtocol) ExecuteWithResults(ctx *scan.ScanContext) error {
|
||||
m.options.GetTemplateCtx(ctx.Input.MetaInput).Set(key, value)
|
||||
})
|
||||
|
||||
// callback to process results from all protocols
|
||||
multiProtoCallback := func(event *output.InternalWrappedEvent) {
|
||||
if event == nil {
|
||||
return
|
||||
}
|
||||
// log event and generate result for the event
|
||||
ctx.LogEvent(event)
|
||||
// export dynamic values from operators (i.e internal:true)
|
||||
if event.OperatorsResult != nil && len(event.OperatorsResult.DynamicValues) > 0 {
|
||||
for k, v := range event.OperatorsResult.DynamicValues {
|
||||
// TBD: iterate-all is only supported in `http` protocol
|
||||
// we either need to add support for iterate-all in other protocols or implement a different logic (specific to template context)
|
||||
// currently if dynamic value array only contains one value we replace it with the value
|
||||
if len(v) == 1 {
|
||||
m.options.GetTemplateCtx(ctx.Input.MetaInput).Set(k, v[0])
|
||||
} else {
|
||||
// Note: if extracted value contains multiple values then they can be accessed by indexing
|
||||
// ex: if values are dynamic = []string{"a","b","c"} then they are available as
|
||||
// dynamic = "a" , dynamic1 = "b" , dynamic2 = "c"
|
||||
// we intentionally omit first index for unknown situations (where no of extracted values are not known)
|
||||
for i, val := range v {
|
||||
if i == 0 {
|
||||
m.options.GetTemplateCtx(ctx.Input.MetaInput).Set(k, val)
|
||||
} else {
|
||||
m.options.GetTemplateCtx(ctx.Input.MetaInput).Set(k+strconv.Itoa(i), val)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// evaluate all variables after execution of each protocol
|
||||
variableMap := m.options.Variables.Evaluate(m.options.GetTemplateCtx(ctx.Input.MetaInput).GetAll())
|
||||
m.options.GetTemplateCtx(ctx.Input.MetaInput).Merge(variableMap) // merge all variables into template context
|
||||
}
|
||||
previous := mapsutil.NewSyncLockMap[string, any]()
|
||||
|
||||
// template context: contains values extracted using `internal` extractor from previous protocols
|
||||
// these values are extracted from each protocol in queue and are passed to next protocol in queue
|
||||
@ -117,7 +85,53 @@ func (m *MultiProtocol) ExecuteWithResults(ctx *scan.ScanContext) error {
|
||||
}
|
||||
// FIXME: this hack of using hash to get templateCtx has known issues scan context based approach should be adopted ASAP
|
||||
values := m.options.GetTemplateCtx(inputItem.MetaInput).GetAll()
|
||||
err := req.ExecuteWithResults(inputItem, output.InternalEvent(values), nil, multiProtoCallback)
|
||||
err := req.ExecuteWithResults(inputItem, output.InternalEvent(values), output.InternalEvent(previous.GetAll()), func(event *output.InternalWrappedEvent) {
|
||||
if event == nil {
|
||||
return
|
||||
}
|
||||
|
||||
ID := req.GetID()
|
||||
if ID != "" {
|
||||
builder := &strings.Builder{}
|
||||
for k, v := range event.InternalEvent {
|
||||
builder.WriteString(ID)
|
||||
builder.WriteString("_")
|
||||
builder.WriteString(k)
|
||||
_ = previous.Set(builder.String(), v)
|
||||
builder.Reset()
|
||||
}
|
||||
}
|
||||
|
||||
// log event and generate result for the event
|
||||
ctx.LogEvent(event)
|
||||
// export dynamic values from operators (i.e internal:true)
|
||||
if event.OperatorsResult != nil && len(event.OperatorsResult.DynamicValues) > 0 {
|
||||
for k, v := range event.OperatorsResult.DynamicValues {
|
||||
// TBD: iterate-all is only supported in `http` protocol
|
||||
// we either need to add support for iterate-all in other protocols or implement a different logic (specific to template context)
|
||||
// currently if dynamic value array only contains one value we replace it with the value
|
||||
if len(v) == 1 {
|
||||
m.options.GetTemplateCtx(ctx.Input.MetaInput).Set(k, v[0])
|
||||
} else {
|
||||
// Note: if extracted value contains multiple values then they can be accessed by indexing
|
||||
// ex: if values are dynamic = []string{"a","b","c"} then they are available as
|
||||
// dynamic = "a" , dynamic1 = "b" , dynamic2 = "c"
|
||||
// we intentionally omit first index for unknown situations (where no of extracted values are not known)
|
||||
for i, val := range v {
|
||||
if i == 0 {
|
||||
m.options.GetTemplateCtx(ctx.Input.MetaInput).Set(k, val)
|
||||
} else {
|
||||
m.options.GetTemplateCtx(ctx.Input.MetaInput).Set(k+strconv.Itoa(i), val)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// evaluate all variables after execution of each protocol
|
||||
variableMap := m.options.Variables.Evaluate(m.options.GetTemplateCtx(ctx.Input.MetaInput).GetAll())
|
||||
m.options.GetTemplateCtx(ctx.Input.MetaInput).Merge(variableMap) // merge all variables into template context
|
||||
})
|
||||
// in case of fatal error skip execution of next protocols
|
||||
if err != nil {
|
||||
// always log errors
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user