Skip to content

Commit 6136477

Browse files
authored
Merge branch 'main' into migration/v1.0.0
2 parents 2566459 + c988e54 commit 6136477

File tree

4 files changed

+185
-8
lines changed

4 files changed

+185
-8
lines changed
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/*
2+
·━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━·
3+
: :
4+
: █▀ █ █▀▀ · Blazing-fast pentesting suite :
5+
: ▄█ █ █▀ · BSD 3-Clause License :
6+
: :
7+
: (c) 2022-2025 vmfunc (Celeste Hickenlooper), xyzeva, :
8+
: lunchcat alumni & contributors :
9+
: :
10+
·━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━·
11+
*/
12+
13+
package builtin
14+
15+
import (
16+
"context"
17+
"fmt"
18+
"github.com/dropalldatabases/sif/internal/modules"
19+
"github.com/dropalldatabases/sif/internal/scan"
20+
)
21+
22+
type NucleiModule struct{}
23+
24+
func (m *NucleiModule) Info() modules.Info {
25+
return modules.Info{
26+
ID: "nuclei-scan",
27+
Name: "Nuclei Vulnerability Scanner",
28+
Author: "sif",
29+
Severity: "high",
30+
Description: "Runs Nuclei vulnerability scanning templates against target",
31+
Tags: []string{"vuln", "nuclei", "cve"},
32+
}
33+
}
34+
35+
func (m *NucleiModule) Type() modules.ModuleType {
36+
return modules.TypeScript
37+
}
38+
39+
func (m *NucleiModule) Execute(ctx context.Context, target string, opts modules.Options) (*modules.Result, error) {
40+
// Call existing legacy scan.Nuclei function
41+
nucleiResults, err := scan.Nuclei(target, opts.Timeout, opts.Threads, opts.LogDir)
42+
43+
if err != nil {
44+
return nil, err
45+
}
46+
47+
result := &modules.Result{
48+
ModuleID: m.Info().ID,
49+
Target: target,
50+
Findings: make([]modules.Finding, 0, len(nucleiResults)),
51+
}
52+
53+
// Process nuclei results into module findings
54+
for _, event := range nucleiResults {
55+
severity := "info"
56+
57+
switch event.Info.SeverityHolder.Severity.String() {
58+
case "critical":
59+
severity = "critical"
60+
case "high":
61+
severity = "high"
62+
case "medium":
63+
severity = "medium"
64+
case "low":
65+
severity = "low"
66+
}
67+
68+
evidence := fmt.Sprintf("[%s] %s", event.TemplateID, event.Info.Name)
69+
if event.Matched != "" {
70+
evidence = fmt.Sprintf("[%s] %s - matched: %s", event.TemplateID, event.Info.Name, event.Matched)
71+
}
72+
73+
finding := modules.Finding{
74+
URL: event.Host,
75+
Severity: severity,
76+
Evidence: evidence,
77+
Extracted: map[string]string{
78+
"template_id": event.TemplateID,
79+
"template_name": event.Info.Name,
80+
"severity": event.Info.SeverityHolder.Severity.String(),
81+
},
82+
}
83+
84+
// Template info
85+
if event.Type != "" {
86+
finding.Extracted["type"] = event.Type
87+
}
88+
89+
// Matcher name
90+
if event.MatcherName != "" {
91+
finding.Extracted["matcher_name"] = event.MatcherName
92+
}
93+
94+
// Extractor name
95+
if event.ExtractorName != "" {
96+
finding.Extracted["extractor_name"] = event.ExtractorName
97+
}
98+
99+
// Matched line/data
100+
if event.Matched != "" {
101+
finding.Extracted["matched"] = event.Matched
102+
}
103+
104+
// Metadata
105+
if len(event.Info.Metadata) > 0 {
106+
for key, value := range event.Info.Metadata {
107+
finding.Extracted[fmt.Sprintf("metadata_%s", key)] = fmt.Sprintf("%v", value)
108+
}
109+
}
110+
111+
// Tags
112+
if !event.Info.Tags.IsEmpty() {
113+
tagStr := ""
114+
for _, tag := range event.Info.Tags.ToSlice() {
115+
if tagStr != "" {
116+
tagStr += ", "
117+
}
118+
tagStr += tag
119+
}
120+
121+
finding.Extracted["tags"] = tagStr
122+
}
123+
124+
// Reference
125+
if event.Info.Reference != nil && !event.Info.Reference.IsEmpty() {
126+
refStr := ""
127+
for _, ref := range event.Info.Reference.ToSlice() {
128+
if refStr != "" {
129+
refStr += "; "
130+
}
131+
refStr += ref
132+
}
133+
134+
finding.Extracted["references"] = refStr
135+
}
136+
137+
result.Findings = append(result.Findings, finding)
138+
}
139+
140+
return result, nil
141+
}

