From f6332583b7f62c063b3050db18059c786d2e8e0b Mon Sep 17 00:00:00 2001 From: Mzack9999 Date: Tue, 21 May 2024 18:12:01 +0200 Subject: [PATCH] making ssl errors non fatal (#5203) * making ssl errors non fatal * adding test --- cmd/integration-test/ssl.go | 21 ++++++++++++ .../protocols/ssl/multi-req.yaml | 34 +++++++++++++++++++ pkg/tmplexec/multiproto/multi.go | 14 +++++++- 3 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 integration_tests/protocols/ssl/multi-req.yaml diff --git a/cmd/integration-test/ssl.go b/cmd/integration-test/ssl.go index 70b8c48445..24f6e9b903 100644 --- a/cmd/integration-test/ssl.go +++ b/cmd/integration-test/ssl.go @@ -13,6 +13,7 @@ var sslTestcases = []TestCaseInfo{ {Path: "protocols/ssl/custom-cipher.yaml", TestCase: &sslCustomCipher{}}, {Path: "protocols/ssl/custom-version.yaml", TestCase: &sslCustomVersion{}}, {Path: "protocols/ssl/ssl-with-vars.yaml", TestCase: &sslWithVars{}}, + {Path: "protocols/ssl/multi-req.yaml", TestCase: &sslMultiReq{}}, } type sslBasic struct{} @@ -118,3 +119,23 @@ func (h *sslWithVars) Execute(filePath string) error { return expectResultsCount(results, 1) } + +type sslMultiReq struct{} + +func (h *sslMultiReq) Execute(filePath string) error { + ts := testutils.NewTCPServer(&tls.Config{}, defaultStaticPort, func(conn net.Conn) { + defer conn.Close() + data := make([]byte, 4) + if _, err := conn.Read(data); err != nil { + return + } + }) + defer ts.Close() + + results, err := testutils.RunNucleiTemplateAndGetResults(filePath, ts.URL, debug, "-V") + if err != nil { + return err + } + + return expectResultsCount(results, 2) +} diff --git a/integration_tests/protocols/ssl/multi-req.yaml b/integration_tests/protocols/ssl/multi-req.yaml new file mode 100644 index 0000000000..670ca633d9 --- /dev/null +++ b/integration_tests/protocols/ssl/multi-req.yaml @@ -0,0 +1,34 @@ +id: multi-req + +info: + name: Multi-Request + author: pdteam + severity: info + +ssl: + - address: "{{Host}}:{{Port}}" + min_version: ssl30 + max_version: ssl30 + + extractors: + - type: json + json: + - " .tls_version" + + - address: "{{Host}}:{{Port}}" + min_version: tls10 + max_version: tls10 + + extractors: + - type: json + json: + - " .tls_version" + + - address: "{{Host}}:{{Port}}" + min_version: tls11 + max_version: tls11 + + extractors: + - type: json + json: + - " .tls_version" \ No newline at end of file diff --git a/pkg/tmplexec/multiproto/multi.go b/pkg/tmplexec/multiproto/multi.go index 58858f971e..7bbc2a1403 100644 --- a/pkg/tmplexec/multiproto/multi.go +++ b/pkg/tmplexec/multiproto/multi.go @@ -8,6 +8,8 @@ import ( "github.com/projectdiscovery/nuclei/v3/pkg/protocols" "github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/generators" "github.com/projectdiscovery/nuclei/v3/pkg/scan" + "github.com/projectdiscovery/nuclei/v3/pkg/templates/types" + stringsutil "github.com/projectdiscovery/utils/strings" ) // Mutliprotocol is a template executer engine that executes multiple protocols @@ -110,9 +112,19 @@ func (m *MultiProtocol) ExecuteWithResults(ctx *scan.ScanContext) error { values := m.options.GetTemplateCtx(ctx.Input.MetaInput).GetAll() err := req.ExecuteWithResults(ctx.Input, output.InternalEvent(values), nil, multiProtoCallback) - // if error skip execution of next protocols + // in case of fatal error skip execution of next protocols if err != nil { + // always log errors ctx.LogError(err) + + // for some classes of protocols (i.e ssl) errors like tls handshake are a legitimate behavior so we don't stop execution + // connection failures are already tracked by the internal host error cache + // we use strings comparison as the error is not formalized into instance within the standard library + // within a flow instead we consider ssl errors as fatal, since a specific logic was requested + if req.Type() == types.SSLProtocol && stringsutil.ContainsAnyI(err.Error(), "protocol version not supported", "could not do tls handshake") { + continue + } + return err } }