Merge pull request #968 from projectdiscovery/jsonschema-addition

Added jsonschema generation for yaml syntax
dev
Ice3man 2021-08-25 13:09:07 +05:30 committed by GitHub
commit 535001f937
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 167 additions and 103 deletions

View File

@ -6,7 +6,7 @@ on:
jobs: jobs:
build: functional:
name: Functional Test name: Functional Test
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:

View File

@ -28,7 +28,7 @@ jobs:
fi fi
go generate pkg/templates/templates.go go generate pkg/templates/templates.go
go build -o "cmd/docgen/docgen" cmd/docgen/docgen.go go build -o "cmd/docgen/docgen" cmd/docgen/docgen.go
./cmd/docgen/docgen syntax-reference.md ./cmd/docgen/docgen syntax-reference.md nuclei-jsonschema.json
echo "::set-output name=changes::$(git status -s | wc -l)" echo "::set-output name=changes::$(git status -s | wc -l)"
working-directory: v2 working-directory: v2
@ -37,7 +37,7 @@ jobs:
run: | run: |
git config --local user.email "action@github.com" git config --local user.email "action@github.com"
git config --local user.name "GitHub Action" git config --local user.name "GitHub Action"
git add v2/syntax-reference.md git add v2/syntax-reference.md v2/nuclei-jsonschema.json
git commit -m "Auto Generate Syntax Docs [$(date)] :robot:" -a git commit -m "Auto Generate Syntax Docs [$(date)] :robot:" -a
cat v2/syntax-reference.md cat v2/syntax-reference.md

View File

@ -15,7 +15,7 @@ docs:
fi fi
$(GOCMD) generate pkg/templates/templates.go $(GOCMD) generate pkg/templates/templates.go
$(GOBUILD) -o "cmd/docgen/docgen" cmd/docgen/docgen.go $(GOBUILD) -o "cmd/docgen/docgen" cmd/docgen/docgen.go
./cmd/docgen/docgen docs.md ./cmd/docgen/docgen docs.md nuclei-jsonschema.json
test: test:
$(GOTEST) -v ./... $(GOTEST) -v ./...
tidy: tidy:

View File

