mirror of
https://github.com/projectdiscovery/nuclei.git
synced 2025-12-22 23:05:24 +00:00
Adding global SNI support for HTTP protocol via CLI (#1964)
* Adding global SNI support via CLI * adding integration test * adding cli option to docs * reverting deleted test
This commit is contained in:
parent
7e2489e9d2
commit
2f1330345f
@ -84,7 +84,7 @@ nuclei -h
|
|||||||
This will display help for the tool. Here are all the switches it supports.
|
This will display help for the tool. Here are all the switches it supports.
|
||||||
|
|
||||||
|
|
||||||
```yaml
|
```console
|
||||||
Nuclei is a fast, template based vulnerability scanner focusing
|
Nuclei is a fast, template based vulnerability scanner focusing
|
||||||
on extensive configurability, massive extensibility and ease of use.
|
on extensive configurability, massive extensibility and ease of use.
|
||||||
|
|
||||||
@ -150,6 +150,7 @@ CONFIGURATIONS:
|
|||||||
-ck, -client-key string client key file (PEM-encoded) used for authenticating against scanned hosts
|
-ck, -client-key string client key file (PEM-encoded) used for authenticating against scanned hosts
|
||||||
-ca, -client-ca string client certificate authority file (PEM-encoded) used for authenticating against scanned hosts
|
-ca, -client-ca string client certificate authority file (PEM-encoded) used for authenticating against scanned hosts
|
||||||
-ztls Use ztls library with autofallback to standard one for tls13
|
-ztls Use ztls library with autofallback to standard one for tls13
|
||||||
|
-sni string Global SNI hostname (default: input domain name)
|
||||||
|
|
||||||
INTERACTSH:
|
INTERACTSH:
|
||||||
-iserver, -interactsh-server string interactsh server url for self-hosted instance (default: oast.pro,oast.live,oast.site,oast.online,oast.fun,oast.me)
|
-iserver, -interactsh-server string interactsh server url for self-hosted instance (default: oast.pro,oast.live,oast.site,oast.online,oast.fun,oast.me)
|
||||||
|
|||||||
15
integration_tests/http/get-sni.yaml
Normal file
15
integration_tests/http/get-sni.yaml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
id: basic-get
|
||||||
|
|
||||||
|
info:
|
||||||
|
name: Basic GET Request with CLI SNI
|
||||||
|
author: pdteam
|
||||||
|
severity: info
|
||||||
|
|
||||||
|
requests:
|
||||||
|
- method: GET
|
||||||
|
path:
|
||||||
|
- "{{BaseURL}}"
|
||||||
|
matchers:
|
||||||
|
- type: word
|
||||||
|
words:
|
||||||
|
- "test-ok"
|
||||||
@ -48,6 +48,7 @@ var httpTestcases = map[string]testutils.TestCase{
|
|||||||
"http/stop-at-first-match.yaml": &httpStopAtFirstMatch{},
|
"http/stop-at-first-match.yaml": &httpStopAtFirstMatch{},
|
||||||
"http/stop-at-first-match-with-extractors.yaml": &httpStopAtFirstMatchWithExtractors{},
|
"http/stop-at-first-match-with-extractors.yaml": &httpStopAtFirstMatchWithExtractors{},
|
||||||
"http/variables.yaml": &httpVariables{},
|
"http/variables.yaml": &httpVariables{},
|
||||||
|
"http/get-sni.yaml": &customCLISNI{},
|
||||||
}
|
}
|
||||||
|
|
||||||
type httpInteractshRequest struct{}
|
type httpInteractshRequest struct{}
|
||||||
@ -810,3 +811,25 @@ func (h *httpVariables) Execute(filePath string) error {
|
|||||||
|
|
||||||
return expectResultsCount(results, 1)
|
return expectResultsCount(results, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type customCLISNI struct{}
|
||||||
|
|
||||||
|
// Execute executes a test case and returns an error if occurred
|
||||||
|
func (h *customCLISNI) Execute(filePath string) error {
|
||||||
|
router := httprouter.New()
|
||||||
|
router.GET("/", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
|
||||||
|
if r.TLS.ServerName == "test" {
|
||||||
|
_, _ = w.Write([]byte("test-ok"))
|
||||||
|
} else {
|
||||||
|
_, _ = w.Write([]byte("test-ko"))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
ts := httptest.NewTLSServer(router)
|
||||||
|
defer ts.Close()
|
||||||
|
|
||||||
|
results, err := testutils.RunNucleiTemplateAndGetResults(filePath, ts.URL, debug, "-sni", "test")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return expectResultsCount(results, 1)
|
||||||
|
}
|
||||||
|
|||||||
@ -147,6 +147,7 @@ on extensive configurability, massive extensibility and ease of use.`)
|
|||||||
flagSet.StringVarP(&options.ClientKeyFile, "client-key", "ck", "", "client key file (PEM-encoded) used for authenticating against scanned hosts"),
|
flagSet.StringVarP(&options.ClientKeyFile, "client-key", "ck", "", "client key file (PEM-encoded) used for authenticating against scanned hosts"),
|
||||||
flagSet.StringVarP(&options.ClientCAFile, "client-ca", "ca", "", "client certificate authority file (PEM-encoded) used for authenticating against scanned hosts"),
|
flagSet.StringVarP(&options.ClientCAFile, "client-ca", "ca", "", "client certificate authority file (PEM-encoded) used for authenticating against scanned hosts"),
|
||||||
flagSet.BoolVar(&options.ZTLS, "ztls", false, "Use ztls library with autofallback to standard one for tls13"),
|
flagSet.BoolVar(&options.ZTLS, "ztls", false, "Use ztls library with autofallback to standard one for tls13"),
|
||||||
|
flagSet.StringVar(&options.SNI, "sni", "", "Global SNI hostname (default: input domain name)"),
|
||||||
)
|
)
|
||||||
|
|
||||||
createGroup(flagSet, "interactsh", "interactsh",
|
createGroup(flagSet, "interactsh", "interactsh",
|
||||||
|
|||||||
@ -28,6 +28,10 @@ func newHttpClient(options *types.Options) (*http.Client, error) {
|
|||||||
InsecureSkipVerify: true,
|
InsecureSkipVerify: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if options.SNI != "" {
|
||||||
|
tlsConfig.ServerName = options.SNI
|
||||||
|
}
|
||||||
|
|
||||||
// Add the client certificate authentication to the request if it's configured
|
// Add the client certificate authentication to the request if it's configured
|
||||||
var err error
|
var err error
|
||||||
tlsConfig, err = utils.AddConfiguredClientCertToRequest(tlsConfig, options)
|
tlsConfig, err = utils.AddConfiguredClientCertToRequest(tlsConfig, options)
|
||||||
|
|||||||
@ -179,6 +179,10 @@ func wrappedGet(options *types.Options, configuration *Configuration) (*retryabl
|
|||||||
InsecureSkipVerify: true,
|
InsecureSkipVerify: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if options.SNI != "" {
|
||||||
|
tlsConfig.ServerName = options.SNI
|
||||||
|
}
|
||||||
|
|
||||||
// Add the client certificate authentication to the request if it's configured
|
// Add the client certificate authentication to the request if it's configured
|
||||||
tlsConfig, err = utils.AddConfiguredClientCertToRequest(tlsConfig, options)
|
tlsConfig, err = utils.AddConfiguredClientCertToRequest(tlsConfig, options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -185,11 +185,15 @@ func (request *Request) executeRequestWithPayloads(input, hostname string, dynam
|
|||||||
}
|
}
|
||||||
header.Set(key, string(finalData))
|
header.Set(key, string(finalData))
|
||||||
}
|
}
|
||||||
|
tlsConfig := &tls.Config{InsecureSkipVerify: true, ServerName: hostname}
|
||||||
|
if requestOptions.Options.SNI != "" {
|
||||||
|
tlsConfig.ServerName = requestOptions.Options.SNI
|
||||||
|
}
|
||||||
websocketDialer := ws.Dialer{
|
websocketDialer := ws.Dialer{
|
||||||
Header: ws.HandshakeHeaderHTTP(header),
|
Header: ws.HandshakeHeaderHTTP(header),
|
||||||
Timeout: time.Duration(requestOptions.Options.Timeout) * time.Second,
|
Timeout: time.Duration(requestOptions.Options.Timeout) * time.Second,
|
||||||
NetDial: request.dialer.Dial,
|
NetDial: request.dialer.Dial,
|
||||||
TLSConfig: &tls.Config{InsecureSkipVerify: true, ServerName: hostname},
|
TLSConfig: tlsConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
finalAddress, dataErr := expressions.EvaluateByte([]byte(request.Address), payloadValues)
|
finalAddress, dataErr := expressions.EvaluateByte([]byte(request.Address), payloadValues)
|
||||||
|
|||||||
@ -214,6 +214,8 @@ type Options struct {
|
|||||||
StoreResponseDir string
|
StoreResponseDir string
|
||||||
// DisableRedirects disables following redirects for http request module
|
// DisableRedirects disables following redirects for http request module
|
||||||
DisableRedirects bool
|
DisableRedirects bool
|
||||||
|
// SNI custom hostname
|
||||||
|
SNI string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (options *Options) AddVarPayload(key string, value interface{}) {
|
func (options *Options) AddVarPayload(key string, value interface{}) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user