mirror of https://github.com/daffainfo/nuclei.git
Added more tests and ciphersuits for SSL protocol
parent
85fabf74ce
commit
90b4c09f80
|
@ -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"
|
|
@ -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"'
|
|
@ -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"))
|
||||
})
|
||||
|
|
|
@ -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"))
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue