Skip to content

Commit 5b03a0e

Browse files
brenocssehsandeeptarunKoyalwar
authored
adding checkDnsResponse and fallback methods (#86)
* adding DnsResponse and fallback methods adding CNAME check fix typos adding tests * fix typo * fix typos * refactor with new logic * add retry flag * fix failing functional_test --------- Co-authored-by: Sandeep Singh <[email protected]> Co-authored-by: Tarun Koyalwar <[email protected]>
1 parent 9c6b3ec commit 5b03a0e

File tree

9 files changed

+185
-192
lines changed

9 files changed

+185
-192
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
cmd/generate-index/generate-index
22
cmd/cdncheck/cdncheck
3+
cmd/functional-test/cdncheck_dev
4+
cmd/functional-test/functional-test
35
dist/

README.md

+7-6
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,14 @@ DETECTION:
6868
-waf display only waf in cli output
6969

7070
MATCHER:
71-
-mcdn, -match-cdn string[] match host with specified cdn provider (fastly, cloudfront)
72-
-mcloud, -match-cloud string[] match host with specified cloud provider (google, oracle, aws, azure)
73-
-mwaf, -match-waf string[] match host with specified waf provider (cloudflare, incapsula)
71+
-mcdn, -match-cdn string[] match host with specified cdn provider (cloudfront, fastly, google, leaseweb)
72+
-mcloud, -match-cloud string[] match host with specified cloud provider (aws, google, oracle)
73+
-mwaf, -match-waf string[] match host with specified waf provider (cloudflare, incapsula, sucuri, akamai)
7474

7575
FILTER:
76-
-fcdn, -filter-cdn string[] filter host with specified cdn provider (fastly, cloudfront)
77-
-fcloud, -filter-cloud string[] filter host with specified cloud provider (google, oracle, aws, azure)
78-
-fwaf, -filter-waf string[] filter host with specified waf provider (cloudflare, incapsula)
76+
-fcdn, -filter-cdn string[] filter host with specified cdn provider (cloudfront, fastly, google, leaseweb)
77+
-fcloud, -filter-cloud string[] filter host with specified cloud provider (aws, google, oracle)
78+
-fwaf, -filter-waf string[] filter host with specified waf provider (cloudflare, incapsula, sucuri, akamai)
7979

8080
OUTPUT:
8181
-resp display technology name in cli output
@@ -89,6 +89,7 @@ OUTPUT:
8989
CONFIG:
9090
-r, -resolver string[] list of resolvers to use (file or comma separated)
9191
-e, -exclude exclude detected ip from output
92+
-retry int maximum number of retries for dns resolution (must be at least 1) (default 2)
9293

9394
UPDATE:
9495
-up, -update update cdncheck to latest version

cdncheck.go

+90-11
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"net"
55
"strings"
66
"sync"
7+
8+
"github.com/projectdiscovery/retryabledns"
79
)
810

911
var (
@@ -12,23 +14,50 @@ var (
1214
DefaultCloudProviders string
1315
)
1416

17+
// DefaultResolvers trusted (taken from fastdialer)
18+
var DefaultResolvers = []string{
19+
"1.1.1.1:53",
20+
"1.0.0.1:53",
21+
"8.8.8.8:53",
22+
"8.8.4.4:53",
23+
}
24+
1525
// Client checks for CDN based IPs which should be excluded
1626
// during scans since they belong to third party firewalls.
1727
type Client struct {
1828
sync.Once
19-
cdn *providerScraper
20-
waf *providerScraper
21-
cloud *providerScraper
29+
cdn *providerScraper
30+
waf *providerScraper
31+
cloud *providerScraper
32+
retriabledns *retryabledns.Client
2233
}
2334

24-
// New creates a new firewall IP checking client.
35+
// New creates cdncheck client with default options
36+
// NewWithOpts should be preferred over this function
2537
func New() *Client {
38+
client, _ := NewWithOpts(3, []string{})
39+
return client
40+
}
41+
42+
// NewWithOpts creates cdncheck client with custom options
43+
func NewWithOpts(MaxRetries int, resolvers []string) (*Client, error) {
44+
if MaxRetries <= 0 {
45+
MaxRetries = 3
46+
}
47+
if len(resolvers) == 0 {
48+
resolvers = DefaultResolvers
49+
}
50+
retryabledns, err := retryabledns.New(resolvers, MaxRetries)
51+
if err != nil {
52+
return nil, err
53+
}
2654
client := &Client{
27-
cdn: newProviderScraper(generatedData.CDN),
28-
waf: newProviderScraper(generatedData.WAF),
29-
cloud: newProviderScraper(generatedData.Cloud),
55+
cdn: newProviderScraper(generatedData.CDN),
56+
waf: newProviderScraper(generatedData.WAF),
57+
cloud: newProviderScraper(generatedData.Cloud),
58+
retriabledns: retryabledns,
3059
}
31-
return client
60+
return client, nil
3261
}
3362

3463
// CheckCDN checks if an IP is contained in the cdn denylist
@@ -49,9 +78,7 @@ func (c *Client) CheckCloud(ip net.IP) (matched bool, value string, err error) {
4978
return matched, value, err
5079
}
5180

52-
// Check checks if an IP is contained in the denylist
53-
//
54-
// It includes CDN, WAF and Cloud. Basically all varaint of individual functions
81+
// Check checks if ip belongs to one of CDN, WAF and Cloud . It is generic method for Checkxxx methods
5582
func (c *Client) Check(ip net.IP) (matched bool, value string, itemType string, err error) {
5683
if matched, value, err = c.cdn.Match(ip); err == nil && matched && value != "" {
5784
return matched, value, "cdn", nil
@@ -65,6 +92,58 @@ func (c *Client) Check(ip net.IP) (matched bool, value string, itemType string,
6592
return false, "", "", err
6693
}
6794

95+
// Check Domain with fallback checks if domain belongs to one of CDN, WAF and Cloud . It is generic method for Checkxxx methods
96+
// Since input is domain, as a fallback it queries CNAME records and checks if domain is WAF
97+
func (c *Client) CheckDomainWithFallback(domain string) (matched bool, value string, itemType string, err error) {
98+
dnsData, err := c.retriabledns.Resolve(domain)
99+
if err != nil {
100+
return false, "", "", err
101+
}
102+
matched, value, itemType, err = c.CheckDNSResponse(dnsData)
103+
if err != nil {
104+
return false, "", "", err
105+
}
106+
if matched {
107+
return matched, value, itemType, nil
108+
}
109+
// resolve cname
110+
dnsData, err = c.retriabledns.CNAME(domain)
111+
if err != nil {
112+
return false, "", "", err
113+
}
114+
return c.CheckDNSResponse(dnsData)
115+
}
116+
117+
// CheckDNSResponse is same as CheckDomainWithFallback but takes DNS response as input
118+
func (c *Client) CheckDNSResponse(dnsResponse *retryabledns.DNSData) (matched bool, value string, itemType string, err error) {
119+
if dnsResponse.A != nil {
120+
for _, ip := range dnsResponse.A {
121+
ipAddr := net.ParseIP(ip)
122+
if ipAddr == nil {
123+
continue
124+
}
125+
matched, value, itemType, err := c.Check(ipAddr)
126+
if err != nil {
127+
return false, "", "", err
128+
}
129+
if matched {
130+
return matched, value, itemType, nil
131+
}
132+
}
133+
}
134+
if dnsResponse.CNAME != nil {
135+
matched, discovered, itemType, err := c.CheckSuffix(dnsResponse.CNAME...)
136+
if err != nil {
137+
return false, "", itemType, err
138+
}
139+
if matched {
140+
// for now checkSuffix only checks for wafs
141+
return matched, discovered, itemType, nil
142+
}
143+
}
144+
return false, "", "", err
145+
}
146+
68147
func mapKeys(m map[string][]string) string {
69148
keys := make([]string, 0, len(m))
70149
for k := range m {

go.mod

+3-20
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ require (
77
github.com/ipinfo/go/v2 v2.9.2
88
github.com/logrusorgru/aurora v2.0.3+incompatible
99
github.com/pkg/errors v0.9.1
10-
github.com/projectdiscovery/fastdialer v0.0.25
1110
github.com/projectdiscovery/goflags v0.1.8
1211
github.com/projectdiscovery/gologger v1.1.8
1312
github.com/projectdiscovery/mapcidr v1.1.1
13+
github.com/projectdiscovery/retryabledns v1.0.23
1414
github.com/projectdiscovery/utils v0.0.26
1515
github.com/stretchr/testify v1.8.2
1616
github.com/weppos/publicsuffix-go v0.30.0
@@ -23,7 +23,6 @@ require (
2323
github.com/Masterminds/semver/v3 v3.2.1 // indirect
2424
github.com/Mzack9999/go-http-digest-auth-client v0.6.1-0.20220414142836-eb8883508809 // indirect
2525
github.com/VividCortex/ewma v1.2.0 // indirect
26-
github.com/akrylysov/pogreb v0.10.1 // indirect
2726
github.com/alecthomas/chroma v0.10.0 // indirect
2827
github.com/andybalholm/cascadia v1.3.1 // indirect
2928
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
@@ -33,7 +32,6 @@ require (
3332
github.com/cheggaaa/pb/v3 v3.1.2 // indirect
3433
github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08 // indirect
3534
github.com/davecgh/go-spew v1.1.1 // indirect
36-
github.com/dimchansky/utfbom v1.1.1 // indirect
3735
github.com/dlclark/regexp2 v1.8.1 // indirect
3836
github.com/dsnet/compress v0.0.1 // indirect
3937
github.com/fatih/color v1.14.1 // indirect
@@ -61,29 +59,14 @@ require (
6159
github.com/pierrec/lz4 v2.6.1+incompatible // indirect
6260
github.com/pmezard/go-difflib v1.0.0 // indirect
6361
github.com/projectdiscovery/blackrock v0.0.1 // indirect
64-
github.com/projectdiscovery/hmap v0.0.11 // indirect
65-
github.com/projectdiscovery/networkpolicy v0.0.5 // indirect
66-
github.com/projectdiscovery/retryabledns v1.0.21 // indirect
67-
github.com/projectdiscovery/retryablehttp-go v1.0.14 // indirect
62+
github.com/projectdiscovery/retryablehttp-go v1.0.15 // indirect
6863
github.com/rivo/uniseg v0.4.4 // indirect
64+
github.com/rogpeppe/go-internal v1.9.0 // indirect
6965
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d // indirect
70-
github.com/syndtr/goleveldb v1.0.0 // indirect
71-
github.com/tidwall/btree v1.4.3 // indirect
72-
github.com/tidwall/buntdb v1.2.10 // indirect
73-
github.com/tidwall/gjson v1.14.3 // indirect
74-
github.com/tidwall/grect v0.1.4 // indirect
75-
github.com/tidwall/match v1.1.1 // indirect
76-
github.com/tidwall/pretty v1.2.0 // indirect
77-
github.com/tidwall/rtred v0.1.2 // indirect
78-
github.com/tidwall/tinyqueue v0.1.1 // indirect
7966
github.com/ulikunitz/xz v0.5.11 // indirect
80-
github.com/ulule/deepcopier v0.0.0-20200430083143-45decc6639b6 // indirect
8167
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
8268
github.com/yuin/goldmark v1.5.4 // indirect
8369
github.com/yuin/goldmark-emoji v1.0.1 // indirect
84-
github.com/zmap/rc2 v0.0.0-20131011165748-24b9757f5521 // indirect
85-
github.com/zmap/zcrypto v0.0.0-20220803033029-557f3e4940be // indirect
86-
go.etcd.io/bbolt v1.3.7 // indirect
8770
go.uber.org/multierr v1.11.0 // indirect
8871
golang.org/x/crypto v0.7.0 // indirect
8972
golang.org/x/exp v0.0.0-20230420155640-133eef4313cb // indirect

0 commit comments

Comments
 (0)