mirror of https://github.com/daffainfo/nuclei.git
Expose DNS fields for matchers and extractors (#3613)
* Extend dns extractor to dns answer records * add test template * Ignore error for dns variables are not found * Add all the records of answer section * Fixed the wrong typecastingdev
parent
d55ad995d0
commit
f640187709
|
@ -0,0 +1,23 @@
|
|||
id: dns-template
|
||||
|
||||
info:
|
||||
name: basic dns template
|
||||
author: pdteam
|
||||
severity: info
|
||||
|
||||
dns:
|
||||
- name: "{{FQDN}}"
|
||||
type: CNAME
|
||||
|
||||
matchers:
|
||||
- type: dsl
|
||||
dsl:
|
||||
- "rcode == 0"
|
||||
|
||||
extractors:
|
||||
- type: dsl
|
||||
dsl:
|
||||
- rcode
|
||||
- cname
|
||||
- a
|
||||
- aaaa
|
|
@ -5,11 +5,12 @@ import (
|
|||
)
|
||||
|
||||
var dnsTestCases = map[string]testutils.TestCase{
|
||||
"dns/basic.yaml": &dnsBasic{},
|
||||
"dns/ptr.yaml": &dnsPtr{},
|
||||
"dns/caa.yaml": &dnsCAA{},
|
||||
"dns/tlsa.yaml": &dnsTLSA{},
|
||||
"dns/variables.yaml": &dnsVariables{},
|
||||
"dns/basic.yaml": &dnsBasic{},
|
||||
"dns/ptr.yaml": &dnsPtr{},
|
||||
"dns/caa.yaml": &dnsCAA{},
|
||||
"dns/tlsa.yaml": &dnsTLSA{},
|
||||
"dns/variables.yaml": &dnsVariables{},
|
||||
"dns/dsl-matcher-variable.yaml": &dnsDSLMatcherVariable{},
|
||||
}
|
||||
|
||||
type dnsBasic struct{}
|
||||
|
@ -66,3 +67,14 @@ func (h *dnsVariables) Execute(filePath string) error {
|
|||
}
|
||||
return expectResultsCount(results, 1)
|
||||
}
|
||||
|
||||
type dnsDSLMatcherVariable struct{}
|
||||
|
||||
// Execute executes a test case and returns an error if occurred
|
||||
func (h *dnsDSLMatcherVariable) Execute(filePath string) error {
|
||||
results, err := testutils.RunNucleiTemplateAndGetResults(filePath, "one.one.one.one", debug)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return expectResultsCount(results, 1)
|
||||
}
|
||||
|
|
|
@ -174,7 +174,9 @@ func (e *Extractor) ExtractDSL(data map[string]interface{}) map[string]struct{}
|
|||
|
||||
for _, compiledExpression := range e.dslCompiled {
|
||||
result, err := compiledExpression.Evaluate(data)
|
||||
if err != nil {
|
||||
// ignore errors that are related to missing parameters
|
||||
// eg: dns dsl can have all the parameters that are not present
|
||||
if err != nil && !strings.HasPrefix(err.Error(), "No parameter") {
|
||||
return results
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"github.com/projectdiscovery/nuclei/v2/pkg/operators/matchers"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/output"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/generators"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/types"
|
||||
"github.com/projectdiscovery/retryabledns"
|
||||
)
|
||||
|
@ -79,7 +80,7 @@ func (request *Request) getMatchPart(part string, data output.InternalEvent) (in
|
|||
|
||||
// responseToDSLMap converts a DNS response to a map for use in DSL matching
|
||||
func (request *Request) responseToDSLMap(req, resp *dns.Msg, host, matched string, traceData *retryabledns.TraceData) output.InternalEvent {
|
||||
return output.InternalEvent{
|
||||
ret := output.InternalEvent{
|
||||
"host": host,
|
||||
"matched": matched,
|
||||
"request": req.String(),
|
||||
|
@ -95,6 +96,7 @@ func (request *Request) responseToDSLMap(req, resp *dns.Msg, host, matched strin
|
|||
"type": request.Type().String(),
|
||||
"trace": traceToString(traceData, false),
|
||||
}
|
||||
return generators.MergeMaps(ret, recordsKeyValue(resp.Answer))
|
||||
}
|
||||
|
||||
// MakeResultEvent creates a result event from internal wrapped event
|
||||
|
@ -147,3 +149,23 @@ func traceToString(traceData *retryabledns.TraceData, withSteps bool) string {
|
|||
}
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
func recordsKeyValue(resourceRecords []dns.RR) output.InternalEvent {
|
||||
var oe = make(output.InternalEvent)
|
||||
for _, resourceRecord := range resourceRecords {
|
||||
key := strings.ToLower(dns.TypeToString[resourceRecord.Header().Rrtype])
|
||||
value := strings.ReplaceAll(resourceRecord.String(), resourceRecord.Header().String(), "")
|
||||
|
||||
if preVal, ok := oe[key]; ok {
|
||||
switch v := oe[key].(type) {
|
||||
case string:
|
||||
oe[key] = []string{value, preVal.(string)}
|
||||
case []string:
|
||||
oe[key] = append(v, preVal.([]string)...)
|
||||
}
|
||||
continue
|
||||
}
|
||||
oe[key] = value
|
||||
}
|
||||
return oe
|
||||
}
|
||||
|
|
|
@ -43,11 +43,12 @@ func TestResponseToDSLMap(t *testing.T) {
|
|||
|
||||
resp := new(dns.Msg)
|
||||
resp.Rcode = dns.RcodeSuccess
|
||||
resp.Answer = append(resp.Answer, &dns.A{A: net.ParseIP("1.1.1.1"), Hdr: dns.RR_Header{Name: "one.one.one.one."}})
|
||||
resp.Answer = append(resp.Answer, &dns.A{A: net.ParseIP("1.1.1.1"), Hdr: dns.RR_Header{Name: "one.one.one.one.", Rrtype: dns.TypeA}}, &dns.A{A: net.ParseIP("2.2.2.2"), Hdr: dns.RR_Header{Name: "one.one.one.one.", Rrtype: dns.TypeA}})
|
||||
|
||||
event := request.responseToDSLMap(req, resp, "one.one.one.one", "one.one.one.one", nil)
|
||||
require.Len(t, event, 14, "could not get correct number of items in dsl map")
|
||||
require.Len(t, event, 15, "could not get correct number of items in dsl map")
|
||||
require.Equal(t, dns.RcodeSuccess, event["rcode"], "could not get correct rcode")
|
||||
require.ElementsMatch(t, []string{net.ParseIP("1.1.1.1").String(), net.ParseIP("2.2.2.2").String()}, event["a"], "could not get correct a record")
|
||||
}
|
||||
|
||||
func TestDNSOperatorMatch(t *testing.T) {
|
||||
|
|
Loading…
Reference in New Issue