Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
projectdiscovery
GitHub Repository: projectdiscovery/nuclei
Path: blob/dev/pkg/input/provider/list/hmap_test.go
2070 views
1
package list
2
3
import (
4
"net"
5
"os"
6
"strconv"
7
"strings"
8
"testing"
9
10
"github.com/miekg/dns"
11
"github.com/projectdiscovery/hmap/store/hybrid"
12
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/contextargs"
13
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
14
"github.com/projectdiscovery/nuclei/v3/pkg/types"
15
"github.com/projectdiscovery/nuclei/v3/pkg/utils/expand"
16
"github.com/projectdiscovery/utils/auth/pdcp"
17
"github.com/stretchr/testify/require"
18
)
19
20
func Test_expandCIDR(t *testing.T) {
21
tests := []struct {
22
cidr string
23
expected []string
24
}{
25
{
26
cidr: "173.0.84.0/30",
27
expected: []string{"173.0.84.0", "173.0.84.1", "173.0.84.2", "173.0.84.3"},
28
}, {
29
cidr: "104.154.124.0/29",
30
expected: []string{"104.154.124.0", "104.154.124.1", "104.154.124.2", "104.154.124.3", "104.154.124.4", "104.154.124.5", "104.154.124.6", "104.154.124.7"},
31
},
32
}
33
for _, tt := range tests {
34
hm, err := hybrid.New(hybrid.DefaultDiskOptions)
35
require.Nil(t, err, "could not create temporary input file")
36
input := &ListInputProvider{hostMap: hm}
37
38
ips := expand.CIDR(tt.cidr)
39
input.addTargets("", ips)
40
// scan
41
got := []string{}
42
input.hostMap.Scan(func(k, _ []byte) error {
43
metainput := contextargs.NewMetaInput()
44
if err := metainput.Unmarshal(string(k)); err != nil {
45
return err
46
}
47
got = append(got, metainput.Input)
48
return nil
49
})
50
require.ElementsMatch(t, tt.expected, got, "could not get correct cidrs")
51
input.Close()
52
}
53
}
54
55
type mockDnsHandler struct{}
56
57
func (m *mockDnsHandler) ServeDNS(w dns.ResponseWriter, r *dns.Msg) {
58
msg := dns.Msg{}
59
msg.SetReply(r)
60
switch r.Question[0].Qtype {
61
case dns.TypeA:
62
msg.Authoritative = true
63
domain := msg.Question[0].Name
64
msg.Answer = append(msg.Answer, &dns.A{
65
Hdr: dns.RR_Header{Name: domain, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 60},
66
A: net.ParseIP("128.199.158.128"),
67
})
68
case dns.TypeAAAA:
69
msg.Authoritative = true
70
domain := msg.Question[0].Name
71
msg.Answer = append(msg.Answer, &dns.AAAA{
72
Hdr: dns.RR_Header{Name: domain, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: 60},
73
AAAA: net.ParseIP("2400:6180:0:d0::91:1001"),
74
})
75
}
76
_ = w.WriteMsg(&msg)
77
}
78
79
func Test_scanallips_normalizeStoreInputValue(t *testing.T) {
80
srv := &dns.Server{Addr: ":" + strconv.Itoa(61234), Net: "udp"}
81
srv.Handler = &mockDnsHandler{}
82
83
go func() {
84
err := srv.ListenAndServe()
85
require.Nil(t, err)
86
}()
87
88
defaultOpts := types.DefaultOptions()
89
defaultOpts.InternalResolversList = []string{"127.0.0.1:61234"}
90
_ = protocolstate.Init(defaultOpts)
91
type testcase struct {
92
hostname string
93
ipv4 bool
94
ipv6 bool
95
expected []string
96
}
97
tests := []testcase{
98
{
99
hostname: "scanme.sh",
100
ipv4: true,
101
expected: []string{"128.199.158.128"},
102
}, {
103
hostname: "scanme.sh",
104
ipv6: true,
105
expected: []string{"2400:6180:0:d0::91:1001"},
106
},
107
}
108
// add extra edge cases
109
urls := []string{
110
"https://scanme.sh/",
111
"http://scanme.sh",
112
"https://scanme.sh:443/",
113
"https://scanme.sh:443/somepath",
114
"http://scanme.sh:80/?with=param",
115
"scanme.sh/home",
116
"scanme.sh",
117
}
118
resolvedIps := []string{"128.199.158.128", "2400:6180:0:d0::91:1001"}
119
120
for _, v := range urls {
121
tests = append(tests, testcase{
122
hostname: v,
123
ipv4: true,
124
ipv6: true,
125
expected: resolvedIps,
126
})
127
}
128
for _, tt := range tests {
129
hm, err := hybrid.New(hybrid.DefaultDiskOptions)
130
require.Nil(t, err, "could not create temporary input file")
131
input := &ListInputProvider{
132
hostMap: hm,
133
ipOptions: &ipOptions{
134
ScanAllIPs: true,
135
IPV4: tt.ipv4,
136
IPV6: tt.ipv6,
137
},
138
}
139
140
input.Set("", tt.hostname)
141
// scan
142
got := []string{}
143
input.hostMap.Scan(func(k, v []byte) error {
144
metainput := contextargs.NewMetaInput()
145
if err := metainput.Unmarshal(string(k)); err != nil {
146
return err
147
}
148
got = append(got, metainput.CustomIP)
149
return nil
150
})
151
require.ElementsMatchf(t, tt.expected, got, "could not get correct ips for hostname %v", tt.hostname)
152
input.Close()
153
}
154
}
155
156
func Test_expandASNInputValue(t *testing.T) {
157
// skip this test if pdcp keys are not present
158
h := pdcp.PDCPCredHandler{}
159
creds, err := h.GetCreds()
160
if err != nil || creds == nil || creds.APIKey == "" {
161
t.Logf("Skipping asnmap test as pdcp keys are not present")
162
t.SkipNow()
163
}
164
tests := []struct {
165
asn string
166
expectedOutputFile string
167
}{
168
{
169
asn: "AS14421",
170
expectedOutputFile: "tests/AS14421.txt",
171
},
172
{
173
asn: "AS134029",
174
expectedOutputFile: "tests/AS134029.txt",
175
},
176
}
177
for _, tt := range tests {
178
hm, err := hybrid.New(hybrid.DefaultDiskOptions)
179
require.Nil(t, err, "could not create temporary input file")
180
input := &ListInputProvider{hostMap: hm}
181
// get the IP addresses for ASN number
182
ips := expand.ASN(tt.asn)
183
input.addTargets("", ips)
184
// scan the hmap
185
got := []string{}
186
input.hostMap.Scan(func(k, v []byte) error {
187
metainput := contextargs.NewMetaInput()
188
if err := metainput.Unmarshal(string(k)); err != nil {
189
return err
190
}
191
got = append(got, metainput.Input)
192
return nil
193
})
194
if len(got) == 0 {
195
// asnmap server is down
196
t.SkipNow()
197
}
198
// read the expected IPs from the file
199
fileContent, err := os.ReadFile(tt.expectedOutputFile)
200
require.Nil(t, err, "could not read the expectedOutputFile file")
201
202
items := strings.Split(strings.ReplaceAll(string(fileContent), "\r\n", "\n"), "\n")
203
204
require.ElementsMatch(t, items, got, "could not get correct ips")
205
}
206
}
207
208