mirror of https://github.com/daffainfo/nuclei.git
Merge pull request #372 from projectdiscovery/iceman-add-dynamic-fields
Added dynamic field in info key supportdev
commit
b194472371
|
@ -10,7 +10,7 @@ require (
|
|||
github.com/json-iterator/go v1.1.10
|
||||
github.com/karrick/godirwalk v1.16.1
|
||||
github.com/logrusorgru/aurora v2.0.3+incompatible
|
||||
github.com/miekg/dns v1.1.33
|
||||
github.com/miekg/dns v1.1.34
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/projectdiscovery/gologger v1.0.1
|
||||
github.com/projectdiscovery/httpx v1.0.2
|
||||
|
|
|
@ -37,8 +37,8 @@ github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/Qd
|
|||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc=
|
||||
github.com/miekg/dns v1.1.29/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
github.com/miekg/dns v1.1.33 h1:8KUVEKrUw2dmu1Ys0aWnkEJgoRaLAzNysfCh2KSMWiI=
|
||||
github.com/miekg/dns v1.1.33/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
github.com/miekg/dns v1.1.34 h1:SgTzfkN+oLoIHF1bgUP+C71mzuDl3AhLApHzCCIAMWM=
|
||||
github.com/miekg/dns v1.1.34/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
|
||||
|
|
|
@ -136,16 +136,16 @@ func (r *Runner) getParsedTemplatesFor(templatePaths []string, severities string
|
|||
switch tp := t.(type) {
|
||||
case *templates.Template:
|
||||
// only include if severity matches or no severity filtering
|
||||
sev := strings.ToLower(tp.Info.Severity)
|
||||
sev := strings.ToLower(tp.Info["severity"])
|
||||
if !filterBySeverity || hasMatchingSeverity(sev, allSeverities) {
|
||||
parsedTemplates = append(parsedTemplates, tp)
|
||||
gologger.Infof("%s\n", r.templateLogMsg(tp.ID, tp.Info.Name, tp.Info.Author, tp.Info.Severity))
|
||||
gologger.Infof("%s\n", r.templateLogMsg(tp.ID, tp.Info["name"], tp.Info["author"], tp.Info["severity"]))
|
||||
} else {
|
||||
gologger.Warningf("Excluding template %s due to severity filter (%s not in [%s])", tp.ID, sev, severities)
|
||||
}
|
||||
case *workflows.Workflow:
|
||||
parsedTemplates = append(parsedTemplates, tp)
|
||||
gologger.Infof("%s\n", r.templateLogMsg(tp.ID, tp.Info.Name, tp.Info.Author, tp.Info.Severity))
|
||||
gologger.Infof("%s\n", r.templateLogMsg(tp.ID, tp.Info["name"], tp.Info["author"], tp.Info["severity"]))
|
||||
workflowCount++
|
||||
default:
|
||||
gologger.Errorf("Could not parse file '%s': %s\n", match, err)
|
||||
|
@ -198,9 +198,9 @@ func (r *Runner) logAvailableTemplate(tplPath string) {
|
|||
if t != nil {
|
||||
switch tp := t.(type) {
|
||||
case *templates.Template:
|
||||
gologger.Silentf("%s\n", r.templateLogMsg(tp.ID, tp.Info.Name, tp.Info.Author, tp.Info.Severity))
|
||||
gologger.Silentf("%s\n", r.templateLogMsg(tp.ID, tp.Info["name"], tp.Info["author"], tp.Info["severity"]))
|
||||
case *workflows.Workflow:
|
||||
gologger.Silentf("%s\n", r.templateLogMsg(tp.ID, tp.Info.Name, tp.Info.Author, tp.Info.Severity))
|
||||
gologger.Silentf("%s\n", r.templateLogMsg(tp.ID, tp.Info["name"], tp.Info["author"], tp.Info["severity"]))
|
||||
default:
|
||||
gologger.Errorf("Could not parse file '%s': %s\n", tplPath, err)
|
||||
}
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
package executer
|
||||
|
||||
import "net/url"
|
||||
|
||||
// isURL tests a string to determine if it is a well-structured url or not.
|
||||
func isURL(toTest string) bool {
|
||||
_, err := url.ParseRequestURI(toTest)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
u, err := url.Parse(toTest)
|
||||
if err != nil || u.Scheme == "" || u.Host == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// extractDomain extracts the domain name of a URL
|
||||
func extractDomain(theURL string) string {
|
||||
u, err := url.Parse(theURL)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
hostname := u.Hostname()
|
||||
|
||||
return hostname
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
package executer
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type jsonOutput struct {
|
||||
Template string `json:"template"`
|
||||
Type string `json:"type"`
|
||||
Matched string `json:"matched"`
|
||||
MatcherName string `json:"matcher_name,omitempty"`
|
||||
ExtractedResults []string `json:"extracted_results,omitempty"`
|
||||
Name string `json:"name"`
|
||||
Severity string `json:"severity"`
|
||||
Author string `json:"author"`
|
||||
Description string `json:"description"`
|
||||
Request string `json:"request,omitempty"`
|
||||
Response string `json:"response,omitempty"`
|
||||
Meta map[string]interface{} `json:"meta,omitempty"`
|
||||
}
|
||||
|
||||
// unsafeToString converts byte slice to string with zero allocations
|
||||
func unsafeToString(bs []byte) string {
|
||||
return *(*string)(unsafe.Pointer(&bs))
|
||||
}
|
||||
|
||||
// headersToString converts http headers to string
|
||||
func headersToString(headers http.Header) string {
|
||||
builder := &strings.Builder{}
|
||||
|
||||
for header, values := range headers {
|
||||
builder.WriteString(header)
|
||||
builder.WriteString(": ")
|
||||
|
||||
for i, value := range values {
|
||||
builder.WriteString(value)
|
||||
|
||||
if i != len(values)-1 {
|
||||
builder.WriteRune('\n')
|
||||
builder.WriteString(header)
|
||||
builder.WriteString(": ")
|
||||
}
|
||||
}
|
||||
|
||||
builder.WriteRune('\n')
|
||||
}
|
||||
|
||||
return builder.String()
|
||||
}
|
|
@ -14,36 +14,29 @@ import (
|
|||
// nolint:interfacer // dns.Msg is out of current scope
|
||||
func (e *DNSExecuter) writeOutputDNS(domain string, req, resp *dns.Msg, matcher *matchers.Matcher, extractorResults []string) {
|
||||
if e.jsonOutput {
|
||||
output := jsonOutput{
|
||||
Template: e.template.ID,
|
||||
Type: "dns",
|
||||
Matched: domain,
|
||||
Name: e.template.Info.Name,
|
||||
Severity: e.template.Info.Severity,
|
||||
Author: e.template.Info.Author,
|
||||
Description: e.template.Info.Description,
|
||||
output := make(jsonOutput)
|
||||
output["template"] = e.template.ID
|
||||
output["type"] = "dns"
|
||||
output["matched"] = domain
|
||||
for k, v := range e.template.Info {
|
||||
output[k] = v
|
||||
}
|
||||
|
||||
if matcher != nil && len(matcher.Name) > 0 {
|
||||
output.MatcherName = matcher.Name
|
||||
output["matcher_name"] = matcher.Name
|
||||
}
|
||||
|
||||
if len(extractorResults) > 0 {
|
||||
output.ExtractedResults = extractorResults
|
||||
output["extracted_results"] = extractorResults
|
||||
}
|
||||
|
||||
if e.jsonRequest {
|
||||
output.Request = req.String()
|
||||
output.Response = resp.String()
|
||||
output["request"] = req.String()
|
||||
output["response"] = resp.String()
|
||||
}
|
||||
|
||||
data, err := jsoniter.Marshal(output)
|
||||
if err != nil {
|
||||
gologger.Warningf("Could not marshal json output: %s\n", err)
|
||||
}
|
||||
|
||||
gologger.Silentf("%s", string(data))
|
||||
|
||||
if e.writer != nil {
|
||||
if err := e.writer.Write(data); err != nil {
|
||||
gologger.Errorf("Could not write output data: %s\n", err)
|
||||
|
@ -68,9 +61,9 @@ func (e *DNSExecuter) writeOutputDNS(domain string, req, resp *dns.Msg, matcher
|
|||
builder.WriteString(colorizer.Colorizer.BrightBlue("dns").String())
|
||||
builder.WriteString("] ")
|
||||
|
||||
if e.template.Info.Severity != "" {
|
||||
if e.template.Info["severity"] != "" {
|
||||
builder.WriteString("[")
|
||||
builder.WriteString(colorizer.GetColorizedSeverity(e.template.Info.Severity))
|
||||
builder.WriteString(colorizer.GetColorizedSeverity(e.template.Info["severity"]))
|
||||
builder.WriteString("] ")
|
||||
}
|
||||
|
||||
|
|
|
@ -24,23 +24,21 @@ func (e *HTTPExecuter) writeOutputHTTP(req *requests.HTTPRequest, resp *http.Res
|
|||
}
|
||||
|
||||
if e.jsonOutput {
|
||||
output := jsonOutput{
|
||||
Template: e.template.ID,
|
||||
Type: "http",
|
||||
Matched: URL,
|
||||
Name: e.template.Info.Name,
|
||||
Severity: e.template.Info.Severity,
|
||||
Author: e.template.Info.Author,
|
||||
Description: e.template.Info.Description,
|
||||
Meta: meta,
|
||||
output := make(jsonOutput)
|
||||
output["template"] = e.template.ID
|
||||
output["type"] = "http"
|
||||
output["matched"] = URL
|
||||
if len(meta) > 0 {
|
||||
output["meta"] = meta
|
||||
}
|
||||
for k, v := range e.template.Info {
|
||||
output[k] = v
|
||||
}
|
||||
|
||||
if matcher != nil && len(matcher.Name) > 0 {
|
||||
output.MatcherName = matcher.Name
|
||||
output["matcher_name"] = matcher.Name
|
||||
}
|
||||
|
||||
if len(extractorResults) > 0 {
|
||||
output.ExtractedResults = extractorResults
|
||||
output["extracted_results"] = extractorResults
|
||||
}
|
||||
|
||||
// TODO: URL should be an argument
|
||||
|
@ -49,24 +47,21 @@ func (e *HTTPExecuter) writeOutputHTTP(req *requests.HTTPRequest, resp *http.Res
|
|||
if err != nil {
|
||||
gologger.Warningf("could not dump request: %s\n", err)
|
||||
} else {
|
||||
output.Request = string(dumpedRequest)
|
||||
output["request"] = string(dumpedRequest)
|
||||
}
|
||||
|
||||
dumpedResponse, err := httputil.DumpResponse(resp, false)
|
||||
|
||||
if err != nil {
|
||||
gologger.Warningf("could not dump response: %s\n", err)
|
||||
} else {
|
||||
output.Response = string(dumpedResponse) + body
|
||||
output["response"] = string(dumpedResponse) + body
|
||||
}
|
||||
}
|
||||
|
||||
data, err := jsoniter.Marshal(output)
|
||||
|
||||
if err != nil {
|
||||
gologger.Warningf("Could not marshal json output: %s\n", err)
|
||||
}
|
||||
|
||||
gologger.Silentf("%s", string(data))
|
||||
|
||||
if e.writer != nil {
|
||||
|
@ -75,7 +70,6 @@ func (e *HTTPExecuter) writeOutputHTTP(req *requests.HTTPRequest, resp *http.Res
|
|||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -94,9 +88,9 @@ func (e *HTTPExecuter) writeOutputHTTP(req *requests.HTTPRequest, resp *http.Res
|
|||
builder.WriteString(colorizer.Colorizer.BrightBlue("http").String())
|
||||
builder.WriteString("] ")
|
||||
|
||||
if e.template.Info.Severity != "" {
|
||||
if e.template.Info["severity"] != "" {
|
||||
builder.WriteString("[")
|
||||
builder.WriteString(colorizer.GetColorizedSeverity(e.template.Info.Severity))
|
||||
builder.WriteString(colorizer.GetColorizedSeverity(e.template.Info["severity"]))
|
||||
builder.WriteString("] ")
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
package executer
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type jsonOutput map[string]interface{}
|
||||
|
||||
// unsafeToString converts byte slice to string with zero allocations
|
||||
func unsafeToString(bs []byte) string {
|
||||
return *(*string)(unsafe.Pointer(&bs))
|
||||
}
|
||||
|
||||
// headersToString converts http headers to string
|
||||
func headersToString(headers http.Header) string {
|
||||
builder := &strings.Builder{}
|
||||
|
||||
for header, values := range headers {
|
||||
builder.WriteString(header)
|
||||
builder.WriteString(": ")
|
||||
|
||||
for i, value := range values {
|
||||
builder.WriteString(value)
|
||||
|
||||
if i != len(values)-1 {
|
||||
builder.WriteRune('\n')
|
||||
builder.WriteString(header)
|
||||
builder.WriteString(": ")
|
||||
}
|
||||
}
|
||||
builder.WriteRune('\n')
|
||||
}
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
// isURL tests a string to determine if it is a well-structured url or not.
|
||||
func isURL(toTest string) bool {
|
||||
_, err := url.ParseRequestURI(toTest)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
u, err := url.Parse(toTest)
|
||||
if err != nil || u.Scheme == "" || u.Host == "" {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// extractDomain extracts the domain name of a URL
|
||||
func extractDomain(theURL string) string {
|
||||
u, err := url.Parse(theURL)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return u.Hostname()
|
||||
}
|
|
@ -9,7 +9,7 @@ type Template struct {
|
|||
// ID is the unique id for the template
|
||||
ID string `yaml:"id"`
|
||||
// Info contains information about the template
|
||||
Info Info `yaml:"info"`
|
||||
Info map[string]string `yaml:"info"`
|
||||
// BulkRequestsHTTP contains the http request to make in the template
|
||||
BulkRequestsHTTP []*requests.BulkHTTPRequest `yaml:"requests,omitempty"`
|
||||
// RequestsDNS contains the dns request to make in the template
|
||||
|
@ -22,18 +22,6 @@ func (t *Template) GetPath() string {
|
|||
return t.path
|
||||
}
|
||||
|
||||
// Info contains information about the request template
|
||||
type Info struct {
|
||||
// Name is the name of the template
|
||||
Name string `yaml:"name"`
|
||||
// Author is the name of the author of the template
|
||||
Author string `yaml:"author"`
|
||||
// Severity optionally describes the severity of the template
|
||||
Severity string `yaml:"severity,omitempty"`
|
||||
// Description optionally describes the template.
|
||||
Description string `yaml:"description,omitempty"`
|
||||
}
|
||||
|
||||
func (t *Template) GetHTTPRequestCount() int64 {
|
||||
var count int64 = 0
|
||||
for _, request := range t.BulkRequestsHTTP {
|
||||
|
|
|
@ -5,7 +5,7 @@ type Workflow struct {
|
|||
// ID is the unique id for the template
|
||||
ID string `yaml:"id"`
|
||||
// Info contains information about the template
|
||||
Info Info `yaml:"info"`
|
||||
Info map[string]string `yaml:"info"`
|
||||
// CookieReuse makes all cookies shared by templates within the workflow
|
||||
CookieReuse bool `yaml:"cookie-reuse,omitempty"`
|
||||
// Variables contains the variables accessible to the pseudo-code
|
||||
|
@ -19,15 +19,3 @@ type Workflow struct {
|
|||
func (w *Workflow) GetPath() string {
|
||||
return w.path
|
||||
}
|
||||
|
||||
// Info contains information about workflow
|
||||
type Info struct {
|
||||
// Name is the name of the workflow
|
||||
Name string `yaml:"name"`
|
||||
// Author is the name of the author of the workflow
|
||||
Author string `yaml:"author"`
|
||||
// Severity optionally describes the severity of the template
|
||||
Severity string `yaml:"severity,omitempty"`
|
||||
// Description optionally describes the template.
|
||||
Description string `yaml:"description,omitempty"`
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue