merged master

This commit is contained in:
Mzack9999 2020-07-20 00:47:04 +02:00
commit c2433fdb34
3 changed files with 106 additions and 67 deletions

View File

@ -12,7 +12,7 @@ import (
// the template requesting process.
type Options struct {
Debug bool // Debug mode allows debugging request/responses for the engine
Templates string // Signature specifies the template/templates to use
Templates multiStringFlag // Signature specifies the template/templates to use
Target string // Target is a single URL/Domain to scan usng a template
Targets string // Targets specifies the targets to scan using templates.
Threads int // Thread controls the number of concurrent requests to make.
@ -33,12 +33,23 @@ type Options struct {
Stdin bool // Stdin specifies whether stdin input was given to the process
}
type multiStringFlag []string
func (m *multiStringFlag) String() string {
return ""
}
func (m *multiStringFlag) Set(value string) error {
*m = append(*m, value)
return nil
}
// ParseOptions parses the command line flags provided by a user
func ParseOptions() *Options {
options := &Options{}
flag.StringVar(&options.Target, "target", "", "Target is a single target to scan using template")
flag.StringVar(&options.Templates, "t", "", "Template input file/files to run on host")
flag.Var(&options.Templates, "t","Template input file/files to run on host. Can be used multiple times.")
flag.StringVar(&options.Targets, "l", "", "List of URLs to run templates on")
flag.StringVar(&options.Output, "o", "", "File to write output to (optional)")
flag.StringVar(&options.ProxyURL, "proxy-url", "", "URL of the proxy server")

View File

@ -44,7 +44,7 @@ func New(options *Options) (*Runner, error) {
if err := runner.updateTemplates(); err != nil {
gologger.Warningf("Could not update templates: %s\n", err)
}
if (options.Templates == "" || (options.Targets == "" && !options.Stdin && options.Target == "")) && options.UpdateTemplates {
if (len(options.Templates) == 0 || (options.Targets == "" && !options.Stdin && options.Target == "")) && options.UpdateTemplates {
os.Exit(0)
}
@ -88,66 +88,79 @@ func (r *Runner) Close() {
os.Remove(r.tempFile)
}
func isFilePath(path string) (bool, error) {
info, err := os.Stat(path)
if err != nil {
return false, err
}
return info.Mode().IsRegular(), nil
}
func (r *Runner) resolvePathIfRelative(path string) (string, error) {
if r.isRelative(path) {
newPath, err := r.resolvePath(path)
if err != nil {
return "", err
}
return newPath, nil
}
return path, nil
}
func isNewPath(path string, pathMap map[string]bool) bool {
if _, already := pathMap[path]; already {
gologger.Warningf("Skipping already specified path '%s'", path)
return false
}
return true
}
// RunEnumeration sets up the input layer for giving input nuclei.
// binary and runs the actual enumeration
func (r *Runner) RunEnumeration() {
var err error
// keeps track of processed dirs and files
processed := make(map[string]bool)
allTemplates := []string{}
// Check if the template is an absolute path or relative path.
// If the path is absolute, use it. Otherwise,
if r.isRelative(r.options.Templates) {
newPath, err := r.resolvePath(r.options.Templates)
// parses user input, handle file/directory cases and produce a list of unique templates
for _, t := range r.options.Templates {
// resolve and convert relative to absolute path
absPath, err := r.resolvePathIfRelative(t)
if err != nil {
gologger.Errorf("Could not find template file '%s': %s\n", r.options.Templates, err)
return
}
r.options.Templates = newPath
gologger.Errorf("Could not find template file '%s': %s\n", t, err)
continue
}
// Single yaml provided
if strings.HasSuffix(r.options.Templates, ".yaml") {
t, err := r.parse(r.options.Templates)
switch t.(type) {
case *templates.Template:
var results bool
template := t.(*templates.Template)
// process http requests
for _, request := range template.BulkRequestsHTTP {
results = r.processTemplateRequest(template, request)
}
// process dns requests
for _, request := range template.RequestsDNS {
dnsResults := r.processTemplateRequest(template, request)
if !results {
results = dnsResults
}
// determine file/directory
isFile, err := isFilePath(absPath)
if err != nil {
gologger.Errorf("Could not stat '%s': %s\n", absPath, err)
continue
}
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!")
}
case *workflows.Workflow:
workflow := t.(*workflows.Workflow)
r.ProcessWorkflowWithList(workflow)
default:
gologger.Errorf("Could not parse file '%s': %s\n", r.options.Templates, err)
}
return
// test for uniqueness
if !isNewPath(absPath, processed) {
continue
}
// If the template passed is a directory
// mark this absolute path as processed
// - if it's a file, we'll never process it again
// - if it's a dir, we'll never walk it again
processed[absPath] = true
if isFile {
allTemplates = append(allTemplates, absPath)
} else {
matches := []string{}
// Recursively walk down the Templates directory and run all the template file checks
err = godirwalk.Walk(r.options.Templates, &godirwalk.Options{
err = godirwalk.Walk(absPath, &godirwalk.Options{
Callback: func(path string, d *godirwalk.Dirent) error {
if !d.IsDir() && strings.HasSuffix(path, ".yaml") {
if isNewPath(path, processed) {
matches = append(matches, path)
processed[path] = true
}
}
return nil
},
@ -156,16 +169,31 @@ func (r *Runner) RunEnumeration() {
},
Unsorted: true,
})
// directory couldn't be walked
if err != nil {
gologger.Fatalf("Could not find templates in directory '%s': %s\n", r.options.Templates, err)
}
// 0 matches means no templates were found in directory
if len(matches) == 0 {
gologger.Fatalf("Error, no templates found in directory: '%s'\n", r.options.Templates)
gologger.Labelf("Could not find templates in directory '%s': %s\n", absPath, err)
continue
}
// couldn't find templates in directory
if len(matches) == 0 {
gologger.Labelf("Error, no templates were found in '%s'.\n", absPath)
continue
}
allTemplates = append(allTemplates, matches...)
}
}
// 0 matches means no templates were found in directory
if len(allTemplates) == 0 {
gologger.Fatalf("Error, no templates were found.\n")
}
// run with the specified templates
var results bool
for _, match := range matches {
for _, match := range allTemplates {
t, err := r.parse(match)
switch t.(type) {
case *templates.Template:
@ -195,7 +223,7 @@ func (r *Runner) RunEnumeration() {
r.output.Close()
os.Remove(outputFile)
}
gologger.Infof("No results found for the template. Happy hacking!")
gologger.Infof("No results found. Happy hacking!")
}
return
}

View File

@ -15,7 +15,7 @@ func (options *Options) validateOptions() error {
}
// Check if a list of templates was provided and it exists
if options.Templates == "" && !options.UpdateTemplates {
if len(options.Templates) == 0 && !options.UpdateTemplates {
return errors.New("no template/templates provided")
}