diff --git a/integration_tests/http/dsl-functions.yaml b/integration_tests/http/dsl-functions.yaml index 7c3ec75d..72dffbfc 100644 --- a/integration_tests/http/dsl-functions.yaml +++ b/integration_tests/http/dsl-functions.yaml @@ -98,7 +98,6 @@ requests: 85: {{split("ab,cd,efg", ",", 2)}} 86: {{ip_format('127.0.0.1', 3)}} 87: {{ip_format('127.0.1.0', 11)}} - extractors: - type: regex name: results diff --git a/v2/go.mod b/v2/go.mod index fc6df71f..27a4ff18 100644 --- a/v2/go.mod +++ b/v2/go.mod @@ -82,7 +82,7 @@ require ( github.com/projectdiscovery/sarif v0.0.1 github.com/projectdiscovery/tlsx v1.0.5 github.com/projectdiscovery/uncover v1.0.2 - github.com/projectdiscovery/utils v0.0.10-0.20230217185600-008d111dd1c1 + github.com/projectdiscovery/utils v0.0.13 github.com/projectdiscovery/wappalyzergo v0.0.81 github.com/stretchr/testify v1.8.2 gopkg.in/src-d/go-git.v4 v4.13.1 diff --git a/v2/go.sum b/v2/go.sum index 85323435..b8fe6c26 100644 --- a/v2/go.sum +++ b/v2/go.sum @@ -573,8 +573,8 @@ github.com/projectdiscovery/tlsx v1.0.5 h1:ZDMcwqjwXB0x2XBzvdra7HYiN8yLGBhHc5qE2 github.com/projectdiscovery/tlsx v1.0.5/go.mod h1:4/jsS5OIawsJ11sWWLpBHJV3vTZltB8otwxfi56hROM= github.com/projectdiscovery/uncover v1.0.2 h1:mRFzflYyvwKkHd3XKufMlDRrb6p1mjFZTSHoNAUpFwo= github.com/projectdiscovery/uncover v1.0.2/go.mod h1:lz4QYfArSA6jJkXyB71kN2/Pc7IW7nJB8c95n7xtwqY= -github.com/projectdiscovery/utils v0.0.10-0.20230217185600-008d111dd1c1 h1:ZxRylh56CH9MwmhrF4sLenwqpmhu+Gxwl3o4x+wlTVY= -github.com/projectdiscovery/utils v0.0.10-0.20230217185600-008d111dd1c1/go.mod h1:dZqlayNwgCGn2HgYfKrI71RjBEyKsEPovrU+UDfpQWw= +github.com/projectdiscovery/utils v0.0.13 h1:Bvguo7avXN+Zs9tHL+8+Qld65nwIE8Kr9qddErDDqmw= +github.com/projectdiscovery/utils v0.0.13/go.mod h1:2CyxZXcx62NUiGJZZam23CpphqXy3kaomE9uvgHgkEo= github.com/projectdiscovery/wappalyzergo v0.0.81 h1:i7WYrH+O2EoHbY1g/WnrxO4YF/0OkA/G1bw6z8WKcjA= github.com/projectdiscovery/wappalyzergo v0.0.81/go.mod h1:HvYuW0Be4JCjVds/+XAEaMSqRG9yrI97UmZq0TPk6A0= github.com/projectdiscovery/yamldoc-go v1.0.3-0.20211126104922-00d2c6bb43b6 h1:DvWRQpw7Ib2CRL3ogYm/BWM+X0UGPfz1n9Ix9YKgFM8= diff --git a/v2/pkg/operators/common/dsl/dsl.go b/v2/pkg/operators/common/dsl/dsl.go index c7f9c2e6..db8b559c 100644 --- a/v2/pkg/operators/common/dsl/dsl.go +++ b/v2/pkg/operators/common/dsl/dsl.go @@ -37,11 +37,14 @@ import ( "github.com/logrusorgru/aurora" "github.com/spaolacci/murmur3" + "github.com/miekg/dns" "github.com/projectdiscovery/gologger" "github.com/projectdiscovery/mapcidr" "github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/helpers/deserialization" "github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/randomip" + "github.com/projectdiscovery/nuclei/v2/pkg/protocols/dns/dnsclientpool" "github.com/projectdiscovery/nuclei/v2/pkg/types" + sliceutil "github.com/projectdiscovery/utils/slice" ) const ( @@ -914,6 +917,82 @@ func init() { return buf.String(), nil }), + "resolve": makeMultiSignatureDslFunction([]string{ + "(host string) string", + "(format string) string"}, + func(args ...interface{}) (interface{}, error) { + argCount := len(args) + if argCount == 0 || argCount > 2 { + return nil, ErrinvalidDslFunction + } + format := "4" + var dnsType uint16 + if len(args) > 1 { + format = strings.ToLower(types.ToString(args[1])) + } + + switch format { + case "4", "a": + dnsType = dns.TypeA + case "6", "aaaa": + dnsType = dns.TypeAAAA + case "cname": + dnsType = dns.TypeCNAME + case "ns": + dnsType = dns.TypeNS + case "txt": + dnsType = dns.TypeTXT + case "srv": + dnsType = dns.TypeSRV + case "ptr": + dnsType = dns.TypePTR + case "mx": + dnsType = dns.TypeMX + case "soa": + dnsType = dns.TypeSOA + case "caa": + dnsType = dns.TypeCAA + default: + return nil, fmt.Errorf("invalid dns type") + } + + err := dnsclientpool.Init(&types.Options{}) + if err != nil { + return nil, err + } + dnsClient, err := dnsclientpool.Get(nil, &dnsclientpool.Configuration{}) + if err != nil { + return nil, err + } + + // query + rawResp, err := dnsClient.Query(types.ToString(args[0]), dnsType) + if err != nil { + return nil, err + } + + dnsValues := map[uint16][]string{ + dns.TypeA: rawResp.A, + dns.TypeAAAA: rawResp.AAAA, + dns.TypeCNAME: rawResp.CNAME, + dns.TypeNS: rawResp.NS, + dns.TypeTXT: rawResp.TXT, + dns.TypeSRV: rawResp.SRV, + dns.TypePTR: rawResp.PTR, + dns.TypeMX: rawResp.MX, + dns.TypeSOA: rawResp.SOA, + dns.TypeCAA: rawResp.CAA, + } + + if values, ok := dnsValues[dnsType]; ok { + firstFound, found := sliceutil.FirstNonZero(values) + if found { + return firstFound, nil + } + } + + return "", fmt.Errorf("no records found") + }), "ip_format": makeDslFunction(2, func(args ...interface{}) (interface{}, error) { ipFormat, err := strconv.ParseInt(types.ToString(args[1]), 10, 64) if err != nil { diff --git a/v2/pkg/operators/common/dsl/dsl_test.go b/v2/pkg/operators/common/dsl/dsl_test.go index b9e908a8..ff3fa2b1 100644 --- a/v2/pkg/operators/common/dsl/dsl_test.go +++ b/v2/pkg/operators/common/dsl/dsl_test.go @@ -141,6 +141,8 @@ func TestGetPrintableDslFunctionSignatures(t *testing.T) { repeat(arg1, arg2 interface{}) interface{} replace(arg1, arg2, arg3 interface{}) interface{} replace_regex(arg1, arg2, arg3 interface{}) interface{} + resolve(format string) string + resolve(host string) string reverse(arg1 interface{}) interface{} sha1(arg1 interface{}) interface{} sha256(arg1 interface{}) interface{} @@ -271,10 +273,15 @@ func TestDslExpressions(t *testing.T) { `join(", ", split(hex_encode("abcdefg"), 2))`: "61, 62, 63, 64, 65, 66, 67", `json_minify("{ \"name\": \"John Doe\", \"foo\": \"bar\" }")`: "{\"foo\":\"bar\",\"name\":\"John Doe\"}", `json_prettify("{\"foo\":\"bar\",\"name\":\"John Doe\"}")`: "{\n \"foo\": \"bar\",\n \"name\": \"John Doe\"\n}", - `ip_format('127.0.0.1', '1')`: "127.0.0.1", - `ip_format('127.0.0.1', '3')`: "0177.0.0.01", - `ip_format('127.0.0.1', '5')`: "281472812449793", - `ip_format('127.0.1.0', '11')`: "127.0.256", + `resolve("scanme.sh")`: "128.199.158.128", + `resolve("scanme.sh","a")`: "128.199.158.128", + `resolve("scanme.sh","6")`: "2400:6180:0:d0::91:1001", + `resolve("scanme.sh","aaaa")`: "2400:6180:0:d0::91:1001", + `resolve("scanme.sh","soa")`: "ns69.domaincontrol.com", + `ip_format('127.0.0.1', '1')`: "127.0.0.1", + `ip_format('127.0.0.1', '3')`: "0177.0.0.01", + `ip_format('127.0.0.1', '5')`: "281472812449793", + `ip_format('127.0.1.0', '11')`: "127.0.256", } testDslExpressionScenarios(t, dslExpressions)