More improvements, adding metadata for state between requests

dev
Ice3man543 2020-12-25 20:39:09 +05:30
parent 8bc59fafc4
commit 5a690ca616
4 changed files with 50 additions and 42 deletions

View File

@ -11,6 +11,8 @@ type Executer struct {
options *protocols.ExecuterOptions
}
var _ protocols.Executer = &Executer{}
// NewExecuter creates a new request executer for list of requests
func NewExecuter(requests []*Request, options *protocols.ExecuterOptions) *Executer {
return &Executer{requests: requests, options: options}
@ -40,21 +42,23 @@ func (e *Executer) Execute(input string) (bool, error) {
var results bool
for _, req := range e.requests {
events, err := req.ExecuteWithResults(input)
events, err := req.ExecuteWithResults(input, nil)
if err != nil {
return false, err
}
// If we have a result field, we should add a result to slice.
for _, event := range events {
if event.OperatorsResult != nil {
if event.OperatorsResult == nil {
continue
}
for _, result := range req.makeResultEvent(event) {
results = true
e.options.Output.Write(result)
}
}
}
}
return results, nil
}
@ -63,14 +67,15 @@ func (e *Executer) ExecuteWithResults(input string) ([]*output.ResultEvent, erro
var results []*output.ResultEvent
for _, req := range e.requests {
events, err := req.ExecuteWithResults(input)
events, err := req.ExecuteWithResults(input, nil)
if err != nil {
return nil, err
}
for _, event := range events {
if event.OperatorsResult != nil {
results = append(results, req.makeResultEvent(event)...)
if event.OperatorsResult == nil {
continue
}
results = append(results, req.makeResultEvent(event)...)
}
}
return results, nil

View File

@ -78,35 +78,6 @@ func (r *Request) Extract(data map[string]interface{}, extractor *extractors.Ext
return nil
}
// makeResultEvent creates a result event from internal wrapped event
func (r *Request) makeResultEvent(wrapped *output.InternalWrappedEvent) []*output.ResultEvent {
results := make([]*output.ResultEvent, len(wrapped.OperatorsResult.Matches)+1)
data := output.ResultEvent{
TemplateID: r.options.TemplateID,
Info: r.options.TemplateInfo,
Type: "dns",
Host: wrapped.InternalEvent["host"].(string),
Matched: wrapped.InternalEvent["matched"].(string),
ExtractedResults: wrapped.OperatorsResult.OutputExtracts,
}
if r.options.Options.JSONRequests {
data.Request = wrapped.InternalEvent["request"].(string)
data.Response = wrapped.InternalEvent["raw"].(string)
}
// If we have multiple matchers with names, write each of them separately.
if len(wrapped.OperatorsResult.Matches) > 0 {
for k := range wrapped.OperatorsResult.Matches {
data.MatcherName = k
results = append(results, &data)
}
} else {
results = append(results, &data)
}
return results
}
// responseToDSLMap converts a DNS response to a map for use in DSL matching
func responseToDSLMap(req, resp *dns.Msg, host, matched string) output.InternalEvent {
data := make(output.InternalEvent, 8)
@ -146,3 +117,32 @@ func responseToDSLMap(req, resp *dns.Msg, host, matched string) output.InternalE
data["raw"] = rawData
return data
}
// makeResultEvent creates a result event from internal wrapped event
func (r *Request) makeResultEvent(wrapped *output.InternalWrappedEvent) []*output.ResultEvent {
results := make([]*output.ResultEvent, len(wrapped.OperatorsResult.Matches)+1)
data := output.ResultEvent{
TemplateID: r.options.TemplateID,
Info: r.options.TemplateInfo,
Type: "dns",
Host: wrapped.InternalEvent["host"].(string),
Matched: wrapped.InternalEvent["matched"].(string),
ExtractedResults: wrapped.OperatorsResult.OutputExtracts,
}
if r.options.Options.JSONRequests {
data.Request = wrapped.InternalEvent["request"].(string)
data.Response = wrapped.InternalEvent["raw"].(string)
}
// If we have multiple matchers with names, write each of them separately.
if len(wrapped.OperatorsResult.Matches) > 0 {
for k := range wrapped.OperatorsResult.Matches {
data.MatcherName = k
results = append(results, &data)
}
} else {
results = append(results, &data)
}
return results
}

View File

@ -8,10 +8,13 @@ import (
"github.com/pkg/errors"
"github.com/projectdiscovery/gologger"
"github.com/projectdiscovery/nuclei/v2/pkg/output"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols"
)
var _ protocols.Request = &Request{}
// ExecuteWithResults executes the protocol requests and returns results instead of writing them.
func (r *Request) ExecuteWithResults(input string) ([]*output.InternalWrappedEvent, error) {
func (r *Request) ExecuteWithResults(input string, metadata output.InternalEvent) ([]*output.InternalWrappedEvent, error) {
// Parse the URL and return domain if URL.
var domain string
if isURL(input) {

View File

@ -12,7 +12,7 @@ import (
// Executer is an interface implemented any protocol based request executer.
type Executer interface {
// Compile compiles the execution generators preparing any requests possible.
Compile(options ExecuterOptions) error
Compile() error
// Requests returns the total number of requests the rule will perform
Requests() int64
// Execute executes the protocol group and returns true or false if results were found.
@ -40,7 +40,7 @@ type ExecuterOptions struct {
// Request is an interface implemented any protocol based request generator.
type Request interface {
// Compile compiles the request generators preparing any requests possible.
Compile(options ExecuterOptions) error
Compile(options *ExecuterOptions) error
// Requests returns the total number of requests the rule will perform
Requests() int64
// Match performs matching operation for a matcher on model and returns true or false.
@ -48,5 +48,5 @@ type Request interface {
// Extract performs extracting operation for a extractor on model and returns true or false.
Extract(data map[string]interface{}, matcher *extractors.Extractor) map[string]struct{}
// ExecuteWithResults executes the protocol requests and returns results instead of writing them.
ExecuteWithResults(input string) ([]*output.InternalWrappedEvent, error)
ExecuteWithResults(input string, metadata output.InternalEvent) ([]*output.InternalWrappedEvent, error)
}