mirror of
https://github.com/jtesta/ssh-audit.git
synced 2026-05-25 15:31:23 +02:00
Compare commits
5 Commits
1f12eca050
...
58c51e2c2c
| Author | SHA1 | Date | |
|---|---|---|---|
| 58c51e2c2c | |||
| 6d57c7c0f7 | |||
| ea3258151e | |||
| f9032c8277 | |||
| 3116c2e678 |
@@ -214,13 +214,15 @@ For convenience, a web front-end on top of the command-line tool is available at
|
|||||||
## ChangeLog
|
## ChangeLog
|
||||||
|
|
||||||
### v3.3.0-dev (???)
|
### v3.3.0-dev (???)
|
||||||
- Added built-in policies for Ubuntu 24.04 LTS server and client, and OpenSSH 9.8.
|
- Added built-in policies for Ubuntu 24.04 LTS server & client, OpenSSH 9.8, and OpenSSH 9.9.
|
||||||
- Added IPv6 support for DHEat and connection rate tests.
|
- Added IPv6 support for DHEat and connection rate tests.
|
||||||
- Added TCP port information to JSON policy scan results; credit [Fabian Malte Kopp](https://github.com/dreizehnutters).
|
- Added TCP port information to JSON policy scan results; credit [Fabian Malte Kopp](https://github.com/dreizehnutters).
|
||||||
- Added LANcom LCOS server recognition and Ed448 key extraction; credit [Daniel Lenski](https://github.com/dlenskiSB).
|
- Added LANcom LCOS server recognition and Ed448 key extraction; credit [Daniel Lenski](https://github.com/dlenskiSB).
|
||||||
- Fixed crash when running with `-P` and `-T` options simultaneously.
|
- Fixed crash when running with `-P` and `-T` options simultaneously.
|
||||||
- Fixed host key tests from only reporting a key type at most once despite multiple hosts supporting it; credit [Daniel Lenski](https://github.com/dlenskiSB).
|
- Fixed host key tests from only reporting a key type at most once despite multiple hosts supporting it; credit [Daniel Lenski](https://github.com/dlenskiSB).
|
||||||
- Fixed DHEat connection rate testing on MacOS X and BSD platforms; credit [Drew Noel](https://github.com/drewmnoel) and [Michael Osipov](https://github.com/michael-o).
|
- Fixed DHEat connection rate testing on MacOS X and BSD platforms; credit [Drew Noel](https://github.com/drewmnoel) and [Michael Osipov](https://github.com/michael-o).
|
||||||
|
- Fixed invalid JSON output when a socket error occurs while performing a client audit.
|
||||||
|
- When scanning multiple targets (using `-T`/`--targets`), the `-p`/`--port` option will now be used as the default port (set to 22 if `-p`/`--port` is not given). Hosts specified in the file can override this default with an explicit port number (i.e.: "host1:1234"). For example, when using `-T targets.txt -p 222`, all hosts in `targets.txt` that do not explicitly include a port number will default to 222; when using `-T targets.txt` (without `-p`), all hosts will use a default of 22.
|
||||||
- Added 1 new cipher: `grasshopper-ctr128`.
|
- Added 1 new cipher: `grasshopper-ctr128`.
|
||||||
- Added 2 new key exchanges: `mlkem768x25519-sha256`, `sntrup761x25519-sha512`.
|
- Added 2 new key exchanges: `mlkem768x25519-sha256`, `sntrup761x25519-sha512`.
|
||||||
|
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ BUILTIN_POLICIES: Dict[str, Dict[str, Union[Optional[str], Optional[List[str]],
|
|||||||
|
|
||||||
'Hardened OpenSSH Server v9.8 (version 1)': {'version': '1', 'changelog': 'Initial version.', 'banner': None, 'compressions': None, 'host_keys': ['rsa-sha2-512', 'rsa-sha2-256', 'ssh-ed25519'], 'optional_host_keys': ['sk-ssh-ed25519@openssh.com', 'ssh-ed25519-cert-v01@openssh.com', 'sk-ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['sntrup761x25519-sha512@openssh.com', 'curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256', 'ext-info-s', 'kex-strict-s-v00@openssh.com'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@openssh.com'], 'hostkey_sizes': {"rsa-sha2-256": {"hostkey_size": 4096}, "rsa-sha2-256-cert-v01@openssh.com": {"ca_key_size": 4096, "ca_key_type": "ssh-rsa", "hostkey_size": 4096}, "rsa-sha2-512": {"hostkey_size": 4096}, "rsa-sha2-512-cert-v01@openssh.com": {"ca_key_size": 4096, "ca_key_type": "ssh-rsa", "hostkey_size": 4096}, "sk-ssh-ed25519-cert-v01@openssh.com": {"ca_key_size": 256, "ca_key_type": "ssh-ed25519", "hostkey_size": 256}, "sk-ssh-ed25519@openssh.com": {"hostkey_size": 256}, "ssh-ed25519": {"hostkey_size": 256}, "ssh-ed25519-cert-v01@openssh.com": {"ca_key_size": 256, "ca_key_type": "ssh-ed25519", "hostkey_size": 256}}, 'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 3072}, 'server_policy': True},
|
'Hardened OpenSSH Server v9.8 (version 1)': {'version': '1', 'changelog': 'Initial version.', 'banner': None, 'compressions': None, 'host_keys': ['rsa-sha2-512', 'rsa-sha2-256', 'ssh-ed25519'], 'optional_host_keys': ['sk-ssh-ed25519@openssh.com', 'ssh-ed25519-cert-v01@openssh.com', 'sk-ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['sntrup761x25519-sha512@openssh.com', 'curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256', 'ext-info-s', 'kex-strict-s-v00@openssh.com'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@openssh.com'], 'hostkey_sizes': {"rsa-sha2-256": {"hostkey_size": 4096}, "rsa-sha2-256-cert-v01@openssh.com": {"ca_key_size": 4096, "ca_key_type": "ssh-rsa", "hostkey_size": 4096}, "rsa-sha2-512": {"hostkey_size": 4096}, "rsa-sha2-512-cert-v01@openssh.com": {"ca_key_size": 4096, "ca_key_type": "ssh-rsa", "hostkey_size": 4096}, "sk-ssh-ed25519-cert-v01@openssh.com": {"ca_key_size": 256, "ca_key_type": "ssh-ed25519", "hostkey_size": 256}, "sk-ssh-ed25519@openssh.com": {"hostkey_size": 256}, "ssh-ed25519": {"hostkey_size": 256}, "ssh-ed25519-cert-v01@openssh.com": {"ca_key_size": 256, "ca_key_type": "ssh-ed25519", "hostkey_size": 256}}, 'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 3072}, 'server_policy': True},
|
||||||
|
|
||||||
|
'Hardened OpenSSH Server v9.9 (version 1)': {'version': '1', 'changelog': 'Initial version.', 'banner': None, 'compressions': None, 'host_keys': ['rsa-sha2-512', 'rsa-sha2-256', 'ssh-ed25519'], 'optional_host_keys': ['sk-ssh-ed25519@openssh.com', 'ssh-ed25519-cert-v01@openssh.com', 'sk-ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['sntrup761x25519-sha512', 'sntrup761x25519-sha512@openssh.com', 'mlkem768x25519-sha256', 'curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256', 'ext-info-s', 'kex-strict-s-v00@openssh.com'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@openssh.com'], 'hostkey_sizes': {"rsa-sha2-256": {"hostkey_size": 4096}, "rsa-sha2-256-cert-v01@openssh.com": {"ca_key_size": 4096, "ca_key_type": "ssh-rsa", "hostkey_size": 4096}, "rsa-sha2-512": {"hostkey_size": 4096}, "rsa-sha2-512-cert-v01@openssh.com": {"ca_key_size": 4096, "ca_key_type": "ssh-rsa", "hostkey_size": 4096}, "sk-ssh-ed25519-cert-v01@openssh.com": {"ca_key_size": 256, "ca_key_type": "ssh-ed25519", "hostkey_size": 256}, "sk-ssh-ed25519@openssh.com": {"hostkey_size": 256}, "ssh-ed25519": {"hostkey_size": 256}, "ssh-ed25519-cert-v01@openssh.com": {"ca_key_size": 256, "ca_key_type": "ssh-ed25519", "hostkey_size": 256}}, 'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 3072}, 'server_policy': True},
|
||||||
|
|
||||||
# Amazon Linux Policies
|
# Amazon Linux Policies
|
||||||
|
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ def usage(uout: OutputBuffer, err: Optional[str] = None) -> None:
|
|||||||
uout.info(' -P, --policy=<policy.txt> run a policy test using the specified policy')
|
uout.info(' -P, --policy=<policy.txt> run a policy test using the specified policy')
|
||||||
uout.info(' --skip-rate-test skip the connection rate test during standard audits\n (used to safely infer whether the DHEat attack\n is viable)')
|
uout.info(' --skip-rate-test skip the connection rate test during standard audits\n (used to safely infer whether the DHEat attack\n is viable)')
|
||||||
uout.info(' -t, --timeout=<secs> timeout (in seconds) for connection and reading\n (default: 5)')
|
uout.info(' -t, --timeout=<secs> timeout (in seconds) for connection and reading\n (default: 5)')
|
||||||
uout.info(' -T, --targets=<hosts.txt> a file containing a list of target hosts (one\n per line, format HOST[:PORT]). Use --threads\n to control concurrent scans.')
|
uout.info(' -T, --targets=<hosts.txt> a file containing a list of target hosts (one\n per line, format HOST[:PORT]). Use -p/--port\n to set the default port for all hosts. Use\n --threads to control concurrent scans.')
|
||||||
uout.info(' --threads=<threads> number of threads to use when scanning multiple\n targets (-T/--targets) (default: 32)')
|
uout.info(' --threads=<threads> number of threads to use when scanning multiple\n targets (-T/--targets) (default: 32)')
|
||||||
uout.info(' -v, --verbose verbose output')
|
uout.info(' -v, --verbose verbose output')
|
||||||
uout.sep()
|
uout.sep()
|
||||||
@@ -1587,10 +1587,10 @@ def main() -> int:
|
|||||||
if aconf.json:
|
if aconf.json:
|
||||||
print('[', end='')
|
print('[', end='')
|
||||||
|
|
||||||
# Loop through each target in the list.
|
# Loop through each target in the list. Entries can specify a port number to use, otherwise the value provided on the command line (--port=N) will be used by default (set to 22 if --port is not used).
|
||||||
target_servers = []
|
target_servers = []
|
||||||
for _, target in enumerate(aconf.target_list):
|
for _, target in enumerate(aconf.target_list):
|
||||||
host, port = Utils.parse_host_and_port(target, default_port=22)
|
host, port = Utils.parse_host_and_port(target, default_port=aconf.port)
|
||||||
target_servers.append((host, port))
|
target_servers.append((host, port))
|
||||||
|
|
||||||
# A ranked list of return codes. Those with higher indices will take precedence over lower ones. For example, if three servers are scanned, yielding WARNING, GOOD, and UNKNOWN_ERROR, the overall result will be UNKNOWN_ERROR, since its index is the highest. Errors have highest priority, followed by failures, then warnings.
|
# A ranked list of return codes. Those with higher indices will take precedence over lower ones. For example, if three servers are scanned, yielding WARNING, GOOD, and UNKNOWN_ERROR, the overall result will be UNKNOWN_ERROR, since its index is the highest. Errors have highest priority, followed by failures, then warnings.
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ class SSH_Socket(ReadBuf, WriteBuf):
|
|||||||
s.listen()
|
s.listen()
|
||||||
self.__sock_map[s.fileno()] = s
|
self.__sock_map[s.fileno()] = s
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("Warning: failed to listen on any IPv4 interfaces: %s" % str(e))
|
print("Warning: failed to listen on any IPv4 interfaces: %s" % str(e), file=sys.stderr)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Socket to listen on all IPv6 addresses.
|
# Socket to listen on all IPv6 addresses.
|
||||||
@@ -119,11 +119,11 @@ class SSH_Socket(ReadBuf, WriteBuf):
|
|||||||
s.listen()
|
s.listen()
|
||||||
self.__sock_map[s.fileno()] = s
|
self.__sock_map[s.fileno()] = s
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("Warning: failed to listen on any IPv6 interfaces: %s" % str(e))
|
print("Warning: failed to listen on any IPv6 interfaces: %s" % str(e), file=sys.stderr)
|
||||||
|
|
||||||
# If we failed to listen on any interfaces, terminate.
|
# If we failed to listen on any interfaces, terminate.
|
||||||
if len(self.__sock_map.keys()) == 0:
|
if len(self.__sock_map.keys()) == 0:
|
||||||
print("Error: failed to listen on any IPv4 and IPv6 interfaces!")
|
print("Error: failed to listen on any IPv4 and IPv6 interfaces!", file=sys.stderr)
|
||||||
sys.exit(exitcodes.CONNECTION_ERROR)
|
sys.exit(exitcodes.CONNECTION_ERROR)
|
||||||
|
|
||||||
# Wait for an incoming connection. If a timeout was explicitly
|
# Wait for an incoming connection. If a timeout was explicitly
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ class VersionVulnerabilityDB: # pylint: disable=too-few-public-methods
|
|||||||
# then affected = 1 + 4 = 5.
|
# then affected = 1 + 4 = 5.
|
||||||
CVE: Dict[str, List[List[Any]]] = {
|
CVE: Dict[str, List[List[Any]]] = {
|
||||||
'Dropbear SSH': [
|
'Dropbear SSH': [
|
||||||
|
['0.0', '2022.83', 1, 'CVE-2023-48795', 5.9, 'Terrapin attack allows bypassing integrity checks in SSH protocol'],
|
||||||
['0.0', '2020.81', 2, 'CVE-2021-36369', 7.5, 'trivial authentication attack to bypass FIDO tokens and SSH-ASKPASS'],
|
['0.0', '2020.81', 2, 'CVE-2021-36369', 7.5, 'trivial authentication attack to bypass FIDO tokens and SSH-ASKPASS'],
|
||||||
['0.0', '2018.76', 1, 'CVE-2018-15599', 5.0, 'remote users may enumerate users on the system'],
|
['0.0', '2018.76', 1, 'CVE-2018-15599', 5.0, 'remote users may enumerate users on the system'],
|
||||||
['0.0', '2017.74', 5, 'CVE-2017-9079', 4.7, 'local users can read certain files as root'],
|
['0.0', '2017.74', 5, 'CVE-2017-9079', 4.7, 'local users can read certain files as root'],
|
||||||
@@ -67,6 +68,13 @@ class VersionVulnerabilityDB: # pylint: disable=too-few-public-methods
|
|||||||
['0.4.7', '0.5.2', 1, 'CVE-2012-4560', 7.5, 'cause DoS or execute arbitrary code (buffer overflow)'],
|
['0.4.7', '0.5.2', 1, 'CVE-2012-4560', 7.5, 'cause DoS or execute arbitrary code (buffer overflow)'],
|
||||||
['0.4.7', '0.5.2', 1, 'CVE-2012-4559', 6.8, 'cause DoS or execute arbitrary code (double free)']],
|
['0.4.7', '0.5.2', 1, 'CVE-2012-4559', 6.8, 'cause DoS or execute arbitrary code (double free)']],
|
||||||
'OpenSSH': [
|
'OpenSSH': [
|
||||||
|
['1.0', '9.6', 1, 'CVE-2023-51767', 7.0, 'Row hammer threat allows authentication bypass in shared DRAM'],
|
||||||
|
['1.0', '9.5', 2, 'CVE-2023-51385', 7.0, 'OS command injection through expansion tokens containing shell metacharacters'],
|
||||||
|
['1.0', '9.5', 2, 'CVE-2023-51384', 5.5, 'ssh-agent applies destination constraints only to the first PKCS#11 key'],
|
||||||
|
['1.0', '9.5', 1, 'CVE-2023-48795', 5.9, 'Terrapin attack allows bypassing integrity checks in SSH protocol'],
|
||||||
|
['1.0', '9.2', 1, 'CVE-2023-38408', 9.8, 'PKCS#11 feature has a vulnerable search path in ssh-agent, enabling remote code execution'],
|
||||||
|
['8.9', '9.2', 1, 'CVE-2023-28531', 9.8, 'ssh-add improperly adds smartcard keys to ssh-agent, bypassing intended destination restrictions'],
|
||||||
|
['9.1', '9.1', 1, 'CVE-2023-25136', 6.5, 'A double-free vulnerability allows unauthenticated remote attackers to potentially execute code by manipulating memory'],
|
||||||
['6.2', '8.7', 5, 'CVE-2021-41617', 7.0, 'privilege escalation via supplemental groups'],
|
['6.2', '8.7', 5, 'CVE-2021-41617', 7.0, 'privilege escalation via supplemental groups'],
|
||||||
['1.0', '8.8', 2, 'CVE-2021-36368', 3.7, 'trivial authentication attack to bypass FIDO tokens and SSH-ASKPASS'],
|
['1.0', '8.8', 2, 'CVE-2021-36368', 3.7, 'trivial authentication attack to bypass FIDO tokens and SSH-ASKPASS'],
|
||||||
['8.2', '8.4', 2, 'CVE-2021-28041', 7.1, 'double free via ssh-agent'],
|
['8.2', '8.4', 2, 'CVE-2021-28041', 7.1, 'double free via ssh-agent'],
|
||||||
@@ -140,6 +148,8 @@ class VersionVulnerabilityDB: # pylint: disable=too-few-public-methods
|
|||||||
['1.2.3', '2.1.1', 1, 'CVE-2001-0361', 4.0, 'recover plaintext from ciphertext'],
|
['1.2.3', '2.1.1', 1, 'CVE-2001-0361', 4.0, 'recover plaintext from ciphertext'],
|
||||||
['1.2', '2.1', 1, 'CVE-2000-0525', 10.0, 'execute arbitrary code (improper privileges)']],
|
['1.2', '2.1', 1, 'CVE-2000-0525', 10.0, 'execute arbitrary code (improper privileges)']],
|
||||||
'PuTTY': [
|
'PuTTY': [
|
||||||
|
['0.68', '0.80', 2, 'CVE-2024-31497', 0.0, 'ecdsa private key recovery by malicious remote server'],
|
||||||
|
['0.0', '0.79', 2, 'CVE-2023-48795', 5.9, 'Terrapin attack allows bypassing integrity checks in SSH protocol'],
|
||||||
# info for CVE-2021-36367 - only PuTTY up to 0.71 is affected - see https://www.chiark.greenend.org.uk/~sgtatham/putty/wishlist/reject-trivial-auth.html
|
# info for CVE-2021-36367 - only PuTTY up to 0.71 is affected - see https://www.chiark.greenend.org.uk/~sgtatham/putty/wishlist/reject-trivial-auth.html
|
||||||
['0.0', '0.71', 2, 'CVE-2021-36367', 8.1, 'trivial authentication attack to bypass FIDO tokens and SSH-ASKPASS'],
|
['0.0', '0.71', 2, 'CVE-2021-36367', 8.1, 'trivial authentication attack to bypass FIDO tokens and SSH-ASKPASS'],
|
||||||
['0.0', '0.74', 2, 'CVE-2021-33500', 5.0, 'denial of service of the complete windows desktop'],
|
['0.0', '0.74', 2, 'CVE-2021-33500', 5.0, 'denial of service of the complete windows desktop'],
|
||||||
|
|||||||
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
.TH SSH-AUDIT 1 "April 18, 2024"
|
.TH SSH-AUDIT 1 "September 24, 2024"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
\fBssh-audit\fP \- SSH server & client configuration auditor
|
\fBssh-audit\fP \- SSH server & client configuration auditor
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -149,7 +149,7 @@ The timeout, in seconds, for creating connections and reading data from the sock
|
|||||||
.TP
|
.TP
|
||||||
.B -T, \-\-targets=<hosts.txt>
|
.B -T, \-\-targets=<hosts.txt>
|
||||||
.br
|
.br
|
||||||
A file containing a list of target hosts. Each line must have one host, in the format of HOST[:PORT]. Use --threads to control concurrent scans.
|
A file containing a list of target hosts. Each line must have one host, in the format of HOST[:PORT]. Use -p/--port to set the default port for all hosts. Use --threads to control concurrent scans.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B \-\-threads=<threads>
|
.B \-\-threads=<threads>
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ disable =
|
|||||||
too-many-lines,
|
too-many-lines,
|
||||||
too-many-locals,
|
too-many-locals,
|
||||||
too-many-nested-blocks,
|
too-many-nested-blocks,
|
||||||
|
too-many-positional-arguments,
|
||||||
too-many-return-statements,
|
too-many-return-statements,
|
||||||
too-many-statements,
|
too-many-statements,
|
||||||
consider-using-f-string
|
consider-using-f-string
|
||||||
|
|||||||
Reference in New Issue
Block a user