RES-84 # Improve Nuclei CLI interface

* changed the template info content retrieval logic not to use reflection
dev
forgedhallpass 2021-08-05 16:22:28 +03:00
parent 75b21282ab
commit ccf65ab1d3
2 changed files with 65 additions and 31 deletions

View File

@ -3,9 +3,9 @@ package format
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"reflect"
"strings" "strings"
"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"
) )
@ -35,29 +35,21 @@ func MarkdownDescription(event *output.ResultEvent) string { // TODO remove the
builder.WriteString("**Details**: **") builder.WriteString("**Details**: **")
builder.WriteString(template) builder.WriteString(template)
builder.WriteString("** ") builder.WriteString("** ")
builder.WriteString(" matched at ") builder.WriteString(" matched at ")
builder.WriteString(event.Host) builder.WriteString(event.Host)
builder.WriteString("\n\n**Protocol**: ") builder.WriteString("\n\n**Protocol**: ")
builder.WriteString(strings.ToUpper(event.Type)) builder.WriteString(strings.ToUpper(event.Type))
builder.WriteString("\n\n**Full URL**: ") builder.WriteString("\n\n**Full URL**: ")
builder.WriteString(event.Matched) builder.WriteString(event.Matched)
builder.WriteString("\n\n**Timestamp**: ") builder.WriteString("\n\n**Timestamp**: ")
builder.WriteString(event.Timestamp.Format("Mon Jan 2 15:04:05 -0700 MST 2006")) 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("\n\n**Template Information**\n\n| Key | Value |\n|---|---|\n")
builder.WriteString(toMarkdownTableString(&event.Info))
fields := reflect.TypeOf(event.Info)
values := reflect.ValueOf(event.Info)
numberOfFields := fields.NumField()
for i := 0; i < numberOfFields; i++ { // TODO review
field := fields.Field(i)
value := values.Field(i)
if field.Name == "reference" {
continue
}
builder.WriteString(fmt.Sprintf("| %s | %s |\n", field.Name, value))
}
if event.Request != "" { if event.Request != "" {
builder.WriteString("\n**Request**\n\n```http\n") builder.WriteString("\n**Request**\n\n```http\n")
@ -176,3 +168,27 @@ func GetMatchedTemplate(event *output.ResultEvent) string {
template := builder.String() template := builder.String()
return template return template
} }
/*
TODO remove and reuse the duplicated logic below jira.go <-> format.go
*/
func toMarkdownTableString(templateInfo *model.Info) string {
fields := map[string]string{
"Name": templateInfo.Name,
"Authors": sliceToString(templateInfo.Authors),
"Tags": sliceToString(templateInfo.Tags),
"Description": templateInfo.Description,
"Severity": templateInfo.SeverityHolder.Severity.String(),
}
builder := &bytes.Buffer{}
for k, v := range fields {
builder.WriteString(fmt.Sprintf("| %s | %s |\n", k, v))
}
return builder.String()
}
func sliceToString(stringSlice model.StringSlice) string {
return strings.Join(stringSlice.ToSlice(), ", ")
}

View File

@ -4,11 +4,11 @@ import (
"bytes" "bytes"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"reflect"
"strings" "strings"
"github.com/andygrunwald/go-jira" "github.com/andygrunwald/go-jira"
"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/reporting/format" "github.com/projectdiscovery/nuclei/v2/pkg/reporting/format"
"github.com/projectdiscovery/nuclei/v2/pkg/types" "github.com/projectdiscovery/nuclei/v2/pkg/types"
@ -102,33 +102,27 @@ func jiraFormatDescription(event *output.ResultEvent) string { // TODO remove th
builder.WriteString("*Details*: *") builder.WriteString("*Details*: *")
builder.WriteString(template) builder.WriteString(template)
builder.WriteString("* ") builder.WriteString("* ")
builder.WriteString(" matched at ") builder.WriteString(" matched at ")
builder.WriteString(event.Host) builder.WriteString(event.Host)
builder.WriteString("\n\n*Protocol*: ") builder.WriteString("\n\n*Protocol*: ")
builder.WriteString(strings.ToUpper(event.Type)) builder.WriteString(strings.ToUpper(event.Type))
builder.WriteString("\n\n*Full URL*: ") builder.WriteString("\n\n*Full URL*: ")
builder.WriteString(event.Matched) builder.WriteString(event.Matched)
builder.WriteString("\n\n*Timestamp*: ") builder.WriteString("\n\n*Timestamp*: ")
builder.WriteString(event.Timestamp.Format("Mon Jan 2 15:04:05 -0700 MST 2006")) 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") builder.WriteString("\n\n*Template Information*\n\n| Key | Value |\n")
builder.WriteString(toMarkdownTableString(&event.Info))
fields := reflect.TypeOf(event.Info)
values := reflect.ValueOf(event.Info)
numberOfFields := fields.NumField()
for i := 0; i < numberOfFields; i++ { // TODO review
field := fields.Field(i)
value := values.Field(i)
if field.Name == "reference" {
continue
}
builder.WriteString(fmt.Sprintf("| %s | %s |\n", field.Name, value))
}
builder.WriteString("\n*Request*\n\n{code}\n") builder.WriteString("\n*Request*\n\n{code}\n")
builder.WriteString(event.Request) builder.WriteString(event.Request)
builder.WriteString("\n{code}\n\n*Response*\n\n{code}\n") builder.WriteString("\n{code}\n")
builder.WriteString("\n*Response*\n\n{code}\n")
// If the response is larger than 5 kb, truncate it before writing. // If the response is larger than 5 kb, truncate it before writing.
if len(event.Response) > 5*1024 { if len(event.Response) > 5*1024 {
builder.WriteString(event.Response[:5*1024]) builder.WriteString(event.Response[:5*1024])
@ -221,3 +215,27 @@ func jiraFormatDescription(event *output.ResultEvent) string { // TODO remove th
data := builder.String() data := builder.String()
return data return data
} }
/*
TODO remove and reuse the duplicated logic below jira.go <-> format.go
*/
func toMarkdownTableString(templateInfo *model.Info) string {
fields := map[string]string{
"Name": templateInfo.Name,
"Authors": sliceToString(templateInfo.Authors),
"Tags": sliceToString(templateInfo.Tags),
"Description": templateInfo.Description,
"Severity": templateInfo.SeverityHolder.Severity.String(),
}
builder := &bytes.Buffer{}
for k, v := range fields {
builder.WriteString(fmt.Sprintf("| %s | %s |\n", k, v))
}
return builder.String()
}
func sliceToString(stringSlice model.StringSlice) string {
return strings.Join(stringSlice.ToSlice(), ", ")
}