mirror of
https://github.com/jtesta/ssh-audit.git
synced 2024-12-22 14:05:22 +01:00
Added test for the Terrapin vulnerability (CVE-2023-48795) (#227).
This commit is contained in:
parent
46eb970376
commit
8e972c5e94
@ -184,6 +184,7 @@ For convenience, a web front-end on top of the command-line tool is available at
|
||||
- In Ubuntu 22.04 client policy, moved host key types `sk-ssh-ed25519@openssh.com` and `ssh-ed25519` to the end of all certificate types.
|
||||
- Re-organized option host key types for OpenSSH 9.2 server policy to correspond with updated Debian 12 hardening guide.
|
||||
- Dropped support for Python 3.7 (EOL was reached in June 2023).
|
||||
- Added test for the Terrapin message prefix truncation vulnerability ([CVE-2023-48795](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-48795)).
|
||||
|
||||
### v3.0.0 (2023-09-07)
|
||||
- Results from concurrent scans against multiple hosts are no longer improperly combined; bug discovered by [Adam Russell](https://github.com/thecliguy).
|
||||
|
@ -71,6 +71,8 @@ class SSH2_KexDB: # pylint: disable=too-few-public-methods
|
||||
INFO_REMOVED_IN_OPENSSH69 = 'removed in OpenSSH 6.9: https://www.openssh.com/txt/release-6.9'
|
||||
INFO_REMOVED_IN_OPENSSH70 = 'removed in OpenSSH 7.0: https://www.openssh.com/txt/release-7.0'
|
||||
INFO_WITHDRAWN_PQ_ALG = 'the sntrup4591761 algorithm was withdrawn, as it may not provide strong post-quantum security'
|
||||
INFO_EXTENSION_NEGOTIATION = 'pseudo-algorithm that denotes the peer supports RFC8308 extensions'
|
||||
INFO_STRICT_KEX = 'pseudo-algorithm that denotes the peer supports a stricter key exchange method as a counter-measure to the Terrapin attack (CVE-2023-48795)'
|
||||
|
||||
# Maintains a dictionary per calling thread that yields its own copy of MASTER_DB. This prevents results from one thread polluting the results of another thread.
|
||||
DB_PER_THREAD: Dict[int, Dict[str, Dict[str, List[List[Optional[str]]]]]] = {}
|
||||
@ -154,8 +156,10 @@ class SSH2_KexDB: # pylint: disable=too-few-public-methods
|
||||
'ecdh-sha2-wiRIU8TKjMZ418sMqlqtvQ==': [[], [FAIL_UNPROVEN]], # sect283k1
|
||||
'ecdh-sha2-zD/b3hu/71952ArpUG4OjQ==': [[], [FAIL_UNPROVEN, FAIL_SMALL_ECC_MODULUS]], # sect233k1
|
||||
'ecmqv-sha2': [[], [FAIL_UNPROVEN]],
|
||||
'ext-info-c': [[]], # Extension negotiation (RFC 8308)
|
||||
'ext-info-s': [[]], # Extension negotiation (RFC 8308)
|
||||
'ext-info-c': [[], [], [], [INFO_EXTENSION_NEGOTIATION]], # Extension negotiation (RFC 8308)
|
||||
'ext-info-s': [[], [], [], [INFO_EXTENSION_NEGOTIATION]], # Extension negotiation (RFC 8308)
|
||||
'kex-strict-c-v00@openssh.com': [[], [], [], [INFO_STRICT_KEX]], # Strict KEX marker (countermeasure for CVE-2023-48795).
|
||||
'kex-strict-s-v00@openssh.com': [[], [], [], [INFO_STRICT_KEX]], # Strict KEX marker (countermeasure for CVE-2023-48795).
|
||||
|
||||
# The GSS kex algorithms get special wildcard handling, since they include variable base64 data after their standard prefixes.
|
||||
'gss-13.3.132.0.10-sha256-*': [[], [FAIL_UNKNOWN]],
|
||||
|
@ -447,7 +447,7 @@ def output_info(out: OutputBuffer, software: Optional['Software'], client_audit:
|
||||
out.sep()
|
||||
|
||||
|
||||
def post_process_findings(banner: Optional[Banner], algs: Algorithms) -> List[str]:
|
||||
def post_process_findings(banner: Optional[Banner], algs: Algorithms, client_audit: bool) -> List[str]:
|
||||
'''Perform post-processing on scan results before reporting them to the user. Returns a list of algorithms that should not be recommended'''
|
||||
|
||||
|
||||
@ -466,6 +466,45 @@ def post_process_findings(banner: Optional[Banner], algs: Algorithms) -> List[st
|
||||
# Ensure that this algorithm doesn't appear in the recommendations section since the user cannot control this OpenSSH bug.
|
||||
algorithm_recommendation_suppress_list.append('diffie-hellman-group-exchange-sha256')
|
||||
|
||||
# Check for the Terrapin vulnerability (CVE-2023-48795), and mark the vulnerable algorithms.
|
||||
if algs.ssh2kex is not None and \
|
||||
((client_audit and 'kex-strict-c-v00@openssh.com' not in algs.ssh2kex.kex_algorithms) or (not client_audit and 'kex-strict-s-v00@openssh.com' not in algs.ssh2kex.kex_algorithms)): # Strict KEX marker is not present.
|
||||
|
||||
def add_terrapin_warning(db: Dict[str, Dict[str, List[List[Optional[str]]]]], category: str, algorithm_name: str) -> None:
|
||||
while len(db[category][algorithm_name]) < 3:
|
||||
db[category][algorithm_name].append([])
|
||||
|
||||
db[category][algorithm_name][2].append("vulnerable to the Terrapin attack (CVE-2023-48795), allowing message prefix truncation")
|
||||
|
||||
db = SSH2_KexDB.get_db()
|
||||
|
||||
# Without the strict KEX marker, these algorithms are always vulnerable.
|
||||
add_terrapin_warning(db, "enc", "chacha20-poly1305")
|
||||
add_terrapin_warning(db, "enc", "chacha20-poly1305@openssh.com")
|
||||
|
||||
cbc_ciphers = []
|
||||
etm_macs = []
|
||||
|
||||
# Find the list of CBC ciphers the peer supports.
|
||||
ciphers_supported = algs.ssh2kex.client.encryption if client_audit else algs.ssh2kex.server.encryption
|
||||
for cipher in ciphers_supported:
|
||||
if cipher.endswith("-cbc"):
|
||||
cbc_ciphers.append(cipher)
|
||||
|
||||
# Find the list of ETM MACs the peer supports.
|
||||
macs_supported = algs.ssh2kex.client.mac if client_audit else algs.ssh2kex.server.mac
|
||||
for mac in macs_supported:
|
||||
if mac.endswith("-etm@openssh.com"):
|
||||
etm_macs.append(mac)
|
||||
|
||||
# If at least one CBC cipher and at least one ETM MAC is supported, mark them all as vulnerable.
|
||||
if len(cbc_ciphers) > 0 and len(etm_macs) > 0:
|
||||
for cipher in cbc_ciphers:
|
||||
add_terrapin_warning(db, "enc", cipher)
|
||||
|
||||
for mac in etm_macs:
|
||||
add_terrapin_warning(db, "mac", mac)
|
||||
|
||||
return algorithm_recommendation_suppress_list
|
||||
|
||||
|
||||
@ -478,7 +517,7 @@ def output(out: OutputBuffer, aconf: AuditConf, banner: Optional[Banner], header
|
||||
algs = Algorithms(pkm, kex)
|
||||
|
||||
# Perform post-processing on the findings to make final adjustments before outputting the results.
|
||||
algorithm_recommendation_suppress_list = post_process_findings(banner, algs)
|
||||
algorithm_recommendation_suppress_list = post_process_findings(banner, algs, client_audit)
|
||||
|
||||
with out:
|
||||
if print_target:
|
||||
|
@ -164,7 +164,7 @@ class TestSSH2:
|
||||
self.audit(out, self._conf())
|
||||
out.write()
|
||||
lines = output_spy.flush()
|
||||
assert len(lines) == 70
|
||||
assert len(lines) == 83
|
||||
|
||||
def test_ssh2_server_invalid_first_packet(self, output_spy, virtual_socket):
|
||||
vsocket = virtual_socket
|
||||
|
Loading…
Reference in New Issue
Block a user