Inform user and no output file in case of 0 results

dev
Ice3man543 2020-06-22 19:57:32 +05:30
parent 30c93b97d7
commit 6acf0d4cf6
3 changed files with 91 additions and 11 deletions

View File

@ -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
}

View File

@ -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)
}
}

View File

@ -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
}