[BUGFIX] Set SNI on each redirect to avoid handshake failures / incorrect 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>
https://github.com/zmap/zgrab2/pull/306
This commit is contained in:
AG 2021-04-09 15:36:07 -04:00 committed by GitHub
부모 4e047842a6
커밋 5e9507cacf
No known key found for this signature in database
GPG 키 ID: 4AEE18F83AFDEB23

파일 보기

@ -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"
}
@ -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)
@ -239,16 +239,33 @@ 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
}
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 {
@ -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)
@ -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())