@ -1,14 +1,22 @@
package main package main
import ( import (
"bytes"
"encoding/json"
"io/ioutil" "io/ioutil"
"log" "log"
"os" "os"
"regexp"
"strings"
"github.com/alecthomas/jsonschema"
"github.com/projectdiscovery/nuclei/v2/pkg/templates" "github.com/projectdiscovery/nuclei/v2/pkg/templates"
) )
var pathRegex = regexp.MustCompile(`github.com/projectdiscovery/nuclei/v2/(?:internal|pkg)/(?:.*/)?([A-Za-z\.]+)`)
func main() { func main() {
// Generate yaml syntax documentation
data, err := templates.GetTemplateDoc().Encode() data, err := templates.GetTemplateDoc().Encode()
if err != nil { if err != nil {
log.Fatalf("Could not encode docs: %s\n", err) log.Fatalf("Could not encode docs: %s\n", err)
@ -17,4 +25,26 @@ func main() {
if err != nil { if err != nil {
log.Fatalf("Could not write docs: %s\n", err) log.Fatalf("Could not write docs: %s\n", err)
} }
// Generate jsonschema
r := &jsonschema.Reflector{
PreferYAMLSchema: true,
YAMLEmbeddedStructs: true,
FullyQualifyTypeNames: true,
}
jsonschemaData := r.Reflect(&templates.Template{})
var buf bytes.Buffer
encoder := json.NewEncoder(&buf)
encoder.SetIndent("", " ")
_ = encoder.Encode(jsonschemaData)
schema := buf.String()
for _, match := range pathRegex.FindAllStringSubmatch(schema, -1) {
schema = strings.ReplaceAll(schema, match[0], match[1])
}
err = ioutil.WriteFile(os.Args[2], []byte(schema), 0777)
if err != nil {
log.Fatalf("Could not write jsonschema: %s\n", err)
}
} }

View File

@ -4,6 +4,7 @@ go 1.16
require ( require (
github.com/Knetic/govaluate v3.0.0+incompatible github.com/Knetic/govaluate v3.0.0+incompatible
github.com/alecthomas/jsonschema v0.0.0-20210818095345-1014919a589c
github.com/andygrunwald/go-jira v1.14.0 github.com/andygrunwald/go-jira v1.14.0
github.com/antchfx/htmlquery v1.2.3 github.com/antchfx/htmlquery v1.2.3
github.com/apex/log v1.9.0 github.com/apex/log v1.9.0
@ -33,9 +34,9 @@ require (
github.com/projectdiscovery/interactsh v0.0.4 github.com/projectdiscovery/interactsh v0.0.4
github.com/projectdiscovery/rawhttp v0.0.7 github.com/projectdiscovery/rawhttp v0.0.7
github.com/projectdiscovery/retryabledns v1.0.12 github.com/projectdiscovery/retryabledns v1.0.12
github.com/projectdiscovery/retryablehttp-go v1.0.2-0.20210524224054-9fbe1f2b0727
github.com/projectdiscovery/stringsutil v0.0.0-20210804142656-fd3c28dbaafe github.com/projectdiscovery/stringsutil v0.0.0-20210804142656-fd3c28dbaafe
github.com/projectdiscovery/yamldoc-go v1.0.2 github.com/projectdiscovery/yamldoc-go v1.0.2
github.com/projectdiscovery/retryablehttp-go v1.0.2-0.20210524224054-9fbe1f2b0727
github.com/remeh/sizedwaitgroup v1.0.0 github.com/remeh/sizedwaitgroup v1.0.0
github.com/rs/xid v1.3.0 github.com/rs/xid v1.3.0
github.com/segmentio/ksuid v1.0.4 github.com/segmentio/ksuid v1.0.4

View File

@ -49,6 +49,8 @@ github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDO
github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8=
github.com/akrylysov/pogreb v0.10.0 h1:pVKi+uf3EzZUmiwr9bZnPk4W379KP8QsFzAa9IUuOog= github.com/akrylysov/pogreb v0.10.0 h1:pVKi+uf3EzZUmiwr9bZnPk4W379KP8QsFzAa9IUuOog=
github.com/akrylysov/pogreb v0.10.0/go.mod h1:pNs6QmpQ1UlTJKDezuRWmaqkgUE2TuU0YTWyqJZ7+lI= github.com/akrylysov/pogreb v0.10.0/go.mod h1:pNs6QmpQ1UlTJKDezuRWmaqkgUE2TuU0YTWyqJZ7+lI=
github.com/alecthomas/jsonschema v0.0.0-20210818095345-1014919a589c h1:oJsq4z4xKgZWWOhrSZuLZ5KyYfRFytddLL1E5+psfIY=
github.com/alecthomas/jsonschema v0.0.0-20210818095345-1014919a589c/go.mod h1:/n6+1/DWPltRLWL/VKyUxg6tzsl5kHUCcraimt4vr60=
github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 h1:MzBOUgng9orim59UnfUTLRjMpd09C5uEVQ6RPGeCaVI= github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 h1:MzBOUgng9orim59UnfUTLRjMpd09C5uEVQ6RPGeCaVI=
github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgpPQZYZ8vdbc+48xibu8ALc3yeyd64IhHS+PU6Yyg= github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgpPQZYZ8vdbc+48xibu8ALc3yeyd64IhHS+PU6Yyg=
github.com/andygrunwald/go-jira v1.14.0 h1:7GT/3qhar2dGJ0kq8w0d63liNyHOnxZsUZ9Pe4+AKBI= github.com/andygrunwald/go-jira v1.14.0 h1:7GT/3qhar2dGJ0kq8w0d63liNyHOnxZsUZ9Pe4+AKBI=
@ -224,6 +226,8 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T
github.com/hooklift/assert v0.1.0 h1:UZzFxx5dSb9aBtvMHTtnPuvFnBvcEhHTPb9+0+jpEjs= github.com/hooklift/assert v0.1.0 h1:UZzFxx5dSb9aBtvMHTtnPuvFnBvcEhHTPb9+0+jpEjs=
github.com/hooklift/assert v0.1.0/go.mod h1:pfexfvIHnKCdjh6CkkIZv5ic6dQ6aU2jhKghBlXuwwY= github.com/hooklift/assert v0.1.0/go.mod h1:pfexfvIHnKCdjh6CkkIZv5ic6dQ6aU2jhKghBlXuwwY=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0 h1:i462o439ZjprVSFSZLZxcsoAe592sZB1rci2Z8j4wdk=
github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/itchyny/go-flags v1.5.0/go.mod h1:lenkYuCobuxLBAd/HGFE4LRoW8D3B6iXRQfWYJ+MNbA= github.com/itchyny/go-flags v1.5.0/go.mod h1:lenkYuCobuxLBAd/HGFE4LRoW8D3B6iXRQfWYJ+MNbA=
@ -389,6 +393,7 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=

View File

@ -4,6 +4,7 @@ import (
"encoding/json" "encoding/json"
"strings" "strings"
"github.com/alecthomas/jsonschema"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -57,6 +58,18 @@ type SeverityHolder struct {
Severity Severity Severity Severity
} }
func (severityHolder SeverityHolder) JSONSchemaType() *jsonschema.Type {
gotType := &jsonschema.Type{
Type: "string",
Title: "severity of the template",
Description: "Seriousness of the implications of the template",
}
for _, severity := range GetSupportedSeverities() {
gotType.Enum = append(gotType.Enum, severity.String())
}
return gotType
}
func (severityHolder *SeverityHolder) UnmarshalYAML(unmarshal func(interface{}) error) error { func (severityHolder *SeverityHolder) UnmarshalYAML(unmarshal func(interface{}) error) error {
var marshalledSeverity string var marshalledSeverity string
if err := unmarshal(&marshalledSeverity); err != nil { if err := unmarshal(&marshalledSeverity); err != nil {

View File

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"strings" "strings"
"github.com/alecthomas/jsonschema"
"github.com/projectdiscovery/nuclei/v2/internal/severity" "github.com/projectdiscovery/nuclei/v2/internal/severity"
"github.com/projectdiscovery/nuclei/v2/pkg/utils" "github.com/projectdiscovery/nuclei/v2/pkg/utils"
) )
@ -17,13 +18,13 @@ type Info struct {
// examples: // examples:
// - value: "\"bower.json file disclosure\"" // - value: "\"bower.json file disclosure\""
// - value: "\"Nagios Default Credentials Check\"" // - value: "\"Nagios Default Credentials Check\""
Name string `json:"name,omitempty" yaml:"name,omitempty"` Name string `json:"name,omitempty" yaml:"name,omitempty" jsonschema:"title=name of the template,description=Name is a short summary of what the template does,example=Nagios Default Credentials Check"`
// description: | // description: |
// Author of the template. // Author of the template.
// //
// examples: // examples:
// - value: "\"<username>\"" // - value: "\"<username>\""
Authors StringSlice `json:"author,omitempty" yaml:"author,omitempty"` Authors StringSlice `json:"author,omitempty" yaml:"author,omitempty" jsonschema:"title=author of the template,description=Author is the author of the template,example=username"`
// description: | // description: |
// Any tags for the template. // Any tags for the template.
// //
@ -32,7 +33,7 @@ type Info struct {
// examples: // examples:
// - name: Example tags // - name: Example tags
// value: "\"cve,cve2019,grafana,auth-bypass,dos\"" // value: "\"cve,cve2019,grafana,auth-bypass,dos\""
Tags StringSlice `json:"tags,omitempty" yaml:"tags,omitempty"` Tags StringSlice `json:"tags,omitempty" yaml:"tags,omitempty" jsonschema:"title=tags of the template,description=Any tags for the template"`
// description: | // description: |
// Description of the template. // Description of the template.
// //
@ -41,7 +42,7 @@ type Info struct {
// examples: // examples:
// - value: "\"Bower is a package manager which stores packages informations in bower.json file\"" // - value: "\"Bower is a package manager which stores packages informations in bower.json file\""
// - value: "\"Subversion ALM for the enterprise before 8.8.2 allows reflected XSS at multiple locations\"" // - value: "\"Subversion ALM for the enterprise before 8.8.2 allows reflected XSS at multiple locations\""
Description string `json:"description,omitempty" yaml:"description,omitempty"` Description string `json:"description,omitempty" yaml:"description,omitempty" jsonschema:"title=description of the template,description=In-depth explanation on what the template does,example=Bower is a package manager which stores packages informations in bower.json file"`
// description: | // description: |
// References for the template. // References for the template.
// //
@ -50,7 +51,7 @@ type Info struct {
// examples: // examples:
// - value: > // - value: >
// []string{"https://github.com/strapi/strapi", "https://github.com/getgrav/grav"} // []string{"https://github.com/strapi/strapi", "https://github.com/getgrav/grav"}
Reference StringSlice `json:"reference,omitempty" yaml:"reference,omitempty"` Reference StringSlice `json:"reference,omitempty" yaml:"reference,omitempty" jsonschema:"title=references for the template,description=Links relevant to the template"`
// description: | // description: |
// Severity of the template. // Severity of the template.
// //
@ -67,7 +68,7 @@ type Info struct {
// examples: // examples:
// - value: > // - value: >
// map[string]string{"customField1":"customValue1"} // map[string]string{"customField1":"customValue1"}
AdditionalFields map[string]string `json:"additional-fields,omitempty" yaml:"additional-fields,omitempty"` AdditionalFields map[string]string `json:"additional-fields,omitempty" yaml:"additional-fields,omitempty" jsonschema:"title=additional metadata for the template,description=Additional metadata fields for the template"`
} }
// StringSlice represents a single (in-lined) or multiple string value(s). // StringSlice represents a single (in-lined) or multiple string value(s).
@ -76,6 +77,13 @@ type StringSlice struct {
Value interface{} Value interface{}
} }
func (stringSlice StringSlice) JSONSchemaType() *jsonschema.Type {
gotType := &jsonschema.Type{
OneOf: []*jsonschema.Type{{Type: "string"}, {Type: "array"}},
}
return gotType
}
func (stringSlice *StringSlice) IsEmpty() bool { func (stringSlice *StringSlice) IsEmpty() bool {
return len(stringSlice.ToSlice()) == 0 return len(stringSlice.ToSlice()) == 0
} }

View File

@ -13,13 +13,15 @@ type Extractor struct {
// spaces or dashes (-). // spaces or dashes (-).
// examples: // examples:
// - value: "\"cookie-extractor\"" // - value: "\"cookie-extractor\""
Name string `yaml:"name,omitempty"` Name string `yaml:"name,omitempty" jsonschema:"title=name of the extractor,description=Name of the extractor"`
// description: | // description: |
// Type is the type of the extractor. // Type is the type of the extractor.
// values: // values:
// - "regex" // - "regex"
// - "kval" // - "kval"
Type string `yaml:"type"` // - "json"
// - "xpath"
Type string `yaml:"type" jsonschema:"title=type of the extractor,description=Type of the extractor,enum=regex,enum=kval,enum=json,enum=xpath"`
// extractorType is the internal type of the extractor // extractorType is the internal type of the extractor
extractorType ExtractorType extractorType ExtractorType
@ -35,13 +37,13 @@ type Extractor struct {
// - name: Wordpress Author Extraction regex // - name: Wordpress Author Extraction regex
// value: > // value: >
// []string{"Author:(?:[A-Za-z0-9 -\\_=\"]+)?<span(?:[A-Za-z0-9 -\\_=\"]+)?>([A-Za-z0-9]+)<\\/span>"} // []string{"Author:(?:[A-Za-z0-9 -\\_=\"]+)?<span(?:[A-Za-z0-9 -\\_=\"]+)?>([A-Za-z0-9]+)<\\/span>"}
Regex []string `yaml:"regex,omitempty"` Regex []string `yaml:"regex,omitempty" jsonschema:"title=regex to extract from part,description=Regex to extract from part"`
// description: | // description: |
// Group specifies a numbered group to extract from the regex. // Group specifies a numbered group to extract from the regex.
// examples: // examples:
// - name: Example Regex Group // - name: Example Regex Group
// value: "1" // value: "1"
RegexGroup int `yaml:"group,omitempty"` RegexGroup int `yaml:"group,omitempty" jsonschema:"title=group to extract from regex,description=Group to extract from regex"`
// regexCompiled is the compiled variant // regexCompiled is the compiled variant
regexCompiled []*regexp.Regexp regexCompiled []*regexp.Regexp
@ -58,7 +60,7 @@ type Extractor struct {
// - name: Extracting value of PHPSESSID Cookie // - name: Extracting value of PHPSESSID Cookie
// value: > // value: >
// []string{"PHPSESSID"} // []string{"PHPSESSID"}
KVal []string `yaml:"kval,omitempty"` KVal []string `yaml:"kval,omitempty" jsonschema:"title=kval pairs to extract from response,description=Kval pairs to extract from response"`
// description: | // description: |
// JSON allows using jq-style syntax to extract items from json response // JSON allows using jq-style syntax to extract items from json response
@ -68,7 +70,7 @@ type Extractor struct {
// []string{".[] | .id"} // []string{".[] | .id"}
// - value: > // - value: >
// []string{".batters | .batter | .[] | .id"} // []string{".batters | .batter | .[] | .id"}
JSON []string `yaml:"json,omitempty"` JSON []string `yaml:"json,omitempty" jsonschema:"title=json jq expressions to extract data,description=JSON JQ expressions to evaluate from response part"`
// description: | // description: |
// XPath allows using xpath expressions to extract items from html response // XPath allows using xpath expressions to extract items from html response
// //
@ -77,13 +79,13 @@ type Extractor struct {
// []string{"/html/body/div/p[2]/a"} // []string{"/html/body/div/p[2]/a"}
// - value: > // - value: >
// []string{".batters | .batter | .[] | .id"} // []string{".batters | .batter | .[] | .id"}
XPath []string `yaml:"xpath,omitempty"` XPath []string `yaml:"xpath,omitempty" jsonschema:"title=html xpath expressions to extract data,description=XPath allows using xpath expressions to extract items from html response"`
// description: | // description: |
// Attribute is an optional attribute to extract from response XPath. // Attribute is an optional attribute to extract from response XPath.
// //
// examples: // examples:
// - value: "\"href\"" // - value: "\"href\""
Attribute string `yaml:"attribute,omitempty"` Attribute string `yaml:"attribute,omitempty" jsonschema:"title=optional attribute to extract from xpath,description=Optional attribute to extract from response XPath"`
// jsonCompiled is the compiled variant // jsonCompiled is the compiled variant
jsonCompiled []*gojq.Code jsonCompiled []*gojq.Code
@ -96,11 +98,11 @@ type Extractor struct {
// examples: // examples:
// - value: "\"body\"" // - value: "\"body\""
// - value: "\"raw\"" // - value: "\"raw\""
Part string `yaml:"part,omitempty"` Part string `yaml:"part,omitempty" jsonschema:"title=part of response to extract data from,description=Part of the request response to extract data from"`
// description: | // description: |
// Internal, when set to true will allow using the value extracted // Internal, when set to true will allow using the value extracted
// in the next request for some protocols (like HTTP). // in the next request for some protocols (like HTTP).
Internal bool `yaml:"internal,omitempty"` Internal bool `yaml:"internal,omitempty" jsonschema:"title=mark extracted value for internal variable use,description=Internal when set to true will allow using the value extracted in the next request for some protocols"`
} }
// ExtractorType is the type of the extractor specified // ExtractorType is the type of the extractor specified

View File

@ -17,14 +17,14 @@ type Matcher struct {
// - "regex" // - "regex"
// - "binary" // - "binary"
// - "dsl" // - "dsl"
Type string `yaml:"type"` Type string `yaml:"type" jsonschema:"title=type of matcher,description=Type of the matcher,enum=status,enum=size,enum=word,enum=regex,enum=dsl"`
// description: | // description: |
// Condition is the optional condition between two matcher variables. By default, // Condition is the optional condition between two matcher variables. By default,
// the condition is assumed to be OR. // the condition is assumed to be OR.
// values: // values:
// - "and" // - "and"
// - "or" // - "or"
Condition string `yaml:"condition,omitempty"` Condition string `yaml:"condition,omitempty" jsonschema:"title=condition between matcher variables,description=Condition between the matcher variables,enum=and,enum=or"`
// description: | // description: |
// Part is the part of the request response to match data from. // Part is the part of the request response to match data from.
@ -34,31 +34,31 @@ type Matcher struct {
// examples: // examples:
// - value: "\"body\"" // - value: "\"body\""
// - value: "\"raw\"" // - value: "\"raw\""
Part string `yaml:"part,omitempty"` Part string `yaml:"part,omitempty" jsonschema:"title=part of response to match,description=Part of response to match data from"`
// description: | // description: |
// Negative specifies if the match should be reversed // Negative specifies if the match should be reversed
// It will only match if the condition is not true. // It will only match if the condition is not true.
Negative bool `yaml:"negative,omitempty"` Negative bool `yaml:"negative,omitempty" jsonschema:"title=negative specifies if match reversed,description=Negative specifies if the match should be reversed. It will only match if the condition is not true"`
// description: | // description: |
// Name of the matcher. Name should be lowercase and must not contain // Name of the matcher. Name should be lowercase and must not contain
// spaces or dashes (-). // spaces or dashes (-).
// examples: // examples:
// - value: "\"cookie-matcher\"" // - value: "\"cookie-matcher\""
Name string `yaml:"name,omitempty"` Name string `yaml:"name,omitempty" jsonschema:"title=name of the matcher,description=Name of the matcher"`
// description: | // description: |
// Status are the acceptable status codes for the response. // Status are the acceptable status codes for the response.
// examples: // examples:
// - value: > // - value: >
// []int{200, 302} // []int{200, 302}
Status []int `yaml:"status,omitempty"` Status []int `yaml:"status,omitempty" jsonschema:"title=status to match,description=Status to match for the response"`
// description: | // description: |
// Size is the acceptable size for the response // Size is the acceptable size for the response
// examples: // examples:
// - value: > // - value: >
// []int{3029, 2042} // []int{3029, 2042}
Size []int `yaml:"size,omitempty"` Size []int `yaml:"size,omitempty" jsonschema:"title=acceptable size for response,description=Size is the acceptable size for the response"`
// description: | // description: |
// Words contains word patterns required to be present in the response part. // Words contains word patterns required to be present in the response part.
// examples: // examples:
@ -68,7 +68,7 @@ type Matcher struct {
// - name: Match for application/json in response headers // - name: Match for application/json in response headers
// value: > // value: >
// []string{"application/json"} // []string{"application/json"}
Words []string `yaml:"words,omitempty"` Words []string `yaml:"words,omitempty" jsonschema:"title=words to match in response,description= Words contains word patterns required to be present in the response part"`
// description: | // description: |
// Regex contains Regular Expression patterns required to be present in the response part. // Regex contains Regular Expression patterns required to be present in the response part.
// examples: // examples:
@ -78,7 +78,7 @@ type Matcher struct {
// - name: Match for Open Redirect via Location header // - name: Match for Open Redirect via Location header
// value: > // value: >
// []string{`(?m)^(?:Location\\s*?:\\s*?)(?:https?://|//)?(?:[a-zA-Z0-9\\-_\\.@]*)example\\.com.*$`} // []string{`(?m)^(?:Location\\s*?:\\s*?)(?:https?://|//)?(?:[a-zA-Z0-9\\-_\\.@]*)example\\.com.*$`}
Regex []string `yaml:"regex,omitempty"` Regex []string `yaml:"regex,omitempty" jsonschema:"title=regex to match in response,description=Regex contains regex patterns required to be present in the response part"`
// description: | // description: |
// Binary are the binary patterns required to be present in the response part. // Binary are the binary patterns required to be present in the response part.
// examples: // examples:
@ -88,7 +88,7 @@ type Matcher struct {
// - name: Match for 7zip files // - name: Match for 7zip files
// value: > // value: >
// []string{"377ABCAF271C"} // []string{"377ABCAF271C"}
Binary []string `yaml:"binary,omitempty"` Binary []string `yaml:"binary,omitempty" jsonschema:"title=binary patterns to match in response,description=Binary are the binary patterns required to be present in the response part"`
// description: | // description: |
// DSL are the dsl expressions that will be evaluated as part of nuclei matching rules. // DSL are the dsl expressions that will be evaluated as part of nuclei matching rules.
// A list of these helper functions are available [here](https://nuclei.projectdiscovery.io/templating-guide/helper-functions/). // A list of these helper functions are available [here](https://nuclei.projectdiscovery.io/templating-guide/helper-functions/).
@ -99,12 +99,12 @@ type Matcher struct {
// - name: DSL Matcher for missing strict transport security header // - name: DSL Matcher for missing strict transport security header
// value: > // value: >
// []string{"!contains(tolower(all_headers), ''strict-transport-security'')"} // []string{"!contains(tolower(all_headers), ''strict-transport-security'')"}
DSL []string `yaml:"dsl,omitempty"` DSL []string `yaml:"dsl,omitempty" jsonschema:"title=dsl expressions to match in response,description=DSL are the dsl expressions that will be evaluated as part of nuclei matching rules"`
// description: | // description: |
// Encoding specifies the encoding for the words field if any. // Encoding specifies the encoding for the words field if any.
// values: // values:
// - "hex" // - "hex"
Encoding string `yaml:"encoding,omitempty"` Encoding string `yaml:"encoding,omitempty" jsonschema:"title=encoding for word field,description=Optional encoding for the word fields,enum=hex"`
// cached data for the compiled matcher // cached data for the compiled matcher
condition ConditionType condition ConditionType

View File

@ -16,17 +16,17 @@ type Operators struct {
// //
// Multiple matchers can be combined together with `matcher-condition` flag // Multiple matchers can be combined together with `matcher-condition` flag
// which accepts either `and` or `or` as argument. // which accepts either `and` or `or` as argument.
Matchers []*matchers.Matcher `yaml:"matchers,omitempty"` Matchers []*matchers.Matcher `yaml:"matchers,omitempty" jsonschema:"title=matchers to run on response,description=Detection mechanism to identify whether the request was successful by doing pattern matching"`
// description: | // description: |
// Extractors contains the extraction mechanism for the request to identify // Extractors contains the extraction mechanism for the request to identify
// and extract parts of the response. // and extract parts of the response.
Extractors []*extractors.Extractor `yaml:"extractors,omitempty"` Extractors []*extractors.Extractor `yaml:"extractors,omitempty" jsonschema:"title=extractors to run on response,description=Extractors contains the extraction mechanism for the request to identify and extract parts of the response"`
// description: | // description: |
// MatchersCondition is the condition between the matchers. Default is OR. // MatchersCondition is the condition between the matchers. Default is OR.
// values: // values:
// - "and" // - "and"
// - "or" // - "or"
MatchersCondition string `yaml:"matchers-condition,omitempty"` MatchersCondition string `yaml:"matchers-condition,omitempty" jsonschema:"title=condition between the matchers,description=Conditions between the matchers,enum=and,enum=or"`
// cached variables that may be used along with request. // cached variables that may be used along with request.
matchersCondition matchers.ConditionType matchersCondition matchers.ConditionType
} }

View File

@ -19,7 +19,7 @@ type Request struct {
operators.Operators `yaml:",inline"` operators.Operators `yaml:",inline"`
// ID is the ID of the request // ID is the ID of the request
ID string `yaml:"id,omitempty"` ID string `yaml:"id,omitempty" jsonschema:"title=id of the dns request,description=ID is the optional ID of the DNS Request"`
// description: | // description: |
// Name is the Hostname to make DNS request for. // Name is the Hostname to make DNS request for.
@ -27,19 +27,20 @@ type Request struct {
// Generally, it is set to {{FQDN}} which is the domain we get from input. // Generally, it is set to {{FQDN}} which is the domain we get from input.
// examples: // examples:
// - value: "\"{{FQDN}}\"" // - value: "\"{{FQDN}}\""
Name string `yaml:"name,omitempty"` Name string `yaml:"name,omitempty" jsonschema:"title=hostname to make dns request for,description=Name is the Hostname to make DNS request for"`
// description: | // description: |
// Type is the type of DNS request to make. // Type is the type of DNS request to make.
// values: // values:
// - "A" // - "A"
// - "NS" // - "NS"
// - "DS"
// - "CNAME" // - "CNAME"
// - "SOA" // - "SOA"
// - "PTR" // - "PTR"
// - "MX" // - "MX"
// - "TXT" // - "TXT"
// - "AAAA" // - "AAAA"
Type string `yaml:"type,omitempty"` Type string `yaml:"type,omitempty" jsonschema:"title=type of dns request to make,description=Type is the type of DNS request to make,enum=A,enum=NS,enum=DS,enum=CNAME,enum=SOA,enum=PTR,enum=MX,enum=TXT,enum=AAAA"`
// description: | // description: |
// Class is the class of the DNS request. // Class is the class of the DNS request.
// //
@ -51,13 +52,13 @@ type Request struct {
// - "HESIOD" // - "HESIOD"
// - "NONE" // - "NONE"
// - "ANY" // - "ANY"
Class string `yaml:"class,omitempty"` Class string `yaml:"class,omitempty" jsonschema:"title=class of DNS request,description=Class is the class of the DNS request,enum=INET,enum=CSNET,enum=CHAOS,enum=HESIOD,enum=NONE,enum=ANY"`
// description: | // description: |
// Retries is the number of retries for the DNS request // Retries is the number of retries for the DNS request
// examples: // examples:
// - name: Use a retry of 3 to 5 generally // - name: Use a retry of 3 to 5 generally
// value: 5 // value: 5
Retries int `yaml:"retries,omitempty"` Retries int `yaml:"retries,omitempty" jsonschema:"title=retries for dns request,description=Retries is the number of retries for the DNS request"`
CompiledOperators *operators.Operators `yaml:"-"` CompiledOperators *operators.Operators `yaml:"-"`
dnsClient *retryabledns.Client dnsClient *retryabledns.Client
@ -69,7 +70,7 @@ type Request struct {
// description: | // description: |
// Recursion determines if resolver should recurse all records to get fresh results. // Recursion determines if resolver should recurse all records to get fresh results.
Recursion bool `yaml:"recursion,omitempty"` Recursion bool `yaml:"recursion,omitempty" jsonschema:"title=recurse all servers,description=Recursion determines if resolver should recurse all records to get fresh results"`
} }
// GetID returns the unique ID of the request if any. // GetID returns the unique ID of the request if any.

View File

@ -16,7 +16,7 @@ type Request struct {
// Extensions is the list of extensions to perform matching on. // Extensions is the list of extensions to perform matching on.
// examples: // examples:
// - value: '[]string{".txt", ".go", ".json"}' // - value: '[]string{".txt", ".go", ".json"}'
Extensions []string `yaml:"extensions,omitempty"` Extensions []string `yaml:"extensions,omitempty" jsonschema:"title=extensions to match,description=List of extensions to perform matching on"`
// description: | // description: |
// ExtensionDenylist is the list of file extensions to deny during matching. // ExtensionDenylist is the list of file extensions to deny during matching.
// //
@ -24,10 +24,10 @@ type Request struct {
// in nuclei. // in nuclei.
// examples: // examples:
// - value: '[]string{".avi", ".mov", ".mp3"}' // - value: '[]string{".avi", ".mov", ".mp3"}'
ExtensionDenylist []string `yaml:"denylist,omitempty"` ExtensionDenylist []string `yaml:"denylist,omitempty" jsonschema:"title=extensions to deny match,description=List of file extensions to deny during matching"`
// ID is the ID of the request // ID is the ID of the request
ID string `yaml:"id,omitempty"` ID string `yaml:"id,omitempty" jsonschema:"title=id of the request,description=ID is the optional ID for the request"`
// description: | // description: |
// MaxSize is the maximum size of the file to run request on. // MaxSize is the maximum size of the file to run request on.
@ -36,7 +36,7 @@ type Request struct {
// It can be set to much lower or higher depending on use. // It can be set to much lower or higher depending on use.
// examples: // examples:
// - value: 2048 // - value: 2048
MaxSize int `yaml:"max-size,omitempty"` MaxSize int `yaml:"max-size,omitempty" jsonschema:"title=max size data to run request on,description=Maximum size of the file to run request on"`
CompiledOperators *operators.Operators `yaml:"-"` CompiledOperators *operators.Operators `yaml:"-"`
// cache any variables that may be needed for operation. // cache any variables that may be needed for operation.
@ -46,7 +46,7 @@ type Request struct {
// description: | // description: |
// NoRecursive specifies whether to not do recursive checks if folders are provided. // NoRecursive specifies whether to not do recursive checks if folders are provided.
NoRecursive bool `yaml:"no-recursive,omitempty"` NoRecursive bool `yaml:"no-recursive,omitempty" jsonschema:"title=do not perform recursion,description=Specifies whether to not do recursive checks if folders are provided"`
allExtensions bool allExtensions bool
} }

View File

@ -113,17 +113,17 @@ type Action struct {
// Args contain arguments for the headless action. // Args contain arguments for the headless action.
// //
// Per action arguments are described in detail [here](https://nuclei.projectdiscovery.io/templating-guide/protocols/headless/). // Per action arguments are described in detail [here](https://nuclei.projectdiscovery.io/templating-guide/protocols/headless/).
Data map[string]string `yaml:"args,omitempty"` Data map[string]string `yaml:"args,omitempty" jsonschema:"title=arguments for headless action,description=Args contain arguments for the headless action"`
// description: | // description: |
// Name is the name assigned to the headless action. // Name is the name assigned to the headless action.
// //
// This can be used to execute code, for instance in browser // This can be used to execute code, for instance in browser
// DOM using script action, and get the result in a variable // DOM using script action, and get the result in a variable
// which can be matched upon by nuclei. An Example template [here](https://github.com/projectdiscovery/nuclei-templates/blob/master/headless/prototype-pollution-check.yaml). // which can be matched upon by nuclei. An Example template [here](https://github.com/projectdiscovery/nuclei-templates/blob/master/headless/prototype-pollution-check.yaml).
Name string `yaml:"name,omitempty"` Name string `yaml:"name,omitempty" jsonschema:"title=name for headless action,description=Name is the name assigned to the headless action"`
// description: | // description: |
// Description is the optional description of the headless action // Description is the optional description of the headless action
Description string `yaml:"description,omitempty"` Description string `yaml:"description,omitempty" jsonschema:"title=description for headless action,description=Description of the headless action"`
// description: | // description: |
// Action is the type of the action to perform. // Action is the type of the action to perform.
// values: // values:
@ -148,7 +148,7 @@ type Action struct {
// - "keyboard" // - "keyboard"
// - "debug" // - "debug"
// - "sleep" // - "sleep"
ActionType string `yaml:"action"` ActionType string `yaml:"action" jsonschema:"title=action to perform,description=Type of actions to perform,enum=navigate,enum=script,enum=click,enum=rightclick,enum=text,enum=screenshot,enum=time,enum=select,enum=files,enum=waitload,enum=getresource,enum=extract,enum=setmethod,enum=addheader,enum=setheader,enum=deleteheader,enum=setbody,enum=waitevent,enum=keyboard,enum=debug,enum=sleep"`
} }
// String returns the string representation of an action // String returns the string representation of an action

View File

@ -10,11 +10,11 @@ import (
// Request contains a Headless protocol request to be made from a template // Request contains a Headless protocol request to be made from a template
type Request struct { type Request struct {
// ID is the ID of the request // ID is the ID of the request
ID string `yaml:"id,omitempty"` ID string `yaml:"id,omitempty" jsonschema:"title=id of the request,description=Optional ID of the headless request"`
// description: | // description: |
// Steps is the list of actions to run for headless request // Steps is the list of actions to run for headless request
Steps []*engine.Action `yaml:"steps,omitempty"` Steps []*engine.Action `yaml:"steps,omitempty" jsonschema:"title=list of actions for headless request,description=List of actions to run for headless request"`
// Operators for the current request go here. // Operators for the current request go here.
operators.Operators `yaml:",inline,omitempty"` operators.Operators `yaml:",inline,omitempty"`

View File

@ -23,22 +23,22 @@ type Request struct {
// - name: Some example path values // - name: Some example path values
// value: > // value: >
// []string{"{{BaseURL}}", "{{BaseURL}}/+CSCOU+/../+CSCOE+/files/file_list.json?path=/sessions"} // []string{"{{BaseURL}}", "{{BaseURL}}/+CSCOU+/../+CSCOE+/files/file_list.json?path=/sessions"}
Path []string `yaml:"path,omitempty"` Path []string `yaml:"path,omitempty" jsonschema:"title=path(s) for the http request,description=Path(s) to send http requests to"`
// description: | // description: |
// Raw contains HTTP Requests in Raw format. // Raw contains HTTP Requests in Raw format.
// examples: // examples:
// - name: Some example raw requests // - name: Some example raw requests
// value: | // value: |
// []string{"GET /etc/passwd HTTP/1.1\nHost:\nContent-Length: 4", "POST /.%0d./.%0d./.%0d./.%0d./bin/sh HTTP/1.1\nHost: {{Hostname}}\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:71.0) Gecko/20100101 Firefox/71.0\nContent-Length: 1\nConnection: close\n\necho\necho\ncat /etc/passwd 2>&1"} // []string{"GET /etc/passwd HTTP/1.1\nHost:\nContent-Length: 4", "POST /.%0d./.%0d./.%0d./.%0d./bin/sh HTTP/1.1\nHost: {{Hostname}}\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:71.0) Gecko/20100101 Firefox/71.0\nContent-Length: 1\nConnection: close\n\necho\necho\ncat /etc/passwd 2>&1"}
Raw []string `yaml:"raw,omitempty"` Raw []string `yaml:"raw,omitempty" jsonschema:"http requests in raw format,description=HTTP Requests in Raw Format"`
// ID is the ID of the request // ID is the ID of the request
ID string `yaml:"id,omitempty"` ID string `yaml:"id,omitempty" jsonschema:"title=id for the http request,description=ID for the HTTP Request"`
// description: | // description: |
// Name is the optional name of the request. // Name is the optional name of the request.
// //
// If a name is specified, all the named request in a template can be matched upon // If a name is specified, all the named request in a template can be matched upon
// in a combined manner allowing multirequest based matchers. // in a combined manner allowing multirequest based matchers.
Name string `yaml:"name,omitempty"` Name string `yaml:"name,omitempty" jsonschema:"title=name for the http request,description=Optional name for the HTTP Request"`
// description: | // description: |
// Attack is the type of payload combinations to perform. // Attack is the type of payload combinations to perform.
// //
@ -48,58 +48,63 @@ type Request struct {
// - "sniper" // - "sniper"
// - "pitchfork" // - "pitchfork"
// - "clusterbomb" // - "clusterbomb"
AttackType string `yaml:"attack,omitempty"` AttackType string `yaml:"attack,omitempty" jsonschema:"title=attack is the payload combination,description=Attack is the type of payload combinations to perform,enum=sniper,enum=pitchfork,enum=clusterbomb"`
// description: | // description: |
// Method is the HTTP Request Method. // Method is the HTTP Request Method.
// values: // values:
// - "GET" // - "GET"
// - "HEAD"
// - "POST" // - "POST"
// - "PUT" // - "PUT"
// - "DELETE" // - "DELETE"
Method string `yaml:"method,omitempty"` // - "CONNECT"
// - "OPTIONS"
// - "TRACE"
// - "PATCH"
Method string `yaml:"method,omitempty" jsonschema:"title=method is the http request method,description=Method is the HTTP Request Method,enum=GET,enum=HEAD,enum=POST,enum=PUT,enum=DELETE,enum=CONNECT,enum=OPTIONS,enum=TRACE,enum=PATCH"`
// description: | // description: |
// Body is an optional parameter which contains HTTP Request body. // Body is an optional parameter which contains HTTP Request body.
// examples: // examples:
// - name: Same Body for a Login POST request // - name: Same Body for a Login POST request
// value: "\"username=test&password=test\"" // value: "\"username=test&password=test\""
Body string `yaml:"body,omitempty"` Body string `yaml:"body,omitempty" jsonschema:"title=body is the http request body,description=Body is an optional parameter which contains HTTP Request body"`
// description: | // description: |
// Payloads contains any payloads for the current request. // Payloads contains any payloads for the current request.
// //
// Payloads support both key-values combinations where a list // Payloads support both key-values combinations where a list
// of payloads is provided, or optionally a single file can also // of payloads is provided, or optionally a single file can also
// be provided as payload which will be read on run-time. // be provided as payload which will be read on run-time.
Payloads map[string]interface{} `yaml:"payloads,omitempty"` Payloads map[string]interface{} `yaml:"payloads,omitempty" jsonschema:"title=payloads for the http request,description=Payloads contains any payloads for the current request"`
// description: | // description: |
// Headers contains HTTP Headers to send with the request. // Headers contains HTTP Headers to send with the request.
// examples: // examples:
// - value: | // - value: |
// map[string]string{"Content-Type": "application/x-www-form-urlencoded", "Content-Length": "1", "Any-Header": "Any-Value"} // map[string]string{"Content-Type": "application/x-www-form-urlencoded", "Content-Length": "1", "Any-Header": "Any-Value"}
Headers map[string]string `yaml:"headers,omitempty"` Headers map[string]string `yaml:"headers,omitempty" jsonschema:"title=headers to send with the http request,description=Headers contains HTTP Headers to send with the request"`
// description: | // description: |
// RaceCount is the number of times to send a request in Race Condition Attack. // RaceCount is the number of times to send a request in Race Condition Attack.
// examples: // examples:
// - name: Send a request 5 times // - name: Send a request 5 times
// value: "5" // value: "5"
RaceNumberRequests int `yaml:"race_count,omitempty"` RaceNumberRequests int `yaml:"race_count,omitempty" jsonschema:"title=number of times to repeat request in race condition,description=Number of times to send a request in Race Condition Attack"`
// description: | // description: |
// MaxRedirects is the maximum number of redirects that should be followed. // MaxRedirects is the maximum number of redirects that should be followed.
// examples: // examples:
// - name: Follow upto 5 redirects // - name: Follow upto 5 redirects
// value: "5" // value: "5"
MaxRedirects int `yaml:"max-redirects,omitempty"` MaxRedirects int `yaml:"max-redirects,omitempty" jsonschema:"title=maximum number of redirects to follow,description=Maximum number of redirects that should be followed"`
// description: | // description: |
// PipelineConcurrentConnections is number of connections to create during pipelining. // PipelineConcurrentConnections is number of connections to create during pipelining.
// examples: // examples:
// - name: Create 40 concurrent connections // - name: Create 40 concurrent connections
// value: 40 // value: 40
PipelineConcurrentConnections int `yaml:"pipeline-concurrent-connections,omitempty"` PipelineConcurrentConnections int `yaml:"pipeline-concurrent-connections,omitempty" jsonschema:"title=number of pipelining connections,description=Number of connections to create during pipelining"`
// description: | // description: |
// PipelineRequestsPerConnection is number of requests to send per connection when pipelining. // PipelineRequestsPerConnection is number of requests to send per connection when pipelining.
// examples: // examples:
// - name: Send 100 requests per pipeline connection // - name: Send 100 requests per pipeline connection
// value: 100 // value: 100
PipelineRequestsPerConnection int `yaml:"pipeline-requests-per-connection,omitempty"` PipelineRequestsPerConnection int `yaml:"pipeline-requests-per-connection,omitempty" jsonschema:"title=number of requests to send per pipelining connections,description=Number of requests to send per connection when pipelining"`
// description: | // description: |
// Threads specifies number of threads to use sending requests. This enables Connection Pooling. // Threads specifies number of threads to use sending requests. This enables Connection Pooling.
// //
@ -108,14 +113,13 @@ type Request struct {
// examples: // examples:
// - name: Send requests using 10 concurrent threads // - name: Send requests using 10 concurrent threads
// value: 10 // value: 10
Threads int `yaml:"threads,omitempty"` Threads int `yaml:"threads,omitempty" jsonschema:"title=threads for sending requests,description=Threads specifies number of threads to use sending requests. This enables Connection Pooling"`
// description: | // description: |
// MaxSize is the maximum size of http response body to read in bytes. // MaxSize is the maximum size of http response body to read in bytes.
// examples: // examples:
// - name: Read max 2048 bytes of the response // - name: Read max 2048 bytes of the response
// value: 2048 // value: 2048
MaxSize int `yaml:"max-size,omitempty"` MaxSize int `yaml:"max-size,omitempty" jsonschema:"title=maximum http response body size,description=Maximum size of http response body to read in bytes"`
CompiledOperators *operators.Operators `yaml:"-"` CompiledOperators *operators.Operators `yaml:"-"`
@ -130,33 +134,33 @@ type Request struct {
// description: | // description: |
// CookieReuse is an optional setting that enables cookie reuse for // CookieReuse is an optional setting that enables cookie reuse for
// all requests defined in raw section. // all requests defined in raw section.
CookieReuse bool `yaml:"cookie-reuse,omitempty"` CookieReuse bool `yaml:"cookie-reuse,omitempty" jsonschema:"title=optional cookie reuse enable,description=Optional setting that enables cookie reuse"`
// description: | // description: |
// Redirects specifies whether redirects should be followed by the HTTP Client. // Redirects specifies whether redirects should be followed by the HTTP Client.
// //
// This can be used in conjunction with `max-redirects` to control the HTTP request redirects. // This can be used in conjunction with `max-redirects` to control the HTTP request redirects.
Redirects bool `yaml:"redirects,omitempty"` Redirects bool `yaml:"redirects,omitempty" jsonschema:"title=follow http redirects,description=Specifies whether redirects should be followed by the HTTP Client"`
// description: | // description: |
// Pipeline defines if the attack should be performed with HTTP 1.1 Pipelining // Pipeline defines if the attack should be performed with HTTP 1.1 Pipelining
// //
// All requests must be indempotent (GET/POST). This can be used for race conditions/billions requests. // All requests must be indempotent (GET/POST). This can be used for race conditions/billions requests.
Pipeline bool `yaml:"pipeline,omitempty"` Pipeline bool `yaml:"pipeline,omitempty" jsonschema:"title=perform HTTP 1.1 pipelining,description=Pipeline defines if the attack should be performed with HTTP 1.1 Pipelining"`
// description: | // description: |
// Unsafe specifies whether to use rawhttp engine for sending Non RFC-Compliant requests. // Unsafe specifies whether to use rawhttp engine for sending Non RFC-Compliant requests.
// //
// This uses the [rawhttp](https://github.com/projectdiscovery/rawhttp) engine to achieve complete // This uses the [rawhttp](https://github.com/projectdiscovery/rawhttp) engine to achieve complete
// control over the request, with no normalization performed by the client. // control over the request, with no normalization performed by the client.
Unsafe bool `yaml:"unsafe,omitempty"` Unsafe bool `yaml:"unsafe,omitempty" jsonschema:"title=use rawhttp non-strict-rfc client,description=Unsafe specifies whether to use rawhttp engine for sending Non RFC-Compliant requests"`
// description: | // description: |
// Race determines if all the request have to be attempted at the same time (Race Condition) // Race determines if all the request have to be attempted at the same time (Race Condition)
// //
// The actual number of requests that will be sent is determined by the `race_count` field. // The actual number of requests that will be sent is determined by the `race_count` field.
Race bool `yaml:"race,omitempty"` Race bool `yaml:"race,omitempty" jsonschema:"title=perform race-http request coordination attack,description=Race determines if all the request have to be attempted at the same time (Race Condition)"`
// description: | // description: |
// ReqCondition automatically assigns numbers to requests and preserves their history. // ReqCondition automatically assigns numbers to requests and preserves their history.
// //
// This allows matching on them later for multi-request conditions. // This allows matching on them later for multi-request conditions.
ReqCondition bool `yaml:"req-condition,omitempty"` ReqCondition bool `yaml:"req-condition,omitempty" jsonschema:"title=preserve request history,description=Automatically assigns numbers to requests and preserves their history"`
} }
// GetID returns the unique ID of the request if any. // GetID returns the unique ID of the request if any.

View File

@ -16,17 +16,17 @@ import (
// Request contains a Network protocol request to be made from a template // Request contains a Network protocol request to be made from a template
type Request struct { type Request struct {
// ID is the ID of the request // ID is the ID of the request
ID string `yaml:"id,omitempty"` ID string `yaml:"id,omitempty" jsonschema:"title=id of the request,description=ID of the network request"`
// description: | // description: |
// Address is the address to send requests to. // Host to send network requests to.
// //
// Usually it's set to `{{Hostname}}`. If you want to enable TLS for // Usually it's set to `{{Hostname}}`. If you want to enable TLS for
// TCP Connection, you can use `tls://{{Hostname}}`. // TCP Connection, you can use `tls://{{Hostname}}`.
// examples: // examples:
// - value: | // - value: |
// []string{"{{Hostname}}"} // []string{"{{Hostname}}"}
Address []string `yaml:"host,omitempty"` Address []string `yaml:"host,omitempty" jsonschema:"title=host to send requests to,description=Host to send network requests to"`
addresses []addressKV addresses []addressKV
// description: | // description: |
@ -38,25 +38,25 @@ type Request struct {
// - "sniper" // - "sniper"
// - "pitchfork" // - "pitchfork"
// - "clusterbomb" // - "clusterbomb"
AttackType string `yaml:"attack,omitempty"` AttackType string `yaml:"attack,omitempty" jsonschema:"title=attack is the payload combination,description=Attack is the type of payload combinations to perform,enum=sniper,enum=pitchfork,enum=clusterbomb"`
// description: | // description: |
// Payloads contains any payloads for the current request. // Payloads contains any payloads for the current request.
// //
// Payloads support both key-values combinations where a list // Payloads support both key-values combinations where a list
// of payloads is provided, or optionally a single file can also // of payloads is provided, or optionally a single file can also
// be provided as payload which will be read on run-time. // be provided as payload which will be read on run-time.
Payloads map[string]interface{} `yaml:"payloads,omitempty"` Payloads map[string]interface{} `yaml:"payloads,omitempty" jsonschema:"title=payloads for the network request,description=Payloads contains any payloads for the current request"`
// description: | // description: |
// Inputs contains inputs for the network socket // Inputs contains inputs for the network socket
Inputs []*Input `yaml:"inputs,omitempty"` Inputs []*Input `yaml:"inputs,omitempty" jsonschema:"title=inputs for the network request,description=Inputs contains any input/output for the current request"`
// description: | // description: |
// ReadSize is the size of response to read at the end // ReadSize is the size of response to read at the end
// //
// Default value for read-size is 1024. // Default value for read-size is 1024.
// examples: // examples:
// - value: "2048" // - value: "2048"
ReadSize int `yaml:"read-size,omitempty"` ReadSize int `yaml:"read-size,omitempty" jsonschema:"title=size of network response to read,description=Size of response to read at the end. Default is 1024 bytes"`
// Operators for the current request go here. // Operators for the current request go here.
operators.Operators `yaml:",inline,omitempty"` operators.Operators `yaml:",inline,omitempty"`
@ -84,7 +84,7 @@ type Input struct {
// examples: // examples:
// - value: "\"TEST\"" // - value: "\"TEST\""
// - value: "\"hex_decode('50494e47')\"" // - value: "\"hex_decode('50494e47')\""
Data string `yaml:"data,omitempty"` Data string `yaml:"data,omitempty" jsonschema:"title=data to send as input,description=Data is the data to send as the input"`
// description: | // description: |
// Type is the type of input specified in `data` field. // Type is the type of input specified in `data` field.
// //
@ -92,7 +92,7 @@ type Input struct {
// values: // values:
// - "hex" // - "hex"
// - "text" // - "text"
Type string `yaml:"type,omitempty"` Type string `yaml:"type,omitempty" jsonschema:"title=type is the type of input data,description=Type of input specified in data field,enum=hex,enum=text"`
// description: | // description: |
// Read is the number of bytes to read from socket. // Read is the number of bytes to read from socket.
// //
@ -103,12 +103,12 @@ type Input struct {
// The [network docs](https://nuclei.projectdiscovery.io/templating-guide/protocols/network/) highlight more on how to do this. // The [network docs](https://nuclei.projectdiscovery.io/templating-guide/protocols/network/) highlight more on how to do this.
// examples: // examples:
// - value: "1024" // - value: "1024"
Read int `yaml:"read,omitempty"` Read int `yaml:"read,omitempty" jsonschema:"title=bytes to read from socket,description=Number of bytes to read from socket"`
// description: | // description: |
// Name is the optional name of the data read to provide matching on. // Name is the optional name of the data read to provide matching on.
// examples: // examples:
// - value: "\"prefix\"" // - value: "\"prefix\""
Name string `yaml:"name,omitempty"` Name string `yaml:"name,omitempty" jsonschema:"title=optional name for data read,description=Optional name of the data read to provide matching on"`
} }
// GetID returns the unique ID of the request if any. // GetID returns the unique ID of the request if any.

View File

@ -55,7 +55,7 @@ func (i *Exporter) Export(event *output.ResultEvent) error {
templatePath := strings.TrimPrefix(event.TemplatePath, i.home) templatePath := strings.TrimPrefix(event.TemplatePath, i.home)
h := sha1.New() h := sha1.New()
h.Write([]byte(event.Host)) _, _ = h.Write([]byte(event.Host))
templateID := event.TemplateID + "-" + hex.EncodeToString(h.Sum(nil)) templateID := event.TemplateID + "-" + hex.EncodeToString(h.Sum(nil))
fullDescription := format.MarkdownDescription(event) fullDescription := format.MarkdownDescription(event)

View File

@ -28,39 +28,39 @@ type Template struct {
// examples: // examples:
// - name: ID Example // - name: ID Example
// value: "\"cve-2021-19520\"" // value: "\"cve-2021-19520\""
ID string `yaml:"id"` ID string `yaml:"id" jsonschema:"title=id of the template,description=The Unique ID for the template,example=cve-2021-19520"`
// description: | // description: |
// Info contains metadata information about the template. // Info contains metadata information about the template.
// examples: // examples:
// - value: exampleInfoStructure // - value: exampleInfoStructure
Info model.Info `yaml:"info"` Info model.Info `yaml:"info" jsonschema:"title=info for the template,description=Info contains metadata for the template"`
// description: | // description: |
// Requests contains the http request to make in the template. // Requests contains the http request to make in the template.
// examples: // examples:
// - value: exampleNormalHTTPRequest // - value: exampleNormalHTTPRequest
RequestsHTTP []*http.Request `yaml:"requests,omitempty" json:"requests"` RequestsHTTP []*http.Request `yaml:"requests,omitempty" json:"requests,omitempty" jsonschema:"title=http requests to make,description=HTTP requests to make for the template"`
// description: | // description: |
// DNS contains the dns request to make in the template // DNS contains the dns request to make in the template
// examples: // examples:
// - value: exampleNormalDNSRequest // - value: exampleNormalDNSRequest
RequestsDNS []*dns.Request `yaml:"dns,omitempty" json:"dns"` RequestsDNS []*dns.Request `yaml:"dns,omitempty" json:"dns,omitempty" jsonschema:"title=dns requests to make,description=DNS requests to make for the template"`
// description: | // description: |
// File contains the file request to make in the template // File contains the file request to make in the template
// examples: // examples:
// - value: exampleNormalFileRequest // - value: exampleNormalFileRequest
RequestsFile []*file.Request `yaml:"file,omitempty" json:"file"` RequestsFile []*file.Request `yaml:"file,omitempty" json:"file,omitempty" jsonschema:"title=file requests to make,description=File requests to make for the template"`
// description: | // description: |
// Network contains the network request to make in the template // Network contains the network request to make in the template
// examples: // examples:
// - value: exampleNormalNetworkRequest // - value: exampleNormalNetworkRequest
RequestsNetwork []*network.Request `yaml:"network,omitempty" json:"network"` RequestsNetwork []*network.Request `yaml:"network,omitempty" json:"network,omitempty" jsonschema:"title=network requests to make,description=Network requests to make for the template"`
// description: | // description: |
// Headless contains the headless request to make in the template. // Headless contains the headless request to make in the template.
RequestsHeadless []*headless.Request `yaml:"headless,omitempty" json:"headless"` RequestsHeadless []*headless.Request `yaml:"headless,omitempty" json:"headless,omitempty" jsonschema:"title=headless requests to make,description=Headless requests to make for the template"`
// description: | // description: |
// Workflows is a yaml based workflow declaration code. // Workflows is a yaml based workflow declaration code.
workflows.Workflow `yaml:",inline,omitempty"` workflows.Workflow `yaml:",inline,omitempty" jsonschema:"title=workflows to run,description=Workflows to run for the template"`
CompiledWorkflow *workflows.Workflow `yaml:"-" json:"-" jsonschema:"-"` CompiledWorkflow *workflows.Workflow `yaml:"-" json:"-" jsonschema:"-"`
// TotalRequests is the total number of requests for the template. // TotalRequests is the total number of requests for the template.

View File

@ -9,9 +9,9 @@ import (
type Workflow struct { type Workflow struct {
// description: | // description: |
// Workflows is a list of workflows to execute for a template. // Workflows is a list of workflows to execute for a template.
Workflows []*WorkflowTemplate `yaml:"workflows,omitempty"` Workflows []*WorkflowTemplate `yaml:"workflows,omitempty" jsonschema:"title=list of workflows to execute,description=List of workflows to execute for template"`
Options *protocols.ExecuterOptions Options *protocols.ExecuterOptions `yaml:"-"`
} }
// WorkflowTemplate is a template to be ran as part of a workflow // WorkflowTemplate is a template to be ran as part of a workflow
@ -23,16 +23,16 @@ type WorkflowTemplate struct {
// value: "\"dns/worksites-detection.yaml\"" // value: "\"dns/worksites-detection.yaml\""
// - name: A template directory // - name: A template directory
// value: "\"misconfigurations/aem\"" // value: "\"misconfigurations/aem\""
Template string `yaml:"template,omitempty"` Template string `yaml:"template,omitempty" jsonschema:"title=template/directory to execute,description=Template or directory to execute as part of workflow"`
// description: | // description: |
// Tags to run templates based on. // Tags to run templates based on.
Tags model.StringSlice `yaml:"tags,omitempty"` Tags model.StringSlice `yaml:"tags,omitempty" jsonschema:"title=tags to execute,description=Tags to run template based on"`
// description: | // description: |
// Matchers perform name based matching to run subtemplates for a workflow. // Matchers perform name based matching to run subtemplates for a workflow.
Matchers []*Matcher `yaml:"matchers,omitempty"` Matchers []*Matcher `yaml:"matchers,omitempty" jsonschema:"title=name based template result matchers,description=Matchers perform name based matching to run subtemplates for a workflow"`
// description: | // description: |
// Subtemplates are ran if the `template` field Template matches. // Subtemplates are ran if the `template` field Template matches.
Subtemplates []*WorkflowTemplate `yaml:"subtemplates,omitempty"` Subtemplates []*WorkflowTemplate `yaml:"subtemplates,omitempty" jsonschema:"title=subtemplate based result matchers,description=Subtemplates are ran if the template field Template matches"`
// Executers perform the actual execution for the workflow template // Executers perform the actual execution for the workflow template
Executers []*ProtocolExecuterPair `yaml:"-"` Executers []*ProtocolExecuterPair `yaml:"-"`
} }
@ -47,8 +47,8 @@ type ProtocolExecuterPair struct {
type Matcher struct { type Matcher struct {
// description: | // description: |
// Name is the name of the item to match. // Name is the name of the item to match.
Name string `yaml:"name,omitempty"` Name string `yaml:"name,omitempty" jsonschema:"title=name of item to match,description=Name of item to match"`
// description: | // description: |
// Subtemplates are ran if the name of matcher matches. // Subtemplates are ran if the name of matcher matches.
Subtemplates []*WorkflowTemplate `yaml:"subtemplates,omitempty"` Subtemplates []*WorkflowTemplate `yaml:"subtemplates,omitempty" jsonschema:"title=templates to run after match,description=Templates to run after match"`
} }