mirror of https://github.com/daffainfo/nuclei.git
Inform user and no output file in case of 0 results
parent
30c93b97d7
commit
6acf0d4cf6
|
@ -77,13 +77,24 @@ func (r *Runner) RunEnumeration() {
|
|||
}
|
||||
|
||||
// process http requests
|
||||
var results bool
|
||||
for _, request := range template.RequestsHTTP {
|
||||
r.processTemplateRequest(template, request)
|
||||
results = r.processTemplateRequest(template, request)
|
||||
}
|
||||
|
||||
// process dns requests
|
||||
for _, request := range template.RequestsDNS {
|
||||
r.processTemplateRequest(template, request)
|
||||
dnsResults := r.processTemplateRequest(template, request)
|
||||
if !results {
|
||||
results = dnsResults
|
||||
}
|
||||
}
|
||||
if !results {
|
||||
if r.output != nil {
|
||||
outputFile := r.output.Name()
|
||||
r.output.Close()
|
||||
os.Remove(outputFile)
|
||||
}
|
||||
gologger.Infof("No results found for the template. Happy hacking!")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -95,6 +106,7 @@ func (r *Runner) RunEnumeration() {
|
|||
gologger.Fatalf("Could not evaluate template path '%s': %s\n", r.options.Templates, err)
|
||||
}
|
||||
|
||||
var results bool
|
||||
for _, match := range matches {
|
||||
template, err := templates.ParseTemplate(match)
|
||||
if err != nil {
|
||||
|
@ -102,12 +114,26 @@ func (r *Runner) RunEnumeration() {
|
|||
return
|
||||
}
|
||||
for _, request := range template.RequestsDNS {
|
||||
r.processTemplateRequest(template, request)
|
||||
dnsResults := r.processTemplateRequest(template, request)
|
||||
if dnsResults {
|
||||
results = dnsResults
|
||||
}
|
||||
}
|
||||
for _, request := range template.RequestsHTTP {
|
||||
r.processTemplateRequest(template, request)
|
||||
httpResults := r.processTemplateRequest(template, request)
|
||||
if httpResults {
|
||||
results = httpResults
|
||||
}
|
||||
}
|
||||
}
|
||||
if !results {
|
||||
if r.output != nil {
|
||||
outputFile := r.output.Name()
|
||||
r.output.Close()
|
||||
os.Remove(outputFile)
|
||||
}
|
||||
gologger.Infof("No results found for the templates. Happy hacking!")
|
||||
}
|
||||
return
|
||||
}
|
||||
// If the template passed is a directory
|
||||
|
@ -132,6 +158,7 @@ func (r *Runner) RunEnumeration() {
|
|||
if len(matches) == 0 {
|
||||
gologger.Fatalf("Error, no templates found in directory: '%s'\n", r.options.Templates)
|
||||
}
|
||||
var results bool
|
||||
for _, match := range matches {
|
||||
template, err := templates.ParseTemplate(match)
|
||||
if err != nil {
|
||||
|
@ -139,17 +166,31 @@ func (r *Runner) RunEnumeration() {
|
|||
return
|
||||
}
|
||||
for _, request := range template.RequestsDNS {
|
||||
r.processTemplateRequest(template, request)
|
||||
dnsResults := r.processTemplateRequest(template, request)
|
||||
if dnsResults {
|
||||
results = dnsResults
|
||||
}
|
||||
}
|
||||
for _, request := range template.RequestsHTTP {
|
||||
r.processTemplateRequest(template, request)
|
||||
httpResults := r.processTemplateRequest(template, request)
|
||||
if httpResults {
|
||||
results = httpResults
|
||||
}
|
||||
}
|
||||
}
|
||||
if !results {
|
||||
if r.output != nil {
|
||||
outputFile := r.output.Name()
|
||||
r.output.Close()
|
||||
os.Remove(outputFile)
|
||||
}
|
||||
gologger.Infof("No results found for the template. Happy hacking!")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// processTemplate processes a template and runs the enumeration on all the targets
|
||||
func (r *Runner) processTemplateRequest(template *templates.Template, request interface{}) {
|
||||
func (r *Runner) processTemplateRequest(template *templates.Template, request interface{}) bool {
|
||||
var file *os.File
|
||||
var err error
|
||||
|
||||
|
@ -162,12 +203,13 @@ func (r *Runner) processTemplateRequest(template *templates.Template, request in
|
|||
if err != nil {
|
||||
gologger.Fatalf("Could not open targets file '%s': %s\n", r.options.Targets, err)
|
||||
}
|
||||
r.processTemplateWithList(template, request, file)
|
||||
results := r.processTemplateWithList(template, request, file)
|
||||
file.Close()
|
||||
return results
|
||||
}
|
||||
|
||||
// processDomain processes the list with a template
|
||||
func (r *Runner) processTemplateWithList(template *templates.Template, request interface{}, reader io.Reader) {
|
||||
func (r *Runner) processTemplateWithList(template *templates.Template, request interface{}, reader io.Reader) bool {
|
||||
// Display the message for the template
|
||||
message := fmt.Sprintf("[%s] Loaded template %s (@%s)", template.ID, template.Info.Name, template.Info.Author)
|
||||
if template.Info.Severity != "" {
|
||||
|
@ -209,7 +251,7 @@ func (r *Runner) processTemplateWithList(template *templates.Template, request i
|
|||
}
|
||||
if err != nil {
|
||||
gologger.Warningf("Could not create http client: %s\n", err)
|
||||
return
|
||||
return false
|
||||
}
|
||||
|
||||
limiter := make(chan struct{}, r.options.Threads)
|
||||
|
@ -242,4 +284,16 @@ func (r *Runner) processTemplateWithList(template *templates.Template, request i
|
|||
}
|
||||
close(limiter)
|
||||
wg.Wait()
|
||||
|
||||
// See if we got any results from the executors
|
||||
var results bool
|
||||
if httpExecutor != nil {
|
||||
results = httpExecutor.GotResults()
|
||||
}
|
||||
if dnsExecutor != nil {
|
||||
if !results {
|
||||
results = dnsExecutor.GotResults()
|
||||
}
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
@ -28,6 +29,7 @@ import (
|
|||
// for a template.
|
||||
type HTTPExecutor struct {
|
||||
debug bool
|
||||
results uint32
|
||||
httpClient *retryablehttp.Client
|
||||
template *templates.Template
|
||||
httpRequest *requests.HTTPRequest
|
||||
|
@ -68,6 +70,7 @@ func NewHTTPExecutor(options *HTTPOptions) (*HTTPExecutor, error) {
|
|||
|
||||
executer := &HTTPExecutor{
|
||||
debug: options.Debug,
|
||||
results: 0,
|
||||
httpClient: client,
|
||||
template: options.Template,
|
||||
httpRequest: options.HTTPRequest,
|
||||
|
@ -78,6 +81,14 @@ func NewHTTPExecutor(options *HTTPOptions) (*HTTPExecutor, error) {
|
|||
return executer, nil
|
||||
}
|
||||
|
||||
// GotResults returns true if there were any results for the executor
|
||||
func (e *HTTPExecutor) GotResults() bool {
|
||||
if atomic.LoadUint32(&e.results) == 0 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// ExecuteHTTP executes the HTTP request on a URL
|
||||
func (e *HTTPExecutor) ExecuteHTTP(URL string) error {
|
||||
// Compile each request for the template based on the URL
|
||||
|
@ -159,6 +170,7 @@ mainLoop:
|
|||
// write the first output then move to next matcher.
|
||||
if matcherCondition == matchers.ORCondition && len(e.httpRequest.Extractors) == 0 {
|
||||
e.writeOutputHTTP(compiledRequest, matcher, nil)
|
||||
atomic.CompareAndSwapUint32(&e.results, 0, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -180,6 +192,7 @@ mainLoop:
|
|||
// AND or if we have extractors for the mechanism too.
|
||||
if len(e.httpRequest.Extractors) > 0 || matcherCondition == matchers.ANDCondition {
|
||||
e.writeOutputHTTP(compiledRequest, nil, extractorResults)
|
||||
atomic.CompareAndSwapUint32(&e.results, 0, 1)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/projectdiscovery/gologger"
|
||||
|
@ -18,6 +19,7 @@ import (
|
|||
// for a template.
|
||||
type DNSExecutor struct {
|
||||
debug bool
|
||||
results uint32
|
||||
dnsClient *retryabledns.Client
|
||||
template *templates.Template
|
||||
dnsRequest *requests.DNSRequest
|
||||
|
@ -48,6 +50,7 @@ func NewDNSExecutor(options *DNSOptions) *DNSExecutor {
|
|||
|
||||
executer := &DNSExecutor{
|
||||
debug: options.Debug,
|
||||
results: 0,
|
||||
dnsClient: dnsClient,
|
||||
template: options.Template,
|
||||
dnsRequest: options.DNSRequest,
|
||||
|
@ -57,6 +60,14 @@ func NewDNSExecutor(options *DNSOptions) *DNSExecutor {
|
|||
return executer
|
||||
}
|
||||
|
||||
// GotResults returns true if there were any results for the executor
|
||||
func (e *DNSExecutor) GotResults() bool {
|
||||
if atomic.LoadUint32(&e.results) == 0 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// ExecuteDNS executes the DNS request on a URL
|
||||
func (e *DNSExecutor) ExecuteDNS(URL string) error {
|
||||
// Parse the URL and return domain if URL.
|
||||
|
@ -104,6 +115,7 @@ func (e *DNSExecutor) ExecuteDNS(URL string) error {
|
|||
// write the first output then move to next matcher.
|
||||
if matcherCondition == matchers.ORCondition && len(e.dnsRequest.Extractors) == 0 {
|
||||
e.writeOutputDNS(domain, matcher, nil)
|
||||
atomic.CompareAndSwapUint32(&e.results, 0, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -121,6 +133,7 @@ func (e *DNSExecutor) ExecuteDNS(URL string) error {
|
|||
// AND or if we have extractors for the mechanism too.
|
||||
if len(e.dnsRequest.Extractors) > 0 || matcherCondition == matchers.ANDCondition {
|
||||
e.writeOutputDNS(domain, nil, extractorResults)
|
||||
atomic.CompareAndSwapUint32(&e.results, 0, 1)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue