mirror of https://github.com/daffainfo/nuclei.git
More improvements, adding metadata for state between requests
parent
8bc59fafc4
commit
5a690ca616
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue