Merge remote-tracking branch 'origin/dev' into code_smells

dev
forgedhallpass 2021-09-10 15:33:09 +03:00
commit c762cc88aa
23 changed files with 672 additions and 3725 deletions

View File

@ -2,7 +2,9 @@ name: ⏰ Publish Docs
on:
push:
pull_request:
branches:
- master
- dev
workflow_dispatch:
jobs:

View File

@ -282,7 +282,7 @@ name: Nagios Default Credentials Check
<div class="dd">
<code>author</code> <i>StringSlice</i>
<code>author</code> <i><a href="#stringslicestringslice">stringslice.StringSlice</a></i>
</div>
<div class="dt">
@ -307,7 +307,7 @@ author: <username>
<div class="dd">
<code>tags</code> <i>StringSlice</i>
<code>tags</code> <i><a href="#stringslicestringslice">stringslice.StringSlice</a></i>
</div>
<div class="dt">
@ -362,7 +362,7 @@ description: Subversion ALM for the enterprise before 8.8.2 allows reflected XSS
<div class="dd">
<code>reference</code> <i>StringSlice</i>
<code>reference</code> <i><a href="#stringslicestringslice">stringslice.StringSlice</a></i>
</div>
<div class="dt">
@ -389,7 +389,7 @@ reference:
<div class="dd">
<code>severity</code> <i><a href="#severityseverityholder">severity.SeverityHolder</a></i>
<code>severity</code> <i><a href="#severityholder">severity.Holder</a></i>
</div>
<div class="dt">
@ -437,22 +437,90 @@ additional-fields:
<hr />
<div class="dd">
<code>classification</code> <i><a href="#modelclassification">model.Classification</a></i>
</div>
<div class="dt">
Classification contains classification information about the template.
</div>
<hr />
<div class="dd">
<code>remediation</code> <i>string</i>
</div>
<div class="dt">
Remediation steps for the template.
You can go in-depth here on how to mitigate the problem found by this template.
Examples:
```yaml
remediation: Change the default administrative username and password of Apache ActiveMQ by editing the file jetty-realm.properties
```
</div>
<hr />
## model.StringSlice
## stringslice.StringSlice
StringSlice represents a single (in-lined) or multiple string value(s).
The unmarshaller does not automatically convert in-lined strings to []string, hence the interface{} type is required.
Appears in:
- <code><a href="#modelinfo">model.Info</a>.author</code>
- <code><a href="#modelinfo">model.Info</a>.tags</code>
- <code><a href="#modelinfo">model.Info</a>.reference</code>
- <code><a href="#modelclassification">model.Classification</a>.cve-id</code>
- <code><a href="#modelclassification">model.Classification</a>.cwe-id</code>
- <code><a href="#workflowsworkflowtemplate">workflows.WorkflowTemplate</a>.tags</code>
```yaml
<username>
```
```yaml
# Example tags
cve,cve2019,grafana,auth-bypass,dos
```
```yaml
- https://github.com/strapi/strapi
- https://github.com/getgrav/grav
```
```yaml
CVE-2020-14420
```
```yaml
CWE-22
```
## severity.SeverityHolder
## severity.Holder
Holder holds a Severity type. Required for un/marshalling purposes
Appears in:
@ -463,6 +531,113 @@ Appears in:
## model.Classification
Appears in:
- <code><a href="#modelinfo">model.Info</a>.classification</code>
<hr />
<div class="dd">
<code>cve-id</code> <i><a href="#stringslicestringslice">stringslice.StringSlice</a></i>
</div>
<div class="dt">
CVE ID for the template
Examples:
```yaml
cve-id: CVE-2020-14420
```
</div>
<hr />
<div class="dd">
<code>cwe-id</code> <i><a href="#stringslicestringslice">stringslice.StringSlice</a></i>
</div>
<div class="dt">
CWE ID for the template.
Examples:
```yaml
cwe-id: CWE-22
```
</div>
<hr />
<div class="dd">
<code>cvss-metrics</code> <i>string</i>
</div>
<div class="dt">
CVSS Metrics for the template.
Examples:
```yaml
cvss-metrics: 3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
```
</div>
<hr />
<div class="dd">
<code>cvss-score</code> <i>float64</i>
</div>
<div class="dt">
CVSS Score for the template.
Examples:
```yaml
cvss-score: "9.8"
```
</div>
<hr />
## http.Request
Request contains a http request to be made from a template
@ -2617,7 +2792,7 @@ template: misconfigurations/aem
<div class="dd">
<code>tags</code> <i><a href="#modelstringslice">model.StringSlice</a></i>
<code>tags</code> <i><a href="#stringslicestringslice">stringslice.StringSlice</a></i>
</div>
<div class="dt">

View File