internal/scan/builtin/register.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
·━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━·
3+
: :
4+
: █▀ █ █▀▀ · Blazing-fast pentesting suite :
5+
: ▄█ █ █▀ · BSD 3-Clause License :
6+
: :
7+
: (c) 2022-2025 vmfunc (Celeste Hickenlooper), xyzeva, :
8+
: lunchcat alumni & contributors :
9+
: :
10+
·━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━·
11+
*/
12+
13+
package builtin
14+
15+
import "github.com/dropalldatabases/sif/internal/modules"
16+
17+
// Register registers all Go-based built-in scans as modules.
18+
// Allows complex Go scans to participate in the module system
19+
func Register() {
20+
modules.Register(&NucleiModule{})
21+
}

internal/scan/nuclei.go

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ func Nuclei(url string, timeout time.Duration, threads int, logdir string) ([]ou
5959
options.TemplateThreads = threads
6060
options.Timeout = int(timeout.Seconds())
6161

62+
if logdir != "" {
63+
options.ProjectPath = logdir
64+
}
65+
66+
options.Headless = false
67+
6268
// Get templates
6369
templates.Install(nucleilog)
6470
pwd, err := os.Getwd()
@@ -101,14 +107,16 @@ func Nuclei(url string, timeout time.Duration, threads int, logdir string) ([]ou
101107
protocolinit.Init(options)
102108

103109
executorOpts := protocols.ExecutorOptions{
104-
Output: outputWriter,
105-
Progress: progressClient,
106-
Catalog: catalog,
107-
Options: options,
108-
IssuesClient: reportingClient,
109-
RateLimiter: ratelimit.New(context.Background(), 150, time.Second),
110-
Interactsh: interactClient,
111-
ResumeCfg: types.NewResumeCfg(),
110+
Colorizer: aurora.NewAurora(false),
111+
Output: outputWriter,
112+
Progress: progressClient,
113+
Catalog: catalog,
114+
Options: options,
115+
IssuesClient: reportingClient,
116+
RateLimiter: ratelimit.New(context.Background(), 150, time.Second),
117+
Interactsh: interactClient,
118+
HostErrorsCache: cache,
119+
ResumeCfg: types.NewResumeCfg(),
112120
}
113121
engine := core.New(options)
114122
engine.SetExecuterOptions(executorOpts)

sif.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,10 @@ func (app *App) Run() error {
140140
if err := loader.LoadAll(); err != nil {
141141
log.Warnf("Failed to load modules: %v", err)
142142
}
143+
144+
// Register built-in Go modules
145+
builtin.Register()
146+
143147
fmt.Println("Available modules:")
144148
for _, m := range modules.All() {
145149
info := m.Info()
@@ -352,6 +356,9 @@ func (app *App) Run() error {
352356
log.Warnf("Failed to load modules: %v", err)
353357
}
354358

359+
// Register built-in Go modules
360+
builtin.Register()
361+
355362
// Determine which modules to run
356363
var toRun []modules.Module
357364
if app.settings.AllModules {

0 commit comments

Comments
 (0)