Added more tests and ciphersuits for SSL protocol

dev
Ice3man 2022-03-07 14:07:30 +05:30
parent 85fabf74ce
commit 90b4c09f80
8 changed files with 176 additions and 38 deletions

View File

@ -0,0 +1,16 @@
id: expired-ssl
info:
name: Basic SSL Request
author: pdteam
severity: info
ssl:
- address: "{{Host}}:{{Port}}"
cipher_suites:
- TLS_AES_128_GCM_SHA256
matchers:
- type: word
part: cipher_matched
words:
- "true"

View File

@ -0,0 +1,16 @@
id: expired-ssl
info:
name: Basic SSL Request
author: pdteam
severity: info
ssl:
- address: "{{Host}}:{{Port}}"
min_version: tls12
max_version: tls12
matchers:
- type: word
part: response
words:
- '"tls_version":"TLS12"'

View File

@ -554,7 +554,7 @@ type httpRawUnsafeRequest struct{}
func (h *httpRawUnsafeRequest) Execute(filePath string) error {
var routerErr error
ts := testutils.NewTCPServer(false, defaultStaticPort, func(conn net.Conn) {
ts := testutils.NewTCPServer(nil, 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"))
})

View File

@ -21,7 +21,7 @@ type networkBasic struct{}
func (h *networkBasic) Execute(filePath string) error {
var routerErr error
ts := testutils.NewTCPServer(false, defaultStaticPort, func(conn net.Conn) {
ts := testutils.NewTCPServer(nil, 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(false, defaultStaticPort, func(conn net.Conn) {
ts := testutils.NewTCPServer(nil, defaultStaticPort, func(conn net.Conn) {
defer conn.Close()
data := make([]byte, 5)
@ -100,7 +100,7 @@ type networkRequestSelContained struct{}
func (h *networkRequestSelContained) Execute(filePath string) error {
var routerErr error
ts := testutils.NewTCPServer(false, defaultStaticPort, func(conn net.Conn) {
ts := testutils.NewTCPServer(nil, defaultStaticPort, func(conn net.Conn) {
defer conn.Close()
_, _ = conn.Write([]byte("Authentication successful"))

View File

@ -1,21 +1,24 @@
package main
import (
"crypto/tls"
"net"
"github.com/projectdiscovery/nuclei/v2/pkg/testutils"
)
var sslTestcases = map[string]testutils.TestCase{
"ssl/basic.yaml": &sslBasic{},
"ssl/basic-ztls.yaml": &sslBasicZtls{},
"ssl/basic.yaml": &sslBasic{},
"ssl/basic-ztls.yaml": &sslBasicZtls{},
"ssl/custom-cipher.yaml": &sslCustomCipher{},
"ssl/custom-version.yaml": &sslCustomVersion{},
}
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) {
ts := testutils.NewTCPServer(&tls.Config{}, defaultStaticPort, func(conn net.Conn) {
defer conn.Close()
data := make([]byte, 4)
if _, err := conn.Read(data); err != nil {
@ -36,7 +39,7 @@ 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) {
ts := testutils.NewTCPServer(&tls.Config{}, defaultStaticPort, func(conn net.Conn) {
defer conn.Close()
data := make([]byte, 4)
if _, err := conn.Read(data); err != nil {
@ -52,3 +55,45 @@ func (h *sslBasicZtls) Execute(filePath string) error {
return expectResultsCount(results, 1)
}
type sslCustomCipher struct{}
// Execute executes a test case and returns an error if occurred
func (h *sslCustomCipher) Execute(filePath string) error {
ts := testutils.NewTCPServer(&tls.Config{CipherSuites: []uint16{tls.TLS_AES_128_GCM_SHA256}}, 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 sslCustomVersion struct{}
// Execute executes a test case and returns an error if occurred
func (h *sslCustomVersion) Execute(filePath string) error {
ts := testutils.NewTCPServer(&tls.Config{MinVersion: tls.VersionTLS12, MaxVersion: tls.VersionTLS12}, 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)
}

View File

@ -1,12 +1,68 @@
package ssl
import (
"crypto/tls"
"fmt"
ztls "github.com/zmap/zcrypto/tls"
)
var ciphers = map[string]uint16{
func toTLSCiphers(items []string) ([]uint16, error) {
var convertedCiphers []uint16
for _, item := range items {
cipher, ok := tlsCiphers[item]
if !ok {
return nil, fmt.Errorf("unsupported cipher suite: %s", item)
}
convertedCiphers = append(convertedCiphers, cipher)
}
return convertedCiphers, nil
}
func toZTLSCiphers(items []string) ([]uint16, error) {
var convertedCiphers []uint16
for _, item := range items {
zcipher, ok := ztlsCiphers[item]
if !ok {
return nil, fmt.Errorf("unsupported cipher suite: %s", item)
}
convertedCiphers = append(convertedCiphers, zcipher)
}
return convertedCiphers, nil
}
var tlsCiphers = map[string]uint16{
"TLS_RSA_WITH_RC4_128_SHA": tls.TLS_RSA_WITH_RC4_128_SHA,
"TLS_RSA_WITH_3DES_EDE_CBC_SHA": tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
"TLS_RSA_WITH_AES_128_CBC_SHA": tls.TLS_RSA_WITH_AES_128_CBC_SHA,
"TLS_RSA_WITH_AES_256_CBC_SHA": tls.TLS_RSA_WITH_AES_256_CBC_SHA,
"TLS_RSA_WITH_AES_128_CBC_SHA256": tls.TLS_RSA_WITH_AES_128_CBC_SHA256,
"TLS_RSA_WITH_AES_128_GCM_SHA256": tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
"TLS_RSA_WITH_AES_256_GCM_SHA384": tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA": tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
"TLS_ECDHE_RSA_WITH_RC4_128_SHA": tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA,
"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256": tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256": tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
"TLS_AES_128_GCM_SHA256": tls.TLS_AES_128_GCM_SHA256,
"TLS_AES_256_GCM_SHA384": tls.TLS_AES_256_GCM_SHA384,
"TLS_CHACHA20_POLY1305_SHA256": tls.TLS_CHACHA20_POLY1305_SHA256,
"TLS_FALLBACK_SCSV": tls.TLS_FALLBACK_SCSV,
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305": tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305": tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
}
var ztlsCiphers = map[string]uint16{
"TLS_NULL_WITH_NULL_NULL": ztls.TLS_NULL_WITH_NULL_NULL,
"TLS_RSA_WITH_NULL_MD5": ztls.TLS_RSA_WITH_NULL_MD5,
"TLS_RSA_WITH_NULL_SHA": ztls.TLS_RSA_WITH_NULL_SHA,
@ -353,15 +409,3 @@ var ciphers = map[string]uint16{
"SSL_EN_RC2_128_CBC_WITH_MD5": ztls.SSL_EN_RC2_128_CBC_WITH_MD5,
"OP_PCL_TLS10_AES_128_CBC_SHA512": ztls.OP_PCL_TLS10_AES_128_CBC_SHA512,
}
func toCiphers(items []string) ([]uint16, error) {
var convertedCiphers []uint16
for _, item := range items {
zcipher, ok := ciphers[item]
if !ok {
return nil, fmt.Errorf("unsupported cipher suite: %s", item)
}
convertedCiphers = append(convertedCiphers, zcipher)
}
return convertedCiphers, nil
}

View File

@ -56,7 +56,8 @@ type Request struct {
MaxVersion string `yaml:"max_version,omitempty" jsonschema:"title=TLS version,description=Max tls version - automatic if not specified.,enum=sslv3,enum=tls10,enum=tls11,enum=tls12,enum=tls13"`
// description: |
// Client Cipher Suites - auto if not specified.
CiperSuites []string `yaml:"cipher_suites,omitempty"`
CiperSuites []string `yaml:"cipher_suites,omitempty"`
cipherSuites []uint16
// cache any variables that may be needed for operation.
dialer *fastdialer.Dialer
@ -73,6 +74,15 @@ func (request *Request) Compile(options *protocols.ExecuterOptions) error {
}
request.dialer = client
if request.options.Options.ZTLS {
request.cipherSuites, err = toZTLSCiphers(request.CiperSuites)
} else {
request.cipherSuites, err = toTLSCiphers(request.CiperSuites)
}
if err != nil {
return errors.Wrap(err, "invalid ciphersuites specified")
}
if len(request.Matchers) > 0 || len(request.Extractors) > 0 {
compiled := &request.Operators
if err := compiled.Compile(); err != nil {
@ -133,10 +143,6 @@ func (request *Request) ExecuteWithResults(input string, dynamicValues, previous
}
maxVersion = version
}
cipherSuites, err := toCiphers(request.CiperSuites)
if err != nil {
return err
}
var conn net.Conn
if request.options.Options.ZTLS {
@ -147,8 +153,8 @@ func (request *Request) ExecuteWithResults(input string, dynamicValues, previous
if maxVersion > 0 {
zconfig.MaxVersion = maxVersion
}
if len(cipherSuites) > 0 {
zconfig.CipherSuites = cipherSuites
if len(request.cipherSuites) > 0 {
zconfig.CipherSuites = request.cipherSuites
}
conn, err = request.dialer.DialZTLSWithConfig(context.Background(), "tcp", addressToDial, zconfig)
} else {
@ -159,8 +165,8 @@ func (request *Request) ExecuteWithResults(input string, dynamicValues, previous
if maxVersion > 0 {
config.MaxVersion = maxVersion
}
if len(cipherSuites) > 0 {
config.CipherSuites = cipherSuites
if len(request.cipherSuites) > 0 {
config.CipherSuites = request.cipherSuites
}
conn, err = request.dialer.DialTLSWithConfig(context.Background(), "tcp", addressToDial, config)
}
@ -183,6 +189,7 @@ func (request *Request) ExecuteWithResults(input string, dynamicValues, previous
var (
tlsData interface{}
certNotAfter int64
gotCipher uint16
)
if request.options.Options.ZTLS {
connTLS, ok := conn.(*ztls.Conn)
@ -193,9 +200,9 @@ func (request *Request) ExecuteWithResults(input string, dynamicValues, previous
if len(state.PeerCertificates) == 0 {
return nil
}
tlsData = cryptoutil.ZTLSGrab(connTLS)
cert := connTLS.ConnectionState().PeerCertificates[0]
gotCipher = state.CipherSuite
certNotAfter = cert.NotAfter.Unix()
} else {
connTLS, ok := conn.(*tls.Conn)
@ -208,8 +215,15 @@ func (request *Request) ExecuteWithResults(input string, dynamicValues, previous
}
tlsData = cryptoutil.TLSGrab(&state)
cert := connTLS.ConnectionState().PeerCertificates[0]
gotCipher = state.CipherSuite
certNotAfter = cert.NotAfter.Unix()
}
var cipherSuiteMatched bool
for _, cipher := range request.cipherSuites {
if cipher == gotCipher {
cipherSuiteMatched = true
}
}
jsonData, _ := jsoniter.Marshal(tlsData)
jsonDataString := string(jsonData)
@ -219,6 +233,7 @@ func (request *Request) ExecuteWithResults(input string, dynamicValues, previous
data["type"] = request.Type().String()
data["response"] = jsonDataString
data["host"] = input
data["cipher_matched"] = cipherSuiteMatched
data["matched"] = addressToDial
data["not_after"] = float64(certNotAfter)
data["ip"] = request.dialer.GetDialedIP(hostname)

View File

@ -135,7 +135,7 @@ TCxxGzcAlUAAJE6+SJpY7fPRe+n2EvPS
`
// NewTCPServer creates a new TCP server from a handler
func NewTCPServer(withTls bool, port int, handler func(conn net.Conn)) *TCPServer {
func NewTCPServer(tlsConfig *tls.Config, port int, handler func(conn net.Conn)) *TCPServer {
server := &TCPServer{}
l, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", port))
@ -145,11 +145,13 @@ func NewTCPServer(withTls bool, port int, handler func(conn net.Conn)) *TCPServe
server.URL = l.Addr().String()
server.listener = l
cer, err := tls.X509KeyPair([]byte(serverCert), []byte(serverKey))
if err != nil {
panic(err)
if tlsConfig != nil {
cer, err := tls.X509KeyPair([]byte(serverCert), []byte(serverKey))
if err != nil {
panic(err)
}
tlsConfig.Certificates = []tls.Certificate{cer}
}
config := &tls.Config{Certificates: []tls.Certificate{cer}}
go func() {
for {
@ -159,8 +161,8 @@ func NewTCPServer(withTls bool, port int, handler func(conn net.Conn)) *TCPServe
continue
}
// Handle connections in a new goroutine.
if withTls {
connTls := tls.Server(conn, config)
if tlsConfig != nil {
connTls := tls.Server(conn, tlsConfig)
go handler(connTls)
} else {
go handler(conn)