189 lines
5.8 KiB
Go
Raw Normal View History

package format
import (
"bytes"
"fmt"
2021-09-09 03:30:17 +05:30
"strconv"
"strings"
2021-09-09 03:30:17 +05:30
"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"
)
// Summary returns a formatted built one line summary of the event
2021-02-26 13:13:11 +05:30
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 ")
2021-02-26 13:13:11 +05:30
builder.WriteString(event.Host)
data := builder.String()
return data
}
// MarkdownDescription formats a short description of the generated
// event by the nuclei scanner in Markdown format.
func MarkdownDescription(event *output.ResultEvent) string { // TODO remove the code duplication: format.go <-> jira.go
2021-02-26 13:13:11 +05:30
template := GetMatchedTemplate(event)
builder := &bytes.Buffer{}
builder.WriteString("**Details**: **")
builder.WriteString(template)
builder.WriteString("** ")
builder.WriteString(" matched at ")
2021-02-26 13:13:11 +05:30
builder.WriteString(event.Host)
builder.WriteString("\n\n**Protocol**: ")
2021-02-26 13:13:11 +05:30
builder.WriteString(strings.ToUpper(event.Type))
builder.WriteString("\n\n**Full URL**: ")
2021-02-26 13:13:11 +05:30
builder.WriteString(event.Matched)
builder.WriteString("\n\n**Timestamp**: ")
2021-02-26 13:13:11 +05:30
builder.WriteString(event.Timestamp.Format("Mon Jan 2 15:04:05 -0700 MST 2006"))
builder.WriteString("\n\n**Template Information**\n\n| Key | Value |\n|---|---|\n")
builder.WriteString(ToMarkdownTableString(&event.Info))
if event.Request != "" {
2021-03-22 15:00:26 +05:30
builder.WriteString("\n**Request**\n\n```http\n")
builder.WriteString(event.Request)
2021-03-22 15:00:26 +05:30
builder.WriteString("\n```\n")
}
if event.Response != "" {
2021-03-22 15:00:26 +05:30
builder.WriteString("\n**Response**\n\n```http\n")
// If the response is larger than 5 kb, truncate it before writing.
if len(event.Response) > 5*1024 {
builder.WriteString(event.Response[:5*1024])
builder.WriteString(".... Truncated ....")
} else {
builder.WriteString(event.Response)
}
2021-06-06 17:38:39 +05:30
builder.WriteString("\n```\n")
}
2021-02-26 13:13:11 +05:30
if len(event.ExtractedResults) > 0 || len(event.Metadata) > 0 {
2021-06-06 17:38:39 +05:30
builder.WriteString("\n**Extra Information**\n\n")
2021-02-26 13:13:11 +05:30
if len(event.ExtractedResults) > 0 {
builder.WriteString("**Extracted results**:\n\n")
2021-02-26 13:13:11 +05:30
for _, v := range event.ExtractedResults {
builder.WriteString("- ")
builder.WriteString(v)
builder.WriteString("\n")
}
builder.WriteString("\n")
}
2021-02-26 13:13:11 +05:30
if len(event.Metadata) > 0 {
builder.WriteString("**Metadata**:\n\n")
2021-02-26 13:13:11 +05:30
for k, v := range event.Metadata {
builder.WriteString("- ")
builder.WriteString(k)
builder.WriteString(": ")
builder.WriteString(types.ToString(v))
builder.WriteString("\n")
}
builder.WriteString("\n")
}
}
if event.Interaction != nil {
builder.WriteString("**Interaction Data**\n---\n")
builder.WriteString(event.Interaction.Protocol)
if event.Interaction.QType != "" {
builder.WriteString(" (")
builder.WriteString(event.Interaction.QType)
builder.WriteString(")")
}
builder.WriteString(" Interaction from ")
builder.WriteString(event.Interaction.RemoteAddress)
builder.WriteString(" at ")
builder.WriteString(event.Interaction.UniqueID)
if event.Interaction.RawRequest != "" {
builder.WriteString("\n\n**Interaction Request**\n\n```\n")
builder.WriteString(event.Interaction.RawRequest)
builder.WriteString("\n```\n")
}
if event.Interaction.RawResponse != "" {
builder.WriteString("\n**Interaction Response**\n\n```\n")
builder.WriteString(event.Interaction.RawResponse)
builder.WriteString("\n```\n")
}
}
reference := event.Info.Reference
if !reference.IsEmpty() {
builder.WriteString("\nReferences: \n")
2021-06-05 23:00:59 +05:30
referenceSlice := reference.ToSlice()
for i, item := range referenceSlice {
builder.WriteString("- ")
builder.WriteString(item)
if len(referenceSlice)-1 != i {
builder.WriteString("\n")
}
2021-06-05 23:00:59 +05:30
}
}
2021-03-22 14:36:08 +05:30
builder.WriteString("\n---\nGenerated by [Nuclei](https://github.com/projectdiscovery/nuclei)")
data := builder.String()
return data
}
// GetMatchedTemplate returns the matched template from a result event
2021-02-26 13:13:11 +05:30
func GetMatchedTemplate(event *output.ResultEvent) string {
builder := &strings.Builder{}
2021-02-26 13:13:11 +05:30
builder.WriteString(event.TemplateID)
if event.MatcherName != "" {
builder.WriteString(":")
2021-02-26 13:13:11 +05:30
builder.WriteString(event.MatcherName)
}
2021-02-26 13:13:11 +05:30
if event.ExtractorName != "" {
builder.WriteString(":")
2021-02-26 13:13:11 +05:30
builder.WriteString(event.ExtractorName)
}
template := builder.String()
return template
}
func ToMarkdownTableString(templateInfo *model.Info) string {
fields := utils.NewEmptyInsertionOrderedStringMap(5)
fields.Set("Name", templateInfo.Name)
fields.Set("Authors", templateInfo.Authors.String())
fields.Set("Tags", templateInfo.Tags.String())
fields.Set("Severity", templateInfo.SeverityHolder.Severity.String())
fields.Set("Description", templateInfo.Description)
2021-09-09 03:30:17 +05:30
fields.Set("Remediation", templateInfo.Remediation)
classification := templateInfo.Classification
if classification != nil {
fields.Set("CVSS-Metrics", classification.CVSSMetrics)
fields.Set("CVE-ID", classification.CVEID.String())
fields.Set("CWE-ID", classification.CWEID.String())
fields.Set("CVSS-Score", strconv.FormatFloat(classification.CVSSScore, 'f', 2, 64))
}
builder := &bytes.Buffer{}
toMarkDownTable := func(insertionOrderedStringMap *utils.InsertionOrderedStringMap) {
insertionOrderedStringMap.ForEach(func(key string, value string) {
if utils.IsNotBlank(value) {
builder.WriteString(fmt.Sprintf("| %s | %s |\n", key, value))
}
})
}
toMarkDownTable(fields)
toMarkDownTable(utils.NewInsertionOrderedStringMap(templateInfo.AdditionalFields))
return builder.String()
}