Skip to content

Commit

Permalink
[BUGFIX] Set SNI on each redirect to avoid handshake failures / incor…
Browse files Browse the repository at this point in the history
…rect server name (#306)

* Set SNI explicitly, in case it's a redirect (fix for #300)

* Fix the SNI issue correctly, using the host portion of addr, while respecting --server-name and --no-sni

* Clean up double error logging pointed out by dadrien

* Comply with RFC4366, do not set SNI server name for IP address

Co-authored-by: Adam Greene <copyright@mzpqnxow.com>
#306
  • Loading branch information
mzpqnxow authored Apr 9, 2021
1 parent 4e04784 commit 5e9507c
Showing 1 changed file with 27 additions and 11 deletions.
38 changes: 27 additions & 11 deletions modules/http/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ func (flags *Flags) Help() string {
}

// Protocol returns the protocol identifer for the scanner.
func (s *Scanner) Protocol() string {
func (scanner *Scanner) Protocol() string {
return "http"
}

Expand All @@ -143,13 +143,13 @@ func (scanner *Scanner) Init(flags zgrab2.ScanFlags) error {

if fl.ComputeDecodedBodyHashAlgorithm == "sha1" {
scanner.decodedHashFn = func(body []byte) string {
raw_hash := sha1.Sum(body)
return fmt.Sprintf("sha1:%s", hex.EncodeToString(raw_hash[:]))
rawHash := sha1.Sum(body)
return fmt.Sprintf("sha1:%s", hex.EncodeToString(rawHash[:]))
}
} else if fl.ComputeDecodedBodyHashAlgorithm == "sha256" {
scanner.decodedHashFn = func(body []byte) string {
raw_hash := sha256.Sum256(body)
return fmt.Sprintf("sha256:%s", hex.EncodeToString(raw_hash[:]))
rawHash := sha256.Sum256(body)
return fmt.Sprintf("sha256:%s", hex.EncodeToString(rawHash[:]))
}
} else if fl.ComputeDecodedBodyHashAlgorithm != "" {
log.Panicf("Invalid ComputeDecodedBodyHashAlgorithm choice made it through zflags: %s", scanner.config.ComputeDecodedBodyHashAlgorithm)
Expand Down Expand Up @@ -239,18 +239,35 @@ func (scan *scan) dialContext(ctx context.Context, network string, addr string)

// getTLSDialer returns a Dial function that connects using the
// zgrab2.GetTLSConnection()
func (scan *scan) getTLSDialer(t *zgrab2.ScanTarget) func(net, addr string) (net.Conn, error) {
return func(net, addr string) (net.Conn, error) {
outer, err := scan.dialContext(context.Background(), net, addr)
func (scan *scan) getTLSDialer(t *zgrab2.ScanTarget) func(network, addr string) (net.Conn, error) {
return func(network, addr string) (net.Conn, error) {
outer, err := scan.dialContext(context.Background(), network, addr)
if err != nil {
return nil, err
}

cfg, err := scan.scanner.config.TLSFlags.GetTLSConfigForTarget(t)
if err != nil {
return nil, err
}

// Set SNI server name on redirects unless --server-name was used (issue #300)
// - t.Domain is always set to the *original* Host so it's not useful for setting SNI
// - host is the current target of the request in this context; this is true for the
// initial request as well as subsequent requests caused by redirects
// - scan.scanner.config.ServerName is the value from --server-name if one was specified

// If SNI is enabled and --server-name is not set, use the target host for the SNI server name
if !scan.scanner.config.NoSNI && scan.scanner.config.ServerName == "" {
host, _, err := net.SplitHostPort(addr)
if err != nil {
log.Errorf("getTLSDialer(): Something went wrong splitting host/port '%s': %s", addr, err)
}
// RFC4366: Literal IPv4 and IPv6 addresses are not permitted in "HostName"
if i := net.ParseIP(host); i == nil {
cfg.ServerName = host
}
}

if scan.scanner.config.OverrideSH {
cfg.SignatureAndHashes = []tls.SigAndHash{
{0x01, 0x04}, // rsa, sha256
Expand All @@ -262,7 +279,6 @@ func (scan *scan) getTLSDialer(t *zgrab2.ScanTarget) func(net, addr string) (net
{0x01, 0x06}, // rsa, sha512
}
}

tlsConn := scan.scanner.config.TLSFlags.GetWrappedConnection(outer, cfg)

// lib/http/transport.go fills in the TLSLog in the http.Request instance(s)
Expand Down Expand Up @@ -431,7 +447,7 @@ func (scan *scan) Grab() *zgrab2.ScanError {
bodyText := ""
decodedSuccessfully := false
decoder := encoder.NewDecoder()

//"windows-1252" is the default value and will likely not decode correctly
if certain || encoding != "windows-1252" {
decoded, decErr := decoder.Bytes(buf.Bytes())
Expand Down

0 comments on commit 5e9507c

Please sign in to comment.