From 19d2b80a1c8266d666700c306bffc514b7ae57a4 Mon Sep 17 00:00:00 2001 From: mzack Date: Thu, 27 Jan 2022 21:29:28 +0100 Subject: [PATCH] adding ssl test cases + tcpserver refactor --- integration_tests/ssl/basic-ztls.yaml | 15 ++++++ integration_tests/ssl/basic.yaml | 13 +++++ v2/cmd/integration-test/http.go | 2 +- v2/cmd/integration-test/integration-test.go | 1 + v2/cmd/integration-test/network.go | 8 +-- v2/cmd/integration-test/ssl.go | 54 +++++++++++++++++++++ v2/pkg/testutils/integration.go | 48 +++++++++++++++--- 7 files changed, 129 insertions(+), 12 deletions(-) create mode 100644 integration_tests/ssl/basic-ztls.yaml create mode 100644 integration_tests/ssl/basic.yaml create mode 100644 v2/cmd/integration-test/ssl.go diff --git a/integration_tests/ssl/basic-ztls.yaml b/integration_tests/ssl/basic-ztls.yaml new file mode 100644 index 000000000..dcb023298 --- /dev/null +++ b/integration_tests/ssl/basic-ztls.yaml @@ -0,0 +1,15 @@ +id: basic-ssl-tls + +info: + name: Basic SSL Request with ztls + author: pdteam + severity: info + +ssl: + - address: "{{Host}}:{{Port}}" + min_version: sslv3 + max_version: tls12 + matchers: + - type: dsl + dsl: + - "not_after>=0" diff --git a/integration_tests/ssl/basic.yaml b/integration_tests/ssl/basic.yaml new file mode 100644 index 000000000..83dae1f4a --- /dev/null +++ b/integration_tests/ssl/basic.yaml @@ -0,0 +1,13 @@ +id: expired-ssl + +info: + name: Basic SSL Request + author: pdteam + severity: info + +ssl: + - address: "{{Host}}:{{Port}}" + matchers: + - type: dsl + dsl: + - "not_after>=0" diff --git a/v2/cmd/integration-test/http.go b/v2/cmd/integration-test/http.go index 5f7f5ae8c..90a776ba0 100644 --- a/v2/cmd/integration-test/http.go +++ b/v2/cmd/integration-test/http.go @@ -552,7 +552,7 @@ type httpRawUnsafeRequest struct{} func (h *httpRawUnsafeRequest) Execute(filePath string) error { var routerErr error - ts := testutils.NewTCPServer(func(conn net.Conn) { + ts := testutils.NewTCPServer(false, defaultStaticPort, func(conn net.Conn) { defer conn.Close() _, _ = conn.Write([]byte("HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Length: 36\r\nContent-Type: text/plain; charset=utf-8\r\n\r\nThis is test raw-unsafe-matcher test")) }) diff --git a/v2/cmd/integration-test/integration-test.go b/v2/cmd/integration-test/integration-test.go index 4bbed10a1..c0140a7a0 100644 --- a/v2/cmd/integration-test/integration-test.go +++ b/v2/cmd/integration-test/integration-test.go @@ -27,6 +27,7 @@ var ( "websocket": websocketTestCases, "headless": headlessTestcases, "whois": whoisTestCases, + "ssl": sslTestcases, } ) diff --git a/v2/cmd/integration-test/network.go b/v2/cmd/integration-test/network.go index 52d78b347..e959cf3a3 100644 --- a/v2/cmd/integration-test/network.go +++ b/v2/cmd/integration-test/network.go @@ -21,7 +21,7 @@ type networkBasic struct{} func (h *networkBasic) Execute(filePath string) error { var routerErr error - ts := testutils.NewTCPServer(func(conn net.Conn) { + ts := testutils.NewTCPServer(false, defaultStaticPort, func(conn net.Conn) { defer conn.Close() data := make([]byte, 4) @@ -52,7 +52,7 @@ type networkMultiStep struct{} func (h *networkMultiStep) Execute(filePath string) error { var routerErr error - ts := testutils.NewTCPServer(func(conn net.Conn) { + ts := testutils.NewTCPServer(false, defaultStaticPort, func(conn net.Conn) { defer conn.Close() data := make([]byte, 5) @@ -100,11 +100,11 @@ type networkRequestSelContained struct{} func (h *networkRequestSelContained) Execute(filePath string) error { var routerErr error - ts := testutils.NewTCPServer(func(conn net.Conn) { + ts := testutils.NewTCPServer(false, defaultStaticPort, func(conn net.Conn) { defer conn.Close() _, _ = conn.Write([]byte("Authentication successful")) - }, defaultStaticPort) + }) defer ts.Close() results, err := testutils.RunNucleiTemplateAndGetResults(filePath, "", debug) if err != nil { diff --git a/v2/cmd/integration-test/ssl.go b/v2/cmd/integration-test/ssl.go new file mode 100644 index 000000000..2c389e6a6 --- /dev/null +++ b/v2/cmd/integration-test/ssl.go @@ -0,0 +1,54 @@ +package main + +import ( + "net" + + "github.com/projectdiscovery/nuclei/v2/pkg/testutils" +) + +var sslTestcases = map[string]testutils.TestCase{ + "ssl/basic.yaml": &sslBasic{}, + "ssl/basic-ztls.yaml": &sslBasicZtls{}, +} + +type sslBasic struct{} + +// Execute executes a test case and returns an error if occurred +func (h *sslBasic) Execute(filePath string) error { + ts := testutils.NewTCPServer(true, 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) + if err != nil { + return err + } + + return expectResultsCount(results, 1) +} + +type sslBasicZtls struct{} + +// Execute executes a test case and returns an error if occurred +func (h *sslBasicZtls) Execute(filePath string) error { + ts := testutils.NewTCPServer(true, 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, "-ztls") + if err != nil { + return err + } + + return expectResultsCount(results, 1) +} diff --git a/v2/pkg/testutils/integration.go b/v2/pkg/testutils/integration.go index 3590dba16..8db6b26a8 100644 --- a/v2/pkg/testutils/integration.go +++ b/v2/pkg/testutils/integration.go @@ -1,6 +1,7 @@ package testutils import ( + "crypto/tls" "errors" "fmt" "net" @@ -97,21 +98,49 @@ type TCPServer struct { listener net.Listener } +// keys taken from https://pascal.bach.ch/2015/12/17/from-tcp-to-tls-in-go/ +const serverKey = `-----BEGIN EC PARAMETERS----- +BggqhkjOPQMBBw== +-----END EC PARAMETERS----- +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIHg+g2unjA5BkDtXSN9ShN7kbPlbCcqcYdDu+QeV8XWuoAoGCCqGSM49 +AwEHoUQDQgAEcZpodWh3SEs5Hh3rrEiu1LZOYSaNIWO34MgRxvqwz1FMpLxNlx0G +cSqrxhPubawptX5MSr02ft32kfOlYbaF5Q== +-----END EC PRIVATE KEY----- +` + +const serverCert = `-----BEGIN CERTIFICATE----- +MIIB+TCCAZ+gAwIBAgIJAL05LKXo6PrrMAoGCCqGSM49BAMCMFkxCzAJBgNVBAYT +AkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn +aXRzIFB0eSBMdGQxEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0xNTEyMDgxNDAxMTNa +Fw0yNTEyMDUxNDAxMTNaMFkxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0 +YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEjAQBgNVBAMM +CWxvY2FsaG9zdDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABHGaaHVod0hLOR4d +66xIrtS2TmEmjSFjt+DIEcb6sM9RTKS8TZcdBnEqq8YT7m2sKbV+TEq9Nn7d9pHz +pWG2heWjUDBOMB0GA1UdDgQWBBR0fqrecDJ44D/fiYJiOeBzfoqEijAfBgNVHSME +GDAWgBR0fqrecDJ44D/fiYJiOeBzfoqEijAMBgNVHRMEBTADAQH/MAoGCCqGSM49 +BAMCA0gAMEUCIEKzVMF3JqjQjuM2rX7Rx8hancI5KJhwfeKu1xbyR7XaAiEA2UT7 +1xOP035EcraRmWPe7tO0LpXgMxlh2VItpc2uc2w= +-----END CERTIFICATE----- +` + // NewTCPServer creates a new TCP server from a handler -func NewTCPServer(handler func(conn net.Conn), port ...int) *TCPServer { +func NewTCPServer(withTls bool, port int, handler func(conn net.Conn)) *TCPServer { server := &TCPServer{} - var gotPort int - if len(port) > 0 { - gotPort = port[0] - } - l, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", gotPort)) + l, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", port)) if err != nil { panic(err) } server.URL = l.Addr().String() server.listener = l + cer, err := tls.X509KeyPair([]byte(serverCert), []byte(serverKey)) + if err != nil { + panic(err) + } + config := &tls.Config{Certificates: []tls.Certificate{cer}} + go func() { for { // Listen for an incoming connection. @@ -120,7 +149,12 @@ func NewTCPServer(handler func(conn net.Conn), port ...int) *TCPServer { continue } // Handle connections in a new goroutine. - go handler(conn) + if withTls { + connTls := tls.Server(conn, config) + go handler(connTls) + } else { + go handler(conn) + } } }() return server