2020-11-12 17:58:24 +00:00
|
|
|
package workflows
|
|
|
|
|
2021-01-01 14:06:21 +00:00
|
|
|
import (
|
2021-01-17 07:26:29 +00:00
|
|
|
"github.com/projectdiscovery/gologger"
|
2021-01-01 14:06:21 +00:00
|
|
|
"github.com/projectdiscovery/nuclei/v2/pkg/output"
|
2021-02-22 12:19:02 +00:00
|
|
|
"github.com/remeh/sizedwaitgroup"
|
2021-01-01 14:06:21 +00:00
|
|
|
"go.uber.org/atomic"
|
|
|
|
)
|
2020-11-12 17:58:24 +00:00
|
|
|
|
2020-12-25 20:38:48 +00:00
|
|
|
// RunWorkflow runs a workflow on an input and returns true or false
|
2021-02-22 12:19:02 +00:00
|
|
|
func (w *Workflow) RunWorkflow(input string) bool {
|
2020-12-25 20:38:48 +00:00
|
|
|
results := &atomic.Bool{}
|
2020-11-12 17:58:24 +00:00
|
|
|
|
2021-02-22 12:19:02 +00:00
|
|
|
swg := sizedwaitgroup.New(w.options.Options.TemplateThreads)
|
2020-11-12 17:58:24 +00:00
|
|
|
for _, template := range w.Workflows {
|
2021-02-22 12:19:02 +00:00
|
|
|
swg.Add()
|
|
|
|
func(template *WorkflowTemplate) {
|
|
|
|
err := w.runWorkflowStep(template, input, results, &swg)
|
|
|
|
if err != nil {
|
|
|
|
gologger.Warning().Msgf("[%s] Could not execute workflow step: %s\n", template.Template, err)
|
|
|
|
}
|
|
|
|
swg.Done()
|
|
|
|
}(template)
|
2020-11-12 17:58:24 +00:00
|
|
|
}
|
2021-02-22 12:19:02 +00:00
|
|
|
swg.Wait()
|
|
|
|
return results.Load()
|
2020-11-12 17:58:24 +00:00
|
|
|
}
|
|
|
|
|
2020-12-25 20:38:48 +00:00
|
|
|
// runWorkflowStep runs a workflow step for the workflow. It executes the workflow
|
|
|
|
// in a recursive manner running all subtemplates and matchers.
|
2021-02-22 12:19:02 +00:00
|
|
|
func (w *Workflow) runWorkflowStep(template *WorkflowTemplate, input string, results *atomic.Bool, swg *sizedwaitgroup.SizedWaitGroup) error {
|
2020-12-26 07:50:56 +00:00
|
|
|
var firstMatched bool
|
2021-01-17 07:26:29 +00:00
|
|
|
|
|
|
|
var mainErr error
|
2020-12-26 07:50:56 +00:00
|
|
|
if len(template.Matchers) == 0 {
|
2021-01-17 07:26:29 +00:00
|
|
|
for _, executer := range template.Executers {
|
|
|
|
executer.Options.Progress.AddToTotal(int64(executer.Executer.Requests()))
|
2020-12-29 12:32:45 +00:00
|
|
|
|
2021-01-17 07:26:29 +00:00
|
|
|
matched, err := executer.Executer.Execute(input)
|
|
|
|
if err != nil {
|
|
|
|
if len(template.Executers) == 1 {
|
|
|
|
mainErr = err
|
|
|
|
} else {
|
2021-02-04 16:30:09 +00:00
|
|
|
gologger.Warning().Msgf("[%s] Could not execute workflow step: %s\n", template.Template, err)
|
2021-01-17 07:26:29 +00:00
|
|
|
}
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if matched {
|
|
|
|
firstMatched = matched
|
|
|
|
results.CAS(false, matched)
|
|
|
|
}
|
2020-12-29 15:02:04 +00:00
|
|
|
}
|
2020-12-26 07:50:56 +00:00
|
|
|
}
|
|
|
|
|
2020-11-12 17:58:24 +00:00
|
|
|
if len(template.Matchers) > 0 {
|
2021-01-17 07:26:29 +00:00
|
|
|
for _, executer := range template.Executers {
|
|
|
|
executer.Options.Progress.AddToTotal(int64(executer.Executer.Requests()))
|
|
|
|
|
|
|
|
err := executer.Executer.ExecuteWithResults(input, func(event *output.InternalWrappedEvent) {
|
|
|
|
if event.OperatorsResult == nil {
|
|
|
|
return
|
2020-12-25 20:38:48 +00:00
|
|
|
}
|
2020-11-12 17:58:24 +00:00
|
|
|
|
2021-01-17 07:26:29 +00:00
|
|
|
for _, matcher := range template.Matchers {
|
|
|
|
_, matchOK := event.OperatorsResult.Matches[matcher.Name]
|
|
|
|
_, extractOK := event.OperatorsResult.Extracts[matcher.Name]
|
|
|
|
if !matchOK && !extractOK {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, subtemplate := range matcher.Subtemplates {
|
2021-02-22 12:19:02 +00:00
|
|
|
swg.Add()
|
|
|
|
|
|
|
|
go func(subtemplate *WorkflowTemplate) {
|
|
|
|
if err := w.runWorkflowStep(subtemplate, input, results, swg); err != nil {
|
|
|
|
gologger.Warning().Msgf("[%s] Could not execute workflow step: %s\n", subtemplate.Template, err)
|
|
|
|
}
|
|
|
|
swg.Done()
|
|
|
|
}(subtemplate)
|
2020-12-25 20:38:48 +00:00
|
|
|
}
|
2020-11-12 17:58:24 +00:00
|
|
|
}
|
2021-01-17 07:26:29 +00:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
if len(template.Executers) == 1 {
|
|
|
|
mainErr = err
|
|
|
|
} else {
|
2021-02-04 16:30:09 +00:00
|
|
|
gologger.Warning().Msgf("[%s] Could not execute workflow step: %s\n", template.Template, err)
|
2021-01-17 07:26:29 +00:00
|
|
|
}
|
|
|
|
continue
|
|
|
|
}
|
2020-11-12 17:58:24 +00:00
|
|
|
}
|
2021-01-17 07:26:29 +00:00
|
|
|
return mainErr
|
2020-11-12 17:58:24 +00:00
|
|
|
}
|
2020-12-26 07:50:56 +00:00
|
|
|
if len(template.Subtemplates) > 0 && firstMatched {
|
2020-11-12 17:58:24 +00:00
|
|
|
for _, subtemplate := range template.Subtemplates {
|
2021-02-22 12:19:02 +00:00
|
|
|
swg.Add()
|
|
|
|
|
|
|
|
func(template *WorkflowTemplate) {
|
|
|
|
err := w.runWorkflowStep(template, input, results, swg)
|
|
|
|
if err != nil {
|
|
|
|
gologger.Warning().Msgf("[%s] Could not execute workflow step: %s\n", template.Template, err)
|
|
|
|
}
|
|
|
|
swg.Done()
|
|
|
|
}(subtemplate)
|
2020-11-12 17:58:24 +00:00
|
|
|
}
|
|
|
|
}
|
2021-01-17 07:26:29 +00:00
|
|
|
return mainErr
|
2020-11-12 17:58:24 +00:00
|
|
|
}
|