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
|
options *protocols.ExecuterOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ protocols.Executer = &Executer{}
|
||||||
|
|
||||||
// NewExecuter creates a new request executer for list of requests
|
// NewExecuter creates a new request executer for list of requests
|
||||||
func NewExecuter(requests []*Request, options *protocols.ExecuterOptions) *Executer {
|
func NewExecuter(requests []*Request, options *protocols.ExecuterOptions) *Executer {
|
||||||
return &Executer{requests: requests, options: options}
|
return &Executer{requests: requests, options: options}
|
||||||
|
@ -40,21 +42,23 @@ func (e *Executer) Execute(input string) (bool, error) {
|
||||||
var results bool
|
var results bool
|
||||||
|
|
||||||
for _, req := range e.requests {
|
for _, req := range e.requests {
|
||||||
events, err := req.ExecuteWithResults(input)
|
events, err := req.ExecuteWithResults(input, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have a result field, we should add a result to slice.
|
// If we have a result field, we should add a result to slice.
|
||||||
for _, event := range events {
|
for _, event := range events {
|
||||||
if event.OperatorsResult != nil {
|
if event.OperatorsResult == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
for _, result := range req.makeResultEvent(event) {
|
for _, result := range req.makeResultEvent(event) {
|
||||||
results = true
|
results = true
|
||||||
e.options.Output.Write(result)
|
e.options.Output.Write(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return results, nil
|
return results, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,14 +67,15 @@ func (e *Executer) ExecuteWithResults(input string) ([]*output.ResultEvent, erro
|
||||||
var results []*output.ResultEvent
|
var results []*output.ResultEvent
|
||||||
|
|
||||||
for _, req := range e.requests {
|
for _, req := range e.requests {
|
||||||
events, err := req.ExecuteWithResults(input)
|
events, err := req.ExecuteWithResults(input, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for _, event := range events {
|
for _, event := range events {
|
||||||
if event.OperatorsResult != nil {
|
if event.OperatorsResult == nil {
|
||||||
results = append(results, req.makeResultEvent(event)...)
|
continue
|
||||||
}
|
}
|
||||||
|
results = append(results, req.makeResultEvent(event)...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return results, nil
|
return results, nil
|
||||||
|
|
|
@ -78,35 +78,6 @@ func (r *Request) Extract(data map[string]interface{}, extractor *extractors.Ext
|
||||||
return nil
|
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
|
// responseToDSLMap converts a DNS response to a map for use in DSL matching
|
||||||
func responseToDSLMap(req, resp *dns.Msg, host, matched string) output.InternalEvent {
|
func responseToDSLMap(req, resp *dns.Msg, host, matched string) output.InternalEvent {
|
||||||
data := make(output.InternalEvent, 8)
|
data := make(output.InternalEvent, 8)
|
||||||
|
@ -146,3 +117,32 @@ func responseToDSLMap(req, resp *dns.Msg, host, matched string) output.InternalE
|
||||||
data["raw"] = rawData
|
data["raw"] = rawData
|
||||||
return data
|
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/pkg/errors"
|
||||||
"github.com/projectdiscovery/gologger"
|
"github.com/projectdiscovery/gologger"
|
||||||
"github.com/projectdiscovery/nuclei/v2/pkg/output"
|
"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.
|
// 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.
|
// Parse the URL and return domain if URL.
|
||||||
var domain string
|
var domain string
|
||||||
if isURL(input) {
|
if isURL(input) {
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
// Executer is an interface implemented any protocol based request executer.
|
// Executer is an interface implemented any protocol based request executer.
|
||||||
type Executer interface {
|
type Executer interface {
|
||||||
// Compile compiles the execution generators preparing any requests possible.
|
// 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 returns the total number of requests the rule will perform
|
||||||
Requests() int64
|
Requests() int64
|
||||||
// Execute executes the protocol group and returns true or false if results were found.
|
// 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.
|
// Request is an interface implemented any protocol based request generator.
|
||||||
type Request interface {
|
type Request interface {
|
||||||
// Compile compiles the request generators preparing any requests possible.
|
// 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 returns the total number of requests the rule will perform
|
||||||
Requests() int64
|
Requests() int64
|
||||||
// Match performs matching operation for a matcher on model and returns true or false.
|
// 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 performs extracting operation for a extractor on model and returns true or false.
|
||||||
Extract(data map[string]interface{}, matcher *extractors.Extractor) map[string]struct{}
|
Extract(data map[string]interface{}, matcher *extractors.Extractor) map[string]struct{}
|
||||||
// ExecuteWithResults executes the protocol requests and returns results instead of writing them.
|
// 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