2020-06-26 10:23:54 +02:00
package workflows
2021-07-15 13:41:41 +03:00
import (
2022-09-19 16:49:30 +05:30
"fmt"
2023-10-17 17:44:13 +05:30
"github.com/projectdiscovery/nuclei/v3/pkg/model/types/stringslice"
"github.com/projectdiscovery/nuclei/v3/pkg/operators"
"github.com/projectdiscovery/nuclei/v3/pkg/protocols"
templateTypes "github.com/projectdiscovery/nuclei/v3/pkg/templates/types"
2021-07-15 13:41:41 +03:00
)
2020-12-26 02:08:48 +05:30
2020-06-29 17:43:08 +05:30
// Workflow is a workflow to execute with chained requests, etc.
2020-06-26 10:23:54 +02:00
type Workflow struct {
2021-07-27 16:03:56 +05:30
// description: |
// Workflows is a list of workflows to execute for a template.
2023-02-07 16:10:40 +08:00
Workflows [ ] * WorkflowTemplate ` yaml:"workflows,omitempty" json:"workflows,omitempty" jsonschema:"title=list of workflows to execute,description=List of workflows to execute for template" `
2021-02-22 17:49:02 +05:30
2023-05-31 16:58:10 -04:00
Options * protocols . ExecutorOptions ` yaml:"-" json:"-" `
2020-11-12 23:28:24 +05:30
}
2021-09-07 17:31:46 +03:00
// WorkflowTemplate is a template to be run as part of a workflow
2020-11-12 23:28:24 +05:30
type WorkflowTemplate struct {
2021-07-27 16:03:56 +05:30
// description: |
// Template is a single template or directory to execute as part of workflow.
// examples:
// - name: A single template
// value: "\"dns/worksites-detection.yaml\""
// - name: A template directory
// value: "\"misconfigurations/aem\""
2023-02-07 16:10:40 +08:00
Template string ` yaml:"template,omitempty" json:"template,omitempty" jsonschema:"title=template/directory to execute,description=Template or directory to execute as part of workflow" `
2021-07-27 16:03:56 +05:30
// description: |
// Tags to run templates based on.
2023-02-07 16:10:40 +08:00
Tags stringslice . StringSlice ` yaml:"tags,omitempty" json:"tags,omitempty" jsonschema:"title=tags to execute,description=Tags to run template based on" `
2021-07-27 16:03:56 +05:30
// description: |
// Matchers perform name based matching to run subtemplates for a workflow.
2023-02-07 16:10:40 +08:00
Matchers [ ] * Matcher ` yaml:"matchers,omitempty" json:"matchers,omitempty" jsonschema:"title=name based template result matchers,description=Matchers perform name based matching to run subtemplates for a workflow" `
2021-07-27 16:03:56 +05:30
// description: |
2021-09-07 17:31:46 +03:00
// Subtemplates are run if the `template` field Template matches.
2023-02-07 16:10:40 +08:00
Subtemplates [ ] * WorkflowTemplate ` yaml:"subtemplates,omitempty" json:"subtemplates,omitempty" jsonschema:"title=subtemplate based result matchers,description=Subtemplates are ran if the template field Template matches" `
2021-01-17 12:56:29 +05:30
// Executers perform the actual execution for the workflow template
2023-02-07 16:10:40 +08:00
Executers [ ] * ProtocolExecuterPair ` yaml:"-" json:"-" `
2021-01-17 12:56:29 +05:30
}
// ProtocolExecuterPair is a pair of protocol executer and its options
type ProtocolExecuterPair struct {
2022-10-20 17:23:00 +05:30
Executer protocols . Executer
2023-05-31 16:58:10 -04:00
Options * protocols . ExecutorOptions
2022-10-20 17:23:00 +05:30
TemplateType templateTypes . ProtocolType
2020-11-12 23:28:24 +05:30
}
// Matcher performs conditional matching on the workflow template results.
type Matcher struct {
2021-07-27 16:03:56 +05:30
// description: |
2022-09-19 16:49:30 +05:30
// Name is the name of the items to match.
2023-02-07 16:10:40 +08:00
Name stringslice . StringSlice ` yaml:"name,omitempty" json:"name,omitempty" jsonschema:"title=name of items to match,description=Name of items to match" `
2022-09-19 16:49:30 +05:30
// description: |
// Condition is the optional condition between names. By default,
// the condition is assumed to be OR.
// values:
// - "and"
// - "or"
2023-02-07 16:10:40 +08:00
Condition string ` yaml:"condition,omitempty" json:"condition,omitempty" jsonschema:"title=condition between names,description=Condition between the names,enum=and,enum=or" `
2021-07-27 16:03:56 +05:30
// description: |
2021-09-07 17:31:46 +03:00
// Subtemplates are run if the name of matcher matches.
2023-02-07 16:10:40 +08:00
Subtemplates [ ] * WorkflowTemplate ` yaml:"subtemplates,omitempty" json:"subtemplates,omitempty" jsonschema:"title=templates to run after match,description=Templates to run after match" `
2022-09-19 16:49:30 +05:30
condition ConditionType
}
// ConditionType is the type of condition for matcher
type ConditionType int
const (
// ANDCondition matches responses with AND condition in arguments.
ANDCondition ConditionType = iota + 1
// ORCondition matches responses with AND condition in arguments.
ORCondition
)
// ConditionTypes is a table for conversion of condition type from string.
var ConditionTypes = map [ string ] ConditionType {
"and" : ANDCondition ,
"or" : ORCondition ,
}
// Compile compiles the matcher for workflow
func ( matcher * Matcher ) Compile ( ) error {
var ok bool
if matcher . Condition != "" {
matcher . condition , ok = ConditionTypes [ matcher . Condition ]
if ! ok {
return fmt . Errorf ( "unknown condition specified: %s" , matcher . Condition )
}
} else {
matcher . condition = ORCondition
}
return nil
}
// Match matches a name for matcher names or name
func ( matcher * Matcher ) Match ( result * operators . Result ) bool {
names := matcher . Name . ToSlice ( )
if len ( names ) == 0 {
return false
}
for i , name := range names {
2022-11-25 17:22:50 +01:00
matchOK := result . HasMatch ( name )
extractOK := result . HasExtract ( name )
2022-09-19 16:49:30 +05:30
if ! matchOK && ! extractOK {
if matcher . condition == ANDCondition {
return false
}
continue
}
if matcher . condition == ORCondition {
return true
} else if len ( names ) - 1 == i {
return true
}
}
return false
2020-07-26 20:14:05 +02:00
}