@ -2,17 +2,34 @@
"$schema": "http://json-schema.org/draft-04/schema#",
"$ref": "#/definitions/templates.Template",
"definitions": {
"severity.SeverityHolder": {
"enum": [
"info",
"low",
"medium",
"high",
"critical"
],
"type": "string",
"title": "severity of the template",
"description": "Seriousness of the implications of the template"
"model.Classification": {
"properties": {
"cve-id": {
"$ref": "#/definitions/stringslice.StringSlice",
"title": "cve ids for the template",
"description": "CVE IDs for the template"
},
"cwe-id": {
"$ref": "#/definitions/stringslice.StringSlice",
"title": "cwe ids for the template",
"description": "CWE IDs for the template"
},
"cvss-metrics": {
"type": "string",
"title": "cvss metrics for the template",
"description": "CVSS Metrics for the template",
"examples": [
"3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
]
},
"cvss-score": {
"type": "number",
"title": "cvss score for the template",
"description": "CVSS Score for the template"
}
},
"additionalProperties": false,
"type": "object"
},
"model.Info": {
"properties": {
@ -26,12 +43,12 @@
},
"author": {
"$schema": "http://json-schema.org/draft-04/schema#",
"$ref": "#/definitions/model.StringSlice",
"$ref": "#/definitions/stringslice.StringSlice",
"title": "author of the template",
"description": "Author is the author of the template"
},
"tags": {
"$ref": "#/definitions/model.StringSlice",
"$ref": "#/definitions/stringslice.StringSlice",
"title": "tags of the template",
"description": "Any tags for the template"
},
@ -44,13 +61,13 @@
]
},
"reference": {
"$ref": "#/definitions/model.StringSlice",
"$ref": "#/definitions/stringslice.StringSlice",
"title": "references for the template",
"description": "Links relevant to the template"
},
"severity": {
"$schema": "http://json-schema.org/draft-04/schema#",
"$ref": "#/definitions/severity.SeverityHolder"
"$ref": "#/definitions/severity.Holder"
},
"additional-fields": {
"patternProperties": {
@ -61,12 +78,38 @@
"type": "object",
"title": "additional metadata for the template",
"description": "Additional metadata fields for the template"
},
"classification": {
"$schema": "http://json-schema.org/draft-04/schema#",
"$ref": "#/definitions/model.Classification",
"title": "classification info for the template",
"description": "Classification information for the template"
},
"remediation": {
"type": "string",
"title": "remediation steps for the template",
"description": "In-depth explanation on how to fix the issues found by the template",
"examples": [
"Change the default administrative username and password of Apache ActiveMQ by editing the file jetty-realm.properties"
]
}
},
"additionalProperties": false,
"type": "object"
},
"model.StringSlice": {
"severity.Holder": {
"enum": [
"info",
"low",
"medium",
"high",
"critical"
],
"type": "string",
"title": "severity of the template",
"description": "Seriousness of the implications of the template"
},
"stringslice.StringSlice": {
"oneOf": [
{
"type": "string"
@ -885,7 +928,7 @@
"description": "Template or directory to execute as part of workflow"
},
"tags": {
"$ref": "#/definitions/model.StringSlice",
"$ref": "#/definitions/stringslice.StringSlice",
"title": "tags to execute",
"description": "Tags to run template based on"
},

159
v2/cmd/cve-annotate/main.go Normal file
View File

@ -0,0 +1,159 @@
package main
import (
"flag"
"fmt"
"io/ioutil"
"log"
"os"
"regexp"
"strings"
"github.com/Ice3man543/nvd"
"github.com/projectdiscovery/nuclei/v2/pkg/catalog"
)
var (
input = flag.String("i", "", "Templates to annotate")
templateDir = flag.String("d", "", "Custom template directory for update")
)
func main() {
flag.Parse()
if *input == "" || *templateDir == "" {
log.Fatalf("invalid input, see -h\n")
}
if err := process(); err != nil {
log.Fatalf("could not process: %s\n", err)
}
}
func process() error {
tempDir, err := ioutil.TempDir("", "nuclei-nvd-%s")
if err != nil {
return err
}
defer os.RemoveAll(tempDir)
client, err := nvd.NewClient(tempDir)
if err != nil {
return err
}
catalog := catalog.New(*templateDir)
paths, err := catalog.GetTemplatePath(*input)
if err != nil {
return err
}
for _, path := range paths {
data, err := ioutil.ReadFile(path)
if err != nil {
return err
}
getCVEData(client, path, string(data))
}
return nil
}
var (
idRegex = regexp.MustCompile("id: ([C|c][V|v][E|e]-[0-9]+-[0-9]+)")
severityRegex = regexp.MustCompile(`severity: ([a-z]+)`)
)
func getCVEData(client *nvd.Client, filePath, data string) {
matches := idRegex.FindAllStringSubmatch(data, 1)
if len(matches) == 0 {
return
}
cveName := matches[0][1]
severityMatches := severityRegex.FindAllStringSubmatch(data, 1)
if len(matches) == 0 {
return
}
severityValue := severityMatches[0][1]
cveItem, err := client.FetchCVE(cveName)
if err != nil {
log.Printf("Could not fetch cve %s: %s\n", cveName, err)
return
}
var cweID []string
for _, problemData := range cveItem.CVE.Problemtype.ProblemtypeData {
for _, description := range problemData.Description {
cweID = append(cweID, description.Value)
}
}
cvssScore := cveItem.Impact.BaseMetricV3.CvssV3.BaseScore
cvssMetrics := cveItem.Impact.BaseMetricV3.CvssV3.VectorString
// Perform some hacky string replacement to place the metadata in templates
infoBlockIndexData := data[strings.Index(data, "info:"):]
requestsIndex := strings.Index(infoBlockIndexData, "requests:")
networkIndex := strings.Index(infoBlockIndexData, "network:")
if requestsIndex == -1 && networkIndex == -1 {
return
}
if networkIndex != -1 {
requestsIndex = networkIndex
}
infoBlockData := infoBlockIndexData[:requestsIndex]
infoBlockClean := strings.TrimRight(infoBlockData, "\n")
newInfoBlock := infoBlockClean
var changed bool
if newSeverity := isSeverityMatchingCvssScore(severityValue, cvssScore); newSeverity != "" {
changed = true
newInfoBlock = strings.ReplaceAll(newInfoBlock, severityMatches[0][0], "severity: "+newSeverity)
fmt.Printf("Adjusting severity for %s from %s=>%s (%.2f)\n", filePath, severityValue, newSeverity, cvssScore)
}
// Start with additional-fields as that is the one most likely to break stuff.
if !strings.Contains(infoBlockClean, "classification") && (cvssScore != 0 && cvssMetrics != "") {
changed = true
newInfoBlock = newInfoBlock + fmt.Sprintf("\n classification:\n cvss-metrics: %s\n cvss-score: %.2f\n cve-id: %s", cvssMetrics, cvssScore, cveName)
if len(cweID) > 0 && (cweID[0] != "NVD-CWE-Other" && cweID[0] != "NVD-CWE-noinfo") {
newInfoBlock = newInfoBlock + fmt.Sprintf("\n cwe-id: %s", strings.Join(cweID, ","))
}
}
// If there is no description field, fill the description from CVE information
if !strings.Contains(infoBlockClean, "description:") {
changed = true
newInfoBlock = newInfoBlock + fmt.Sprintf("\n description: %s", fmt.Sprintf("%q", cveItem.CVE.Description.DescriptionData[0].Value))
}
if !strings.Contains(infoBlockClean, "reference:") && len(cveItem.CVE.References.ReferenceData) > 0 {
changed = true
newInfoBlock = newInfoBlock + "\n reference:"
for _, reference := range cveItem.CVE.References.ReferenceData {
newInfoBlock = newInfoBlock + fmt.Sprintf("\n - %s", reference.URL)
}
}
newTemplate := strings.ReplaceAll(data, infoBlockClean, newInfoBlock)
if changed {
_ = ioutil.WriteFile(filePath, []byte(newTemplate), 0777)
fmt.Printf("Wrote updated template to %s\n", filePath)
}
}
func isSeverityMatchingCvssScore(severity string, score float64) string {
if score == 0.0 {
return ""
}
var expected string
if score >= 0.1 && score <= 3.9 {
expected = "low"
} else if score >= 4.0 && score <= 6.9 {
expected = "medium"
} else if score >= 7.0 && score <= 8.9 {
expected = "high"
} else if score >= 9.0 && score <= 10.0 {
expected = "critical"
}
if expected != "" && expected != severity {
return expected
}
return ""
}

View File

@ -3,6 +3,7 @@ module github.com/projectdiscovery/nuclei/v2
go 1.16
require (
github.com/Ice3man543/nvd v1.0.6
github.com/Knetic/govaluate v3.0.0+incompatible
github.com/akrylysov/pogreb v0.10.1 // indirect
github.com/alecthomas/jsonschema v0.0.0-20210818095345-1014919a589c
@ -13,7 +14,6 @@ require (
github.com/bluele/gcache v0.0.2
github.com/c4milo/unpackit v0.1.0 // indirect
github.com/corpix/uarand v0.1.1
github.com/davecgh/go-spew v1.1.1
github.com/go-rod/rod v0.91.1
github.com/google/go-github v17.0.0+incompatible
github.com/gosuri/uilive v0.0.4 // indirect

View File

@ -37,6 +37,8 @@ github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIo
github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Ice3man543/nvd v1.0.6 h1:QnCqnuYAA9tY2F38oNXp/kFV5fnYq+44mmcDFhKyawc=
github.com/Ice3man543/nvd v1.0.6/go.mod h1:0DxLJk6revOcJKiZxa2K+rNF/HO1zJO97lqQtXhXfSc=
github.com/Knetic/govaluate v3.0.0+incompatible h1:7o6+MAPhYTCF0+fdvoz1xDedhRb4f6s9Tn1Tt7/WTEg=
github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/Masterminds/glide v0.13.2/go.mod h1:STyF5vcenH/rUqTEv+/hBXlSTo7KYwg2oc2f4tzPWic=
@ -45,9 +47,10 @@ github.com/Masterminds/vcs v1.13.0/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHS
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8=
github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
github.com/PuerkitoBio/goquery v1.6.0 h1:j7taAbelrdcsOlGeMenZxc2AWXD5fieT1/znArdnx94=
github.com/PuerkitoBio/goquery v1.6.0/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA=
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/go.mod h1:pNs6QmpQ1UlTJKDezuRWmaqkgUE2TuU0YTWyqJZ7+lI=
github.com/akrylysov/pogreb v0.10.1 h1:FqlR8VR7uCbJdfUob916tPM+idpKgeESDXOA1K0DK4w=
github.com/akrylysov/pogreb v0.10.1/go.mod h1:pNs6QmpQ1UlTJKDezuRWmaqkgUE2TuU0YTWyqJZ7+lI=
@ -55,6 +58,8 @@ github.com/alecthomas/jsonschema v0.0.0-20210818095345-1014919a589c h1:oJsq4z4xK
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/go.mod h1:rFgpPQZYZ8vdbc+48xibu8ALc3yeyd64IhHS+PU6Yyg=
github.com/andybalholm/cascadia v1.1.0 h1:BuuO6sSfQNFRu1LppgbD25Hr2vLYW25JvxHs5zzsLTo=
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
github.com/andygrunwald/go-jira v1.14.0 h1:7GT/3qhar2dGJ0kq8w0d63liNyHOnxZsUZ9Pe4+AKBI=
github.com/andygrunwald/go-jira v1.14.0/go.mod h1:KMo2f4DgMZA1C9FdImuLc04x4WQhn5derQpnsuBFgqE=
github.com/antchfx/htmlquery v1.2.3 h1:sP3NFDneHx2stfNXCKbhHFo8XgNjCACnU/4AO5gWz6M=
@ -96,6 +101,8 @@ github.com/corpix/uarand v0.1.1 h1:RMr1TWc9F4n5jiPDzFHtmaUXLKLNUFK0SgCLo4BhX/U=
github.com/corpix/uarand v0.1.1/go.mod h1:SFKZvkcRoLqVRFZ4u25xPmp6m9ktANfbpXZ7SJ0/FNU=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/daehee/nvd v1.0.4 h1:qC0kJ68vAYS86v8GwBORReBhyC5yUaUzsBokxjlsT98=
github.com/daehee/nvd v1.0.4/go.mod h1:iBRJHIdIs+ylfq8630my2eMw8kwzH4Z7qsetjJZxCzs=
github.com/dave/dst v0.26.2 h1:lnxLAKI3tx7MgLNVDirFCsDTlTG9nKTk7GcptKcWSwY=
github.com/dave/dst v0.26.2/go.mod h1:UMDJuIRPfyUCC78eFuB+SV/WI8oDeyFDvM/JR6NI3IU=
github.com/dave/gopackages v0.0.0-20170318123100-46e7023ec56e/go.mod h1:i00+b/gKdIDIxuLDFob7ustLAVqhsZRk2qVZrArELGQ=
@ -229,7 +236,6 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO
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/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
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/gojq v0.12.4 h1:8zgOZWMejEWCLjbF/1mWY7hY7QEARm7dtuhC6Bp4R8o=
@ -276,13 +282,11 @@ github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczG
github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA=
github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
@ -510,6 +514,7 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0 h1:8pl+sMODzuvGJkmj2W4kZihvVb5mKm8pB/X44PIQHv8=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -614,7 +619,6 @@ golang.org/x/sys v0.0.0-20210415045647-66c3f260301c/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210601080250-7ecdf8ef093b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf h1:2ucpDCmfkl8Bd/FsLtiD653Wf96cW37s+iGx93zsu4k=
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -705,7 +709,6 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=

View File

@ -20,6 +20,6 @@ func showBanner() {
gologger.Print().Msgf("%s\n", banner)
gologger.Print().Msgf("\t\tprojectdiscovery.io\n\n")
gologger.Error().Label("WRN").Msgf("Use with caution. You are responsible for your actions\n")
gologger.Error().Label("WRN").Msgf("Use with caution. You are responsible for your actions.\n")
gologger.Error().Label("WRN").Msgf("Developers assume no liability and are not responsible for any misuse or damage.\n")
}

View File

@ -189,7 +189,7 @@ func New(options *types.Options) (*Runner, error) {
}
// Create the output file if asked
outputWriter, err := output.NewStandardWriter(!options.NoColor, options.NoMeta, options.NoTimestamp, options.JSON, options.Output, options.TraceLogFile)
outputWriter, err := output.NewStandardWriter(!options.NoColor, options.NoMeta, options.NoTimestamp, options.JSON, options.JSONRequests, options.Output, options.TraceLogFile)
if err != nil {
return nil, errors.Wrap(err, "could not create output file")
}
@ -439,7 +439,7 @@ func (r *Runner) RunEnumeration() error {
}
templatesMap := make(map[string]*templates.Template)
for _, v := range store.Templates() {
templatesMap[v.ID] = v
templatesMap[v.Path] = v
}
originalTemplatesCount := len(store.Templates())
clusterCount := 0
@ -471,6 +471,7 @@ func (r *Runner) RunEnumeration() error {
finalTemplates = append(finalTemplates, cluster...)
}
}
finalTemplates = append(finalTemplates, store.Workflows()...)
var totalRequests int64

View File

@ -1,914 +0,0 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"$ref": "#/definitions/templates.Template",
"definitions": {
"severity.SeverityHolder": {
"enum": [
"info",
"low",
"medium",
"high",
"critical"
],
"type": "string",
"title": "severity of the template",
"description": "Seriousness of the implications of the template"
},
"model.Info": {
"properties": {
"name": {
"type": "string",
"title": "name of the template",
"description": "Name is a short summary of what the template does",
"examples": [
"Nagios Default Credentials Check"
]
},
"author": {
"$schema": "http://json-schema.org/draft-04/schema#",
"$ref": "#/definitions/model.StringSlice",
"title": "author of the template",
"description": "Author is the author of the template"
},
"tags": {
"$ref": "#/definitions/model.StringSlice",
"title": "tags of the template",
"description": "Any tags for the template"
},
"description": {
"type": "string",
"title": "description of the template",
"description": "In-depth explanation on what the template does",
"examples": [
"Bower is a package manager which stores packages informations in bower.json file"
]
},
"reference": {
"$ref": "#/definitions/model.StringSlice",
"title": "references for the template",
"description": "Links relevant to the template"
},
"severity": {
"$schema": "http://json-schema.org/draft-04/schema#",
"$ref": "#/definitions/severity.SeverityHolder"
},
"additional-fields": {
"patternProperties": {
".*": {
"type": "string"
}
},
"type": "object",
"title": "additional metadata for the template",
"description": "Additional metadata fields for the template"
}
},
"additionalProperties": false,
"type": "object"
},
"model.StringSlice": {
"oneOf": [
{
"type": "string"
},
{
"type": "array"
}
]
},
"extractors.Extractor": {
"required": [
"type"
],
"properties": {
"name": {
"type": "string",
"title": "name of the extractor",
"description": "Name of the extractor"
},
"type": {
"enum": [
"regex",
"kval",
"json",
"xpath"
],
"type": "string",
"title": "type of the extractor",
"description": "Type of the extractor"
},
"regex": {
"items": {
"type": "string"
},
"type": "array",
"title": "regex to extract from part",
"description": "Regex to extract from part"
},
"group": {
"type": "integer",
"title": "group to extract from regex",
"description": "Group to extract from regex"
},
"kval": {
"items": {
"type": "string"
},
"type": "array",
"title": "kval pairs to extract from response",
"description": "Kval pairs to extract from response"
},
"json": {
"items": {
"type": "string"
},
"type": "array",
"title": "json jq expressions to extract data",
"description": "JSON JQ expressions to evaluate from response part"
},
"xpath": {
"items": {
"type": "string"
},
"type": "array",
"title": "html xpath expressions to extract data",
"description": "XPath allows using xpath expressions to extract items from html response"
},
"attribute": {
"type": "string",
"title": "optional attribute to extract from xpath",
"description": "Optional attribute to extract from response XPath"
},
"part": {
"type": "string",
"title": "part of response to extract data from",
"description": "Part of the request response to extract data from"
},
"internal": {
"type": "boolean",
"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"
}
},
"additionalProperties": false,
"type": "object"
},
"matchers.Matcher": {
"required": [
"type"
],
"properties": {
"type": {
"enum": [
"status",
"size",
"word",
"regex",
"dsl"
],
"type": "string",
"title": "type of matcher",
"description": "Type of the matcher"
},
"condition": {
"enum": [
"and",
"or"
],
"type": "string",
"title": "condition between matcher variables",
"description": "Condition between the matcher variables"
},
"part": {
"type": "string",
"title": "part of response to match",
"description": "Part of response to match data from"
},
"negative": {
"type": "boolean",
"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"
},
"name": {
"type": "string",
"title": "name of the matcher",
"description": "Name of the matcher"
},
"status": {
"items": {
"type": "integer"
},
"type": "array",
"title": "status to match",
"description": "Status to match for the response"
},
"size": {
"items": {
"type": "integer"
},
"type": "array",
"title": "acceptable size for response",
"description": "Size is the acceptable size for the response"
},
"words": {
"items": {
"type": "string"
},
"type": "array",
"title": "words to match in response",
"description": " Words contains word patterns required to be present in the response part"
},
"regex": {
"items": {
"type": "string"
},
"type": "array",
"title": "regex to match in response",
"description": "Regex contains regex patterns required to be present in the response part"
},
"binary": {
"items": {
"type": "string"
},
"type": "array",
"title": "binary patterns to match in response",
"description": "Binary are the binary patterns required to be present in the response part"
},
"dsl": {
"items": {
"type": "string"
},
"type": "array",
"title": "dsl expressions to match in response",
"description": "DSL are the dsl expressions that will be evaluated as part of nuclei matching rules"
},
"encoding": {
"enum": [
"hex"
],
"type": "string",
"title": "encoding for word field",
"description": "Optional encoding for the word fields"
}
},
"additionalProperties": false,
"type": "object"
},
"dns.Request": {
"properties": {
"matchers": {
"items": {
"$ref": "#/definitions/matchers.Matcher"
},
"type": "array",
"title": "matchers to run on response",
"description": "Detection mechanism to identify whether the request was successful by doing pattern matching"
},
"extractors": {
"items": {
"$ref": "#/definitions/extractors.Extractor"
},
"type": "array",
"title": "extractors to run on response",
"description": "Extractors contains the extraction mechanism for the request to identify and extract parts of the response"
},
"matchers-condition": {
"enum": [
"and",
"or"
],
"type": "string",
"title": "condition between the matchers",
"description": "Conditions between the matchers"
},
"id": {
"type": "string",
"title": "id of the dns request",
"description": "ID is the optional ID of the DNS Request"
},
"name": {
"type": "string",
"title": "hostname to make dns request for",
"description": "Name is the Hostname to make DNS request for"
},
"type": {
"enum": [
"A",
"NS",
"DS",
"CNAME",
"SOA",
"PTR",
"MX",
"TXT",
"AAAA"
],
"type": "string",
"title": "type of dns request to make",
"description": "Type is the type of DNS request to make"
},
"class": {
"enum": [
"inet",
"csnet",
"chaos",
"hesiod",
"none",
"any"
],
"type": "string",
"title": "class of DNS request",
"description": "Class is the class of the DNS request"
},
"retries": {
"type": "integer",
"title": "retries for dns request",
"description": "Retries is the number of retries for the DNS request"
},
"recursion": {
"type": "boolean",
"title": "recurse all servers",
"description": "Recursion determines if resolver should recurse all records to get fresh results"
}
},
"additionalProperties": false,
"type": "object"
},
"file.Request": {
"properties": {
"matchers": {
"items": {
"$ref": "#/definitions/matchers.Matcher"
},
"type": "array",
"title": "matchers to run on response",
"description": "Detection mechanism to identify whether the request was successful by doing pattern matching"
},
"extractors": {
"items": {
"$ref": "#/definitions/extractors.Extractor"
},
"type": "array",
"title": "extractors to run on response",
"description": "Extractors contains the extraction mechanism for the request to identify and extract parts of the response"
},
"matchers-condition": {
"enum": [
"and",
"or"
],
"type": "string",
"title": "condition between the matchers",
"description": "Conditions between the matchers"
},
"extensions": {
"items": {
"type": "string"
},
"type": "array",
"title": "extensions to match",
"description": "List of extensions to perform matching on"
},
"denylist": {
"items": {
"type": "string"
},
"type": "array",
"title": "extensions to deny match",
"description": "List of file extensions to deny during matching"
},
"id": {
"type": "string",
"title": "id of the request",
"description": "ID is the optional ID for the request"
},
"max-size": {
"type": "integer",
"title": "max size data to run request on",
"description": "Maximum size of the file to run request on"
},
"no-recursive": {
"type": "boolean",
"title": "do not perform recursion",
"description": "Specifies whether to not do recursive checks if folders are provided"
}
},
"additionalProperties": false,
"type": "object"
},
"headless.Request": {
"properties": {
"id": {
"type": "string",
"title": "id of the request",
"description": "Optional ID of the headless request"
},
"steps": {
"items": {
"$schema": "http://json-schema.org/draft-04/schema#",
"$ref": "#/definitions/engine.Action"
},
"type": "array",
"title": "list of actions for headless request",
"description": "List of actions to run for headless request"
},
"matchers": {
"items": {
"$ref": "#/definitions/matchers.Matcher"
},
"type": "array",
"title": "matchers to run on response",
"description": "Detection mechanism to identify whether the request was successful by doing pattern matching"
},
"extractors": {
"items": {
"$ref": "#/definitions/extractors.Extractor"
},
"type": "array",
"title": "extractors to run on response",
"description": "Extractors contains the extraction mechanism for the request to identify and extract parts of the response"
},
"matchers-condition": {
"enum": [
"and",
"or"
],
"type": "string",
"title": "condition between the matchers",
"description": "Conditions between the matchers"
}
},
"additionalProperties": false,
"type": "object"
},
"engine.Action": {
"required": [
"action"
],
"properties": {
"args": {
"patternProperties": {
".*": {
"type": "string"
}
},
"type": "object",
"title": "arguments for headless action",
"description": "Args contain arguments for the headless action"
},
"name": {
"type": "string",
"title": "name for headless action",
"description": "Name is the name assigned to the headless action"
},
"description": {
"type": "string",
"title": "description for headless action",
"description": "Description of the headless action"
},
"action": {
"enum": [
"navigate",
"script",
"click",
"rightclick",
"text",
"screenshot",
"time",
"select",
"files",
"waitload",
"getresource",
"extract",
"setmethod",
"addheader",
"setheader",
"deleteheader",
"setbody",
"waitevent",
"keyboard",
"debug",
"sleep"
],
"type": "string",
"title": "action to perform",
"description": "Type of actions to perform"
}
},
"additionalProperties": false,
"type": "object"
},
"http.Request": {
"properties": {
"matchers": {
"items": {
"$schema": "http://json-schema.org/draft-04/schema#",
"$ref": "#/definitions/matchers.Matcher"
},
"type": "array",
"title": "matchers to run on response",
"description": "Detection mechanism to identify whether the request was successful by doing pattern matching"
},
"extractors": {
"items": {
"$schema": "http://json-schema.org/draft-04/schema#",
"$ref": "#/definitions/extractors.Extractor"
},
"type": "array",
"title": "extractors to run on response",
"description": "Extractors contains the extraction mechanism for the request to identify and extract parts of the response"
},
"matchers-condition": {
"enum": [
"and",
"or"
],
"type": "string",
"title": "condition between the matchers",
"description": "Conditions between the matchers"
},
"path": {
"items": {
"type": "string"
},
"type": "array",
"title": "path(s) for the http request",
"description": "Path(s) to send http requests to"
},
"raw": {
"items": {
"type": "string"
},
"type": "array",
"description": "HTTP Requests in Raw Format"
},
"id": {
"type": "string",
"title": "id for the http request",
"description": "ID for the HTTP Request"
},
"name": {
"type": "string",
"title": "name for the http request",
"description": "Optional name for the HTTP Request"
},
"attack": {
"enum": [
"sniper",
"pitchfork",
"clusterbomb"
],
"type": "string",
"title": "attack is the payload combination",
"description": "Attack is the type of payload combinations to perform"
},
"method": {
"enum": [
"GET",
"HEAD",
"POST",
"PUT",
"DELETE",
"CONNECT",
"OPTIONS",
"TRACE",
"PATCH"
],
"type": "string",
"title": "method is the http request method",
"description": "Method is the HTTP Request Method"
},
"body": {
"type": "string",
"title": "body is the http request body",
"description": "Body is an optional parameter which contains HTTP Request body"
},
"payloads": {
"patternProperties": {
".*": {
"additionalProperties": true
}
},
"type": "object",
"title": "payloads for the http request",
"description": "Payloads contains any payloads for the current request"
},
"headers": {
"patternProperties": {
".*": {
"type": "string"
}
},
"type": "object",
"title": "headers to send with the http request",
"description": "Headers contains HTTP Headers to send with the request"
},
"race_count": {
"type": "integer",
"title": "number of times to repeat request in race condition",
"description": "Number of times to send a request in Race Condition Attack"
},
"max-redirects": {
"type": "integer",
"title": "maximum number of redirects to follow",
"description": "Maximum number of redirects that should be followed"
},
"pipeline-concurrent-connections": {
"type": "integer",
"title": "number of pipelining connections",
"description": "Number of connections to create during pipelining"
},
"pipeline-requests-per-connection": {
"type": "integer",
"title": "number of requests to send per pipelining connections",
"description": "Number of requests to send per connection when pipelining"
},
"threads": {
"type": "integer",
"title": "threads for sending requests",
"description": "Threads specifies number of threads to use sending requests. This enables Connection Pooling"
},
"max-size": {
"type": "integer",
"title": "maximum http response body size",
"description": "Maximum size of http response body to read in bytes"
},
"cookie-reuse": {
"type": "boolean",
"title": "optional cookie reuse enable",
"description": "Optional setting that enables cookie reuse"
},
"redirects": {
"type": "boolean",
"title": "follow http redirects",
"description": "Specifies whether redirects should be followed by the HTTP Client"
},
"pipeline": {
"type": "boolean",
"title": "perform HTTP 1.1 pipelining",
"description": "Pipeline defines if the attack should be performed with HTTP 1.1 Pipelining"
},
"unsafe": {
"type": "boolean",
"title": "use rawhttp non-strict-rfc client",
"description": "Unsafe specifies whether to use rawhttp engine for sending Non RFC-Compliant requests"
},
"race": {
"type": "boolean",
"title": "perform race-http request coordination attack",
"description": "Race determines if all the request have to be attempted at the same time (Race Condition)"
},
"req-condition": {
"type": "boolean",
"title": "preserve request history",
"description": "Automatically assigns numbers to requests and preserves their history"
},
"stop-at-first-match": {
"type": "boolean",
"title": "stop at first match",
"description": "Stop the execution after a match is found"
}
},
"additionalProperties": false,
"type": "object"
},
"network.Input": {
"properties": {
"data": {
"type": "string",
"title": "data to send as input",
"description": "Data is the data to send as the input"
},
"type": {
"enum": [
"hex",
"text"
],
"type": "string",
"title": "type is the type of input data",
"description": "Type of input specified in data field"
},
"read": {
"type": "integer",
"title": "bytes to read from socket",
"description": "Number of bytes to read from socket"
},
"name": {
"type": "string",
"title": "optional name for data read",
"description": "Optional name of the data read to provide matching on"
}
},
"additionalProperties": false,
"type": "object"
},
"network.Request": {
"properties": {
"id": {
"type": "string",
"title": "id of the request",
"description": "ID of the network request"
},
"host": {
"items": {
"type": "string"
},
"type": "array",
"title": "host to send requests to",
"description": "Host to send network requests to"
},
"attack": {
"enum": [
"sniper",
"pitchfork",
"clusterbomb"
],
"type": "string",
"title": "attack is the payload combination",
"description": "Attack is the type of payload combinations to perform"
},
"payloads": {
"patternProperties": {
".*": {
"additionalProperties": true
}
},
"type": "object",
"title": "payloads for the network request",
"description": "Payloads contains any payloads for the current request"
},
"inputs": {
"items": {
"$schema": "http://json-schema.org/draft-04/schema#",
"$ref": "#/definitions/network.Input"
},
"type": "array",
"title": "inputs for the network request",
"description": "Inputs contains any input/output for the current request"
},
"read-size": {
"type": "integer",
"title": "size of network response to read",
"description": "Size of response to read at the end. Default is 1024 bytes"
},
"matchers": {
"items": {
"$ref": "#/definitions/matchers.Matcher"
},
"type": "array",
"title": "matchers to run on response",
"description": "Detection mechanism to identify whether the request was successful by doing pattern matching"
},
"extractors": {
"items": {
"$ref": "#/definitions/extractors.Extractor"
},
"type": "array",
"title": "extractors to run on response",
"description": "Extractors contains the extraction mechanism for the request to identify and extract parts of the response"
},
"matchers-condition": {
"enum": [
"and",
"or"
],
"type": "string",
"title": "condition between the matchers",
"description": "Conditions between the matchers"
}
},
"additionalProperties": false,
"type": "object"
},
"templates.Template": {
"required": [
"id",
"info"
],
"properties": {
"id": {
"type": "string",
"title": "id of the template",
"description": "The Unique ID for the template",
"examples": [
"cve-2021-19520"
]
},
"info": {
"$schema": "http://json-schema.org/draft-04/schema#",
"$ref": "#/definitions/model.Info",
"title": "info for the template",
"description": "Info contains metadata for the template"
},
"requests": {
"items": {
"$schema": "http://json-schema.org/draft-04/schema#",
"$ref": "#/definitions/http.Request"
},
"type": "array",
"title": "http requests to make",
"description": "HTTP requests to make for the template"
},
"dns": {
"items": {
"$schema": "http://json-schema.org/draft-04/schema#",
"$ref": "#/definitions/dns.Request"
},
"type": "array",
"title": "dns requests to make",
"description": "DNS requests to make for the template"
},
"file": {
"items": {
"$schema": "http://json-schema.org/draft-04/schema#",
"$ref": "#/definitions/file.Request"
},
"type": "array",
"title": "file requests to make",
"description": "File requests to make for the template"
},
"network": {
"items": {
"$schema": "http://json-schema.org/draft-04/schema#",
"$ref": "#/definitions/network.Request"
},
"type": "array",
"title": "network requests to make",
"description": "Network requests to make for the template"
},
"headless": {
"items": {
"$schema": "http://json-schema.org/draft-04/schema#",
"$ref": "#/definitions/headless.Request"
},
"type": "array",
"title": "headless requests to make",
"description": "Headless requests to make for the template"
},
"workflows": {
"items": {
"$schema": "http://json-schema.org/draft-04/schema#",
"$ref": "#/definitions/workflows.WorkflowTemplate"
},
"type": "array",
"title": "list of workflows to execute",
"description": "List of workflows to execute for template"
}
},
"additionalProperties": false,
"type": "object"
},
"workflows.Matcher": {
"properties": {
"name": {
"type": "string",
"title": "name of item to match",
"description": "Name of item to match"
},
"subtemplates": {
"items": {
"$ref": "#/definitions/workflows.WorkflowTemplate"
},
"type": "array",
"title": "templates to run after match",
"description": "Templates to run after match"
}
},
"additionalProperties": false,
"type": "object"
},
"workflows.WorkflowTemplate": {
"properties": {
"template": {
"type": "string",
"title": "template/directory to execute",
"description": "Template or directory to execute as part of workflow"
},
"tags": {
"$ref": "#/definitions/model.StringSlice",
"title": "tags to execute",
"description": "Tags to run template based on"
},
"matchers": {
"items": {
"$schema": "http://json-schema.org/draft-04/schema#",
"$ref": "#/definitions/workflows.Matcher"
},
"type": "array",
"title": "name based template result matchers",
"description": "Matchers perform name based matching to run subtemplates for a workflow"
},
"subtemplates": {
"items": {
"$ref": "#/definitions/workflows.WorkflowTemplate"
},
"type": "array",
"title": "subtemplate based result matchers",
"description": "Subtemplates are ran if the template field Template matches"
}
},
"additionalProperties": false,
"type": "object"
}
}
}

View File

@ -65,4 +65,41 @@ type Info struct {
// - value: >
// map[string]string{"customField1":"customValue1"}
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"`
// description: |
// Classification contains classification information about the template.
Classification *Classification `json:"classification,omitempty" yaml:"classification,omitempty" jsonschema:"title=classification info for the template,description=Classification information for the template"`
// description: |
// Remediation steps for the template.
//
// You can go in-depth here on how to mitigate the problem found by this template.
//
// examples:
// - value: "\"Change the default administrative username and password of Apache ActiveMQ by editing the file jetty-realm.properties\""
Remediation string `json:"remediation,omitempty" yaml:"remediation,omitempty" jsonschema:"title=remediation steps for the template,description=In-depth explanation on how to fix the issues found by the template,example=Change the default administrative username and password of Apache ActiveMQ by editing the file jetty-realm.properties"`
}
// Classification contains the vulnerability classification data for a template.
type Classification struct {
// description: |
// CVE ID for the template
// examples:
// - value: "\"CVE-2020-14420\""
CVEID stringslice.StringSlice `json:"cve-id,omitempty" yaml:"cve-id,omitempty" jsonschema:"title=cve ids for the template,description=CVE IDs for the template,example=CVE-2020-14420"`
// description: |
// CWE ID for the template.
// examples:
// - value: "\"CWE-22\""
CWEID stringslice.StringSlice `json:"cwe-id,omitempty" yaml:"cwe-id,omitempty" jsonschema:"title=cwe ids for the template,description=CWE IDs for the template,example=CWE-22"`
// description: |
// CVSS Metrics for the template.
// examples:
// - value: "\"3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H\""
CVSSMetrics string `json:"cvss-metrics,omitempty" yaml:"cvss-metrics,omitempty" jsonschema:"title=cvss metrics for the template,description=CVSS Metrics for the template,example=3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"`
// description: |
// CVSS Score for the template.
// examples:
// - value: "\"9.8\""
CVSSScore float64 `json:"cvss-score,omitempty" yaml:"cvss-score,omitempty" jsonschema:"title=cvss score for the template,description=CVSS Score for the template,example=9.8"`
}

View File

@ -6,5 +6,9 @@ import (
// formatJSON formats the output for json based formatting
func (w *StandardWriter) formatJSON(output *ResultEvent) ([]byte, error) {
if !w.jsonReqResp { // don't show request-response in json if not asked
output.Request = ""
output.Response = ""
}
return jsoniter.Marshal(output)
}

View File

@ -33,6 +33,7 @@ type Writer interface {
// StandardWriter is a writer writing output to file and screen for results.
type StandardWriter struct {
json bool
jsonReqResp bool
noTimestamp bool
noMetadata bool
aurora aurora.Aurora
@ -94,7 +95,7 @@ type ResultEvent struct {
}
// NewStandardWriter creates a new output writer based on user configurations
func NewStandardWriter(colors, noMetadata, noTimestamp, json bool, file, traceFile string) (*StandardWriter, error) {
func NewStandardWriter(colors, noMetadata, noTimestamp, json, jsonReqResp bool, file, traceFile string) (*StandardWriter, error) {
auroraColorizer := aurora.NewAurora(colors)
var outputFile *fileWriter
@ -115,6 +116,7 @@ func NewStandardWriter(colors, noMetadata, noTimestamp, json bool, file, traceFi
}
writer := &StandardWriter{
json: json,
jsonReqResp: jsonReqResp,
noMetadata: noMetadata,
noTimestamp: noTimestamp,
aurora: auroraColorizer,

View File

@ -6,6 +6,7 @@ import (
"net/url"
"os"
"strings"
"sync"
"sync/atomic"
"time"
@ -36,8 +37,9 @@ type Client struct {
pollDuration time.Duration
cooldownDuration time.Duration
generated uint32 // decide to wait if we have a generated url
matched bool
firstTimeGroup sync.Once
generated uint32 // decide to wait if we have a generated url
matched bool
}
var (
@ -81,14 +83,6 @@ func New(options *Options) (*Client, error) {
return nil, errors.Wrap(err, "could not parse server url")
}
interactsh, err := client.New(&client.Options{
ServerURL: options.ServerURL,
Token: options.Authorization,
PersistentSession: false,
})
if err != nil {
return nil, errors.Wrap(err, "could not create client")
}
configure := ccache.Configure()
configure = configure.MaxSize(options.CacheSize)
cache := ccache.New(configure)
@ -98,7 +92,6 @@ func New(options *Options) (*Client, error) {
interactionsCache := ccache.New(interactionsCfg)
interactClient := &Client{
interactsh: interactsh,
eviction: options.Eviction,
interactions: interactionsCache,
dotHostname: "." + parsed.Host,
@ -107,21 +100,34 @@ func New(options *Options) (*Client, error) {
pollDuration: options.PollDuration,
cooldownDuration: options.ColldownPeriod,
}
return interactClient, nil
}
interactClient.interactsh.StartPolling(interactClient.pollDuration, func(interaction *server.Interaction) {
if options.Debug {
func (c *Client) firstTimeInitializeClient() error {
interactsh, err := client.New(&client.Options{
ServerURL: c.options.ServerURL,
Token: c.options.Authorization,
PersistentSession: false,
})
if err != nil {
return errors.Wrap(err, "could not create client")
}
c.interactsh = interactsh
interactsh.StartPolling(c.pollDuration, func(interaction *server.Interaction) {
if c.options.Debug {
debugPrintInteraction(interaction)
}
item := interactClient.requests.Get(interaction.UniqueID)
item := c.requests.Get(interaction.UniqueID)
if item == nil {
// If we don't have any request for this ID, add it to temporary
// lru cache, so we can correlate when we get an add request.
gotItem := interactClient.interactions.Get(interaction.UniqueID)
gotItem := c.interactions.Get(interaction.UniqueID)
if gotItem == nil {
interactClient.interactions.Set(interaction.UniqueID, []*server.Interaction{interaction}, defaultInteractionDuration)
c.interactions.Set(interaction.UniqueID, []*server.Interaction{interaction}, defaultInteractionDuration)
} else if items, ok := gotItem.Value().([]*server.Interaction); ok {
items = append(items, interaction)
interactClient.interactions.Set(interaction.UniqueID, items, defaultInteractionDuration)
c.interactions.Set(interaction.UniqueID, items, defaultInteractionDuration)
}
return
}
@ -129,9 +135,9 @@ func New(options *Options) (*Client, error) {
if !ok {
return
}
_ = interactClient.processInteractionForRequest(interaction, request)
_ = c.processInteractionForRequest(interaction, request)
})
return interactClient, nil
return nil
}
// processInteractionForRequest processes an interaction for a request
@ -171,6 +177,11 @@ func (c *Client) processInteractionForRequest(interaction *server.Interaction, d
// URL returns a new URL that can be interacted with
func (c *Client) URL() string {
c.firstTimeGroup.Do(func() {
if err := c.firstTimeInitializeClient(); err != nil {
gologger.Error().Msgf("Could not initialize interactsh client: %s", err)
}
})
atomic.CompareAndSwapUint32(&c.generated, 0, 1)
return c.interactsh.URL()
}
@ -180,8 +191,10 @@ func (c *Client) Close() bool {
if c.cooldownDuration > 0 && atomic.LoadUint32(&c.generated) == 1 {
time.Sleep(c.cooldownDuration)
}
c.interactsh.StopPolling()
c.interactsh.Close()
if c.interactsh != nil {
c.interactsh.StopPolling()
c.interactsh.Close()
}
return c.matched
}

View File

@ -147,10 +147,8 @@ func (r *Request) makeResultEventItem(wrapped *output.InternalWrappedEvent) *out
Matched: types.ToString(wrapped.InternalEvent["matched"]),
ExtractedResults: wrapped.OperatorsResult.OutputExtracts,
Timestamp: time.Now(),
}
if r.options.Options.JSONRequests {
data.Request = types.ToString(wrapped.InternalEvent["request"])
data.Response = types.ToString(wrapped.InternalEvent["raw"])
Request: types.ToString(wrapped.InternalEvent["request"]),
Response: types.ToString(wrapped.InternalEvent["raw"]),
}
return data
}

View File

@ -143,10 +143,8 @@ func (r *Request) makeResultEventItem(wrapped *output.InternalWrappedEvent) *out
Matched: types.ToString(wrapped.InternalEvent["matched"]),
Host: types.ToString(wrapped.InternalEvent["matched"]),
ExtractedResults: wrapped.OperatorsResult.OutputExtracts,
Response: types.ToString(wrapped.InternalEvent["raw"]),
Timestamp: time.Now(),
}
if r.options.Options.JSONRequests {
data.Response = types.ToString(wrapped.InternalEvent["raw"])
}
return data
}

View File

@ -116,10 +116,8 @@ func (r *Request) makeResultEventItem(wrapped *output.InternalWrappedEvent) *out
ExtractedResults: wrapped.OperatorsResult.OutputExtracts,
Timestamp: time.Now(),
IP: types.ToString(wrapped.InternalEvent["ip"]),
}
if r.options.Options.JSONRequests {
data.Request = types.ToString(wrapped.InternalEvent["request"])
data.Response = types.ToString(wrapped.InternalEvent["data"])
Request: types.ToString(wrapped.InternalEvent["request"]),
Response: types.ToString(wrapped.InternalEvent["data"]),
}
return data
}

View File

@ -154,10 +154,8 @@ func (r *Request) makeResultEventItem(wrapped *output.InternalWrappedEvent) *out
ExtractedResults: wrapped.OperatorsResult.OutputExtracts,
Timestamp: time.Now(),
IP: types.ToString(wrapped.InternalEvent["ip"]),
}
if r.options.Options.JSONRequests {
data.Request = types.ToString(wrapped.InternalEvent["request"])
data.Response = types.ToString(wrapped.InternalEvent["response"])
Request: types.ToString(wrapped.InternalEvent["request"]),
Response: types.ToString(wrapped.InternalEvent["response"]),
}
return data
}

View File

@ -118,10 +118,8 @@ func (r *Request) makeResultEventItem(wrapped *output.InternalWrappedEvent) *out
Metadata: wrapped.OperatorsResult.PayloadValues,
Timestamp: time.Now(),
IP: types.ToString(wrapped.InternalEvent["ip"]),
}
if r.options.Options.JSONRequests {
data.Request = types.ToString(wrapped.InternalEvent["request"])
data.Response = types.ToString(wrapped.InternalEvent["data"])
Request: types.ToString(wrapped.InternalEvent["request"]),
Response: types.ToString(wrapped.InternalEvent["data"]),
}
return data
}

View File

@ -145,10 +145,8 @@ func (r *Request) makeResultEventItem(wrapped *output.InternalWrappedEvent) *out
Metadata: wrapped.OperatorsResult.PayloadValues,
ExtractedResults: wrapped.OperatorsResult.OutputExtracts,
IP: types.ToString(wrapped.InternalEvent["ip"]),
}
if r.options.Options.JSONRequests {
data.Request = types.ToString(wrapped.InternalEvent["request"])
data.Response = types.ToString(wrapped.InternalEvent["raw"])
Request: types.ToString(wrapped.InternalEvent["request"]),
Response: types.ToString(wrapped.InternalEvent["raw"]),
}
return data
}

View File

@ -3,9 +3,12 @@ package format
import (
"bytes"
"fmt"
"github.com/projectdiscovery/nuclei/v2/pkg/utils"
"strconv"
"strings"
"github.com/projectdiscovery/nuclei/v2/pkg/catalog/config"
"github.com/projectdiscovery/nuclei/v2/pkg/utils"
"github.com/projectdiscovery/nuclei/v2/pkg/model"
"github.com/projectdiscovery/nuclei/v2/pkg/output"
"github.com/projectdiscovery/nuclei/v2/pkg/types"
@ -16,13 +19,10 @@ func Summary(event *output.ResultEvent) string {
template := GetMatchedTemplate(event)
builder := &strings.Builder{}
builder.WriteString("[")
builder.WriteString(template)
builder.WriteString("] [")
builder.WriteString(types.ToString(event.Info.SeverityHolder))
builder.WriteString("] ")
builder.WriteString(types.ToString(event.Info.Name))
builder.WriteString(" found on ")
builder.WriteString(" (")
builder.WriteString(template)
builder.WriteString(") found on ")
builder.WriteString(event.Host)
data := builder.String()
return data
@ -71,6 +71,7 @@ func MarkdownDescription(event *output.ResultEvent) string { // TODO remove the
if len(event.ExtractedResults) > 0 || len(event.Metadata) > 0 {
builder.WriteString("\n**Extra Information**\n\n")
if len(event.ExtractedResults) > 0 {
builder.WriteString("**Extracted results**:\n\n")
for _, v := range event.ExtractedResults {
@ -131,7 +132,7 @@ func MarkdownDescription(event *output.ResultEvent) string { // TODO remove the
}
}
builder.WriteString("\n---\nGenerated by [Nuclei](https://github.com/projectdiscovery/nuclei)")
builder.WriteString(fmt.Sprintf("\n---\nGenerated by [Nuclei %s](https://github.com/projectdiscovery/nuclei)", config.Version))
data := builder.String()
return data
}
@ -159,6 +160,16 @@ func ToMarkdownTableString(templateInfo *model.Info) string {
fields.Set("Tags", templateInfo.Tags.String())
fields.Set("Severity", templateInfo.SeverityHolder.Severity.String())
fields.Set("Description", templateInfo.Description)
fields.Set("Remediation", templateInfo.Remediation)
classification := templateInfo.Classification
if classification != nil {
if classification.CVSSMetrics != "" {
generateCVSSMetricsFromClassification(classification, fields)
}
generateCVECWEIDLinksFromClassification(classification, fields)
fields.Set("CVSS-Score", strconv.FormatFloat(classification.CVSSScore, 'f', 2, 64))
}
builder := &bytes.Buffer{}
@ -175,3 +186,44 @@ func ToMarkdownTableString(templateInfo *model.Info) string {
return builder.String()
}
func generateCVSSMetricsFromClassification(classification *model.Classification, fields *utils.InsertionOrderedStringMap) {
// Generate cvss link
var cvssLinkPrefix string
if strings.Contains(classification.CVSSMetrics, "CVSS:3.0") {
cvssLinkPrefix = "https://www.first.org/cvss/calculator/3.0#"
} else if strings.Contains(classification.CVSSMetrics, "CVSS:3.1") {
cvssLinkPrefix = "https://www.first.org/cvss/calculator/3.1#"
}
if cvssLinkPrefix != "" {
fields.Set("CVSS-Metrics", fmt.Sprintf("[%s](%s%s)", classification.CVSSMetrics, cvssLinkPrefix, classification.CVSSMetrics))
} else {
fields.Set("CVSS-Metrics", classification.CVSSMetrics)
}
}
func generateCVECWEIDLinksFromClassification(classification *model.Classification, fields *utils.InsertionOrderedStringMap) {
cwes := classification.CWEID.ToSlice()
cweIDs := make([]string, 0, len(cwes))
for _, value := range cwes {
parts := strings.Split(value, "-")
if len(parts) != 2 {
continue
}
cweIDs = append(cweIDs, fmt.Sprintf("[%s](https://cwe.mitre.org/data/definitions/%s.html)", strings.ToUpper(value), parts[1]))
}
if len(cweIDs) > 0 {
fields.Set("CWE-ID", strings.Join(cweIDs, ","))
}
cves := classification.CVEID.ToSlice()
cveIDs := make([]string, 0, len(cves))
for _, value := range cves {
cveIDs = append(cveIDs, fmt.Sprintf("[%s](https://cve.mitre.org/cgi-bin/cvename.cgi?name=%s)", strings.ToUpper(value), value))
}
if len(cveIDs) > 0 {
fields.Set("CVE-ID", strings.Join(cveIDs, ","))
}
}

View File

@ -8,6 +8,7 @@ import (
"github.com/andygrunwald/go-jira"
"github.com/projectdiscovery/gologger"
"github.com/projectdiscovery/nuclei/v2/pkg/catalog/config"
"github.com/projectdiscovery/nuclei/v2/pkg/output"
"github.com/projectdiscovery/nuclei/v2/pkg/reporting/format"
"github.com/projectdiscovery/nuclei/v2/pkg/types"
@ -240,7 +241,7 @@ func jiraFormatDescription(event *output.ResultEvent) string { // TODO remove th
}
}
}
builder.WriteString("\n---\nGenerated by [Nuclei|https://github.com/projectdiscovery/nuclei]")
builder.WriteString(fmt.Sprintf("\n---\nGenerated by [Nuclei v%s](https://github.com/projectdiscovery/nuclei)", config.Version))
data := builder.String()
return data
}

View File

@ -1,4 +1,3 @@
// Package templates
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
@ -12,8 +11,9 @@ import (
var (
TemplateDoc encoder.Doc
MODELInfoDoc encoder.Doc
MODELStringSliceDoc encoder.Doc
SEVERITYSeverityHolderDoc encoder.Doc
STRINGSLICEStringSliceDoc encoder.Doc
SEVERITYHolderDoc encoder.Doc
MODELClassificationDoc encoder.Doc
HTTPRequestDoc encoder.Doc
MATCHERSMatcherDoc encoder.Doc
EXTRACTORSExtractorDoc encoder.Doc
@ -96,7 +96,7 @@ func init() {
FieldName: "info",
},
}
MODELInfoDoc.Fields = make([]encoder.Doc, 7)
MODELInfoDoc.Fields = make([]encoder.Doc, 9)
MODELInfoDoc.Fields[0].Name = "name"
MODELInfoDoc.Fields[0].Type = "string"
MODELInfoDoc.Fields[0].Note = ""
@ -107,14 +107,14 @@ func init() {
MODELInfoDoc.Fields[0].AddExample("", "Nagios Default Credentials Check")
MODELInfoDoc.Fields[1].Name = "author"
MODELInfoDoc.Fields[1].Type = "StringSlice"
MODELInfoDoc.Fields[1].Type = "stringslice.StringSlice"
MODELInfoDoc.Fields[1].Note = ""
MODELInfoDoc.Fields[1].Description = "Author of the template.\n\nMultiple values can also be specified separated by commas."
MODELInfoDoc.Fields[1].Comments[encoder.LineComment] = "Author of the template."
MODELInfoDoc.Fields[1].AddExample("", "<username>")
MODELInfoDoc.Fields[2].Name = "tags"
MODELInfoDoc.Fields[2].Type = "StringSlice"
MODELInfoDoc.Fields[2].Type = "stringslice.StringSlice"
MODELInfoDoc.Fields[2].Note = ""
MODELInfoDoc.Fields[2].Description = "Any tags for the template.\n\nMultiple values can also be specified separated by commas."
MODELInfoDoc.Fields[2].Comments[encoder.LineComment] = "Any tags for the template."
@ -130,14 +130,14 @@ func init() {
MODELInfoDoc.Fields[3].AddExample("", "Subversion ALM for the enterprise before 8.8.2 allows reflected XSS at multiple locations")
MODELInfoDoc.Fields[4].Name = "reference"
MODELInfoDoc.Fields[4].Type = "StringSlice"
MODELInfoDoc.Fields[4].Type = "stringslice.StringSlice"
MODELInfoDoc.Fields[4].Note = ""
MODELInfoDoc.Fields[4].Description = "References for the template.\n\nThis should contain links relevant to the template."
MODELInfoDoc.Fields[4].Comments[encoder.LineComment] = "References for the template."
MODELInfoDoc.Fields[4].AddExample("", []string{"https://github.com/strapi/strapi", "https://github.com/getgrav/grav"})
MODELInfoDoc.Fields[5].Name = "severity"
MODELInfoDoc.Fields[5].Type = "severity.SeverityHolder"
MODELInfoDoc.Fields[5].Type = "severity.Holder"
MODELInfoDoc.Fields[5].Note = ""
MODELInfoDoc.Fields[5].Description = "Severity of the template."
MODELInfoDoc.Fields[5].Comments[encoder.LineComment] = "Severity of the template."
@ -155,28 +155,109 @@ func init() {
MODELInfoDoc.Fields[6].Comments[encoder.LineComment] = "AdditionalFields regarding metadata of the template."
MODELInfoDoc.Fields[6].AddExample("", map[string]string{"customField1": "customValue1"})
MODELInfoDoc.Fields[7].Name = "classification"
MODELInfoDoc.Fields[7].Type = "model.Classification"
MODELInfoDoc.Fields[7].Note = ""
MODELInfoDoc.Fields[7].Description = "Classification contains classification information about the template."
MODELInfoDoc.Fields[7].Comments[encoder.LineComment] = "Classification contains classification information about the template."
MODELInfoDoc.Fields[8].Name = "remediation"
MODELInfoDoc.Fields[8].Type = "string"
MODELInfoDoc.Fields[8].Note = ""
MODELInfoDoc.Fields[8].Description = "Remediation steps for the template.\n\nYou can go in-depth here on how to mitigate the problem found by this template."
MODELInfoDoc.Fields[8].Comments[encoder.LineComment] = "Remediation steps for the template."
MODELStringSliceDoc.Type = "model.StringSlice"
MODELStringSliceDoc.Comments[encoder.LineComment] = ""
MODELStringSliceDoc.Description = ""
MODELStringSliceDoc.AppearsIn = []encoder.Appearance{
MODELInfoDoc.Fields[8].AddExample("", "Change the default administrative username and password of Apache ActiveMQ by editing the file jetty-realm.properties")
STRINGSLICEStringSliceDoc.Type = "stringslice.StringSlice"
STRINGSLICEStringSliceDoc.Comments[encoder.LineComment] = " StringSlice represents a single (in-lined) or multiple string value(s)."
STRINGSLICEStringSliceDoc.Description = "StringSlice represents a single (in-lined) or multiple string value(s).\n The unmarshaller does not automatically convert in-lined strings to []string, hence the interface{} type is required."
STRINGSLICEStringSliceDoc.AddExample("", "<username>")
STRINGSLICEStringSliceDoc.AddExample("Example tags", "cve,cve2019,grafana,auth-bypass,dos")
STRINGSLICEStringSliceDoc.AddExample("", []string{"https://github.com/strapi/strapi", "https://github.com/getgrav/grav"})
STRINGSLICEStringSliceDoc.AddExample("", "CVE-2020-14420")
STRINGSLICEStringSliceDoc.AddExample("", "CWE-22")
STRINGSLICEStringSliceDoc.AppearsIn = []encoder.Appearance{
{
TypeName: "model.Info",
FieldName: "author",
},
{
TypeName: "model.Info",
FieldName: "tags",
},
{
TypeName: "model.Info",
FieldName: "reference",
},
{
TypeName: "model.Classification",
FieldName: "cve-id",
},
{
TypeName: "model.Classification",
FieldName: "cwe-id",
},
{
TypeName: "workflows.WorkflowTemplate",
FieldName: "tags",
},
}
MODELStringSliceDoc.Fields = make([]encoder.Doc, 0)
STRINGSLICEStringSliceDoc.Fields = make([]encoder.Doc, 0)
SEVERITYSeverityHolderDoc.Type = "severity.SeverityHolder"
SEVERITYSeverityHolderDoc.Comments[encoder.LineComment] = ""
SEVERITYSeverityHolderDoc.Description = ""
SEVERITYSeverityHolderDoc.AppearsIn = []encoder.Appearance{
SEVERITYHolderDoc.Type = "severity.Holder"
SEVERITYHolderDoc.Comments[encoder.LineComment] = " Holder holds a Severity type. Required for un/marshalling purposes"
SEVERITYHolderDoc.Description = "Holder holds a Severity type. Required for un/marshalling purposes"
SEVERITYHolderDoc.AppearsIn = []encoder.Appearance{
{
TypeName: "model.Info",
FieldName: "severity",
},
}
SEVERITYSeverityHolderDoc.Fields = make([]encoder.Doc, 0)
SEVERITYHolderDoc.Fields = make([]encoder.Doc, 0)
MODELClassificationDoc.Type = "model.Classification"
MODELClassificationDoc.Comments[encoder.LineComment] = ""
MODELClassificationDoc.Description = ""
MODELClassificationDoc.AppearsIn = []encoder.Appearance{
{
TypeName: "model.Info",
FieldName: "classification",
},
}
MODELClassificationDoc.Fields = make([]encoder.Doc, 4)
MODELClassificationDoc.Fields[0].Name = "cve-id"
MODELClassificationDoc.Fields[0].Type = "stringslice.StringSlice"
MODELClassificationDoc.Fields[0].Note = ""
MODELClassificationDoc.Fields[0].Description = "CVE ID for the template"
MODELClassificationDoc.Fields[0].Comments[encoder.LineComment] = "CVE ID for the template"
MODELClassificationDoc.Fields[0].AddExample("", "CVE-2020-14420")
MODELClassificationDoc.Fields[1].Name = "cwe-id"
MODELClassificationDoc.Fields[1].Type = "stringslice.StringSlice"
MODELClassificationDoc.Fields[1].Note = ""
MODELClassificationDoc.Fields[1].Description = "CWE ID for the template."
MODELClassificationDoc.Fields[1].Comments[encoder.LineComment] = "CWE ID for the template."
MODELClassificationDoc.Fields[1].AddExample("", "CWE-22")
MODELClassificationDoc.Fields[2].Name = "cvss-metrics"
MODELClassificationDoc.Fields[2].Type = "string"
MODELClassificationDoc.Fields[2].Note = ""
MODELClassificationDoc.Fields[2].Description = "CVSS Metrics for the template."
MODELClassificationDoc.Fields[2].Comments[encoder.LineComment] = "CVSS Metrics for the template."
MODELClassificationDoc.Fields[2].AddExample("", "3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H")
MODELClassificationDoc.Fields[3].Name = "cvss-score"
MODELClassificationDoc.Fields[3].Type = "float64"
MODELClassificationDoc.Fields[3].Note = ""
MODELClassificationDoc.Fields[3].Description = "CVSS Score for the template."
MODELClassificationDoc.Fields[3].Comments[encoder.LineComment] = "CVSS Score for the template."
MODELClassificationDoc.Fields[3].AddExample("", "9.8")
HTTPRequestDoc.Type = "http.Request"
HTTPRequestDoc.Comments[encoder.LineComment] = " Request contains a http request to be made from a template"
@ -971,7 +1052,7 @@ func init() {
WORKFLOWSWorkflowTemplateDoc.Fields[0].AddExample("A template directory", "misconfigurations/aem")
WORKFLOWSWorkflowTemplateDoc.Fields[1].Name = "tags"
WORKFLOWSWorkflowTemplateDoc.Fields[1].Type = "model.StringSlice"
WORKFLOWSWorkflowTemplateDoc.Fields[1].Type = "stringslice.StringSlice"
WORKFLOWSWorkflowTemplateDoc.Fields[1].Note = ""
WORKFLOWSWorkflowTemplateDoc.Fields[1].Description = "Tags to run templates based on."
WORKFLOWSWorkflowTemplateDoc.Fields[1].Comments[encoder.LineComment] = "Tags to run templates based on."
@ -1016,8 +1097,9 @@ func GetTemplateDoc() *encoder.FileDoc {
Structs: []*encoder.Doc{
&TemplateDoc,
&MODELInfoDoc,
&MODELStringSliceDoc,
&SEVERITYSeverityHolderDoc,
&STRINGSLICEStringSliceDoc,
&SEVERITYHolderDoc,
&MODELClassificationDoc,
&HTTPRequestDoc,
&MATCHERSMatcherDoc,
&EXTRACTORSExtractorDoc,

File diff suppressed because it is too large Load Diff