Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
projectdiscovery
GitHub Repository: projectdiscovery/nuclei
Path: blob/dev/lib/tests/sdk_test.go
2070 views
1
package sdk_test
2
3
import (
4
"context"
5
"os"
6
"os/exec"
7
"testing"
8
"time"
9
10
nuclei "github.com/projectdiscovery/nuclei/v3/lib"
11
"github.com/projectdiscovery/utils/env"
12
"github.com/stretchr/testify/require"
13
"github.com/tarunKoyalwar/goleak"
14
)
15
16
var knownLeaks = []goleak.Option{
17
// prettyify the output and generate dependency graph and more details instead of just stack output
18
goleak.Pretty(),
19
// net/http transport maintains idle connections which are closed with cooldown
20
// hence they don't count as leaks
21
goleak.IgnoreAnyFunction("net/http.(*http2ClientConn).readLoop"),
22
}
23
24
func TestSimpleNuclei(t *testing.T) {
25
fn := func() {
26
defer func() {
27
// resources like leveldb have a delay to commit in-memory resources
28
// to disk, typically 1-2 seconds, so we wait for 2 seconds
29
time.Sleep(2 * time.Second)
30
goleak.VerifyNone(t, knownLeaks...)
31
}()
32
ne, err := nuclei.NewNucleiEngineCtx(
33
context.TODO(),
34
nuclei.WithTemplateFilters(nuclei.TemplateFilters{ProtocolTypes: "dns"}), // filter dns templates
35
nuclei.EnableStatsWithOpts(nuclei.StatsOptions{JSON: true}),
36
)
37
require.Nil(t, err)
38
ne.LoadTargets([]string{"scanme.sh"}, false) // probe non http/https target is set to false here
39
// when callback is nil it nuclei will print JSON output to stdout
40
err = ne.ExecuteWithCallback(nil)
41
require.Nil(t, err)
42
defer ne.Close()
43
}
44
45
// this is shared test so needs to be run as seperate process
46
if env.GetEnvOrDefault("TestSimpleNuclei", false) {
47
// run as new process
48
cmd := exec.Command(os.Args[0], "-test.run=TestSimpleNuclei")
49
cmd.Env = append(os.Environ(), "TestSimpleNuclei=true")
50
out, err := cmd.CombinedOutput()
51
if err != nil {
52
t.Fatalf("process ran with error %s, output: %s", err, out)
53
}
54
} else {
55
fn()
56
}
57
}
58
59
func TestSimpleNucleiRemote(t *testing.T) {
60
fn := func() {
61
defer func() {
62
// resources like leveldb have a delay to commit in-memory resources
63
// to disk, typically 1-2 seconds, so we wait for 2 seconds
64
time.Sleep(2 * time.Second)
65
goleak.VerifyNone(t, knownLeaks...)
66
}()
67
ne, err := nuclei.NewNucleiEngineCtx(
68
context.TODO(),
69
nuclei.WithTemplatesOrWorkflows(
70
nuclei.TemplateSources{
71
RemoteTemplates: []string{"https://cloud.projectdiscovery.io/public/nameserver-fingerprint.yaml"},
72
},
73
),
74
)
75
require.Nil(t, err)
76
ne.LoadTargets([]string{"scanme.sh"}, false) // probe non http/https target is set to false here
77
err = ne.LoadAllTemplates()
78
require.Nil(t, err, "could not load templates")
79
// when callback is nil it nuclei will print JSON output to stdout
80
err = ne.ExecuteWithCallback(nil)
81
require.Nil(t, err)
82
defer ne.Close()
83
}
84
// this is shared test so needs to be run as seperate process
85
if env.GetEnvOrDefault("TestSimpleNucleiRemote", false) {
86
cmd := exec.Command(os.Args[0], "-test.run=TestSimpleNucleiRemote")
87
cmd.Env = append(os.Environ(), "TestSimpleNucleiRemote=true")
88
out, err := cmd.CombinedOutput()
89
if err != nil {
90
t.Fatalf("process ran with error %s, output: %s", err, out)
91
}
92
} else {
93
fn()
94
}
95
}
96
97
func TestThreadSafeNuclei(t *testing.T) {
98
fn := func() {
99
defer func() {
100
// resources like leveldb have a delay to commit in-memory resources
101
// to disk, typically 1-2 seconds, so we wait for 2 seconds
102
time.Sleep(2 * time.Second)
103
goleak.VerifyNone(t, knownLeaks...)
104
}()
105
// create nuclei engine with options
106
ne, err := nuclei.NewThreadSafeNucleiEngineCtx(context.TODO())
107
require.Nil(t, err)
108
109
// scan 1 = run dns templates on scanme.sh
110
t.Run("scanme.sh", func(t *testing.T) {
111
err = ne.ExecuteNucleiWithOpts([]string{"scanme.sh"}, nuclei.WithTemplateFilters(nuclei.TemplateFilters{ProtocolTypes: "dns"}))
112
require.Nil(t, err)
113
})
114
115
// scan 2 = run dns templates on honey.scanme.sh
116
t.Run("honey.scanme.sh", func(t *testing.T) {
117
err = ne.ExecuteNucleiWithOpts([]string{"honey.scanme.sh"}, nuclei.WithTemplateFilters(nuclei.TemplateFilters{ProtocolTypes: "dns"}))
118
require.Nil(t, err)
119
})
120
121
// wait for all scans to finish
122
defer ne.Close()
123
}
124
125
if env.GetEnvOrDefault("TestThreadSafeNuclei", false) {
126
cmd := exec.Command(os.Args[0], "-test.run=TestThreadSafeNuclei")
127
cmd.Env = append(os.Environ(), "TestThreadSafeNuclei=true")
128
out, err := cmd.CombinedOutput()
129
if err != nil {
130
t.Fatalf("process ran with error %s, output: %s", err, out)
131
}
132
} else {
133
fn()
134
}
135
}
136
137
func TestWithVarsNuclei(t *testing.T) {
138
fn := func() {
139
defer func() {
140
// resources like leveldb have a delay to commit in-memory resources
141
// to disk, typically 1-2 seconds, so we wait for 2 seconds
142
time.Sleep(2 * time.Second)
143
goleak.VerifyNone(t, knownLeaks...)
144
}()
145
ne, err := nuclei.NewNucleiEngineCtx(
146
context.TODO(),
147
nuclei.EnableSelfContainedTemplates(),
148
nuclei.WithTemplatesOrWorkflows(nuclei.TemplateSources{Templates: []string{"http/token-spray/api-1forge.yaml"}}),
149
nuclei.WithVars([]string{"token=foobar"}),
150
nuclei.WithVerbosity(nuclei.VerbosityOptions{Debug: true}),
151
)
152
require.Nil(t, err)
153
ne.LoadTargets([]string{"scanme.sh"}, true) // probe http/https target is set to true here
154
err = ne.ExecuteWithCallback(nil)
155
require.Nil(t, err)
156
defer ne.Close()
157
}
158
// this is shared test so needs to be run as seperate process
159
if env.GetEnvOrDefault("TestWithVarsNuclei", false) {
160
cmd := exec.Command(os.Args[0], "-test.run=TestWithVarsNuclei")
161
cmd.Env = append(os.Environ(), "TestWithVarsNuclei=true")
162
out, err := cmd.CombinedOutput()
163
if err != nil {
164
t.Fatalf("process ran with error %s, output: %s", err, out)
165
}
166
} else {
167
fn()
168
}
169
}
170
171