mirror of https://github.com/jtesta/ssh-audit.git
Compare commits
5 Commits
3c459f1428
...
d19b154a46
Author | SHA1 | Date |
---|---|---|
Joe Testa | d19b154a46 | |
Joe Testa | c5d90106e8 | |
Joe Testa | 68cf05d0ff | |
Joe Testa | 2d9ddabcad | |
Joe Testa | 986f83653d |
10
README.md
10
README.md
|
@ -202,7 +202,7 @@ To install from Dockerhub:
|
|||
```
|
||||
$ docker pull positronsecurity/ssh-audit
|
||||
```
|
||||
(Then run with: `docker run -it -p 2222:2222 positronsecurity/ssh-audit 10.1.1.1`)
|
||||
(Then run with: `docker run -it --rm -p 2222:2222 positronsecurity/ssh-audit 10.1.1.1`)
|
||||
|
||||
The status of various other platform packages can be found below (via Repology):
|
||||
|
||||
|
@ -213,19 +213,19 @@ For convenience, a web front-end on top of the command-line tool is available at
|
|||
|
||||
## ChangeLog
|
||||
|
||||
### v3.2.0-dev (???)
|
||||
### v3.2.0 (2024-04-22)
|
||||
- Added implementation of the DHEat denial-of-service attack (see `--dheat` option; [CVE-2002-20001](https://nvd.nist.gov/vuln/detail/CVE-2002-20001)).
|
||||
- Expanded filter of CBC ciphers to flag for the Terrapin vulnerability. It now includes more rarely found ciphers.
|
||||
- Color output is disabled if the `NO_COLOR` environment variable is set (see https://no-color.org/).
|
||||
- Fixed parsing of `ecdsa-sha2-nistp*` CA signatures on host keys. Additionally, they are now flagged as potentially back-doored, just as standard host keys are.
|
||||
- Gracefully handle rare exceptions (i.e.: crashes) while performing GEX tests.
|
||||
- Built-in policies now include a change log (use `-L -v` to view them).
|
||||
- Added built-in policies for Amazon Linux 2023, Debian 12, OpenSSH 9.7, and Rocky Linux 9.
|
||||
- The built-in man page (`-m`, `--manual`) is now available on Docker, PyPI, and Snap builds, in addition to the Windows build.
|
||||
- Snap builds are now architecture-independent.
|
||||
- Changed Docker base image from `python:3-slim` to `python:3-alpine`, resulting in a 59% reduction in image size; credit [Daniel Thamdrup](https://github.com/dallemon).
|
||||
- Added built-in policies for Amazon Linux 2023, Debian 12, OpenSSH 9.7, and Rocky Linux 9.
|
||||
- Built-in policies now include a change log (use `-L -v` to view them).
|
||||
- Custom policies now support the `allow_algorithm_subset_and_reordering` directive to allow targets to pass with a subset and/or re-ordered list of host keys, kex, ciphers, and MACs. This allows for the creation of a baseline policy where targets can optionally implement stricter controls; partial credit [yannik1015](https://github.com/yannik1015).
|
||||
- Custom policies now support the `allow_larger_keys` directive to allow targets to pass with larger host keys, CA keys, and Diffie-Hellman keys. This allows for the creation of a baseline policy where targets can optionally implement stricter controls; partial credit [Damian Szuberski](https://github.com/szubersk).
|
||||
- Color output is disabled if the `NO_COLOR` environment variable is set (see https://no-color.org/).
|
||||
- Added 1 new key exchange algorithm: `gss-nistp384-sha384-*`.
|
||||
- Added 1 new cipher: `aes128-ocb@libassh.org`.
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ class DHEat:
|
|||
MAX_SAFE_RATE = 20.0
|
||||
|
||||
# The warning added to DH algorithms in the UI when dh_rate_test determines that no throttling is being done.
|
||||
DHEAT_WARNING = "Potentially insufficient connection throttling detected, resulting in possible vulnerability to the DHEat DoS attack (CVE-2002-20001). {connections:d} connections were created in {time_elapsed:.3f} seconds, or {rate:.1f} conns/sec; server must respond with a rate less than {max_safe_rate:.1f} conns/sec per IPv4/IPv6 source address to be considered safe. For rate-throttling options, please see <https://www.ssh-audit.com/hardening_guides.html>. Suppress this test and message with the --skip-rate-test option."
|
||||
DHEAT_WARNING = "Potentially insufficient connection throttling detected, resulting in possible vulnerability to the DHEat DoS attack (CVE-2002-20001). {connections:d} connections were created in {time_elapsed:.3f} seconds, or {rate:.1f} conns/sec; server must respond with a rate less than {max_safe_rate:.1f} conns/sec per IPv4/IPv6 source address to be considered safe. For rate-throttling options, please see <https://www.ssh-audit.com/hardening_guides.html>. Be aware that using 'PerSourceMaxStartups 1' properly protects the server from this attack, but will cause this test to yield a false positive. Suppress this test and message with the --skip-rate-test option."
|
||||
|
||||
# List of the Diffie-Hellman group exchange algorithms this test supports.
|
||||
gex_algs = [
|
||||
|
@ -329,6 +329,7 @@ class DHEat:
|
|||
|
||||
# If the user passed --conn-rate-test, then we'll perform an interactive rate test against the target.
|
||||
interactive = False
|
||||
multiline_output = False
|
||||
if aconf.conn_rate_test_enabled:
|
||||
interactive = True
|
||||
max_connections = 999999999999999999
|
||||
|
@ -338,6 +339,11 @@ class DHEat:
|
|||
DHEat.WHITEB = "\033[1;97m"
|
||||
DHEat.BLUEB = "\033[1;94m"
|
||||
|
||||
# Enable multi-line output only if we're running in the Bash shell. This might work in other shells, too, but they are untested.
|
||||
shell = os.getenv("SHELL", default="")
|
||||
if shell.endswith("/bash") or shell == "bash":
|
||||
multiline_output = True
|
||||
|
||||
rate_str = ""
|
||||
if aconf.conn_rate_test_target_rate > 0:
|
||||
rate_str = " at a max rate of %s%u%s connections per second" % (DHEat.WHITEB, aconf.conn_rate_test_target_rate, DHEat.CLEAR)
|
||||
|
@ -346,6 +352,10 @@ class DHEat:
|
|||
print("Performing non-disruptive rate test against %s[%s]:%u%s with %s%u%s concurrent sockets%s. No Diffie-Hellman requests will be sent." % (DHEat.WHITEB, aconf.host, aconf.port, DHEat.CLEAR, DHEat.WHITEB, concurrent_sockets, DHEat.CLEAR, rate_str))
|
||||
print()
|
||||
|
||||
# Make room for the multi-line output.
|
||||
if multiline_output:
|
||||
print("\n\n\n\n")
|
||||
|
||||
else: # We'll do a non-interactive test as part of a standard audit.
|
||||
# Ensure that the server supports at least one DH algorithm. Otherwise, this test is pointless.
|
||||
server_dh_kex = []
|
||||
|
@ -361,6 +371,7 @@ class DHEat:
|
|||
|
||||
num_attempted_connections = 0
|
||||
num_opened_connections = 0
|
||||
num_exceeded_maxstartups = 0
|
||||
socket_dict: Dict[socket.socket, float] = {}
|
||||
start_timer = time.time()
|
||||
now = start_timer
|
||||
|
@ -378,7 +389,14 @@ class DHEat:
|
|||
if interactive:
|
||||
if (now - last_update) >= 1.0:
|
||||
seconds_running = now - start_timer
|
||||
print("%s%s%s Run time: %s%.1f%s; TCP SYNs: %s%u%s; Compl. conns: %s%u%s; TCP SYNs/sec: %s%.1f%s; Compl. conns/sec: %s%.1f%s \r" % (DHEat.WHITEB, spinner[spinner_index], DHEat.CLEAR, DHEat.WHITEB, seconds_running, DHEat.CLEAR, DHEat.WHITEB, num_attempted_connections, DHEat.CLEAR, DHEat.WHITEB, num_opened_connections, DHEat.CLEAR, DHEat.BLUEB, num_attempted_connections / seconds_running, DHEat.CLEAR, DHEat.BLUEB, num_opened_connections / seconds_running, DHEat.CLEAR), end="")
|
||||
if multiline_output:
|
||||
print("\033[5ARun time: %s%.1f%s seconds" % (DHEat.WHITEB, seconds_running, DHEat.CLEAR))
|
||||
print("TCP SYNs: %s%u%s (total); %s%.1f%s (per second)" % (DHEat.WHITEB, num_attempted_connections, DHEat.CLEAR, DHEat.BLUEB, num_attempted_connections / seconds_running, DHEat.CLEAR))
|
||||
print("Completed connections: %s%u%s (total); %s%.1f%s (per second)" % (DHEat.WHITEB, num_opened_connections, DHEat.CLEAR, DHEat.BLUEB, num_opened_connections / seconds_running, DHEat.CLEAR))
|
||||
print("\"Exceeded MaxStartups\" responses: %s%u%s (total); %s%.1f%s (per second)" % (DHEat.WHITEB, num_exceeded_maxstartups, DHEat.CLEAR, DHEat.BLUEB, num_exceeded_maxstartups / seconds_running, DHEat.CLEAR))
|
||||
print("%s%s%s" % (DHEat.WHITEB, spinner[spinner_index], DHEat.CLEAR))
|
||||
else:
|
||||
print("%s%s%s Run time: %s%.1f%s; TCP SYNs: %s%u%s; Compl. conns: %s%u%s; TCP SYNs/sec: %s%.1f%s; Compl. conns/sec: %s%.1f%s \r" % (DHEat.WHITEB, spinner[spinner_index], DHEat.CLEAR, DHEat.WHITEB, seconds_running, DHEat.CLEAR, DHEat.WHITEB, num_attempted_connections, DHEat.CLEAR, DHEat.WHITEB, num_opened_connections, DHEat.CLEAR, DHEat.BLUEB, num_attempted_connections / seconds_running, DHEat.CLEAR, DHEat.BLUEB, num_opened_connections / seconds_running, DHEat.CLEAR), end="")
|
||||
last_update = now
|
||||
spinner_index = (spinner_index + 1) % 4
|
||||
|
||||
|
@ -438,7 +456,10 @@ class DHEat:
|
|||
# If we received the SSH header, we'll count this as an opened connection.
|
||||
if buf.startswith(b"SSH-"):
|
||||
num_opened_connections += 1
|
||||
out.d("Number of opened connections: %u (max: %u)." % (num_opened_connections, max_connections))
|
||||
# out.d("Number of opened connections: %u (max: %u)." % (num_opened_connections, max_connections))
|
||||
elif buf == b"Exceeded":
|
||||
num_exceeded_maxstartups += 1
|
||||
# out.d("Number of \"Exceeded MaxStartups\": %u" % num_exceeded_maxstartups)
|
||||
|
||||
_close_socket(socket_dict, s)
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"""
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (C) 2017-2023 Joe Testa (jtesta@positronsecurity.com)
|
||||
Copyright (C) 2017-2024 Joe Testa (jtesta@positronsecurity.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -22,7 +22,7 @@
|
|||
THE SOFTWARE.
|
||||
"""
|
||||
# The version to display.
|
||||
VERSION = 'v3.2.0-dev'
|
||||
VERSION = 'v3.3.0-dev'
|
||||
|
||||
# SSH software to impersonate
|
||||
SSH_HEADER = 'SSH-{0}-OpenSSH_8.2'
|
||||
|
|
Loading…
Reference in New Issue