Added test for the Terrapin vulnerability (CVE-2023-48795) (#227).

This commit is contained in:
Joe Testa 2023-12-18 18:24:49 -05:00
parent 46eb970376
commit 8e972c5e94
4 changed files with 49 additions and 5 deletions

View File

@ -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. - 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. - 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). - 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) ### 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). - Results from concurrent scans against multiple hosts are no longer improperly combined; bug discovered by [Adam Russell](https://github.com/thecliguy).

View File

@ -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_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_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_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. # 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]]]]]] = {} 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-wiRIU8TKjMZ418sMqlqtvQ==': [[], [FAIL_UNPROVEN]], # sect283k1
'ecdh-sha2-zD/b3hu/71952ArpUG4OjQ==': [[], [FAIL_UNPROVEN, FAIL_SMALL_ECC_MODULUS]], # sect233k1 'ecdh-sha2-zD/b3hu/71952ArpUG4OjQ==': [[], [FAIL_UNPROVEN, FAIL_SMALL_ECC_MODULUS]], # sect233k1
'ecmqv-sha2': [[], [FAIL_UNPROVEN]], 'ecmqv-sha2': [[], [FAIL_UNPROVEN]],
'ext-info-c': [[]], # Extension negotiation (RFC 8308) 'ext-info-c': [[], [], [], [INFO_EXTENSION_NEGOTIATION]], # Extension negotiation (RFC 8308)
'ext-info-s': [[]], # 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. # 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]], 'gss-13.3.132.0.10-sha256-*': [[], [FAIL_UNKNOWN]],

View File

@ -447,7 +447,7 @@ def output_info(out: OutputBuffer, software: Optional['Software'], client_audit:
out.sep() 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''' '''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. # 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') 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 return algorithm_recommendation_suppress_list
@ -478,7 +517,7 @@ def output(out: OutputBuffer, aconf: AuditConf, banner: Optional[Banner], header
algs = Algorithms(pkm, kex) algs = Algorithms(pkm, kex)
# Perform post-processing on the findings to make final adjustments before outputting the results. # 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: with out:
if print_target: if print_target:

View File

@ -164,7 +164,7 @@ class TestSSH2:
self.audit(out, self._conf()) self.audit(out, self._conf())
out.write() out.write()
lines = output_spy.flush() lines = output_spy.flush()
assert len(lines) == 70 assert len(lines) == 83
def test_ssh2_server_invalid_first_packet(self, output_spy, virtual_socket): def test_ssh2_server_invalid_first_packet(self, output_spy, virtual_socket):
vsocket = virtual_socket vsocket = virtual_socket