mirror of
				https://github.com/jtesta/ssh-audit.git
				synced 2025-10-31 05:25:28 +01:00 
			
		
		
		
	Added test for the Terrapin vulnerability (CVE-2023-48795) (#227).
This commit is contained in:
		| @@ -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). | ||||||
|   | |||||||
| @@ -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]], | ||||||
|   | |||||||
| @@ -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: | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Joe Testa
					Joe Testa