mirror of
https://github.com/projectdiscovery/nuclei.git
synced 2025-12-17 19:55:26 +00:00
Merge pull request #1004 from projectdiscovery/new-info-fields
Added new info block fields classification and remediation
This commit is contained in:
commit
8f62da84c0
160
v2/cmd/cve-annotate/main.go
Normal file
160
v2/cmd/cve-annotate/main.go
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/daehee/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 ""
|
||||||
|
}
|
||||||
@ -13,7 +13,7 @@ require (
|
|||||||
github.com/bluele/gcache v0.0.2
|
github.com/bluele/gcache v0.0.2
|
||||||
github.com/c4milo/unpackit v0.1.0 // indirect
|
github.com/c4milo/unpackit v0.1.0 // indirect
|
||||||
github.com/corpix/uarand v0.1.1
|
github.com/corpix/uarand v0.1.1
|
||||||
github.com/davecgh/go-spew v1.1.1
|
github.com/daehee/nvd v1.0.4
|
||||||
github.com/go-rod/rod v0.91.1
|
github.com/go-rod/rod v0.91.1
|
||||||
github.com/google/go-github v17.0.0+incompatible
|
github.com/google/go-github v17.0.0+incompatible
|
||||||
github.com/gosuri/uilive v0.0.4 // indirect
|
github.com/gosuri/uilive v0.0.4 // indirect
|
||||||
|
|||||||
17
v2/go.sum
17
v2/go.sum
@ -45,9 +45,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.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8=
|
github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8=
|
||||||
github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
|
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 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA=
|
||||||
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/go.mod h1:pNs6QmpQ1UlTJKDezuRWmaqkgUE2TuU0YTWyqJZ7+lI=
|
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 h1:FqlR8VR7uCbJdfUob916tPM+idpKgeESDXOA1K0DK4w=
|
||||||
github.com/akrylysov/pogreb v0.10.1/go.mod h1:pNs6QmpQ1UlTJKDezuRWmaqkgUE2TuU0YTWyqJZ7+lI=
|
github.com/akrylysov/pogreb v0.10.1/go.mod h1:pNs6QmpQ1UlTJKDezuRWmaqkgUE2TuU0YTWyqJZ7+lI=
|
||||||
@ -55,6 +56,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/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/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 h1:7GT/3qhar2dGJ0kq8w0d63liNyHOnxZsUZ9Pe4+AKBI=
|
||||||
github.com/andygrunwald/go-jira v1.14.0/go.mod h1:KMo2f4DgMZA1C9FdImuLc04x4WQhn5derQpnsuBFgqE=
|
github.com/andygrunwald/go-jira v1.14.0/go.mod h1:KMo2f4DgMZA1C9FdImuLc04x4WQhn5derQpnsuBFgqE=
|
||||||
github.com/antchfx/htmlquery v1.2.3 h1:sP3NFDneHx2stfNXCKbhHFo8XgNjCACnU/4AO5gWz6M=
|
github.com/antchfx/htmlquery v1.2.3 h1:sP3NFDneHx2stfNXCKbhHFo8XgNjCACnU/4AO5gWz6M=
|
||||||
@ -96,7 +99,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/corpix/uarand v0.1.1/go.mod h1:SFKZvkcRoLqVRFZ4u25xPmp6m9ktANfbpXZ7SJ0/FNU=
|
||||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
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/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
github.com/dave/dst v0.26.2 h1:lnxLAKI3tx7MgLNVDirFCsDTlTG9nKTk7GcptKcWSwY=
|
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/go.mod h1:UMDJuIRPfyUCC78eFuB+SV/WI8oDeyFDvM/JR6NI3IU=
|
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=
|
github.com/dave/gopackages v0.0.0-20170318123100-46e7023ec56e/go.mod h1:i00+b/gKdIDIxuLDFob7ustLAVqhsZRk2qVZrArELGQ=
|
||||||
github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg=
|
github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg=
|
||||||
@ -229,7 +233,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 h1:i462o439ZjprVSFSZLZxcsoAe592sZB1rci2Z8j4wdk=
|
||||||
github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA=
|
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 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
|
||||||
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=
|
||||||
github.com/itchyny/gojq v0.12.4 h1:8zgOZWMejEWCLjbF/1mWY7hY7QEARm7dtuhC6Bp4R8o=
|
github.com/itchyny/gojq v0.12.4 h1:8zgOZWMejEWCLjbF/1mWY7hY7QEARm7dtuhC6Bp4R8o=
|
||||||
@ -276,13 +279,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/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/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.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-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.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.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 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA=
|
||||||
github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
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.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 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
|
||||||
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||||
@ -508,8 +509,8 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
|
|||||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
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.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/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-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-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
@ -614,7 +615,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-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-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-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-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 h1:2ucpDCmfkl8Bd/FsLtiD653Wf96cW37s+iGx93zsu4k=
|
||||||
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
@ -676,7 +676,6 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc
|
|||||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.0.0-20210101214203-2dba1e4ea05c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20210101214203-2dba1e4ea05c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=
|
|
||||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
@ -705,7 +704,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.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.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
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.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||||
@ -792,7 +790,6 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
|||||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
mvdan.cc/gofumpt v0.1.1 h1:bi/1aS/5W00E2ny5q65w9SnKpWEF/UIOqDYBILpo9rA=
|
|
||||||
mvdan.cc/gofumpt v0.1.1/go.mod h1:yXG1r1WqZVKWbVRtBWKWX9+CxGYfA51nSomhM0woR48=
|
mvdan.cc/gofumpt v0.1.1/go.mod h1:yXG1r1WqZVKWbVRtBWKWX9+CxGYfA51nSomhM0woR48=
|
||||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||||
|
|||||||
@ -189,7 +189,7 @@ func New(options *types.Options) (*Runner, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create the output file if asked
|
// 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 {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "could not create output file")
|
return nil, errors.Wrap(err, "could not create output file")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -65,4 +65,41 @@ type Info struct {
|
|||||||
// - value: >
|
// - value: >
|
||||||
// map[string]string{"customField1":"customValue1"}
|
// 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"`
|
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"`
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,5 +6,9 @@ import (
|
|||||||
|
|
||||||
// formatJSON formats the output for json based formatting
|
// formatJSON formats the output for json based formatting
|
||||||
func (w *StandardWriter) formatJSON(output *ResultEvent) ([]byte, error) {
|
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)
|
return jsoniter.Marshal(output)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,6 +33,7 @@ type Writer interface {
|
|||||||
// StandardWriter is a writer writing output to file and screen for results.
|
// StandardWriter is a writer writing output to file and screen for results.
|
||||||
type StandardWriter struct {
|
type StandardWriter struct {
|
||||||
json bool
|
json bool
|
||||||
|
jsonReqResp bool
|
||||||
noTimestamp bool
|
noTimestamp bool
|
||||||
noMetadata bool
|
noMetadata bool
|
||||||
aurora aurora.Aurora
|
aurora aurora.Aurora
|
||||||
@ -94,7 +95,7 @@ type ResultEvent struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewStandardWriter creates a new output writer based on user configurations
|
// 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)
|
auroraColorizer := aurora.NewAurora(colors)
|
||||||
|
|
||||||
var outputFile *fileWriter
|
var outputFile *fileWriter
|
||||||
@ -115,6 +116,7 @@ func NewStandardWriter(colors, noMetadata, noTimestamp, json bool, file, traceFi
|
|||||||
}
|
}
|
||||||
writer := &StandardWriter{
|
writer := &StandardWriter{
|
||||||
json: json,
|
json: json,
|
||||||
|
jsonReqResp: jsonReqResp,
|
||||||
noMetadata: noMetadata,
|
noMetadata: noMetadata,
|
||||||
noTimestamp: noTimestamp,
|
noTimestamp: noTimestamp,
|
||||||
aurora: auroraColorizer,
|
aurora: auroraColorizer,
|
||||||
|
|||||||
@ -147,10 +147,8 @@ func (r *Request) makeResultEventItem(wrapped *output.InternalWrappedEvent) *out
|
|||||||
Matched: types.ToString(wrapped.InternalEvent["matched"]),
|
Matched: types.ToString(wrapped.InternalEvent["matched"]),
|
||||||
ExtractedResults: wrapped.OperatorsResult.OutputExtracts,
|
ExtractedResults: wrapped.OperatorsResult.OutputExtracts,
|
||||||
Timestamp: time.Now(),
|
Timestamp: time.Now(),
|
||||||
}
|
Request: types.ToString(wrapped.InternalEvent["request"]),
|
||||||
if r.options.Options.JSONRequests {
|
Response: types.ToString(wrapped.InternalEvent["raw"]),
|
||||||
data.Request = types.ToString(wrapped.InternalEvent["request"])
|
|
||||||
data.Response = types.ToString(wrapped.InternalEvent["raw"])
|
|
||||||
}
|
}
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|||||||
@ -143,10 +143,8 @@ func (r *Request) makeResultEventItem(wrapped *output.InternalWrappedEvent) *out
|
|||||||
Matched: types.ToString(wrapped.InternalEvent["matched"]),
|
Matched: types.ToString(wrapped.InternalEvent["matched"]),
|
||||||
Host: types.ToString(wrapped.InternalEvent["matched"]),
|
Host: types.ToString(wrapped.InternalEvent["matched"]),
|
||||||
ExtractedResults: wrapped.OperatorsResult.OutputExtracts,
|
ExtractedResults: wrapped.OperatorsResult.OutputExtracts,
|
||||||
|
Response: types.ToString(wrapped.InternalEvent["raw"]),
|
||||||
Timestamp: time.Now(),
|
Timestamp: time.Now(),
|
||||||
}
|
}
|
||||||
if r.options.Options.JSONRequests {
|
|
||||||
data.Response = types.ToString(wrapped.InternalEvent["raw"])
|
|
||||||
}
|
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|||||||
@ -116,10 +116,8 @@ func (r *Request) makeResultEventItem(wrapped *output.InternalWrappedEvent) *out
|
|||||||
ExtractedResults: wrapped.OperatorsResult.OutputExtracts,
|
ExtractedResults: wrapped.OperatorsResult.OutputExtracts,
|
||||||
Timestamp: time.Now(),
|
Timestamp: time.Now(),
|
||||||
IP: types.ToString(wrapped.InternalEvent["ip"]),
|
IP: types.ToString(wrapped.InternalEvent["ip"]),
|
||||||
}
|
Request: types.ToString(wrapped.InternalEvent["request"]),
|
||||||
if r.options.Options.JSONRequests {
|
Response: types.ToString(wrapped.InternalEvent["data"]),
|
||||||
data.Request = types.ToString(wrapped.InternalEvent["request"])
|
|
||||||
data.Response = types.ToString(wrapped.InternalEvent["data"])
|
|
||||||
}
|
}
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|||||||
@ -154,10 +154,8 @@ func (r *Request) makeResultEventItem(wrapped *output.InternalWrappedEvent) *out
|
|||||||
ExtractedResults: wrapped.OperatorsResult.OutputExtracts,
|
ExtractedResults: wrapped.OperatorsResult.OutputExtracts,
|
||||||
Timestamp: time.Now(),
|
Timestamp: time.Now(),
|
||||||
IP: types.ToString(wrapped.InternalEvent["ip"]),
|
IP: types.ToString(wrapped.InternalEvent["ip"]),
|
||||||
}
|
Request: types.ToString(wrapped.InternalEvent["request"]),
|
||||||
if r.options.Options.JSONRequests {
|
Response: types.ToString(wrapped.InternalEvent["response"]),
|
||||||
data.Request = types.ToString(wrapped.InternalEvent["request"])
|
|
||||||
data.Response = types.ToString(wrapped.InternalEvent["response"])
|
|
||||||
}
|
}
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|||||||
@ -118,10 +118,8 @@ func (r *Request) makeResultEventItem(wrapped *output.InternalWrappedEvent) *out
|
|||||||
Metadata: wrapped.OperatorsResult.PayloadValues,
|
Metadata: wrapped.OperatorsResult.PayloadValues,
|
||||||
Timestamp: time.Now(),
|
Timestamp: time.Now(),
|
||||||
IP: types.ToString(wrapped.InternalEvent["ip"]),
|
IP: types.ToString(wrapped.InternalEvent["ip"]),
|
||||||
}
|
Request: types.ToString(wrapped.InternalEvent["request"]),
|
||||||
if r.options.Options.JSONRequests {
|
Response: types.ToString(wrapped.InternalEvent["data"]),
|
||||||
data.Request = types.ToString(wrapped.InternalEvent["request"])
|
|
||||||
data.Response = types.ToString(wrapped.InternalEvent["data"])
|
|
||||||
}
|
}
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|||||||
@ -145,10 +145,8 @@ func (r *Request) makeResultEventItem(wrapped *output.InternalWrappedEvent) *out
|
|||||||
Metadata: wrapped.OperatorsResult.PayloadValues,
|
Metadata: wrapped.OperatorsResult.PayloadValues,
|
||||||
ExtractedResults: wrapped.OperatorsResult.OutputExtracts,
|
ExtractedResults: wrapped.OperatorsResult.OutputExtracts,
|
||||||
IP: types.ToString(wrapped.InternalEvent["ip"]),
|
IP: types.ToString(wrapped.InternalEvent["ip"]),
|
||||||
}
|
Request: types.ToString(wrapped.InternalEvent["request"]),
|
||||||
if r.options.Options.JSONRequests {
|
Response: types.ToString(wrapped.InternalEvent["raw"]),
|
||||||
data.Request = types.ToString(wrapped.InternalEvent["request"])
|
|
||||||
data.Response = types.ToString(wrapped.InternalEvent["raw"])
|
|
||||||
}
|
}
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,9 +3,12 @@ package format
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/projectdiscovery/nuclei/v2/pkg/utils"
|
"strconv"
|
||||||
"strings"
|
"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/model"
|
||||||
"github.com/projectdiscovery/nuclei/v2/pkg/output"
|
"github.com/projectdiscovery/nuclei/v2/pkg/output"
|
||||||
"github.com/projectdiscovery/nuclei/v2/pkg/types"
|
"github.com/projectdiscovery/nuclei/v2/pkg/types"
|
||||||
@ -16,13 +19,10 @@ func Summary(event *output.ResultEvent) string {
|
|||||||
template := GetMatchedTemplate(event)
|
template := GetMatchedTemplate(event)
|
||||||
|
|
||||||
builder := &strings.Builder{}
|
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(types.ToString(event.Info.Name))
|
||||||
builder.WriteString(" found on ")
|
builder.WriteString(" (")
|
||||||
|
builder.WriteString(template)
|
||||||
|
builder.WriteString(") found on ")
|
||||||
builder.WriteString(event.Host)
|
builder.WriteString(event.Host)
|
||||||
data := builder.String()
|
data := builder.String()
|
||||||
return data
|
return data
|
||||||
@ -71,6 +71,7 @@ func MarkdownDescription(event *output.ResultEvent) string { // TODO remove the
|
|||||||
|
|
||||||
if len(event.ExtractedResults) > 0 || len(event.Metadata) > 0 {
|
if len(event.ExtractedResults) > 0 || len(event.Metadata) > 0 {
|
||||||
builder.WriteString("\n**Extra Information**\n\n")
|
builder.WriteString("\n**Extra Information**\n\n")
|
||||||
|
|
||||||
if len(event.ExtractedResults) > 0 {
|
if len(event.ExtractedResults) > 0 {
|
||||||
builder.WriteString("**Extracted results**:\n\n")
|
builder.WriteString("**Extracted results**:\n\n")
|
||||||
for _, v := range event.ExtractedResults {
|
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()
|
data := builder.String()
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
@ -159,6 +160,16 @@ func ToMarkdownTableString(templateInfo *model.Info) string {
|
|||||||
fields.Set("Tags", templateInfo.Tags.String())
|
fields.Set("Tags", templateInfo.Tags.String())
|
||||||
fields.Set("Severity", templateInfo.SeverityHolder.Severity.String())
|
fields.Set("Severity", templateInfo.SeverityHolder.Severity.String())
|
||||||
fields.Set("Description", templateInfo.Description)
|
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{}
|
builder := &bytes.Buffer{}
|
||||||
|
|
||||||
@ -175,3 +186,44 @@ func ToMarkdownTableString(templateInfo *model.Info) string {
|
|||||||
|
|
||||||
return builder.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, ","))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import (
|
|||||||
|
|
||||||
"github.com/andygrunwald/go-jira"
|
"github.com/andygrunwald/go-jira"
|
||||||
"github.com/projectdiscovery/gologger"
|
"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/output"
|
||||||
"github.com/projectdiscovery/nuclei/v2/pkg/reporting/format"
|
"github.com/projectdiscovery/nuclei/v2/pkg/reporting/format"
|
||||||
"github.com/projectdiscovery/nuclei/v2/pkg/types"
|
"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()
|
data := builder.String()
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user