mirror of
https://github.com/projectdiscovery/nuclei.git
synced 2026-11-12 01:51:37 -10:00
* feat(templates): add execution-local parser lifecycle * fix(network): include ports and payloads in request count * fix(headless): include payloads in request count * feat(core): expose template execution lifecycle * fix(core): report context-interrupted template executions * perf(interactsh): allocate caches on first use * perf(stats): reuse compiled waf detector * perf(hosterrors): release cache storage on close * fix(deps): use published tlsx release * perf(templates): coalesce concurrent parses * perf(stats): prefilter waf response regexes * perf(stats): scan waf literals once per response * fix(sdk): isolate shared interactsh executions * fix(protocols): preserve interactsh request scope * fix(interactsh): drain in-flight scoped callbacks * perf(hosterrors): allocate storage on first failure * fix(interactsh): recognize raw SNI callbacks * fix(interactsh): guard non-fuzz callback accounting * perf(jarm): integrate bounded shared fingerprints * fix(jarm): honor configured scan proxy * perf(core): support adaptive template concurrency * perf(core): enforce shared template concurrency budget * fix(http): smooth low per-host request limits * perf(http): remove per-host limiter goroutines * fix(http): retain host budgets for large embedded scans * test: consolidate parser and headless coverage * fix: address PR review comments * fix(headless): honor scan cancellation
165 lines
5.0 KiB
Go
165 lines
5.0 KiB
Go
package network
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/projectdiscovery/nuclei/v3/internal/tests/testutils"
|
|
"github.com/projectdiscovery/nuclei/v3/pkg/model"
|
|
"github.com/projectdiscovery/nuclei/v3/pkg/model/types/severity"
|
|
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/generators"
|
|
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/portutil"
|
|
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/variables"
|
|
"github.com/projectdiscovery/nuclei/v3/pkg/utils"
|
|
)
|
|
|
|
func TestResolvePort(t *testing.T) {
|
|
tests := []struct {
|
|
input string
|
|
expected string
|
|
wantErr bool
|
|
}{
|
|
{input: "80", expected: "80"},
|
|
{input: "443", expected: "443"},
|
|
{input: "ftp", expected: "21"},
|
|
{input: "ssh", expected: "22"},
|
|
{input: "smtp", expected: "25"},
|
|
{input: "http", expected: "80"},
|
|
{input: "https", expected: "443"},
|
|
{input: "mysql", expected: "3306"},
|
|
{input: "0", wantErr: true},
|
|
{input: "65536", wantErr: true},
|
|
{input: "nonsense", wantErr: true},
|
|
{input: "", wantErr: true},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.input, func(t *testing.T) {
|
|
got, err := portutil.ResolvePort(tt.input)
|
|
if tt.wantErr {
|
|
require.Error(t, err)
|
|
return
|
|
}
|
|
require.NoError(t, err)
|
|
require.Equal(t, tt.expected, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCompileWithServiceName(t *testing.T) {
|
|
options := testutils.DefaultOptions
|
|
|
|
testutils.Init(options)
|
|
templateID := "testing-network-service"
|
|
request := &Request{
|
|
ID: templateID,
|
|
Address: []string{"{{Host}}"},
|
|
Port: "ftp,ssh",
|
|
ReadSize: 1024,
|
|
Inputs: []*Input{{Data: "test-data"}},
|
|
}
|
|
executerOpts := testutils.NewMockExecuterOptions(options, &testutils.TemplateInfo{
|
|
ID: templateID,
|
|
Info: model.Info{SeverityHolder: severity.Holder{Severity: severity.Low}, Name: "test"},
|
|
})
|
|
err := request.Compile(executerOpts)
|
|
require.NoError(t, err)
|
|
require.Equal(t, []string{"21", "22"}, request.ports)
|
|
}
|
|
|
|
func TestCompileDeduplicatesPorts(t *testing.T) {
|
|
options := testutils.DefaultOptions
|
|
|
|
testutils.Init(options)
|
|
templateID := "testing-network-dedup"
|
|
request := &Request{
|
|
ID: templateID,
|
|
Address: []string{"{{Host}}"},
|
|
Port: "ftp, 21, ssh, 22",
|
|
ReadSize: 1024,
|
|
Inputs: []*Input{{Data: "test-data"}},
|
|
}
|
|
executerOpts := testutils.NewMockExecuterOptions(options, &testutils.TemplateInfo{
|
|
ID: templateID,
|
|
Info: model.Info{SeverityHolder: severity.Holder{Severity: severity.Low}, Name: "test"},
|
|
})
|
|
err := request.Compile(executerOpts)
|
|
require.NoError(t, err)
|
|
require.Equal(t, []string{"21", "22"}, request.ports)
|
|
}
|
|
|
|
func TestRequestsIncludesPayloadExecutions(t *testing.T) {
|
|
options := testutils.DefaultOptions
|
|
testutils.Init(options)
|
|
|
|
request := &Request{
|
|
ID: "testing-network-payload-count",
|
|
Address: []string{"{{Host}}"},
|
|
Port: "ftp,2121",
|
|
Inputs: []*Input{{Data: "USER {{username}}\r\nPASS {{password}}\r\n"}},
|
|
AttackType: generators.AttackTypeHolder{
|
|
Value: generators.ClusterBombAttack,
|
|
},
|
|
Payloads: map[string]interface{}{
|
|
"username": []string{"admin", "root"},
|
|
"password": []string{"password", "toor", "guest"},
|
|
},
|
|
}
|
|
executerOpts := testutils.NewMockExecuterOptions(options, &testutils.TemplateInfo{
|
|
ID: request.ID,
|
|
Info: model.Info{SeverityHolder: severity.Holder{Severity: severity.Low}, Name: "test"},
|
|
})
|
|
|
|
require.NoError(t, request.Compile(executerOpts))
|
|
require.Equal(t, 12, request.Requests(), "two ports times six payload combinations")
|
|
}
|
|
|
|
func TestNetworkCompileMake(t *testing.T) {
|
|
options := testutils.DefaultOptions
|
|
|
|
testutils.Init(options)
|
|
templateID := "testing-network"
|
|
request := &Request{
|
|
ID: templateID,
|
|
Address: []string{"tls://{{Host}}:443"},
|
|
ReadSize: 1024,
|
|
Inputs: []*Input{{Data: "test-data"}},
|
|
}
|
|
executerOpts := testutils.NewMockExecuterOptions(options, &testutils.TemplateInfo{
|
|
ID: templateID,
|
|
Info: model.Info{SeverityHolder: severity.Holder{Severity: severity.Low}, Name: "test"},
|
|
})
|
|
err := request.Compile(executerOpts)
|
|
require.Nil(t, err, "could not compile network request")
|
|
|
|
require.Equal(t, 1, len(request.addresses), "could not get correct number of input address")
|
|
t.Run("check-tls-with-port", func(t *testing.T) {
|
|
require.True(t, request.addresses[0].tls, "could not get correct port for host")
|
|
})
|
|
}
|
|
|
|
func TestCompileDoesNotPersistValueIntroducedInteractshMarker(t *testing.T) {
|
|
options := testutils.DefaultOptions
|
|
|
|
testutils.Init(options)
|
|
templateID := "testing-network-defer-value-marker"
|
|
request := &Request{
|
|
ID: templateID,
|
|
Address: []string{"{{Host}}"},
|
|
ReadSize: 1024,
|
|
Inputs: []*Input{{Data: "{{callback}}"}},
|
|
}
|
|
executerOpts := testutils.NewMockExecuterOptions(options, &testutils.TemplateInfo{
|
|
ID: templateID,
|
|
Info: model.Info{SeverityHolder: severity.Holder{Severity: severity.Low}, Name: "test"},
|
|
})
|
|
executerOpts.Variables = variables.Variable{
|
|
InsertionOrderedStringMap: *utils.NewEmptyInsertionOrderedStringMap(1),
|
|
}
|
|
executerOpts.Variables.Set("callback", "{{interactsh-url}}")
|
|
|
|
err := request.Compile(executerOpts)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "{{callback}}", request.Inputs[0].Data)
|
|
}
|