Support workflows + general code refactor

dev
Ice3man543 2021-07-07 19:15:09 +05:30
parent da37020939
commit 8a80d11467
3 changed files with 45 additions and 15 deletions

View File

@ -24,7 +24,9 @@ func main() {
if err != nil {
gologger.Fatal().Msgf("Could not create runner: %s\n", err)
}
nucleiRunner.RunEnumeration()
if err := nucleiRunner.RunEnumeration(); err != nil {
gologger.Fatal().Msgf("Could not run nuclei: %s\n", err)
}
nucleiRunner.Close()
}

View File

@ -9,6 +9,7 @@ import (
"time"
"github.com/logrusorgru/aurora"
"github.com/pkg/errors"
"github.com/projectdiscovery/gologger"
"github.com/projectdiscovery/hmap/store/hybrid"
"github.com/projectdiscovery/nuclei/v2/internal/colorizer"
@ -74,13 +75,13 @@ func New(options *types.Options) (*Runner, error) {
if options.ReportingConfig != "" {
file, err := os.Open(options.ReportingConfig)
if err != nil {
gologger.Fatal().Msgf("Could not open reporting config file: %s\n", err)
return nil, errors.Wrap(err, "could not open reporting config file")
}
reportingOptions = &reporting.Options{}
if parseErr := yaml.NewDecoder(file).Decode(reportingOptions); parseErr != nil {
file.Close()
gologger.Fatal().Msgf("Could not parse reporting config file: %s\n", parseErr)
return nil, errors.Wrap(parseErr, "could not parse reporting config file")
}
file.Close()
}
@ -102,7 +103,7 @@ func New(options *types.Options) (*Runner, error) {
}
if reportingOptions != nil {
if client, err := reporting.New(reportingOptions, options.ReportingDB); err != nil {
gologger.Fatal().Msgf("Could not create issue reporting client: %s\n", err)
return nil, errors.Wrap(err, "could not create issue reporting client")
} else {
runner.issuesClient = client
}
@ -122,7 +123,7 @@ func New(options *types.Options) (*Runner, error) {
os.Exit(0)
}
if hm, err := hybrid.New(hybrid.DefaultDiskOptions); err != nil {
gologger.Fatal().Msgf("Could not create temporary input file: %s\n", err)
return nil, errors.Wrap(err, "could not create temporary input file")
} else {
runner.hostMap = hm
}
@ -159,7 +160,7 @@ func New(options *types.Options) (*Runner, error) {
if options.Targets != "" {
input, err := os.Open(options.Targets)
if err != nil {
gologger.Fatal().Msgf("Could not open targets file '%s': %s\n", options.Targets, err)
return nil, errors.Wrap(err, "could not open targets file")
}
scanner := bufio.NewScanner(input)
for scanner.Scan() {
@ -185,7 +186,7 @@ func New(options *types.Options) (*Runner, error) {
// Create the output file if asked
outputWriter, err := output.NewStandardWriter(!options.NoColor, options.NoMeta, options.JSON, options.Output, options.TraceLogFile)
if err != nil {
gologger.Fatal().Msgf("Could not create output file '%s': %s\n", options.Output, err)
return nil, errors.Wrap(err, "could not create output file")
}
runner.output = outputWriter
@ -245,14 +246,14 @@ func (r *Runner) Close() {
// RunEnumeration sets up the input layer for giving input nuclei.
// binary and runs the actual enumeration
func (r *Runner) RunEnumeration() {
func (r *Runner) RunEnumeration() error {
defer r.Close()
// If user asked for new templates to be executed, collect the list from template directory.
if r.options.NewTemplates {
templatesLoaded, err := r.readNewTemplatesFile()
if err != nil {
gologger.Warning().Msgf("Could not get newly added templates: %s\n", err)
return errors.Wrap(err, "could not get newly added templates")
}
r.options.Templates = append(r.options.Templates, templatesLoaded...)
}
@ -287,14 +288,14 @@ func (r *Runner) RunEnumeration() {
}
store, err := loader.New(&loaderConfig)
if err != nil {
gologger.Fatal().Msgf("Could not load templates from config: %s\n", err)
return errors.Wrap(err, "could not load templates from config")
}
if r.options.Validate {
if !store.ValidateTemplates(r.options.Templates) {
gologger.Fatal().Msgf("An Error occurred during templates validation\n")
if !store.ValidateTemplates(r.options.Templates, r.options.Workflows) {
return errors.New("an error occurred during templates validation")
} else {
gologger.Info().Msgf("All templates validated successfully\n")
os.Exit(0)
return nil // exit
}
}
store.Load()
@ -413,7 +414,7 @@ func (r *Runner) RunEnumeration() {
// 0 matches means no templates were found in directory
if templateCount == 0 {
gologger.Fatal().Msgf("Error, no templates were found.\n")
return errors.New("no templates were found")
}
results := &atomic.Bool{}
@ -453,6 +454,7 @@ func (r *Runner) RunEnumeration() {
if r.browser != nil {
r.browser.Close()
}
return nil
}
// readNewTemplatesFile reads newly added templates from directory if it exists

View File

@ -85,9 +85,11 @@ func (s *Store) Load() {
// ValidateTemplates takes a list of templates and validates them
// erroring out on discovering any faulty templates.
func (s *Store) ValidateTemplates(templatesList []string) bool {
func (s *Store) ValidateTemplates(templatesList []string, workflowsList []string) bool {
includedTemplates := s.config.Catalog.GetTemplatesPath(templatesList)
includedWorkflows := s.config.Catalog.GetTemplatesPath(workflowsList)
templatesMap := s.pathFilter.Match(includedTemplates)
workflowsMap := s.pathFilter.Match(includedWorkflows)
notErrored := true
for k := range templatesMap {
@ -114,6 +116,30 @@ func (s *Store) ValidateTemplates(templatesList []string) bool {
gologger.Error().Msgf("Error occurred parsing template %s: %s\n", k, err)
}
}
for k := range workflowsMap {
_, err := s.loadTemplate(k, true)
if err != nil {
if strings.Contains(err.Error(), "cannot create template executer") {
continue
}
if err == filter.ErrExcluded {
continue
}
notErrored = false
gologger.Error().Msgf("Error occurred loading workflow %s: %s\n", k, err)
}
_, err = templates.Parse(k, s.config.ExecutorOptions)
if err != nil {
if strings.Contains(err.Error(), "cannot create template executer") {
continue
}
if err == filter.ErrExcluded {
continue
}
notErrored = false
gologger.Error().Msgf("Error occurred parsing workflow %s: %s\n", k, err)
}
}
return notErrored
}