mirror of
				https://github.com/jtesta/ssh-audit.git
				synced 2025-11-04 11:12:15 +01:00 
			
		
		
		
	Now handles exceptions during server KEX parsing more gracefully.
This commit is contained in:
		@@ -26,6 +26,8 @@
 | 
			
		||||
from typing import Dict, List, Set, Sequence, Tuple, Iterable  # noqa: F401
 | 
			
		||||
from typing import Callable, Optional, Union, Any  # noqa: F401
 | 
			
		||||
 | 
			
		||||
import traceback
 | 
			
		||||
 | 
			
		||||
from ssh_audit.kexdh import KexGroupExchange_SHA1, KexGroupExchange_SHA256
 | 
			
		||||
from ssh_audit.ssh2_kexdb import SSH2_KexDB
 | 
			
		||||
from ssh_audit.ssh2_kex import SSH2_Kex
 | 
			
		||||
@@ -58,9 +60,13 @@ class GEXTest:
 | 
			
		||||
        # server's own values.
 | 
			
		||||
        s.send_kexinit(key_exchanges=[gex_alg], hostkeys=kex.key_algorithms, ciphers=kex.server.encryption, macs=kex.server.mac, compressions=kex.server.compression, languages=kex.server.languages)
 | 
			
		||||
 | 
			
		||||
        # Parse the server's KEX.
 | 
			
		||||
        _, payload = s.read_packet(2)
 | 
			
		||||
        SSH2_Kex.parse(payload)
 | 
			
		||||
        try:
 | 
			
		||||
            # Parse the server's KEX.
 | 
			
		||||
            _, payload = s.read_packet(2)
 | 
			
		||||
            SSH2_Kex.parse(payload)
 | 
			
		||||
        except Exception:
 | 
			
		||||
            out.v("Failed to parse server's kex.  Stack trace:\n%s" % str(traceback.format_exc()), write_now=True)
 | 
			
		||||
            return False
 | 
			
		||||
 | 
			
		||||
        return True
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,8 @@
 | 
			
		||||
from typing import Dict, List, Set, Sequence, Tuple, Iterable  # noqa: F401
 | 
			
		||||
from typing import Callable, Optional, Union, Any  # noqa: F401
 | 
			
		||||
 | 
			
		||||
import traceback
 | 
			
		||||
 | 
			
		||||
from ssh_audit.kexdh import KexDH, KexGroup1, KexGroup14_SHA1, KexGroup14_SHA256, KexCurve25519_SHA256, KexGroup16_SHA512, KexGroup18_SHA512, KexGroupExchange_SHA1, KexGroupExchange_SHA256, KexNISTP256, KexNISTP384, KexNISTP521
 | 
			
		||||
from ssh_audit.ssh2_kex import SSH2_Kex
 | 
			
		||||
from ssh_audit.ssh2_kexdb import SSH2_KexDB
 | 
			
		||||
@@ -123,10 +125,13 @@ class HostKeyTest:
 | 
			
		||||
                    # Send our KEX using the specified group-exchange and most of the server's own values.
 | 
			
		||||
                    s.send_kexinit(key_exchanges=[kex_str], hostkeys=[host_key_type], ciphers=server_kex.server.encryption, macs=server_kex.server.mac, compressions=server_kex.server.compression, languages=server_kex.server.languages)
 | 
			
		||||
 | 
			
		||||
                    # Parse the server's KEX.
 | 
			
		||||
                    _, payload = s.read_packet()
 | 
			
		||||
                    SSH2_Kex.parse(payload)
 | 
			
		||||
 | 
			
		||||
                    try:
 | 
			
		||||
                        # Parse the server's KEX.
 | 
			
		||||
                        _, payload = s.read_packet()
 | 
			
		||||
                        SSH2_Kex.parse(payload)
 | 
			
		||||
                    except Exception:
 | 
			
		||||
                        out.v("Failed to parse server's kex.  Stack trace:\n%s" % str(traceback.format_exc()), write_now=True)
 | 
			
		||||
                        return
 | 
			
		||||
 | 
			
		||||
                # Do the initial DH exchange.  The server responds back
 | 
			
		||||
                # with the host key and its length.  Bingo.  We also get back the host key fingerprint.
 | 
			
		||||
 
 | 
			
		||||
@@ -895,7 +895,12 @@ def audit(out: OutputBuffer, aconf: AuditConf, sshv: Optional[int] = None, print
 | 
			
		||||
    if sshv == 1:
 | 
			
		||||
        program_retval = output(out, aconf, banner, header, pkm=SSH1_PublicKeyMessage.parse(payload))
 | 
			
		||||
    elif sshv == 2:
 | 
			
		||||
        kex = SSH2_Kex.parse(payload)
 | 
			
		||||
        try:
 | 
			
		||||
            kex = SSH2_Kex.parse(payload)
 | 
			
		||||
        except Exception:
 | 
			
		||||
            out.fail("Failed to parse server's kex.  Stack trace:\n%s" % str(traceback.format_exc()))
 | 
			
		||||
            return exitcodes.CONNECTION_ERROR
 | 
			
		||||
 | 
			
		||||
        if aconf.client_audit is False:
 | 
			
		||||
            HostKeyTest.run(out, s, kex)
 | 
			
		||||
            GEXTest.run(out, s, kex)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user