mirror of
https://github.com/jtesta/ssh-audit.git
synced 2025-04-05 05:00:14 -05:00
Compare commits
57 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
e318787a5c | ||
![]() |
d9c703c777 | ||
![]() |
28a1e23986 | ||
![]() |
a01baadfa8 | ||
![]() |
45abc3aaf4 | ||
![]() |
99c64787d9 | ||
![]() |
3fa62c3ac5 | ||
![]() |
d7fff591fa | ||
![]() |
84647ecb32 | ||
![]() |
772204ce8b | ||
![]() |
c0133a8d5f | ||
![]() |
3220043aaf | ||
![]() |
40ed92bbe6 | ||
![]() |
720150b471 | ||
![]() |
d0628f6eb4 | ||
![]() |
1e060a94c0 | ||
![]() |
8563c2925b | ||
![]() |
556306be5e | ||
![]() |
7ab6d20454 | ||
![]() |
1f1a51d591 | ||
![]() |
77a63de133 | ||
![]() |
cffa126277 | ||
![]() |
dc615cef7f | ||
![]() |
cb6142c609 | ||
![]() |
629008e55e | ||
![]() |
016a5d89f7 | ||
![]() |
93b30b4258 | ||
![]() |
3b8a75e407 | ||
![]() |
67e11f82b3 | ||
![]() |
2cd96f1785 | ||
![]() |
a4b78b752e | ||
![]() |
ac540c8b5f | ||
![]() |
e11492b7a3 | ||
![]() |
02bc48c574 | ||
![]() |
24d7d46c42 | ||
![]() |
e97bbd9782 | ||
![]() |
6d57c7c0f7 | ||
![]() |
ea3258151e | ||
![]() |
f9032c8277 | ||
![]() |
d7398baad7 | ||
![]() |
4621d52223 | ||
![]() |
2a7cb13895 | ||
![]() |
06ebdbd0fe | ||
![]() |
7752023dc2 | ||
![]() |
a6f02ae8e8 | ||
![]() |
9049c8476a | ||
![]() |
bbbdf71e50 | ||
![]() |
92db5f0138 | ||
![]() |
bc2a89eb11 | ||
![]() |
ea117b203b | ||
![]() |
d8f8b7c57c | ||
![]() |
e42961fa9a | ||
![]() |
dcbc43acdf | ||
![]() |
87e22ae26b | ||
![]() |
46ec4e3edc | ||
![]() |
d19b154a46 | ||
![]() |
c5d90106e8 |
1
.github/FUNDING.yml
vendored
Normal file
1
.github/FUNDING.yml
vendored
Normal file
@ -0,0 +1 @@
|
||||
github: jtesta
|
12
.github/workflows/tox.yaml
vendored
12
.github/workflows/tox.yaml
vendored
@ -7,18 +7,18 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
|
||||
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v2
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -U codecov coveralls flake8 mypy pylint pytest tox
|
||||
python3 -m pip install --upgrade pip
|
||||
python3 -m pip install -U codecov coveralls flake8 mypy pylint pytest tox
|
||||
- name: Run Tox
|
||||
run: |
|
||||
tox
|
||||
python3 -m tox
|
||||
|
@ -11,7 +11,7 @@ However, if you can submit patches that pass all of our automated tests, then yo
|
||||
|
||||
[Tox](https://tox.wiki/) is used to automate testing. Linting is done with [pylint](http://pylint.pycqa.org/en/latest/) & [flake8](https://flake8.pycqa.org/en/latest/), and static type-checking is done with [mypy](https://mypy.readthedocs.io/en/stable/).
|
||||
|
||||
For Ubuntu systems, install tox with `apt install tox`, then simply run `tox` in the top-level directory. Look for any error messages in the (verbose) output.
|
||||
Install the required packages with `python3 -m pip install -U codecov coveralls flake8 mypy pylint pytest tox`, then run the tests with `python3 -m tox`. Look for any error messages in the (verbose) output.
|
||||
|
||||
|
||||
## Docker Tests
|
||||
|
18
PACKAGING.md
18
PACKAGING.md
@ -15,10 +15,10 @@ An executable can only be made on a Windows host because the PyInstaller tool (h
|
||||
|
||||
# PyPI
|
||||
|
||||
To create package and upload to test server (hint: use username '\_\_token\_\_' and API token for test.pypi.org):
|
||||
To create package and upload to test server (hint: use API token for test.pypi.org):
|
||||
|
||||
```
|
||||
$ sudo apt install python3-virtualenv python3.10-venv
|
||||
$ sudo apt install python3-virtualenv python3.12-venv
|
||||
$ make -f Makefile.pypi
|
||||
$ make -f Makefile.pypi uploadtest
|
||||
```
|
||||
@ -26,12 +26,12 @@ To create package and upload to test server (hint: use username '\_\_token\_\_'
|
||||
To download from test server and verify:
|
||||
|
||||
```
|
||||
$ virtualenv -p /usr/bin/python3 /tmp/pypi_test
|
||||
$ virtualenv /tmp/pypi_test
|
||||
$ cd /tmp/pypi_test; source bin/activate
|
||||
$ pip3 install --index-url https://test.pypi.org/simple ssh-audit
|
||||
```
|
||||
|
||||
To upload to production server (hint: use username '\_\_token\_\_' and API token for production pypi.org):
|
||||
To upload to production server (hint: use API token for production pypi.org):
|
||||
|
||||
```
|
||||
$ make -f Makefile.pypi uploadprod
|
||||
@ -40,7 +40,7 @@ To upload to production server (hint: use username '\_\_token\_\_' and API token
|
||||
To download from production server and verify:
|
||||
|
||||
```
|
||||
$ virtualenv -p /usr/bin/python3 /tmp/pypi_prod
|
||||
$ virtualenv /tmp/pypi_prod
|
||||
$ cd /tmp/pypi_prod; source bin/activate
|
||||
$ pip3 install ssh-audit
|
||||
```
|
||||
@ -48,14 +48,14 @@ To download from production server and verify:
|
||||
|
||||
# Snap
|
||||
|
||||
To create the snap package, run a fully-updated Ubuntu Server 22.04 VM.
|
||||
To create the Snap package, run a fully-updated Ubuntu Server 24.04 VM.
|
||||
|
||||
Create the snap package with:
|
||||
Create the Snap package with:
|
||||
```
|
||||
$ ./build_snap.sh
|
||||
```
|
||||
|
||||
Upload the snap with:
|
||||
Upload the Snap with:
|
||||
|
||||
```
|
||||
$ snapcraft export-login ~/snap_creds.txt
|
||||
@ -68,7 +68,7 @@ Upload the snap with:
|
||||
|
||||
# Docker
|
||||
|
||||
Ensure that the buildx plugin is available by following the installation instructions available at: https://docs.docker.com/engine/install/ubuntu/
|
||||
Ensure that the `buildx` plugin is available by following the installation instructions available at: https://docs.docker.com/engine/install/ubuntu/
|
||||
|
||||
Build a local image with:
|
||||
|
||||
|
149
README.md
149
README.md
@ -1,10 +1,15 @@
|
||||
# ssh-audit
|
||||
[](https://github.com/jtesta/ssh-audit/blob/master/LICENSE)
|
||||
[](https://pypi.org/project/ssh-audit/)
|
||||
[](https://hub.docker.com/r/positronsecurity/ssh-audit)
|
||||
[](https://github.com/jtesta/ssh-audit/actions)
|
||||
[](https://github.com/jtesta/ssh-audit/blob/master/CONTRIBUTING.md)
|
||||
|
||||
[](https://pypi.org/project/ssh-audit/)
|
||||
[](https://formulae.brew.sh/formula/ssh-audit)
|
||||
[](https://hub.docker.com/r/positronsecurity/ssh-audit)
|
||||
[](https://snapcraft.io/ssh-audit)
|
||||
|
||||
[](https://github.com/sponsors/jtesta)
|
||||
|
||||
**ssh-audit** is a tool for ssh server & client configuration auditing.
|
||||
|
||||
[jtesta/ssh-audit](https://github.com/jtesta/ssh-audit/) (v2.0+) is the updated and maintained version of ssh-audit forked from [arthepsy/ssh-audit](https://github.com/arthepsy/ssh-audit) (v1.x) due to inactivity.
|
||||
@ -25,74 +30,72 @@
|
||||
- analyze SSH client configuration;
|
||||
- grab banner, recognize device or software and operating system, detect compression;
|
||||
- gather key-exchange, host-key, encryption and message authentication code algorithms;
|
||||
- output algorithm information (available since, removed/disabled, unsafe/weak/legacy, etc);
|
||||
- output algorithm security information (available since, removed/disabled, unsafe/weak/legacy, etc);
|
||||
- output algorithm recommendations (append or remove based on recognized software version);
|
||||
- output security information (related issues, assigned CVE list, etc);
|
||||
- analyze SSH version compatibility based on algorithm information;
|
||||
- historical information from OpenSSH, Dropbear SSH and libssh;
|
||||
- policy scans to ensure adherence to a hardened/standard configuration;
|
||||
- runs on Linux and Windows;
|
||||
- supports Python 3.8 - 3.12;
|
||||
- supports Python 3.8 - 3.13;
|
||||
- no dependencies
|
||||
|
||||
## Usage
|
||||
```
|
||||
usage: ssh-audit.py [options] <host>
|
||||
usage: ssh-audit.py [-h] [-1] [-2] [-4] [-6] [-b] [-c] [-d]
|
||||
[-g <min1:pref1:max1[,min2:pref2:max2,...]> / <x-y[:step]>] [-j] [-l {info,warn,fail}] [-L]
|
||||
[-M custom_policy.txt] [-m] [-n] [-P "Built-In Policy Name" / custom_policy.txt] [-p N]
|
||||
[-T targets.txt] [-t N] [-v] [--conn-rate-test N[:max_rate]] [--dheat N[:kex[:e_len]]]
|
||||
[--lookup alg1[,alg2,...]] [--skip-rate-test] [--threads N]
|
||||
[host]
|
||||
|
||||
-h, --help print this help
|
||||
-1, --ssh1 force ssh version 1 only
|
||||
-2, --ssh2 force ssh version 2 only
|
||||
-4, --ipv4 enable IPv4 (order of precedence)
|
||||
-6, --ipv6 enable IPv6 (order of precedence)
|
||||
-b, --batch batch output
|
||||
-c, --client-audit starts a server on port 2222 to audit client
|
||||
software config (use -p to change port;
|
||||
use -t to change timeout)
|
||||
--conn-rate-test=N[:max_rate] perform a connection rate test (useful
|
||||
for collecting metrics related to
|
||||
susceptibility of the DHEat vuln).
|
||||
Testing is conducted with N concurrent
|
||||
sockets with an optional maximum rate
|
||||
of connections per second.
|
||||
-d, --debug Enable debug output.
|
||||
--dheat=N[:kex[:e_len]] continuously perform the DHEat DoS attack
|
||||
(CVE-2002-20001) against the target using N
|
||||
concurrent sockets. Optionally, a specific
|
||||
key exchange algorithm can be specified
|
||||
instead of allowing it to be automatically
|
||||
chosen. Additionally, a small length of
|
||||
the fake e value sent to the server can
|
||||
be chosen for a more efficient attack (such
|
||||
as 4).
|
||||
-g, --gex-test=<x[,y,...]> dh gex modulus size test
|
||||
<min1:pref1:max1[,min2:pref2:max2,...]>
|
||||
<x-y[:step]>
|
||||
-j, --json JSON output (use -jj to enable indents)
|
||||
-l, --level=<level> minimum output level (info|warn|fail)
|
||||
-L, --list-policies list all the official, built-in policies. Use with -v
|
||||
to view policy change logs.
|
||||
--lookup=<alg1,alg2,...> looks up an algorithm(s) without
|
||||
connecting to a server
|
||||
-m, --manual print the man page (Docker, PyPI, Snap, and Windows
|
||||
builds only)
|
||||
-M, --make-policy=<policy.txt> creates a policy based on the target server
|
||||
(i.e.: the target server has the ideal
|
||||
configuration that other servers should
|
||||
adhere to)
|
||||
-n, --no-colors disable colors
|
||||
-p, --port=<port> port to connect
|
||||
-P, --policy=<"policy name" | policy.txt> run a policy test using the
|
||||
specified policy
|
||||
--skip-rate-test skip the connection rate test during standard audits
|
||||
(used to safely infer whether the DHEat attack
|
||||
is viable)
|
||||
-t, --timeout=<secs> timeout (in seconds) for connection and reading
|
||||
(default: 5)
|
||||
-T, --targets=<hosts.txt> a file containing a list of target hosts (one
|
||||
per line, format HOST[:PORT])
|
||||
--threads=<threads> number of threads to use when scanning multiple
|
||||
targets (-T/--targets) (default: 32)
|
||||
-v, --verbose verbose output
|
||||
positional arguments:
|
||||
host target hostname or IPv4/IPv6 address
|
||||
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
-1, --ssh1 force ssh version 1 only
|
||||
-2, --ssh2 force ssh version 2 only
|
||||
-4, --ipv4 enable IPv4 (order of precedence)
|
||||
-6, --ipv6 enable IPv6 (order of precedence)
|
||||
-b, --batch batch output
|
||||
-c, --client-audit starts a server on port 2222 to audit client software config (use -p to change port; use -t
|
||||
to change timeout)
|
||||
-d, --debug enable debugging output
|
||||
-g <min1:pref1:max1[,min2:pref2:max2,...]> / <x-y[:step]>, --gex-test <min1:pref1:max1[,min2:pref2:max2,...]> / <x-y[:step]>
|
||||
conducts a very customized Diffie-Hellman GEX modulus size test. Tests an array of minimum,
|
||||
preferred, and maximum values, or a range of values with an optional incremental step amount
|
||||
-j, --json enable JSON output (use -jj to enable indentation for better readability)
|
||||
-l {info,warn,fail}, --level {info,warn,fail}
|
||||
minimum output level (default: info)
|
||||
-L, --list-policies list all the official, built-in policies. Combine with -v to view policy change logs
|
||||
-M custom_policy.txt, --make-policy custom_policy.txt
|
||||
creates a policy based on the target server (i.e.: the target server has the ideal
|
||||
configuration that other servers should adhere to), and stores it in the file path specified
|
||||
-m, --manual print the man page (Docker, PyPI, Snap, and Windows builds only)
|
||||
-n, --no-colors disable colors (automatic when the NO_COLOR environment variable is set)
|
||||
-P "Built-In Policy Name" / custom_policy.txt, --policy "Built-In Policy Name" / custom_policy.txt
|
||||
run a policy test using the specified policy (use -L to see built-in policies, or specify
|
||||
filesystem path to custom policy created by -M)
|
||||
-p N, --port N the TCP port to connect to (or to listen on when -c is used)
|
||||
-T targets.txt, --targets targets.txt
|
||||
a file containing a list of target hosts (one per line, format HOST[:PORT]). Use -p/--port
|
||||
to set the default port for all hosts. Use --threads to control concurrent scans
|
||||
-t N, --timeout N timeout (in seconds) for connection and reading (default: 5)
|
||||
-v, --verbose enable verbose output
|
||||
--conn-rate-test N[:max_rate]
|
||||
perform a connection rate test (useful for collecting metrics related to susceptibility of
|
||||
the DHEat vuln). Testing is conducted with N concurrent sockets with an optional maximum
|
||||
rate of connections per second
|
||||
--dheat N[:kex[:e_len]]
|
||||
continuously perform the DHEat DoS attack (CVE-2002-20001) against the target using N
|
||||
concurrent sockets. Optionally, a specific key exchange algorithm can be specified instead
|
||||
of allowing it to be automatically chosen. Additionally, a small length of the fake e value
|
||||
sent to the server can be chosen for a more efficient attack (such as 4).
|
||||
--lookup alg1[,alg2,...]
|
||||
looks up an algorithm(s) without connecting to a server.
|
||||
--skip-rate-test skip the connection rate test during standard audits (used to safely infer whether the DHEat
|
||||
attack is viable)
|
||||
--threads N number of threads to use when scanning multiple targets (-T/--targets) (default: 32)
|
||||
```
|
||||
* if both IPv4 and IPv6 are used, order of precedence can be set by using either `-46` or `-64`.
|
||||
* batch flag `-b` will output sections without header and without empty lines (implies verbose flag).
|
||||
@ -202,7 +205,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,6 +216,30 @@ For convenience, a web front-end on top of the command-line tool is available at
|
||||
|
||||
## ChangeLog
|
||||
|
||||
### v3.4.0-dev
|
||||
- Added warning to all key exchanges that do not include protections against quantum attacks due to the Harvest Now, Decrypt Later strategy (see https://en.wikipedia.org/wiki/Harvest_now,_decrypt_later).
|
||||
- Migrated from deprecated `getopt` module to `argparse`; partial credit [oam7575](https://github.com/oam7575).
|
||||
- When running against multiple hosts, now prints each target host regardless of output level.
|
||||
- Batch mode (`-b`) no longer automatically enables verbose mode, due to sometimes confusing results; users can still explicitly enable verbose mode using the `-v` flag.
|
||||
|
||||
### v3.3.0 (2024-10-15)
|
||||
- Added Python 3.13 support.
|
||||
- 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 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).
|
||||
- Now reports ECDSA and DSS fingerprints when in verbose mode; partial credit [Daniel Lenski](https://github.com/dlenskiSB).
|
||||
- Removed CVE information based on server/client version numbers, as this was wildly inaccurate (see [this thread](https://github.com/jtesta/ssh-audit/issues/240) for the full discussion, as well as the results of the community vote on this matter).
|
||||
- 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 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.
|
||||
- Fixed `--conn-rate-test` feature on Windows.
|
||||
- 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.
|
||||
- Updated built-in server & client policies for Amazon Linux 2023, Debian 12, Rocky Linux 9, and Ubuntu 22.04 to improve host key efficiency and cipher resistance to quantum attacks.
|
||||
- Added 1 new cipher: `grasshopper-ctr128`.
|
||||
- Added 2 new key exchanges: `mlkem768x25519-sha256`, `sntrup761x25519-sha512`.
|
||||
|
||||
### 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.
|
||||
|
@ -111,18 +111,9 @@ echo "Processing man page at ${MAN_PAGE} and placing output into ${GLOBALS_PY}..
|
||||
# * 'MAN_KEEP_FORMATTING' preserves the backspace-overwrite sequence when
|
||||
# redirected to a file or a pipe.
|
||||
# * sed converts unicode hyphens into an ASCI equivalent.
|
||||
# * The 'ul' command converts the backspace-overwrite sequence to an ANSI
|
||||
# escape sequence. Not required under Cygwin because man outputs ANSI escape
|
||||
# codes automatically.
|
||||
|
||||
echo BUILTIN_MAN_PAGE = '"""' >> "${GLOBALS_PY}"
|
||||
|
||||
if [[ "${PLATFORM}" == CYGWIN* ]]; then
|
||||
MANWIDTH=80 MAN_KEEP_FORMATTING=1 man "${MAN_PAGE}" | sed $'s/\u2010/-/g' >> "${GLOBALS_PY}"
|
||||
else
|
||||
MANWIDTH=80 MAN_KEEP_FORMATTING=1 man "${MAN_PAGE}" | ul | sed $'s/\u2010/-/g' >> "${GLOBALS_PY}"
|
||||
fi
|
||||
|
||||
MANWIDTH=80 MAN_KEEP_FORMATTING=1 man "${MAN_PAGE}" | sed $'s/\u2010/-/g' >> "${GLOBALS_PY}"
|
||||
echo '"""' >> "${GLOBALS_PY}"
|
||||
|
||||
echo "Done."
|
||||
|
@ -24,6 +24,7 @@ classifiers =
|
||||
Programming Language :: Python :: 3.10
|
||||
Programming Language :: Python :: 3.11
|
||||
Programming Language :: Python :: 3.12
|
||||
Programming Language :: Python :: 3.13
|
||||
Programming Language :: Python :: Implementation :: CPython
|
||||
Programming Language :: Python :: Implementation :: PyPy
|
||||
Topic :: Security
|
||||
|
@ -172,8 +172,11 @@ class Algorithms:
|
||||
if fc > 0:
|
||||
faults += pow(10, 2 - i) * fc
|
||||
if n not in alg_list:
|
||||
# Don't recommend certificate or token types; these will only appear in the server's list if they are fully configured & functional on the server.
|
||||
if faults > 0 or (alg_type == 'key' and (('-cert-' in n) or (n.startswith('sk-')))) or empty_version:
|
||||
# Don't recommend certificate or token types; these will only appear in the server's list if they are fully configured & functional on the server. Also don't recommend 'ext-info-[cs]' nor 'kex-strict-[cs]-v00@openssh.com' key exchanges.
|
||||
if faults > 0 or \
|
||||
(alg_type == 'key' and (('-cert-' in n) or (n.startswith('sk-')))) or \
|
||||
(alg_type == 'kex' and (n.startswith('ext-info-') or n.startswith('kex-strict-'))) or \
|
||||
empty_version:
|
||||
continue
|
||||
rec[sshv][alg_type]['add'][n] = 0
|
||||
else:
|
||||
|
@ -30,14 +30,20 @@ BUILTIN_POLICIES: Dict[str, Dict[str, Union[Optional[str], Optional[List[str]],
|
||||
# Amazon Linux 2023
|
||||
'Hardened Amazon Linux 2023 (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', '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 Amazon Linux 2023 (version 2)': {'version': '2', 'changelog': 'Re-ordered host keys to prioritize ED25519 due to efficiency. Re-ordered cipher list to prioritize larger key sizes as a countermeasure to quantum attacks.', 'banner': None, 'compressions': None, 'host_keys': ['ssh-ed25519', 'rsa-sha2-512', 'rsa-sha2-256'], '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', 'kex-strict-s-v00@openssh.com'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-gcm@openssh.com', '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},
|
||||
|
||||
|
||||
# Debian Server 12
|
||||
'Hardened Debian 12 (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', '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 Debian 12 (version 2)': {'version': '2', 'changelog': 'Re-ordered host keys to prioritize ED25519 due to efficiency. Re-ordered cipher list to prioritize larger key sizes as a countermeasure to quantum attacks.', 'banner': None, 'compressions': None, 'host_keys': ['ssh-ed25519', 'rsa-sha2-512', 'rsa-sha2-256'], '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', 'kex-strict-s-v00@openssh.com'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-gcm@openssh.com', '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},
|
||||
|
||||
|
||||
# Rocky Linux 9
|
||||
'Hardened Rocky Linux 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@openssh.com', 'curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256', '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 Rocky Linux 9 (version 2)': {'version': '2', 'changelog': 'Re-ordered host keys to prioritize ED25519 due to efficiency. Re-ordered cipher list to prioritize larger key sizes as a countermeasure to quantum attacks.', 'banner': None, 'compressions': None, 'host_keys': ['ssh-ed25519', 'rsa-sha2-512', 'rsa-sha2-256'], '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', 'kex-strict-s-v00@openssh.com'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-gcm@openssh.com', '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},
|
||||
|
||||
|
||||
# Ubuntu Server policies
|
||||
|
||||
@ -49,6 +55,9 @@ BUILTIN_POLICIES: Dict[str, Dict[str, Union[Optional[str], Optional[List[str]],
|
||||
|
||||
'Hardened Ubuntu Server 22.04 LTS (version 5)': {'version': '5', 'changelog': 'Added kex-strict-s-v00@openssh.com to kex list.', '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', '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 Ubuntu Server 22.04 LTS (version 6)': {'version': '6', 'changelog': 'Re-ordered host keys to prioritize ED25519 due to efficiency. Re-ordered cipher list to prioritize larger key sizes as a countermeasure to quantum attacks.', 'banner': None, 'compressions': None, 'host_keys': ['ssh-ed25519', 'rsa-sha2-512', 'rsa-sha2-256'], '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', 'kex-strict-s-v00@openssh.com'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-gcm@openssh.com', '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 Ubuntu Server 24.04 LTS (version 1)': {'version': '1', 'changelog': 'Initial version.', 'banner': None, 'compressions': None, 'host_keys': ['ssh-ed25519', 'rsa-sha2-512', 'rsa-sha2-256'], '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-group18-sha512', 'diffie-hellman-group-exchange-sha256', 'diffie-hellman-group16-sha512', 'ext-info-s', 'kex-strict-s-v00@openssh.com'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-gcm@openssh.com', 'aes128-ctr'], 'macs': ['hmac-sha2-512-etm@openssh.com', 'hmac-sha2-256-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},
|
||||
|
||||
# Generic OpenSSH Server policies
|
||||
|
||||
@ -94,21 +103,29 @@ BUILTIN_POLICIES: Dict[str, Dict[str, Union[Optional[str], Optional[List[str]],
|
||||
|
||||
'Hardened OpenSSH Server v9.7 (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
|
||||
|
||||
'Hardened Amazon Linux Client 2023 (version 1)': {'version': '1', 'changelog': 'Initial version.', 'banner': None, 'compressions': None, 'host_keys': ['sk-ssh-ed25519-cert-v01@openssh.com', 'ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'sk-ssh-ed25519@openssh.com', 'ssh-ed25519', 'rsa-sha2-512', 'rsa-sha2-256'], 'optional_host_keys': None, '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-c', 'kex-strict-c-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': None, 'dh_modulus_sizes': None, 'server_policy': False},
|
||||
|
||||
'Hardened Amazon Linux Client 2023 (version 2)': {'version': '2', 'changelog': 'Re-ordered cipher list to prioritize larger key sizes as a countermeasure to quantum attacks.', 'banner': None, 'compressions': None, 'host_keys': ['sk-ssh-ed25519-cert-v01@openssh.com', 'ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'sk-ssh-ed25519@openssh.com', 'ssh-ed25519', 'rsa-sha2-512', 'rsa-sha2-256'], 'optional_host_keys': None, '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-c', 'kex-strict-c-v00@openssh.com'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-gcm@openssh.com', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@openssh.com'], 'hostkey_sizes': None, 'dh_modulus_sizes': None, 'server_policy': False},
|
||||
|
||||
|
||||
# Debian Client Policies
|
||||
|
||||
'Hardened Debian Client 12 (version 1)': {'version': '1', 'changelog': 'Initial version.', 'banner': None, 'compressions': None, 'host_keys': ['sk-ssh-ed25519-cert-v01@openssh.com', 'ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'sk-ssh-ed25519@openssh.com', 'ssh-ed25519', 'rsa-sha2-512', 'rsa-sha2-256'], 'optional_host_keys': None, '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-c', 'kex-strict-c-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': None, 'dh_modulus_sizes': None, 'server_policy': False},
|
||||
|
||||
'Hardened Debian Client 12 (version 2)': {'version': '2', 'changelog': 'Re-ordered cipher list to prioritize larger key sizes as a countermeasure to quantum attacks.', 'banner': None, 'compressions': None, 'host_keys': ['sk-ssh-ed25519-cert-v01@openssh.com', 'ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'sk-ssh-ed25519@openssh.com', 'ssh-ed25519', 'rsa-sha2-512', 'rsa-sha2-256'], 'optional_host_keys': None, '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-c', 'kex-strict-c-v00@openssh.com'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-gcm@openssh.com', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@openssh.com'], 'hostkey_sizes': None, 'dh_modulus_sizes': None, 'server_policy': False},
|
||||
|
||||
|
||||
# Rocky Linux Policies
|
||||
|
||||
'Hardened Rocky Linux Client 9 (version 1)': {'version': '1', 'changelog': 'Initial version.', 'banner': None, 'compressions': None, 'host_keys': ['sk-ssh-ed25519-cert-v01@openssh.com', 'ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'sk-ssh-ed25519@openssh.com', 'ssh-ed25519', 'rsa-sha2-512', 'rsa-sha2-256'], 'optional_host_keys': None, '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-c', 'kex-strict-c-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': None, 'dh_modulus_sizes': None, 'server_policy': False},
|
||||
|
||||
'Hardened Rocky Linux Client 9 (version 2)': {'version': '2', 'changelog': 'Re-ordered cipher list to prioritize larger key sizes as a countermeasure to quantum attacks.', 'banner': None, 'compressions': None, 'host_keys': ['sk-ssh-ed25519-cert-v01@openssh.com', 'ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'sk-ssh-ed25519@openssh.com', 'ssh-ed25519', 'rsa-sha2-512', 'rsa-sha2-256'], 'optional_host_keys': None, '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-c', 'kex-strict-c-v00@openssh.com'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-gcm@openssh.com', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@openssh.com'], 'hostkey_sizes': None, 'dh_modulus_sizes': None, 'server_policy': False},
|
||||
|
||||
# Ubuntu Client policies
|
||||
|
||||
@ -120,5 +137,8 @@ BUILTIN_POLICIES: Dict[str, Dict[str, Union[Optional[str], Optional[List[str]],
|
||||
|
||||
'Hardened Ubuntu Client 22.04 LTS (version 4)': {'version': '4', 'changelog': 'Added kex-strict-c-v00@openssh.com to kex list.', 'banner': None, 'compressions': None, 'host_keys': ['sk-ssh-ed25519-cert-v01@openssh.com', 'ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'sk-ssh-ed25519@openssh.com', 'ssh-ed25519', 'rsa-sha2-512', 'rsa-sha2-256'], 'optional_host_keys': None, '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-c', 'kex-strict-c-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': None, 'dh_modulus_sizes': None, 'server_policy': False},
|
||||
|
||||
'Hardened Ubuntu Client 22.04 LTS (version 5)': {'version': '5', 'changelog': 'Re-ordered cipher list to prioritize larger key sizes as a countermeasure to quantum attacks.', 'banner': None, 'compressions': None, 'host_keys': ['sk-ssh-ed25519-cert-v01@openssh.com', 'ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'sk-ssh-ed25519@openssh.com', 'ssh-ed25519', 'rsa-sha2-512', 'rsa-sha2-256'], 'optional_host_keys': None, '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-c', 'kex-strict-c-v00@openssh.com'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-gcm@openssh.com', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@openssh.com'], 'hostkey_sizes': None, 'dh_modulus_sizes': None, 'server_policy': False},
|
||||
|
||||
'Hardened Ubuntu Client 24.04 LTS (version 1)': {'version': '1', 'changelog': 'Initial version.', 'banner': None, 'compressions': None, 'host_keys': ['sk-ssh-ed25519-cert-v01@openssh.com', 'ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'sk-ssh-ed25519@openssh.com', 'ssh-ed25519', 'rsa-sha2-512', 'rsa-sha2-256'], 'optional_host_keys': None, 'kex': ['sntrup761x25519-sha512@openssh.com', 'curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256', 'diffie-hellman-group16-sha512', 'ext-info-c', 'kex-strict-c-v00@openssh.com'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-gcm@openssh.com', 'aes128-ctr'], 'macs': ['hmac-sha2-512-etm@openssh.com', 'hmac-sha2-256-etm@openssh.com', 'umac-128-etm@openssh.com'], 'hostkey_sizes': None, 'dh_modulus_sizes': None, 'server_policy': False},
|
||||
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
import errno
|
||||
import multiprocessing
|
||||
import os
|
||||
import queue
|
||||
@ -160,6 +161,11 @@ class DHEat:
|
||||
# The SSH2_Kex object that we recieved from the server in a prior connection. We'll use it as a template to craft our own kex.
|
||||
self.kex = kex
|
||||
|
||||
# Resolve the target to an IP address depending on the user preferences (IPv4 or IPv6).
|
||||
self.debug("Resolving target %s..." % self.target)
|
||||
self.target_address_family, self.target_ip_address = DHEat._resolve_hostname(self.target, aconf.ip_version_preference)
|
||||
self.debug("Resolved %s to %s (address family %u)" % (self.target, self.target_ip_address, self.target_address_family))
|
||||
|
||||
# The connection and read timeouts.
|
||||
self.connect_timeout = aconf.timeout
|
||||
self.read_timeout = aconf.timeout
|
||||
@ -318,11 +324,10 @@ class DHEat:
|
||||
|
||||
del socket_dict[s]
|
||||
|
||||
if sys.platform == "win32":
|
||||
DHEat.YELLOWB = "\033[1;93m"
|
||||
DHEat.CLEAR = "\033[0m"
|
||||
print("\n%sUnfortunately, this feature is not currently functional under Windows.%s This should get fixed in a future release. See: <https://github.com/jtesta/ssh-audit/issues/261>" % (DHEat.YELLOWB, DHEat.CLEAR))
|
||||
return ""
|
||||
# Resolve the target into an IP address
|
||||
out.d("Resolving target %s..." % aconf.host)
|
||||
target_address_family, target_ip_address = DHEat._resolve_hostname(aconf.host, aconf.ip_version_preference)
|
||||
out.d("Resolved %s to %s (address family %u)" % (aconf.host, target_ip_address, target_address_family))
|
||||
|
||||
spinner = ["-", "\\", "|", "/"]
|
||||
spinner_index = 0
|
||||
@ -349,7 +354,7 @@ class DHEat:
|
||||
rate_str = " at a max rate of %s%u%s connections per second" % (DHEat.WHITEB, aconf.conn_rate_test_target_rate, DHEat.CLEAR)
|
||||
|
||||
print()
|
||||
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("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, target_ip_address, aconf.port, DHEat.CLEAR, DHEat.WHITEB, concurrent_sockets, DHEat.CLEAR, rate_str))
|
||||
print()
|
||||
|
||||
# Make room for the multi-line output.
|
||||
@ -426,16 +431,16 @@ class DHEat:
|
||||
|
||||
# Open new sockets until we've hit the number of concurrent sockets, or if we exceeded the number of maximum connections.
|
||||
while (len(socket_dict) < concurrent_sockets) and (len(socket_dict) + num_opened_connections < max_connections):
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s = socket.socket(target_address_family, socket.SOCK_STREAM)
|
||||
s.setblocking(False)
|
||||
|
||||
# out.d("Creating socket (%u of %u already exist)..." % (len(socket_dict), concurrent_sockets), write_now=True)
|
||||
ret = s.connect_ex((aconf.host, aconf.port))
|
||||
ret = s.connect_ex((target_ip_address, aconf.port))
|
||||
num_attempted_connections += 1
|
||||
if ret in [0, 115]: # Check if connection is successful or EINPROGRESS.
|
||||
if ret in [0, errno.EINPROGRESS, errno.EWOULDBLOCK]:
|
||||
socket_dict[s] = now
|
||||
else:
|
||||
out.d("connect_ex() returned: %d" % ret, write_now=True)
|
||||
out.d("connect_ex() returned: %s (%d)" % (os.strerror(ret), ret), write_now=True)
|
||||
|
||||
# out.d("Calling select() on %u sockets..." % len(socket_dict), write_now=True)
|
||||
socket_list: List[socket.socket] = [*socket_dict] # Get a list of sockets from the dictionary.
|
||||
@ -743,6 +748,22 @@ class DHEat:
|
||||
print()
|
||||
|
||||
|
||||
@staticmethod
|
||||
def _resolve_hostname(host: str, ip_version_preference: List[int]) -> Tuple[int, str]:
|
||||
'''Resolves a hostname to its IPv4 or IPv6 address, depending on user preference.'''
|
||||
|
||||
family = socket.AF_UNSPEC
|
||||
if len(ip_version_preference) == 1:
|
||||
family = socket.AF_INET if ip_version_preference[0] == 4 else socket.AF_INET6
|
||||
|
||||
r = socket.getaddrinfo(host, 0, family, socket.SOCK_STREAM)
|
||||
for address_family, socktype, _, _, addr in r:
|
||||
if socktype == socket.SOCK_STREAM:
|
||||
return address_family, addr[0]
|
||||
|
||||
return -1, ''
|
||||
|
||||
|
||||
def _run(self) -> bool:
|
||||
'''Where all the magic happens.'''
|
||||
|
||||
@ -751,7 +772,7 @@ class DHEat:
|
||||
if sys.platform == "win32":
|
||||
self.output("%sWARNING:%s this feature has not been thoroughly tested on Windows. It may perform worse than on UNIX OSes." % (self.YELLOWB, self.CLEAR))
|
||||
|
||||
self.output("Running DHEat test against %s[%s]:%u%s with %s%u%s concurrent sockets..." % (self.WHITEB, self.target, self.port, self.CLEAR, self.WHITEB, self.concurrent_connections, self.CLEAR))
|
||||
self.output("Running DHEat test against %s[%s]:%u%s with %s%u%s concurrent sockets..." % (self.WHITEB, self.target_ip_address, self.port, self.CLEAR, self.WHITEB, self.concurrent_connections, self.CLEAR))
|
||||
|
||||
# If the user didn't specify an exact kex algorithm to test, check our prioritized list against what the server supports. Larger p-values (such as group18: 8192-bits) cause the most strain on the server.
|
||||
chosen_alg = ""
|
||||
@ -894,7 +915,8 @@ class DHEat:
|
||||
|
||||
# Copy variables from the object (which might exist in another process?). This might cut down on inter-process overhead.
|
||||
connect_timeout = self.connect_timeout
|
||||
target = self.target
|
||||
target_ip_address = self.target_ip_address
|
||||
target_address_family = self.target_address_family
|
||||
port = self.port
|
||||
|
||||
# Determine if we are attacking with a GEX.
|
||||
@ -945,17 +967,17 @@ class DHEat:
|
||||
num_socket_exceptions = 0
|
||||
num_openssh_throttled_connections = 0
|
||||
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s = socket.socket(target_address_family, socket.SOCK_STREAM)
|
||||
s.settimeout(connect_timeout)
|
||||
|
||||
# Loop until a successful TCP connection is made.
|
||||
connected = False
|
||||
while not connected:
|
||||
|
||||
# self.debug("Connecting to %s:%d" % (self.target, self.port))
|
||||
# self.debug("Connecting to %s:%d" % (self.target_ip_address, self.port))
|
||||
try:
|
||||
num_attempted_tcp_connections += 1
|
||||
s.connect((target, port))
|
||||
s.connect((target_ip_address, port))
|
||||
connected = True
|
||||
except OSError as e:
|
||||
self.debug("Failed to connect: %s" % str(e))
|
||||
|
@ -22,7 +22,7 @@
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
# The version to display.
|
||||
VERSION = 'v3.2.0'
|
||||
VERSION = 'v3.4.0-dev'
|
||||
|
||||
# SSH software to impersonate
|
||||
SSH_HEADER = 'SSH-{0}-OpenSSH_8.2'
|
||||
|
@ -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
|
||||
@ -40,7 +40,7 @@ class HostKeyTest:
|
||||
# Tracks the RSA host key types. As of this writing, testing one in this family yields valid results for the rest.
|
||||
RSA_FAMILY = ['ssh-rsa', 'rsa-sha2-256', 'rsa-sha2-512']
|
||||
|
||||
# Dict holding the host key types we should extract & parse. 'cert' is True to denote that a host key type handles certificates (thus requires additional parsing). 'variable_key_len' is True for host key types that can have variable sizes (True only for RSA types, as the rest are of fixed-size). After the host key type is fully parsed, the key 'parsed' is added with a value of True.
|
||||
# Dict holding the host key types we should extract & parse. 'cert' is True to denote that a host key type handles certificates (thus requires additional parsing). 'variable_key_len' is True for host key types that can have variable sizes (True only for RSA types, as the rest are of fixed-size).
|
||||
HOST_KEY_TYPES = {
|
||||
'ssh-rsa': {'cert': False, 'variable_key_len': True},
|
||||
'rsa-sha2-256': {'cert': False, 'variable_key_len': True},
|
||||
@ -52,6 +52,20 @@ class HostKeyTest:
|
||||
|
||||
'ssh-ed25519': {'cert': False, 'variable_key_len': False},
|
||||
'ssh-ed25519-cert-v01@openssh.com': {'cert': True, 'variable_key_len': False},
|
||||
|
||||
'ssh-ed448': {'cert': False, 'variable_key_len': False},
|
||||
# 'ssh-ed448-cert-v01@openssh.com': {'cert': True, 'variable_key_len': False},
|
||||
|
||||
'ecdsa-sha2-nistp256': {'cert': False, 'variable_key_len': False},
|
||||
'ecdsa-sha2-nistp384': {'cert': False, 'variable_key_len': False},
|
||||
'ecdsa-sha2-nistp521': {'cert': False, 'variable_key_len': False},
|
||||
|
||||
'ecdsa-sha2-nistp256-cert-v01@openssh.com': {'cert': True, 'variable_key_len': False},
|
||||
'ecdsa-sha2-nistp384-cert-v01@openssh.com': {'cert': True, 'variable_key_len': False},
|
||||
'ecdsa-sha2-nistp521-cert-v01@openssh.com': {'cert': True, 'variable_key_len': False},
|
||||
|
||||
'ssh-dss': {'cert': False, 'variable_key_len': True},
|
||||
'ssh-dss-cert-v01@openssh.com': {'cert': True, 'variable_key_len': True},
|
||||
}
|
||||
|
||||
TWO2K_MODULUS_WARNING = '2048-bit modulus only provides 112-bits of symmetric strength'
|
||||
@ -93,6 +107,7 @@ class HostKeyTest:
|
||||
def perform_test(out: 'OutputBuffer', s: 'SSH_Socket', server_kex: 'SSH2_Kex', kex_str: str, kex_group: 'KexDH', host_key_types: Dict[str, Dict[str, bool]]) -> None:
|
||||
hostkey_modulus_size = 0
|
||||
ca_modulus_size = 0
|
||||
parsed_host_key_types = set()
|
||||
|
||||
# If the connection still exists, close it so we can test
|
||||
# using a clean slate (otherwise it may exist in a non-testable
|
||||
@ -106,7 +121,7 @@ class HostKeyTest:
|
||||
key_warn_comments = []
|
||||
|
||||
# Skip those already handled (i.e.: those in the RSA family, as testing one tests them all).
|
||||
if 'parsed' in host_key_types[host_key_type] and host_key_types[host_key_type]['parsed']:
|
||||
if host_key_type in parsed_host_key_types:
|
||||
continue
|
||||
|
||||
# If this host key type is supported by the server, we test it.
|
||||
@ -136,7 +151,12 @@ class HostKeyTest:
|
||||
_, payload = s.read_packet()
|
||||
SSH2_Kex.parse(out, payload)
|
||||
except Exception:
|
||||
out.v("Failed to parse server's kex. Stack trace:\n%s" % str(traceback.format_exc()), write_now=True)
|
||||
msg = "Failed to parse server's kex."
|
||||
if not out.debug:
|
||||
msg += " Re-run in debug mode to see stack trace."
|
||||
|
||||
out.v(msg, write_now=True)
|
||||
out.d("Stack trace:\n%s" % str(traceback.format_exc()), write_now=True)
|
||||
return
|
||||
|
||||
# Do the initial DH exchange. The server responds back
|
||||
@ -147,7 +167,12 @@ class HostKeyTest:
|
||||
kex_reply = kex_group.recv_reply(s)
|
||||
raw_hostkey_bytes = kex_reply if kex_reply is not None else b''
|
||||
except KexDHException:
|
||||
out.v("Failed to parse server's host key. Stack trace:\n%s" % str(traceback.format_exc()), write_now=True)
|
||||
msg = "Failed to parse server's host key."
|
||||
if not out.debug:
|
||||
msg += " Re-run in debug mode to see stack trace."
|
||||
|
||||
out.v(msg, write_now=True)
|
||||
out.d("Stack trace:\n%s" % str(traceback.format_exc()), write_now=True)
|
||||
|
||||
# Since parsing this host key failed, there's nothing more to do but close the socket and move on to the next host key type.
|
||||
s.close()
|
||||
@ -157,6 +182,7 @@ class HostKeyTest:
|
||||
ca_key_type = kex_group.get_ca_type()
|
||||
ca_modulus_size = kex_group.get_ca_size()
|
||||
out.d("Hostkey type: [%s]; hostkey size: %u; CA type: [%s]; CA modulus size: %u" % (host_key_type, hostkey_modulus_size, ca_key_type, ca_modulus_size), write_now=True)
|
||||
out.d("Raw hostkey bytes (%d): [%s]" % (len(raw_hostkey_bytes), raw_hostkey_bytes.hex()), write_now=True)
|
||||
|
||||
# Record all the host key info.
|
||||
server_kex.set_host_key(host_key_type, raw_hostkey_bytes, hostkey_modulus_size, ca_key_type, ca_modulus_size)
|
||||
@ -186,7 +212,7 @@ class HostKeyTest:
|
||||
cakey_warn_str = HostKeyTest.SMALL_ECC_MODULUS_WARNING
|
||||
|
||||
# Keys smaller than 2048 result in a failure. Keys smaller 3072 result in a warning. Update the database accordingly.
|
||||
if (cert is False) and (hostkey_modulus_size < hostkey_min_good):
|
||||
if (cert is False) and (hostkey_modulus_size < hostkey_min_good) and (host_key_type != 'ssh-dss'): # Skip ssh-dss, otherwise we get duplicate failure messages (SSH2_KexDB will always flag it).
|
||||
|
||||
# If the key is under 2048, add to the failure list.
|
||||
if hostkey_modulus_size < hostkey_min_warn:
|
||||
@ -216,7 +242,7 @@ class HostKeyTest:
|
||||
# If this host key type is in the RSA family, then mark them all as parsed (since results in one are valid for them all).
|
||||
if host_key_type in HostKeyTest.RSA_FAMILY:
|
||||
for rsa_type in HostKeyTest.RSA_FAMILY:
|
||||
host_key_types[rsa_type]['parsed'] = True
|
||||
parsed_host_key_types.add(rsa_type)
|
||||
|
||||
# If the current key is a member of the RSA family, then populate all RSA family members with the same
|
||||
# failure and/or warning comments.
|
||||
@ -228,7 +254,7 @@ class HostKeyTest:
|
||||
db['key'][rsa_type][2].extend(key_warn_comments)
|
||||
|
||||
else:
|
||||
host_key_types[host_key_type]['parsed'] = True
|
||||
parsed_host_key_types.add(host_key_type)
|
||||
db = SSH2_KexDB.get_db()
|
||||
while len(db['key'][host_key_type]) < 3:
|
||||
db['key'][host_key_type].append([])
|
||||
|
@ -134,6 +134,9 @@ class KexDH: # pragma: nocover
|
||||
if self.__hostkey_type == 'ssh-ed25519':
|
||||
self.out.d("%s has a fixed host key modulus of 32." % self.__hostkey_type)
|
||||
self.__hostkey_n_len = 32
|
||||
elif self.__hostkey_type == 'ssh-ed448':
|
||||
self.out.d("%s has a fixed host key modulus of 57." % self.__hostkey_type)
|
||||
self.__hostkey_n_len = 57
|
||||
else:
|
||||
# Here is the modulus size & actual modulus of the host key public key.
|
||||
hostkey_n, self.__hostkey_n_len, ptr = KexDH.__get_bytes(hostkey, ptr)
|
||||
|
@ -54,11 +54,11 @@ class OutputBuffer:
|
||||
self.__is_color_supported = ('colorama' in sys.modules) or (os.name == 'posix')
|
||||
self.line_ended = True
|
||||
|
||||
def _print(self, level: str, s: str = '', line_ended: bool = True) -> None:
|
||||
def _print(self, level: str, s: str = '', line_ended: bool = True, always_print: bool = False) -> None:
|
||||
'''Saves output to buffer (if in buffered mode), or immediately prints to stdout otherwise.'''
|
||||
|
||||
# If we're logging only 'warn' or above, and this is an 'info', ignore message.
|
||||
if self.get_level(level) < self.__level:
|
||||
# If we're logging only 'warn' or above, and this is an 'info', ignore message, unless always_print is True (useful for printing informational lines regardless of the level setting).
|
||||
if (always_print is False) and (self.get_level(level) < self.__level):
|
||||
return
|
||||
|
||||
if self.use_colors and self.colors_supported and len(s) > 0 and level != 'info':
|
||||
@ -145,20 +145,22 @@ class OutputBuffer:
|
||||
self._print('head', s, line_ended)
|
||||
return self
|
||||
|
||||
def fail(self, s: str, line_ended: bool = True) -> 'OutputBuffer':
|
||||
self._print('fail', s, line_ended)
|
||||
def fail(self, s: str, line_ended: bool = True, write_now: bool = False, always_print: bool = False) -> 'OutputBuffer':
|
||||
self._print('fail', s, line_ended, always_print=always_print)
|
||||
if write_now:
|
||||
self.write()
|
||||
return self
|
||||
|
||||
def warn(self, s: str, line_ended: bool = True) -> 'OutputBuffer':
|
||||
self._print('warn', s, line_ended)
|
||||
def warn(self, s: str, line_ended: bool = True, always_print: bool = False) -> 'OutputBuffer':
|
||||
self._print('warn', s, line_ended, always_print=always_print)
|
||||
return self
|
||||
|
||||
def info(self, s: str, line_ended: bool = True) -> 'OutputBuffer':
|
||||
self._print('info', s, line_ended)
|
||||
def info(self, s: str, line_ended: bool = True, always_print: bool = False) -> 'OutputBuffer':
|
||||
self._print('info', s, line_ended, always_print=always_print)
|
||||
return self
|
||||
|
||||
def good(self, s: str, line_ended: bool = True) -> 'OutputBuffer':
|
||||
self._print('good', s, line_ended)
|
||||
def good(self, s: str, line_ended: bool = True, always_print: bool = False) -> 'OutputBuffer':
|
||||
self._print('good', s, line_ended, always_print=always_print)
|
||||
return self
|
||||
|
||||
def sep(self) -> 'OutputBuffer':
|
||||
|
@ -57,6 +57,7 @@ class Policy:
|
||||
self._allow_algorithm_subset_and_reordering = False
|
||||
self._allow_larger_keys = False
|
||||
self._errors: List[Any] = []
|
||||
self._updated_builtin_policy_available = False # If True, an outdated built-in policy was loaded.
|
||||
|
||||
self._name_and_version: str = ''
|
||||
|
||||
@ -496,6 +497,11 @@ macs = %s
|
||||
return self._name_and_version
|
||||
|
||||
|
||||
def is_outdated_builtin_policy(self) -> bool:
|
||||
'''Returns True if this is a built-in policy that has a more recent version available than currently selected.'''
|
||||
return self._updated_builtin_policy_available
|
||||
|
||||
|
||||
def is_server_policy(self) -> bool:
|
||||
'''Returns True if this is a server policy, or False if this is a client policy.'''
|
||||
return self._server_policy
|
||||
@ -507,18 +513,46 @@ macs = %s
|
||||
server_policy_descriptions = []
|
||||
client_policy_descriptions = []
|
||||
|
||||
latest_server_policies: Dict[str, Dict[str, Union[int, str]]] = {}
|
||||
latest_client_policies: Dict[str, Dict[str, Union[int, str]]] = {}
|
||||
for policy_name, policy in BUILTIN_POLICIES.items():
|
||||
policy_description = ""
|
||||
if verbose:
|
||||
policy_description = "\"{:s}\": {:s}".format(policy_name, policy['changelog'])
|
||||
else:
|
||||
|
||||
# If not in verbose mode, only store the latest version of each policy.
|
||||
if not verbose:
|
||||
policy_description = "\"{:s}\"".format(policy_name)
|
||||
|
||||
if policy['server_policy']:
|
||||
server_policy_descriptions.append(policy_description)
|
||||
else:
|
||||
client_policy_descriptions.append(policy_description)
|
||||
# Truncate the version off the policy name and obtain the version as an integer. (i.e.: "Platform X (version 3)" -> "Platform X", 3
|
||||
policy_name_no_version = ""
|
||||
version = 0
|
||||
version_pos = policy_name.find(" (version ")
|
||||
if version_pos != -1:
|
||||
policy_name_no_version = policy_name[0:version_pos]
|
||||
version = int(cast(str, policy['version'])) # Unit tests guarantee this to be parseable as an int.
|
||||
|
||||
d = latest_server_policies if policy['server_policy'] else latest_client_policies
|
||||
if policy_name_no_version not in d:
|
||||
d[policy_name_no_version] = {}
|
||||
d[policy_name_no_version]['latest_version'] = version
|
||||
d[policy_name_no_version]['description'] = policy_description
|
||||
elif version > cast(int, d[policy_name_no_version]['latest_version']): # If an updated version of the policy was found, replace the old one.
|
||||
d[policy_name_no_version]['latest_version'] = version
|
||||
d[policy_name_no_version]['description'] = policy_description
|
||||
else: # In verbose mode, return all policy versions.
|
||||
policy_description = "\"{:s}\": {:s}".format(policy_name, policy['changelog'])
|
||||
if policy['server_policy']:
|
||||
server_policy_descriptions.append(policy_description)
|
||||
else:
|
||||
client_policy_descriptions.append(policy_description)
|
||||
|
||||
# Now that we have references to the latest policies only, add their full descriptions to the lists for returning.
|
||||
if not verbose:
|
||||
for _, dd in latest_server_policies.items():
|
||||
server_policy_descriptions.append(cast(str, dd['description']))
|
||||
|
||||
for _, dd in latest_client_policies.items():
|
||||
client_policy_descriptions.append(cast(str, dd['description']))
|
||||
|
||||
# Sort the lists for better readability.
|
||||
server_policy_descriptions.sort()
|
||||
client_policy_descriptions.sort()
|
||||
return server_policy_descriptions, client_policy_descriptions
|
||||
@ -549,6 +583,14 @@ macs = %s
|
||||
# Ensure this struct has all the necessary fields.
|
||||
p._normalize_hostkey_sizes() # pylint: disable=protected-access
|
||||
|
||||
# Now check if an updated version of the requested policy exists. If so, set a warning for the user.
|
||||
if p is not None and p._version is not None: # pylint: disable=protected-access
|
||||
next_version = str(int(p._version) + 1) # pylint: disable=protected-access
|
||||
name_version_pos = policy_name.find("(version ")
|
||||
next_version_name = policy_name[0:name_version_pos] + "(version %s)" % next_version
|
||||
if next_version_name in BUILTIN_POLICIES:
|
||||
p._updated_builtin_policy_available = True # pylint: disable=protected-access
|
||||
|
||||
return p
|
||||
|
||||
|
||||
@ -605,3 +647,29 @@ macs = %s
|
||||
dh_modulus_sizes_str = str(self._dh_modulus_sizes)
|
||||
|
||||
return "Name: %s\nVersion: %s\nAllow Algorithm Subset and/or Reordering: %r\nBanner: %s\nCompressions: %s\nHost Keys: %s\nOptional Host Keys: %s\nKey Exchanges: %s\nCiphers: %s\nMACs: %s\nHost Key Sizes: %s\nDH Modulus Sizes: %s\nServer Policy: %r" % (name, version, self._allow_algorithm_subset_and_reordering, banner, compressions_str, host_keys_str, optional_host_keys_str, kex_str, ciphers_str, macs_str, hostkey_sizes_str, dh_modulus_sizes_str, self._server_policy)
|
||||
|
||||
|
||||
def __getstate__(self) -> Dict[str, Any]:
|
||||
'''Called when pickling this object. The file descriptor isn't serializable, so we'll remove it from the state and include a string representation.'''
|
||||
|
||||
state = self.__dict__.copy()
|
||||
|
||||
if state['_warning_target'] == sys.stdout:
|
||||
state['_warning_target_type'] = 'stdout'
|
||||
else:
|
||||
state['_warning_target_type'] = 'stderr'
|
||||
|
||||
del state['_warning_target']
|
||||
return state
|
||||
|
||||
|
||||
def __setstate__(self, state: Dict[str, Any]) -> None:
|
||||
'''Called when unpickling this object. Based on the string representation of the file descriptor, we'll restore the right handle.'''
|
||||
|
||||
if state['_warning_target_type'] == 'stdout':
|
||||
state['_warning_target'] = sys.stdout
|
||||
else:
|
||||
state['_warning_target'] = sys.stderr
|
||||
|
||||
del state['_warning_target_type']
|
||||
self.__dict__.update(state)
|
||||
|
@ -224,4 +224,8 @@ class Software:
|
||||
mx = re.match(r'^PuTTY_Release_(.*)', software)
|
||||
if mx:
|
||||
return cls(None, Product.PuTTY, mx.group(1), None, None)
|
||||
mx = re.match(r'^lancom(.*)', software)
|
||||
if mx:
|
||||
v, p = 'LANcom', 'LCOS sshd'
|
||||
return cls(v, p, mx.group(1), None, None)
|
||||
return None
|
||||
|
@ -1,7 +1,7 @@
|
||||
"""
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (C) 2017-2020 Joe Testa (jtesta@positronsecurity.com)
|
||||
Copyright (C) 2017-2024 Joe Testa (jtesta@positronsecurity.com)
|
||||
Copyright (C) 2017 Andris Raugulis (moo@arthepsy.eu)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
@ -132,3 +132,16 @@ class SSH2_Kex:
|
||||
srv = SSH2_KexParty(srv_enc, srv_mac, srv_compression, srv_languages)
|
||||
kex = cls(outputbuffer, cookie, kex_algs, key_algs, cli, srv, follows, unused)
|
||||
return kex
|
||||
|
||||
def __str__(self) -> str:
|
||||
ret = "----\nSSH2_Kex object:"
|
||||
ret += "\nHost keys: "
|
||||
ret += ", ".join(self.__key_algs)
|
||||
ret += "\nKey exchanges: "
|
||||
ret += ", ".join(self.__kex_algs)
|
||||
ret += "\nClient SSH2_KexParty:"
|
||||
ret += "\n" + str(self.__client)
|
||||
ret += "\nServer SSH2_KexParty:"
|
||||
ret += "\n" + str(self.__server)
|
||||
ret += "\n----"
|
||||
return ret
|
||||
|
@ -57,6 +57,7 @@ class SSH2_KexDB: # pylint: disable=too-few-public-methods
|
||||
WARN_CIPHER_MODE = 'using weak cipher mode'
|
||||
WARN_ENCRYPT_AND_MAC = 'using encrypt-and-MAC mode'
|
||||
WARN_EXPERIMENTAL = 'using experimental algorithm'
|
||||
WARN_NOT_PQ_SAFE = 'does not provide protection against post-quantum attacks'
|
||||
WARN_RNDSIG_KEY = 'using weak random number generator could reveal the key'
|
||||
WARN_TAG_SIZE = 'using small 64-bit tag size'
|
||||
WARN_TAG_SIZE_96 = 'using small 96-bit tag size'
|
||||
@ -64,11 +65,13 @@ class SSH2_KexDB: # pylint: disable=too-few-public-methods
|
||||
INFO_DEFAULT_OPENSSH_CIPHER = 'default cipher since OpenSSH 6.9'
|
||||
INFO_DEFAULT_OPENSSH_KEX_65_TO_73 = 'default key exchange from OpenSSH 6.5 to 7.3'
|
||||
INFO_DEFAULT_OPENSSH_KEX_74_TO_89 = 'default key exchange from OpenSSH 7.4 to 8.9'
|
||||
INFO_DEFAULT_OPENSSH_KEX_90 = 'default key exchange since OpenSSH 9.0'
|
||||
INFO_DEFAULT_OPENSSH_KEX_90_TO_98 = 'default key exchange from OpenSSH 9.0 to 9.8'
|
||||
INFO_DEFAULT_OPENSSH_KEX_99 = 'default key exchange since OpenSSH 9.9'
|
||||
INFO_DEPRECATED_IN_OPENSSH88 = 'deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8'
|
||||
INFO_DISABLED_IN_DBEAR67 = 'disabled in Dropbear SSH 2015.67'
|
||||
INFO_DISABLED_IN_OPENSSH70 = 'disabled in OpenSSH 7.0: https://www.openssh.com/txt/release-7.0'
|
||||
INFO_NEVER_IMPLEMENTED_IN_OPENSSH = 'despite the @openssh.com tag, this was never implemented in OpenSSH'
|
||||
INFO_HYBRID_PQ_X25519_KEX = 'hybrid key exchange based on post-quantum resistant algorithm and proven conventional X25519 algorithm'
|
||||
INFO_REMOVED_IN_OPENSSH61 = 'removed since OpenSSH 6.1, removed from specification'
|
||||
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'
|
||||
@ -82,118 +85,120 @@ class SSH2_KexDB: # pylint: disable=too-few-public-methods
|
||||
MASTER_DB: Dict[str, Dict[str, List[List[Optional[str]]]]] = {
|
||||
# Format: 'algorithm_name': [['version_first_appeared_in'], [reason_for_failure1, reason_for_failure2, ...], [warning1, warning2, ...], [info1, info2, ...]]
|
||||
'kex': {
|
||||
'Curve25519SHA256': [[]],
|
||||
'curve25519-sha256': [['7.4,d2018.76'], [], [], [INFO_DEFAULT_OPENSSH_KEX_74_TO_89]],
|
||||
'curve25519-sha256@libssh.org': [['6.4,d2013.62,l10.6.0'], [], [], [INFO_DEFAULT_OPENSSH_KEX_65_TO_73]],
|
||||
'curve448-sha512': [[]],
|
||||
'curve448-sha512@libssh.org': [[]],
|
||||
'diffie-hellman-group14-sha1': [['3.9,d0.53,l10.6.0'], [FAIL_SHA1], [WARN_2048BIT_MODULUS]],
|
||||
'diffie-hellman-group14-sha224@ssh.com': [[]],
|
||||
'diffie-hellman-group14-sha256': [['7.3,d2016.73'], [], [WARN_2048BIT_MODULUS]],
|
||||
'diffie-hellman-group14-sha256@ssh.com': [[], [], [WARN_2048BIT_MODULUS]],
|
||||
'diffie-hellman-group15-sha256': [[]],
|
||||
'diffie-hellman-group15-sha256@ssh.com': [[]],
|
||||
'diffie-hellman-group15-sha384@ssh.com': [[]],
|
||||
'diffie-hellman-group15-sha512': [[]],
|
||||
'diffie-hellman-group16-sha256': [[]],
|
||||
'diffie-hellman-group16-sha384@ssh.com': [[]],
|
||||
'diffie-hellman-group16-sha512': [['7.3,d2016.73']],
|
||||
'diffie-hellman-group16-sha512@ssh.com': [[]],
|
||||
'diffie-hellman-group17-sha512': [[]],
|
||||
'diffie-hellman_group17-sha512': [[]],
|
||||
'diffie-hellman-group18-sha512': [['7.3']],
|
||||
'diffie-hellman-group18-sha512@ssh.com': [[]],
|
||||
'diffie-hellman-group1-sha1': [['2.3.0,d0.28,l10.2', '6.6', '6.9'], [FAIL_1024BIT_MODULUS, FAIL_LOGJAM_ATTACK, FAIL_SHA1], [], [INFO_REMOVED_IN_OPENSSH69]],
|
||||
'diffie-hellman-group1-sha256': [[], [FAIL_1024BIT_MODULUS]],
|
||||
'diffie-hellman-group-exchange-sha1': [['2.3.0', '6.6', None], [FAIL_SHA1]],
|
||||
'diffie-hellman-group-exchange-sha224@ssh.com': [[]],
|
||||
'diffie-hellman-group-exchange-sha256': [['4.4']],
|
||||
'diffie-hellman-group-exchange-sha256@ssh.com': [[]],
|
||||
'diffie-hellman-group-exchange-sha384@ssh.com': [[]],
|
||||
'diffie-hellman-group-exchange-sha512@ssh.com': [[]],
|
||||
'Curve25519SHA256': [[], [], [WARN_NOT_PQ_SAFE]],
|
||||
'curve25519-sha256': [['7.4,d2018.76'], [], [WARN_NOT_PQ_SAFE], [INFO_DEFAULT_OPENSSH_KEX_74_TO_89]],
|
||||
'curve25519-sha256@libssh.org': [['6.4,d2013.62,l10.6.0'], [], [WARN_NOT_PQ_SAFE], [INFO_DEFAULT_OPENSSH_KEX_65_TO_73]],
|
||||
'curve448-sha512': [[], [], [WARN_NOT_PQ_SAFE]],
|
||||
'curve448-sha512@libssh.org': [[], [], [WARN_NOT_PQ_SAFE]],
|
||||
'diffie-hellman-group14-sha1': [['3.9,d0.53,l10.6.0'], [FAIL_SHA1], [WARN_2048BIT_MODULUS, WARN_NOT_PQ_SAFE]],
|
||||
'diffie-hellman-group14-sha224@ssh.com': [[], [], [WARN_2048BIT_MODULUS, WARN_NOT_PQ_SAFE]],
|
||||
'diffie-hellman-group14-sha256': [['7.3,d2016.73'], [], [WARN_2048BIT_MODULUS, WARN_NOT_PQ_SAFE]],
|
||||
'diffie-hellman-group14-sha256@ssh.com': [[], [], [WARN_2048BIT_MODULUS, WARN_NOT_PQ_SAFE]],
|
||||
'diffie-hellman-group15-sha256': [[], [], [WARN_NOT_PQ_SAFE]],
|
||||
'diffie-hellman-group15-sha256@ssh.com': [[], [], [WARN_NOT_PQ_SAFE]],
|
||||
'diffie-hellman-group15-sha384@ssh.com': [[], [], [WARN_NOT_PQ_SAFE]],
|
||||
'diffie-hellman-group15-sha512': [[], [], [WARN_NOT_PQ_SAFE]],
|
||||
'diffie-hellman-group16-sha256': [[], [], [WARN_NOT_PQ_SAFE]],
|
||||
'diffie-hellman-group16-sha384@ssh.com': [[], [], [WARN_NOT_PQ_SAFE]],
|
||||
'diffie-hellman-group16-sha512': [['7.3,d2016.73'], [], [WARN_NOT_PQ_SAFE]],
|
||||
'diffie-hellman-group16-sha512@ssh.com': [[], [], [WARN_NOT_PQ_SAFE]],
|
||||
'diffie-hellman-group17-sha512': [[], [], [WARN_NOT_PQ_SAFE]],
|
||||
'diffie-hellman_group17-sha512': [[], [], [WARN_NOT_PQ_SAFE]],
|
||||
'diffie-hellman-group18-sha512': [['7.3'], [], [WARN_NOT_PQ_SAFE]],
|
||||
'diffie-hellman-group18-sha512@ssh.com': [[], [], [WARN_NOT_PQ_SAFE]],
|
||||
'diffie-hellman-group1-sha1': [['2.3.0,d0.28,l10.2', '6.6', '6.9'], [FAIL_1024BIT_MODULUS, FAIL_LOGJAM_ATTACK, FAIL_SHA1], [WARN_NOT_PQ_SAFE], [INFO_REMOVED_IN_OPENSSH69]],
|
||||
'diffie-hellman-group1-sha256': [[], [FAIL_1024BIT_MODULUS], [WARN_NOT_PQ_SAFE]],
|
||||
'diffie-hellman-group-exchange-sha1': [['2.3.0', '6.6', None], [FAIL_SHA1], [WARN_NOT_PQ_SAFE]],
|
||||
'diffie-hellman-group-exchange-sha224@ssh.com': [[], [], [WARN_NOT_PQ_SAFE]],
|
||||
'diffie-hellman-group-exchange-sha256': [['4.4'], [], [WARN_NOT_PQ_SAFE]],
|
||||
'diffie-hellman-group-exchange-sha256@ssh.com': [[], [], [WARN_NOT_PQ_SAFE]],
|
||||
'diffie-hellman-group-exchange-sha384@ssh.com': [[], [], [WARN_NOT_PQ_SAFE]],
|
||||
'diffie-hellman-group-exchange-sha512@ssh.com': [[], [], [WARN_NOT_PQ_SAFE]],
|
||||
'ecdh-nistp256-kyber-512r3-sha256-d00@openquantumsafe.org': [[], [FAIL_NSA_BACKDOORED_CURVE]],
|
||||
'ecdh-nistp384-kyber-768r3-sha384-d00@openquantumsafe.org': [[], [FAIL_NSA_BACKDOORED_CURVE]],
|
||||
'ecdh-nistp521-kyber-1024r3-sha512-d00@openquantumsafe.org': [[], [FAIL_NSA_BACKDOORED_CURVE]],
|
||||
'ecdh-sha2-1.2.840.10045.3.1.1': [[], [FAIL_SMALL_ECC_MODULUS, FAIL_NSA_BACKDOORED_CURVE]], # NIST P-192 / secp192r1
|
||||
'ecdh-sha2-1.2.840.10045.3.1.7': [[], [FAIL_NSA_BACKDOORED_CURVE]], # NIST P-256 / secp256r1
|
||||
'ecdh-sha2-1.3.132.0.10': [[]], # ECDH over secp256k1 (i.e.: the Bitcoin curve)
|
||||
'ecdh-sha2-1.3.132.0.16': [[], [FAIL_UNPROVEN]], # sect283k1
|
||||
'ecdh-sha2-1.3.132.0.1': [[], [FAIL_UNPROVEN, FAIL_SMALL_ECC_MODULUS]], # sect163k1
|
||||
'ecdh-sha2-1.3.132.0.26': [[], [FAIL_UNPROVEN, FAIL_SMALL_ECC_MODULUS]], # sect233k1
|
||||
'ecdh-sha2-1.3.132.0.27': [[], [FAIL_SMALL_ECC_MODULUS, FAIL_NSA_BACKDOORED_CURVE]], # sect233r1
|
||||
'ecdh-sha2-1.3.132.0.33': [[], [FAIL_SMALL_ECC_MODULUS, FAIL_NSA_BACKDOORED_CURVE]], # NIST P-224 / secp224r1
|
||||
'ecdh-sha2-1.3.132.0.34': [[], [FAIL_NSA_BACKDOORED_CURVE]], # NIST P-384 / secp384r1
|
||||
'ecdh-sha2-1.3.132.0.35': [[], [FAIL_NSA_BACKDOORED_CURVE]], # NIST P-521 / secp521r1
|
||||
'ecdh-sha2-1.3.132.0.36': [[], [FAIL_UNPROVEN]], # sect409k1
|
||||
'ecdh-sha2-1.3.132.0.37': [[], [FAIL_NSA_BACKDOORED_CURVE]], # sect409r1
|
||||
'ecdh-sha2-1.3.132.0.38': [[], [FAIL_UNPROVEN]], # sect571k1
|
||||
'ecdh-sha2-1.2.840.10045.3.1.1': [[], [FAIL_SMALL_ECC_MODULUS, FAIL_NSA_BACKDOORED_CURVE], [WARN_NOT_PQ_SAFE]], # NIST P-192 / secp192r1
|
||||
'ecdh-sha2-1.2.840.10045.3.1.7': [[], [FAIL_NSA_BACKDOORED_CURVE], [WARN_NOT_PQ_SAFE]], # NIST P-256 / secp256r1
|
||||
'ecdh-sha2-1.3.132.0.10': [[], [], [WARN_NOT_PQ_SAFE]], # ECDH over secp256k1 (i.e.: the Bitcoin curve)
|
||||
'ecdh-sha2-1.3.132.0.16': [[], [FAIL_UNPROVEN], [WARN_NOT_PQ_SAFE]], # sect283k1
|
||||
'ecdh-sha2-1.3.132.0.1': [[], [FAIL_UNPROVEN, FAIL_SMALL_ECC_MODULUS], [WARN_NOT_PQ_SAFE]], # sect163k1
|
||||
'ecdh-sha2-1.3.132.0.26': [[], [FAIL_UNPROVEN, FAIL_SMALL_ECC_MODULUS], [WARN_NOT_PQ_SAFE]], # sect233k1
|
||||
'ecdh-sha2-1.3.132.0.27': [[], [FAIL_SMALL_ECC_MODULUS, FAIL_NSA_BACKDOORED_CURVE], [WARN_NOT_PQ_SAFE]], # sect233r1
|
||||
'ecdh-sha2-1.3.132.0.33': [[], [FAIL_SMALL_ECC_MODULUS, FAIL_NSA_BACKDOORED_CURVE], [WARN_NOT_PQ_SAFE]], # NIST P-224 / secp224r1
|
||||
'ecdh-sha2-1.3.132.0.34': [[], [FAIL_NSA_BACKDOORED_CURVE], [WARN_NOT_PQ_SAFE]], # NIST P-384 / secp384r1
|
||||
'ecdh-sha2-1.3.132.0.35': [[], [FAIL_NSA_BACKDOORED_CURVE], [WARN_NOT_PQ_SAFE]], # NIST P-521 / secp521r1
|
||||
'ecdh-sha2-1.3.132.0.36': [[], [FAIL_UNPROVEN], [WARN_NOT_PQ_SAFE]], # sect409k1
|
||||
'ecdh-sha2-1.3.132.0.37': [[], [FAIL_NSA_BACKDOORED_CURVE], [WARN_NOT_PQ_SAFE]], # sect409r1
|
||||
'ecdh-sha2-1.3.132.0.38': [[], [FAIL_UNPROVEN], [WARN_NOT_PQ_SAFE]], # sect571k1
|
||||
|
||||
# Note: the base64 strings, according to draft 6 of RFC5656, is Base64(MD5(DER(OID))). The final RFC5656 dropped the base64 strings in favor of plain OID concatenation, but apparently some SSH servers implement them anyway. See: https://datatracker.ietf.org/doc/html/draft-green-secsh-ecc-06#section-9.2
|
||||
'ecdh-sha2-4MHB+NBt3AlaSRQ7MnB4cg==': [[], [FAIL_UNPROVEN, FAIL_SMALL_ECC_MODULUS]], # sect163k1
|
||||
'ecdh-sha2-5pPrSUQtIaTjUSt5VZNBjg==': [[], [FAIL_SMALL_ECC_MODULUS, FAIL_NSA_BACKDOORED_CURVE]], # NIST P-192 / secp192r1
|
||||
'ecdh-sha2-9UzNcgwTlEnSCECZa7V1mw==': [[], [FAIL_NSA_BACKDOORED_CURVE]], # NIST P-256 / secp256r1
|
||||
'ecdh-sha2-brainpoolp256r1@genua.de': [[], [FAIL_UNPROVEN]],
|
||||
'ecdh-sha2-brainpoolp384r1@genua.de': [[], [FAIL_UNPROVEN]],
|
||||
'ecdh-sha2-brainpoolp521r1@genua.de': [[], [FAIL_UNPROVEN]],
|
||||
'ecdh-sha2-curve25519': [[], []],
|
||||
'ecdh-sha2-D3FefCjYoJ/kfXgAyLddYA==': [[], [FAIL_NSA_BACKDOORED_CURVE]], # sect409r1
|
||||
'ecdh-sha2-h/SsxnLCtRBh7I9ATyeB3A==': [[], [FAIL_NSA_BACKDOORED_CURVE]], # NIST P-521 / secp521r1
|
||||
'ecdh-sha2-m/FtSAmrV4j/Wy6RVUaK7A==': [[], [FAIL_UNPROVEN]], # sect409k1
|
||||
'ecdh-sha2-mNVwCXAoS1HGmHpLvBC94w==': [[], [FAIL_UNPROVEN]], # sect571k1
|
||||
'ecdh-sha2-nistb233': [[], [FAIL_UNPROVEN, FAIL_SMALL_ECC_MODULUS]],
|
||||
'ecdh-sha2-nistb409': [[], [FAIL_UNPROVEN]],
|
||||
'ecdh-sha2-nistk163': [[], [FAIL_UNPROVEN, FAIL_SMALL_ECC_MODULUS]],
|
||||
'ecdh-sha2-nistk233': [[], [FAIL_UNPROVEN, FAIL_SMALL_ECC_MODULUS]],
|
||||
'ecdh-sha2-nistk283': [[], [FAIL_UNPROVEN]],
|
||||
'ecdh-sha2-nistk409': [[], [FAIL_UNPROVEN]],
|
||||
'ecdh-sha2-nistp192': [[], [FAIL_NSA_BACKDOORED_CURVE]],
|
||||
'ecdh-sha2-nistp224': [[], [FAIL_NSA_BACKDOORED_CURVE]],
|
||||
'ecdh-sha2-nistp256': [['5.7,d2013.62,l10.6.0'], [FAIL_NSA_BACKDOORED_CURVE]],
|
||||
'ecdh-sha2-nistp384': [['5.7,d2013.62'], [FAIL_NSA_BACKDOORED_CURVE]],
|
||||
'ecdh-sha2-nistp521': [['5.7,d2013.62'], [FAIL_NSA_BACKDOORED_CURVE]],
|
||||
'ecdh-sha2-nistt571': [[], [FAIL_UNPROVEN]],
|
||||
'ecdh-sha2-qCbG5Cn/jjsZ7nBeR7EnOA==': [[FAIL_SMALL_ECC_MODULUS, FAIL_NSA_BACKDOORED_CURVE]], # sect233r1
|
||||
'ecdh-sha2-qcFQaMAMGhTziMT0z+Tuzw==': [[], [FAIL_NSA_BACKDOORED_CURVE]], # NIST P-384 / secp384r1
|
||||
'ecdh-sha2-VqBg4QRPjxx1EXZdV0GdWQ==': [[], [FAIL_NSA_BACKDOORED_CURVE, FAIL_SMALL_ECC_MODULUS]], # NIST P-224 / secp224r1
|
||||
'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': [[], [], [], [INFO_EXTENSION_NEGOTIATION]], # Extension negotiation (RFC 8308)
|
||||
'ext-info-s': [[], [], [], [INFO_EXTENSION_NEGOTIATION]], # Extension negotiation (RFC 8308)
|
||||
'ecdh-sha2-4MHB+NBt3AlaSRQ7MnB4cg==': [[], [FAIL_UNPROVEN, FAIL_SMALL_ECC_MODULUS], [WARN_NOT_PQ_SAFE]], # sect163k1
|
||||
'ecdh-sha2-5pPrSUQtIaTjUSt5VZNBjg==': [[], [FAIL_SMALL_ECC_MODULUS, FAIL_NSA_BACKDOORED_CURVE], [WARN_NOT_PQ_SAFE]], # NIST P-192 / secp192r1
|
||||
'ecdh-sha2-9UzNcgwTlEnSCECZa7V1mw==': [[], [FAIL_NSA_BACKDOORED_CURVE], [WARN_NOT_PQ_SAFE]], # NIST P-256 / secp256r1
|
||||
'ecdh-sha2-brainpoolp256r1@genua.de': [[], [FAIL_UNPROVEN], [WARN_NOT_PQ_SAFE]],
|
||||
'ecdh-sha2-brainpoolp384r1@genua.de': [[], [FAIL_UNPROVEN], [WARN_NOT_PQ_SAFE]],
|
||||
'ecdh-sha2-brainpoolp521r1@genua.de': [[], [FAIL_UNPROVEN], [WARN_NOT_PQ_SAFE]],
|
||||
'ecdh-sha2-curve25519': [[], [], [WARN_NOT_PQ_SAFE]],
|
||||
'ecdh-sha2-D3FefCjYoJ/kfXgAyLddYA==': [[], [FAIL_NSA_BACKDOORED_CURVE], [WARN_NOT_PQ_SAFE]], # sect409r1
|
||||
'ecdh-sha2-h/SsxnLCtRBh7I9ATyeB3A==': [[], [FAIL_NSA_BACKDOORED_CURVE], [WARN_NOT_PQ_SAFE]], # NIST P-521 / secp521r1
|
||||
'ecdh-sha2-m/FtSAmrV4j/Wy6RVUaK7A==': [[], [FAIL_UNPROVEN], [WARN_NOT_PQ_SAFE]], # sect409k1
|
||||
'ecdh-sha2-mNVwCXAoS1HGmHpLvBC94w==': [[], [FAIL_UNPROVEN], [WARN_NOT_PQ_SAFE]], # sect571k1
|
||||
'ecdh-sha2-nistb233': [[], [FAIL_UNPROVEN, FAIL_SMALL_ECC_MODULUS], [WARN_NOT_PQ_SAFE]],
|
||||
'ecdh-sha2-nistb409': [[], [FAIL_UNPROVEN], [WARN_NOT_PQ_SAFE]],
|
||||
'ecdh-sha2-nistk163': [[], [FAIL_UNPROVEN, FAIL_SMALL_ECC_MODULUS], [WARN_NOT_PQ_SAFE]],
|
||||
'ecdh-sha2-nistk233': [[], [FAIL_UNPROVEN, FAIL_SMALL_ECC_MODULUS], [WARN_NOT_PQ_SAFE]],
|
||||
'ecdh-sha2-nistk283': [[], [FAIL_UNPROVEN], [WARN_NOT_PQ_SAFE]],
|
||||
'ecdh-sha2-nistk409': [[], [FAIL_UNPROVEN], [WARN_NOT_PQ_SAFE]],
|
||||
'ecdh-sha2-nistp192': [[], [FAIL_NSA_BACKDOORED_CURVE], [WARN_NOT_PQ_SAFE]],
|
||||
'ecdh-sha2-nistp224': [[], [FAIL_NSA_BACKDOORED_CURVE], [WARN_NOT_PQ_SAFE]],
|
||||
'ecdh-sha2-nistp256': [['5.7,d2013.62,l10.6.0'], [FAIL_NSA_BACKDOORED_CURVE], [WARN_NOT_PQ_SAFE]],
|
||||
'ecdh-sha2-nistp384': [['5.7,d2013.62'], [FAIL_NSA_BACKDOORED_CURVE], [WARN_NOT_PQ_SAFE]],
|
||||
'ecdh-sha2-nistp521': [['5.7,d2013.62'], [FAIL_NSA_BACKDOORED_CURVE], [WARN_NOT_PQ_SAFE]],
|
||||
'ecdh-sha2-nistt571': [[], [FAIL_UNPROVEN], [WARN_NOT_PQ_SAFE]],
|
||||
'ecdh-sha2-qCbG5Cn/jjsZ7nBeR7EnOA==': [[], [FAIL_SMALL_ECC_MODULUS, FAIL_NSA_BACKDOORED_CURVE], [WARN_NOT_PQ_SAFE]], # sect233r1
|
||||
'ecdh-sha2-qcFQaMAMGhTziMT0z+Tuzw==': [[], [FAIL_NSA_BACKDOORED_CURVE], [WARN_NOT_PQ_SAFE]], # NIST P-384 / secp384r1
|
||||
'ecdh-sha2-VqBg4QRPjxx1EXZdV0GdWQ==': [[], [FAIL_NSA_BACKDOORED_CURVE, FAIL_SMALL_ECC_MODULUS], [WARN_NOT_PQ_SAFE]], # NIST P-224 / secp224r1
|
||||
'ecdh-sha2-wiRIU8TKjMZ418sMqlqtvQ==': [[], [FAIL_UNPROVEN], [WARN_NOT_PQ_SAFE]], # sect283k1
|
||||
'ecdh-sha2-zD/b3hu/71952ArpUG4OjQ==': [[], [FAIL_UNPROVEN, FAIL_SMALL_ECC_MODULUS], [WARN_NOT_PQ_SAFE]], # sect233k1
|
||||
'ecmqv-sha2': [[], [FAIL_UNPROVEN], [WARN_NOT_PQ_SAFE]],
|
||||
'ext-info-c': [['7.2'], [], [], [INFO_EXTENSION_NEGOTIATION]], # Extension negotiation (RFC 8308)
|
||||
'ext-info-s': [['9.6'], [], [], [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]],
|
||||
'gss-curve25519-sha256-*': [[]],
|
||||
'gss-curve448-sha512-*': [[]],
|
||||
'gss-gex-sha1-*': [[], [FAIL_SHA1]],
|
||||
'gss-gex-sha256-*': [[]],
|
||||
'gss-group14-sha1-*': [[], [FAIL_SHA1], [WARN_2048BIT_MODULUS]],
|
||||
'gss-group14-sha256-*': [[], [], [WARN_2048BIT_MODULUS]],
|
||||
'gss-group15-sha512-*': [[]],
|
||||
'gss-group16-sha512-*': [[]],
|
||||
'gss-group17-sha512-*': [[]],
|
||||
'gss-group18-sha512-*': [[]],
|
||||
'gss-group1-sha1-*': [[], [FAIL_1024BIT_MODULUS, FAIL_LOGJAM_ATTACK, FAIL_SHA1]],
|
||||
'gss-nistp256-sha256-*': [[], [FAIL_NSA_BACKDOORED_CURVE]],
|
||||
'gss-nistp384-sha256-*': [[], [FAIL_NSA_BACKDOORED_CURVE]],
|
||||
'gss-nistp384-sha384-*': [[], [FAIL_NSA_BACKDOORED_CURVE]],
|
||||
'gss-nistp521-sha512-*': [[], [FAIL_NSA_BACKDOORED_CURVE]],
|
||||
'kexAlgoCurve25519SHA256': [[]],
|
||||
'kexAlgoDH14SHA1': [[], [FAIL_SHA1], [WARN_2048BIT_MODULUS]],
|
||||
'kexAlgoDH1SHA1': [[], [FAIL_1024BIT_MODULUS, FAIL_LOGJAM_ATTACK, FAIL_SHA1]],
|
||||
'kexAlgoECDH256': [[], [FAIL_NSA_BACKDOORED_CURVE]],
|
||||
'kexAlgoECDH384': [[], [FAIL_NSA_BACKDOORED_CURVE]],
|
||||
'kexAlgoECDH521': [[], [FAIL_NSA_BACKDOORED_CURVE]],
|
||||
'kexguess2@matt.ucc.asn.au': [['d2013.57']],
|
||||
'm383-sha384@libassh.org': [[], [FAIL_UNPROVEN]],
|
||||
'm511-sha512@libassh.org': [[], [FAIL_UNPROVEN]],
|
||||
'rsa1024-sha1': [[], [FAIL_1024BIT_MODULUS, FAIL_SHA1]],
|
||||
'rsa2048-sha256': [[], [], [WARN_2048BIT_MODULUS]],
|
||||
'sm2kep-sha2-nistp256': [[], [FAIL_NSA_BACKDOORED_CURVE, FAIL_UNTRUSTED]],
|
||||
'gss-13.3.132.0.10-sha256-*': [[], [FAIL_UNKNOWN], [WARN_NOT_PQ_SAFE]],
|
||||
'gss-curve25519-sha256-*': [[], [], [WARN_NOT_PQ_SAFE]],
|
||||
'gss-curve448-sha512-*': [[], [], [WARN_NOT_PQ_SAFE]],
|
||||
'gss-gex-sha1-*': [[], [FAIL_SHA1], [WARN_NOT_PQ_SAFE]],
|
||||
'gss-gex-sha256-*': [[], [], [WARN_NOT_PQ_SAFE]],
|
||||
'gss-group14-sha1-*': [[], [FAIL_SHA1], [WARN_2048BIT_MODULUS, WARN_NOT_PQ_SAFE]],
|
||||
'gss-group14-sha256-*': [[], [], [WARN_2048BIT_MODULUS, WARN_NOT_PQ_SAFE]],
|
||||
'gss-group15-sha512-*': [[], [], [WARN_NOT_PQ_SAFE]],
|
||||
'gss-group16-sha512-*': [[], [], [WARN_NOT_PQ_SAFE]],
|
||||
'gss-group17-sha512-*': [[], [], [WARN_NOT_PQ_SAFE]],
|
||||
'gss-group18-sha512-*': [[], [], [WARN_NOT_PQ_SAFE]],
|
||||
'gss-group1-sha1-*': [[], [FAIL_1024BIT_MODULUS, FAIL_LOGJAM_ATTACK, FAIL_SHA1], [WARN_NOT_PQ_SAFE]],
|
||||
'gss-nistp256-sha256-*': [[], [FAIL_NSA_BACKDOORED_CURVE], [WARN_NOT_PQ_SAFE]],
|
||||
'gss-nistp384-sha256-*': [[], [FAIL_NSA_BACKDOORED_CURVE], [WARN_NOT_PQ_SAFE]],
|
||||
'gss-nistp384-sha384-*': [[], [FAIL_NSA_BACKDOORED_CURVE], [WARN_NOT_PQ_SAFE]],
|
||||
'gss-nistp521-sha512-*': [[], [FAIL_NSA_BACKDOORED_CURVE], [WARN_NOT_PQ_SAFE]],
|
||||
'kexAlgoCurve25519SHA256': [[], [], [WARN_NOT_PQ_SAFE]],
|
||||
'kexAlgoDH14SHA1': [[], [FAIL_SHA1], [WARN_2048BIT_MODULUS, WARN_NOT_PQ_SAFE]],
|
||||
'kexAlgoDH1SHA1': [[], [FAIL_1024BIT_MODULUS, FAIL_LOGJAM_ATTACK, FAIL_SHA1], [WARN_NOT_PQ_SAFE]],
|
||||
'kexAlgoECDH256': [[], [FAIL_NSA_BACKDOORED_CURVE], [WARN_NOT_PQ_SAFE]],
|
||||
'kexAlgoECDH384': [[], [FAIL_NSA_BACKDOORED_CURVE], [WARN_NOT_PQ_SAFE]],
|
||||
'kexAlgoECDH521': [[], [FAIL_NSA_BACKDOORED_CURVE], [WARN_NOT_PQ_SAFE]],
|
||||
'kexguess2@matt.ucc.asn.au': [['d2013.57'], [], [WARN_NOT_PQ_SAFE]],
|
||||
'm383-sha384@libassh.org': [[], [FAIL_UNPROVEN], [WARN_NOT_PQ_SAFE]],
|
||||
'm511-sha512@libassh.org': [[], [FAIL_UNPROVEN], [WARN_NOT_PQ_SAFE]],
|
||||
'mlkem768x25519-sha256': [['9.9'], [], [], [INFO_HYBRID_PQ_X25519_KEX]],
|
||||
'rsa1024-sha1': [[], [FAIL_1024BIT_MODULUS, FAIL_SHA1], [WARN_NOT_PQ_SAFE]],
|
||||
'rsa2048-sha256': [[], [], [WARN_2048BIT_MODULUS, WARN_NOT_PQ_SAFE]],
|
||||
'sm2kep-sha2-nistp256': [[], [FAIL_NSA_BACKDOORED_CURVE, FAIL_UNTRUSTED], [WARN_NOT_PQ_SAFE]],
|
||||
'sntrup4591761x25519-sha512@tinyssh.org': [['8.0', '8.4'], [], [WARN_EXPERIMENTAL], [INFO_WITHDRAWN_PQ_ALG]],
|
||||
'sntrup761x25519-sha512@openssh.com': [['8.5'], [], [], [INFO_DEFAULT_OPENSSH_KEX_90]],
|
||||
'sntrup761x25519-sha512': [['9.9'], [], [], [INFO_DEFAULT_OPENSSH_KEX_99, INFO_HYBRID_PQ_X25519_KEX]],
|
||||
'sntrup761x25519-sha512@openssh.com': [['8.5'], [], [], [INFO_DEFAULT_OPENSSH_KEX_90_TO_98, INFO_HYBRID_PQ_X25519_KEX]],
|
||||
'x25519-kyber-512r3-sha256-d00@amazon.com': [[]],
|
||||
'x25519-kyber512-sha512@aws.amazon.com': [[]],
|
||||
},
|
||||
@ -346,6 +351,7 @@ class SSH2_KexDB: # pylint: disable=too-few-public-methods
|
||||
'des-cbc-ssh1': [[], [FAIL_DES], [WARN_CIPHER_MODE, WARN_BLOCK_SIZE]],
|
||||
'des-cbc@ssh.com': [[], [FAIL_DES], [WARN_CIPHER_MODE, WARN_BLOCK_SIZE]],
|
||||
'des': [[], [FAIL_DES], [WARN_CIPHER_MODE, WARN_BLOCK_SIZE]],
|
||||
'grasshopper-ctr128': [[], [FAIL_UNTRUSTED]],
|
||||
'idea-cbc': [[], [FAIL_IDEA], [WARN_CIPHER_MODE]],
|
||||
'idea-cfb': [[], [FAIL_IDEA], [WARN_CIPHER_MODE]],
|
||||
'idea-ctr': [[], [FAIL_IDEA]],
|
||||
|
@ -1,6 +1,7 @@
|
||||
"""
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (C) 2024 Joe Testa (jtesta@positronsecurity.com)
|
||||
Copyright (C) 2017 Andris Raugulis (moo@arthepsy.eu)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
@ -48,3 +49,10 @@ class SSH2_KexParty:
|
||||
@property
|
||||
def languages(self) -> List[str]:
|
||||
return self.__languages
|
||||
|
||||
def __str__(self) -> str:
|
||||
ret = "Ciphers: " + ", ".join(self.__enc)
|
||||
ret += "\nMACs: " + ", ".join(self.__mac)
|
||||
ret += "\nCompressions: " + ", ".join(self.__compression)
|
||||
ret += "\nLanguages: " + ", ".join(self.__languages)
|
||||
return ret
|
||||
|
@ -2,7 +2,7 @@
|
||||
"""
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (C) 2017-2023 Joe Testa (jtesta@positronsecurity.com)
|
||||
Copyright (C) 2017-2024 Joe Testa (jtesta@positronsecurity.com)
|
||||
Copyright (C) 2017 Andris Raugulis (moo@arthepsy.eu)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
@ -23,9 +23,9 @@
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
import argparse
|
||||
import concurrent.futures
|
||||
import copy
|
||||
import getopt
|
||||
import json
|
||||
import multiprocessing
|
||||
import os
|
||||
@ -33,6 +33,7 @@ import re
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
|
||||
# pylint: disable=unused-import
|
||||
from typing import Dict, List, Set, Sequence, Tuple, Iterable # noqa: F401
|
||||
from typing import cast, Callable, Optional, Union, Any # noqa: F401
|
||||
@ -61,7 +62,6 @@ from ssh_audit.ssh2_kex import SSH2_Kex
|
||||
from ssh_audit.ssh2_kexdb import SSH2_KexDB
|
||||
from ssh_audit.ssh_socket import SSH_Socket
|
||||
from ssh_audit.utils import Utils
|
||||
from ssh_audit.versionvulnerabilitydb import VersionVulnerabilityDB
|
||||
|
||||
|
||||
# no_idna_workaround = False
|
||||
@ -69,7 +69,7 @@ from ssh_audit.versionvulnerabilitydb import VersionVulnerabilityDB
|
||||
# Only import colorama under Windows. Other OSes can natively handle terminal colors.
|
||||
if sys.platform == 'win32':
|
||||
try:
|
||||
from colorama import just_fix_windows_console
|
||||
from colorama import just_fix_windows_console # type: ignore
|
||||
just_fix_windows_console()
|
||||
except ImportError:
|
||||
pass
|
||||
@ -83,61 +83,6 @@ if sys.platform == 'win32':
|
||||
# no_idna_workaround = True
|
||||
|
||||
|
||||
def usage(uout: OutputBuffer, err: Optional[str] = None) -> None:
|
||||
retval = exitcodes.GOOD
|
||||
p = os.path.basename(sys.argv[0])
|
||||
uout.head('# {} {}, https://github.com/jtesta/ssh-audit\n'.format(p, VERSION))
|
||||
if err is not None and len(err) > 0:
|
||||
uout.fail(err + '\n')
|
||||
retval = exitcodes.UNKNOWN_ERROR
|
||||
uout.info('usage: {0} [options] <host>\n'.format(p))
|
||||
uout.info(' -h, --help print this help')
|
||||
uout.info(' -1, --ssh1 force ssh version 1 only')
|
||||
uout.info(' -2, --ssh2 force ssh version 2 only')
|
||||
uout.info(' -4, --ipv4 enable IPv4 (order of precedence)')
|
||||
uout.info(' -6, --ipv6 enable IPv6 (order of precedence)')
|
||||
uout.info(' -b, --batch batch output')
|
||||
uout.info(' -c, --client-audit starts a server on port 2222 to audit client\n software config (use -p to change port;\n use -t to change timeout)')
|
||||
uout.info(' --conn-rate-test=N[:max_rate] perform a connection rate test (useful')
|
||||
uout.info(' for collecting metrics related to')
|
||||
uout.info(' susceptibility of the DHEat vuln).')
|
||||
uout.info(' Testing is conducted with N concurrent')
|
||||
uout.info(' sockets with an optional maximum rate')
|
||||
uout.info(' of connections per second.')
|
||||
uout.info(' -d, --debug debug output')
|
||||
uout.info(' --dheat=N[:kex[:e_len]] continuously perform the DHEat DoS attack')
|
||||
uout.info(' (CVE-2002-20001) against the target using N')
|
||||
uout.info(' concurrent sockets. Optionally, a specific')
|
||||
uout.info(' key exchange algorithm can be specified')
|
||||
uout.info(' instead of allowing it to be automatically')
|
||||
uout.info(' chosen. Additionally, a small length of')
|
||||
uout.info(' the fake e value sent to the server can')
|
||||
uout.info(' be chosen for a more efficient attack (such')
|
||||
uout.info(' as 4).')
|
||||
uout.info(' -g, --gex-test=<x[,y,...]> dh gex modulus size test')
|
||||
uout.info(' <min1:pref1:max1[,min2:pref2:max2,...]>')
|
||||
uout.info(' <x-y[:step]>')
|
||||
uout.info(' -j, --json JSON output (use -jj to enable indents)')
|
||||
uout.info(' -l, --level=<level> minimum output level (info|warn|fail)')
|
||||
uout.info(' -L, --list-policies list all the official, built-in policies. Use with -v')
|
||||
uout.info(' to view policy change logs.')
|
||||
uout.info(' --lookup=<alg1,alg2,...> looks up an algorithm(s) without\n connecting to a server')
|
||||
uout.info(' -M, --make-policy=<policy.txt> creates a policy based on the target server\n (i.e.: the target server has the ideal\n configuration that other servers should\n adhere to)')
|
||||
uout.info(' -m, --manual print the man page (Windows only)')
|
||||
uout.info(' -n, --no-colors disable colors (automatic when the NO_COLOR')
|
||||
uout.info(' environment variable is set)')
|
||||
uout.info(' -p, --port=<port> port to connect')
|
||||
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(' -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(' --threads=<threads> number of threads to use when scanning multiple\n targets (-T/--targets) (default: 32)')
|
||||
uout.info(' -v, --verbose verbose output')
|
||||
uout.sep()
|
||||
uout.write()
|
||||
sys.exit(retval)
|
||||
|
||||
|
||||
def output_algorithms(out: OutputBuffer, title: str, alg_db: Dict[str, Dict[str, List[List[Optional[str]]]]], alg_type: str, algorithms: List[str], unknown_algs: List[str], is_json_output: bool, program_retval: int, maxlen: int = 0, host_keys: Optional[Dict[str, Dict[str, Union[bytes, str, int]]]] = None, dh_modulus_sizes: Optional[Dict[str, int]] = None) -> int: # pylint: disable=too-many-arguments
|
||||
with out:
|
||||
for algorithm in algorithms:
|
||||
@ -273,65 +218,18 @@ def output_compatibility(out: OutputBuffer, algs: Algorithms, client_audit: bool
|
||||
out.good('(gen) compatibility: ' + ', '.join(comp_text))
|
||||
|
||||
|
||||
def output_security_sub(out: OutputBuffer, sub: str, software: Optional[Software], client_audit: bool, padlen: int) -> List[Dict[str, Union[str, float]]]:
|
||||
ret: List[Dict[str, Union[str, float]]] = []
|
||||
|
||||
secdb = VersionVulnerabilityDB.CVE if sub == 'cve' else VersionVulnerabilityDB.TXT
|
||||
if software is None or software.product not in secdb:
|
||||
return ret
|
||||
for line in secdb[software.product]:
|
||||
vfrom: str = ''
|
||||
vtill: str = ''
|
||||
vfrom, vtill = line[0:2]
|
||||
if not software.between_versions(vfrom, vtill):
|
||||
continue
|
||||
target: int = 0
|
||||
name: str = ''
|
||||
target, name = line[2:4]
|
||||
is_server = target & 1 == 1
|
||||
is_client = target & 2 == 2
|
||||
# is_local = target & 4 == 4
|
||||
|
||||
# If this security entry applies only to servers, but we're testing a client, then skip it. Similarly, skip entries that apply only to clients, but we're testing a server.
|
||||
if (is_server and not is_client and client_audit) or (is_client and not is_server and not client_audit):
|
||||
continue
|
||||
p = '' if out.batch else ' ' * (padlen - len(name))
|
||||
if sub == 'cve':
|
||||
cvss: float = 0.0
|
||||
descr: str = ''
|
||||
cvss, descr = line[4:6]
|
||||
|
||||
# Critical CVSS scores (>= 8.0) are printed as a fail, otherwise they are printed as a warning.
|
||||
out_func = out.warn
|
||||
if cvss >= 8.0:
|
||||
out_func = out.fail
|
||||
out_func('(cve) {}{} -- (CVSSv2: {}) {}'.format(name, p, cvss, descr))
|
||||
ret.append({'name': name, 'cvssv2': cvss, 'description': descr})
|
||||
else:
|
||||
descr = line[4]
|
||||
out.fail('(sec) {}{} -- {}'.format(name, p, descr))
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def output_security(out: OutputBuffer, banner: Optional[Banner], client_audit: bool, padlen: int, is_json_output: bool) -> List[Dict[str, Union[str, float]]]:
|
||||
cves = []
|
||||
def output_security(out: OutputBuffer, banner: Optional[Banner], padlen: int, is_json_output: bool) -> None:
|
||||
|
||||
with out:
|
||||
if banner is not None:
|
||||
software = Software.parse(banner)
|
||||
cves = output_security_sub(out, 'cve', software, client_audit, padlen)
|
||||
_ = output_security_sub(out, 'txt', software, client_audit, padlen)
|
||||
if banner.protocol[0] == 1:
|
||||
p = '' if out.batch else ' ' * (padlen - 14)
|
||||
out.fail('(sec) SSH v1 enabled{} -- SSH v1 can be exploited to recover plaintext passwords'.format(p))
|
||||
if (banner is not None) and (banner.protocol[0] == 1):
|
||||
p = '' if out.batch else ' ' * (padlen - 14)
|
||||
out.fail('(sec) SSH v1 enabled{} -- SSH v1 can be exploited to recover plaintext passwords'.format(p))
|
||||
|
||||
if not out.is_section_empty() and not is_json_output:
|
||||
out.head('# security')
|
||||
out.flush_section()
|
||||
out.sep()
|
||||
|
||||
return cves
|
||||
|
||||
|
||||
def output_fingerprints(out: OutputBuffer, algs: Algorithms, is_json_output: bool) -> None:
|
||||
with out:
|
||||
@ -360,11 +258,19 @@ def output_fingerprints(out: OutputBuffer, algs: Algorithms, is_json_output: boo
|
||||
fp_types = sorted(fps.keys())
|
||||
for fp_type in fp_types:
|
||||
fp = fps[fp_type]
|
||||
out.good('(fin) {}: {}'.format(fp_type, fp.sha256))
|
||||
|
||||
# Don't output any ECDSA or DSS fingerprints unless verbose mode is enabled.
|
||||
if fp_type.startswith("ecdsa-") or (fp_type == "ssh-dss"):
|
||||
if out.verbose:
|
||||
out.warn('(fin) {}: {} -- [info] this fingerprint type is insecure and should not be relied upon'.format(fp_type, fp.sha256))
|
||||
else:
|
||||
continue # If verbose mode is not enabled, skip this type entirely.
|
||||
else:
|
||||
out.good('(fin) {}: {}'.format(fp_type, fp.sha256))
|
||||
|
||||
# Output the MD5 hash too if verbose mode is enabled.
|
||||
if out.verbose:
|
||||
out.info('(fin) {}: {} -- [info] do not rely on MD5 fingerprints for server identification; it is insecure for this use case'.format(fp_type, fp.md5))
|
||||
out.warn('(fin) {}: {} -- [info] do not rely on MD5 fingerprints for server identification; it is insecure for this use case'.format(fp_type, fp.md5))
|
||||
|
||||
if not out.is_section_empty() and not is_json_output:
|
||||
out.head('# fingerprints')
|
||||
@ -376,31 +282,6 @@ def output_fingerprints(out: OutputBuffer, algs: Algorithms, is_json_output: boo
|
||||
def output_recommendations(out: OutputBuffer, algs: Algorithms, algorithm_recommendation_suppress_list: List[str], software: Optional[Software], is_json_output: bool, padlen: int = 0) -> bool:
|
||||
|
||||
ret = True
|
||||
# PuTTY's algorithms cannot be modified, so there's no point in issuing recommendations.
|
||||
if (software is not None) and (software.product == Product.PuTTY):
|
||||
max_vuln_version = 0.0
|
||||
max_cvssv2_severity = 0.0
|
||||
# Search the CVE database for the most recent vulnerable version and the max CVSSv2 score.
|
||||
for cve_list in VersionVulnerabilityDB.CVE['PuTTY']:
|
||||
vuln_version = float(cve_list[1])
|
||||
cvssv2_severity = cve_list[4]
|
||||
max_vuln_version = max(vuln_version, max_vuln_version)
|
||||
max_cvssv2_severity = max(cvssv2_severity, max_cvssv2_severity)
|
||||
|
||||
fn = out.warn
|
||||
if max_cvssv2_severity > 8.0:
|
||||
fn = out.fail
|
||||
|
||||
# Assuming that PuTTY versions will always increment by 0.01, we can calculate the first safe version by adding 0.01 to the latest vulnerable version.
|
||||
current_version = float(software.version)
|
||||
upgrade_to_version = max_vuln_version + 0.01
|
||||
if current_version < upgrade_to_version:
|
||||
out.head('# recommendations')
|
||||
fn('(rec) Upgrade to PuTTY v%.2f' % upgrade_to_version)
|
||||
out.sep()
|
||||
ret = False
|
||||
return ret
|
||||
|
||||
level_to_output = {
|
||||
"informational": out.good,
|
||||
"warning": out.warn,
|
||||
@ -421,6 +302,8 @@ def output_recommendations(out: OutputBuffer, algs: Algorithms, algorithm_recomm
|
||||
|
||||
fn = level_to_output[level]
|
||||
|
||||
an = '?'
|
||||
sg = '?'
|
||||
if action == 'del':
|
||||
an, sg = 'remove', '-'
|
||||
ret = False
|
||||
@ -434,7 +317,7 @@ def output_recommendations(out: OutputBuffer, algs: Algorithms, algorithm_recomm
|
||||
notes = " (%s)" % notes
|
||||
|
||||
fm = '(rec) {0}{1}{2}-- {3} algorithm to {4}{5} '
|
||||
fn(fm.format(sg, name, p, alg_type, an, notes))
|
||||
fn(fm.format(sg, name, p, alg_type, an, notes)) # type: ignore[operator]
|
||||
|
||||
if not out.is_section_empty() and not is_json_output:
|
||||
if software is not None:
|
||||
@ -649,9 +532,9 @@ def output(out: OutputBuffer, aconf: AuditConf, banner: Optional[Banner], header
|
||||
else:
|
||||
host = '%s:%d' % (aconf.host, aconf.port)
|
||||
|
||||
out.good('(gen) target: {}'. format(host))
|
||||
out.good('(gen) target: {}'. format(host), always_print=True)
|
||||
if client_audit:
|
||||
out.good('(gen) client IP: {}'.format(client_host))
|
||||
out.good('(gen) client IP: {}'.format(client_host), always_print=True)
|
||||
if len(header) > 0:
|
||||
out.info('(gen) header: ' + '\n'.join(header))
|
||||
if banner is not None:
|
||||
@ -684,7 +567,7 @@ def output(out: OutputBuffer, aconf: AuditConf, banner: Optional[Banner], header
|
||||
out.flush_section()
|
||||
out.sep()
|
||||
maxlen = algs.maxlen + 1
|
||||
cves = output_security(out, banner, client_audit, maxlen, aconf.json)
|
||||
output_security(out, banner, maxlen, aconf.json)
|
||||
# Filled in by output_algorithms() with unidentified algs.
|
||||
unknown_algorithms: List[str] = []
|
||||
|
||||
@ -719,9 +602,9 @@ def output(out: OutputBuffer, aconf: AuditConf, banner: Optional[Banner], header
|
||||
if aconf.json:
|
||||
out.reset()
|
||||
# Build & write the JSON struct.
|
||||
out.info(json.dumps(build_struct(aconf.host + ":" + str(aconf.port), banner, cves, kex=kex, client_host=client_host, software=software, algorithms=algs, algorithm_recommendation_suppress_list=algorithm_recommendation_suppress_list, additional_notes=additional_notes), indent=4 if aconf.json_print_indent else None, sort_keys=True))
|
||||
out.info(json.dumps(build_struct(aconf.host + ":" + str(aconf.port), banner, kex=kex, client_host=client_host, software=software, algorithms=algs, algorithm_recommendation_suppress_list=algorithm_recommendation_suppress_list, additional_notes=additional_notes), indent=4 if aconf.json_print_indent else None, sort_keys=True))
|
||||
elif len(unknown_algorithms) > 0: # If we encountered any unknown algorithms, ask the user to report them.
|
||||
out.warn("\n\n!!! WARNING: unknown algorithm(s) found!: %s. Please email the full output above to the maintainer (jtesta@positronsecurity.com), or create a Github issue at <https://github.com/jtesta/ssh-audit/issues>.\n" % ','.join(unknown_algorithms))
|
||||
out.warn("\n\n!!! WARNING: unknown algorithm(s) found!: %s. If this is the latest version of ssh-audit (see <https://github.com/jtesta/ssh-audit/releases>), please create a new Github issue at <https://github.com/jtesta/ssh-audit/issues> with the full output above.\n" % ','.join(unknown_algorithms))
|
||||
|
||||
return program_retval
|
||||
|
||||
@ -733,7 +616,12 @@ def evaluate_policy(out: OutputBuffer, aconf: AuditConf, banner: Optional['Banne
|
||||
|
||||
passed, error_struct, error_str = aconf.policy.evaluate(banner, kex)
|
||||
if aconf.json:
|
||||
json_struct = {'host': aconf.host, 'policy': aconf.policy.get_name_and_version(), 'passed': passed, 'errors': error_struct}
|
||||
warnings: List[str] = []
|
||||
if aconf.policy.is_outdated_builtin_policy():
|
||||
warnings.append("A newer version of this built-in policy is available.")
|
||||
|
||||
json_struct = {'host': aconf.host, 'port': aconf.port, 'policy': aconf.policy.get_name_and_version(), 'passed': passed, 'errors': error_struct, 'warnings': warnings}
|
||||
|
||||
out.info(json.dumps(json_struct, indent=4 if aconf.json_print_indent else None, sort_keys=True))
|
||||
else:
|
||||
spacing = ''
|
||||
@ -766,6 +654,10 @@ def evaluate_policy(out: OutputBuffer, aconf: AuditConf, banner: Optional['Banne
|
||||
out.fail("%sFailed!" % icon_fail)
|
||||
out.warn("\nErrors:\n%s" % error_str)
|
||||
|
||||
# If the user selected an out-dated built-in policy then issue a warning.
|
||||
if aconf.policy.is_outdated_builtin_policy():
|
||||
out.warn("Note: A newer version of this built-in policy is available. Use the -L option to view all available versions.")
|
||||
|
||||
return passed
|
||||
|
||||
|
||||
@ -836,8 +728,9 @@ def list_policies(out: OutputBuffer, verbose: bool) -> None:
|
||||
out.fail("Error: no built-in policies found!")
|
||||
else:
|
||||
out.info("\nHint: Use -P and provide the full name of a policy to run a policy scan with.\n")
|
||||
out.info("Hint: Use -L -v to also see the change log for each policy.\n")
|
||||
out.info("Hint: Use -L -v to see the change log for each policy, as well as previous versions.\n")
|
||||
out.info("Note: the general OpenSSH policies apply to the official releases only. OS distributions may back-port changes that cause failures (for example, Debian 11 back-ported the strict KEX mode into their package of OpenSSH v8.4, whereas it was only officially added to OpenSSH v9.6 and later). In these cases, consider creating a custom policy (-M option).\n")
|
||||
out.info("Note: instructions for hardening targets, which correspond to the above policies, can be found at: <https://ssh-audit.com/hardening_guides.html>\n")
|
||||
out.write()
|
||||
|
||||
|
||||
@ -876,7 +769,7 @@ def make_policy(aconf: AuditConf, banner: Optional['Banner'], kex: Optional['SSH
|
||||
print(err)
|
||||
|
||||
|
||||
def process_commandline(out: OutputBuffer, args: List[str], usage_cb: Callable[..., None]) -> 'AuditConf': # pylint: disable=too-many-statements
|
||||
def process_commandline(out: OutputBuffer, args: List[str]) -> 'AuditConf': # pylint: disable=too-many-statements
|
||||
# pylint: disable=too-many-branches
|
||||
aconf = AuditConf()
|
||||
|
||||
@ -889,82 +782,92 @@ def process_commandline(out: OutputBuffer, args: List[str], usage_cb: Callable[.
|
||||
aconf.colors = enable_colors
|
||||
out.use_colors = enable_colors
|
||||
|
||||
try:
|
||||
sopts = 'h1246M:p:P:jbcnvl:t:T:Lmdg:'
|
||||
lopts = ['help', 'ssh1', 'ssh2', 'ipv4', 'ipv6', 'make-policy=', 'port=', 'policy=', 'json', 'batch', 'client-audit', 'no-colors', 'verbose', 'level=', 'timeout=', 'targets=', 'list-policies', 'lookup=', 'threads=', 'manual', 'debug', 'gex-test=', 'dheat=', 'skip-rate-test', 'conn-rate-test=']
|
||||
opts, args = getopt.gnu_getopt(args, sopts, lopts)
|
||||
except getopt.GetoptError as err:
|
||||
usage_cb(out, str(err))
|
||||
aconf.ssh1, aconf.ssh2 = False, False
|
||||
host: str = ''
|
||||
oport: Optional[str] = None
|
||||
port: int = 0
|
||||
for o, a in opts:
|
||||
if o in ('-h', '--help'):
|
||||
usage_cb(out)
|
||||
elif o in ('-1', '--ssh1'):
|
||||
aconf.ssh1 = True
|
||||
elif o in ('-2', '--ssh2'):
|
||||
aconf.ssh2 = True
|
||||
elif o in ('-4', '--ipv4'):
|
||||
aconf.ipv4 = True
|
||||
elif o in ('-6', '--ipv6'):
|
||||
aconf.ipv6 = True
|
||||
elif o in ('-p', '--port'):
|
||||
oport = a
|
||||
elif o in ('-b', '--batch'):
|
||||
aconf.batch = True
|
||||
aconf.verbose = True
|
||||
elif o in ('-c', '--client-audit'):
|
||||
aconf.client_audit = True
|
||||
elif o in ('-j', '--json'):
|
||||
if aconf.json: # If specified twice, enable indent printing.
|
||||
aconf.json_print_indent = True
|
||||
else:
|
||||
aconf.json = True
|
||||
elif o in ('-v', '--verbose'):
|
||||
aconf.verbose = True
|
||||
out.verbose = True
|
||||
elif o in ('-l', '--level'):
|
||||
if a not in ('info', 'warn', 'fail'):
|
||||
usage_cb(out, 'level {} is not valid'.format(a))
|
||||
aconf.level = a
|
||||
elif o in ('-t', '--timeout'):
|
||||
aconf.timeout = float(a)
|
||||
aconf.timeout_set = True
|
||||
elif o in ('-M', '--make-policy'):
|
||||
aconf.make_policy = True
|
||||
aconf.policy_file = a
|
||||
elif o in ('-P', '--policy'):
|
||||
aconf.policy_file = a
|
||||
elif o in ('-T', '--targets'):
|
||||
aconf.target_file = a
|
||||
port: int = 22
|
||||
|
||||
# If we're on Windows, and we can't use the idna workaround, force only one thread to be used (otherwise a crash would occur).
|
||||
# if no_idna_workaround:
|
||||
# print("\nWARNING: the idna module was not found on this system, thus only single-threaded scanning will be done (this is a workaround for this Windows-specific crash: https://github.com/python/cpython/issues/73474). Multi-threaded scanning can be enabled by installing the idna module (pip install idna).\n")
|
||||
# aconf.threads = 1
|
||||
elif o == '--threads':
|
||||
aconf.threads = int(a)
|
||||
# if no_idna_workaround:
|
||||
# aconf.threads = 1
|
||||
elif o in ('-L', '--list-policies'):
|
||||
aconf.list_policies = True
|
||||
elif o == '--lookup':
|
||||
aconf.lookup = a
|
||||
elif o in ('-m', '--manual'):
|
||||
aconf.manual = True
|
||||
elif o in ('-d', '--debug'):
|
||||
parser = argparse.ArgumentParser(description="# {} {}, https://github.com/jtesta/ssh-audit".format(os.path.basename(sys.argv[0]), VERSION), allow_abbrev=False)
|
||||
|
||||
# Add short options to the parser
|
||||
parser.add_argument("-1", "--ssh1", action="store_true", dest="ssh1", default=False, help="force ssh version 1 only")
|
||||
parser.add_argument("-2", "--ssh2", action="store_true", dest="ssh2", default=False, help="force ssh version 2 only")
|
||||
parser.add_argument("-4", "--ipv4", action="store_true", dest="ipv4", default=False, help="enable IPv4 (order of precedence)")
|
||||
parser.add_argument("-6", "--ipv6", action="store_true", dest="ipv6", default=False, help="enable IPv6 (order of precedence)")
|
||||
parser.add_argument("-b", "--batch", action="store_true", dest="batch", default=False, help="batch output")
|
||||
parser.add_argument("-c", "--client-audit", action="store_true", dest="client_audit", default=False, help="starts a server on port 2222 to audit client software config (use -p to change port; use -t to change timeout)")
|
||||
parser.add_argument("-d", "--debug", action="store_true", dest="debug", default=False, help="enable debugging output")
|
||||
parser.add_argument("-g", "--gex-test", action="store", dest="gex_test", metavar="<min1:pref1:max1[,min2:pref2:max2,...]> / <x-y[:step]>", type=str, default=None, help="conducts a very customized Diffie-Hellman GEX modulus size test. Tests an array of minimum, preferred, and maximum values, or a range of values with an optional incremental step amount")
|
||||
parser.add_argument("-j", "--json", action="count", dest="json", default=0, help="enable JSON output (use -jj to enable indentation for better readability)")
|
||||
parser.add_argument("-l", "--level", action="store", dest="level", type=str, choices=["info", "warn", "fail"], default="info", help="minimum output level (default: %(default)s)")
|
||||
parser.add_argument("-L", "--list-policies", action="store_true", dest="list_policies", default=False, help="list all the official, built-in policies. Combine with -v to view policy change logs")
|
||||
parser.add_argument("-M", "--make-policy", action="store", dest="make_policy", metavar="custom_policy.txt", type=str, default=None, help="creates a policy based on the target server (i.e.: the target server has the ideal configuration that other servers should adhere to), and stores it in the file path specified")
|
||||
parser.add_argument("-m", "--manual", action="store_true", dest="manual", default=False, help="print the man page (Docker, PyPI, Snap, and Windows builds only)")
|
||||
parser.add_argument("-n", "--no-colors", action="store_true", dest="no_colors", default=False, help="disable colors (automatic when the NO_COLOR environment variable is set)")
|
||||
parser.add_argument("-P", "--policy", action="store", dest="policy", metavar="\"Built-In Policy Name\" / custom_policy.txt", type=str, default=None, help="run a policy test using the specified policy (use -L to see built-in policies, or specify filesystem path to custom policy created by -M)")
|
||||
parser.add_argument("-p", "--port", action="store", dest="oport", metavar="N", type=int, default=None, help="the TCP port to connect to (or to listen on when -c is used)")
|
||||
parser.add_argument("-T", "--targets", action="store", dest="targets", metavar="targets.txt", type=str, default=None, help="a file containing a list of target hosts (one per line, format HOST[:PORT]). Use -p/--port to set the default port for all hosts. Use --threads to control concurrent scans")
|
||||
parser.add_argument("-t", "--timeout", action="store", dest="timeout", metavar="N", type=int, default=5, help="timeout (in seconds) for connection and reading (default: %(default)s)")
|
||||
parser.add_argument("-v", "--verbose", action="store_true", dest="verbose", default=False, help="enable verbose output")
|
||||
|
||||
# Add long options to the parser
|
||||
parser.add_argument("--conn-rate-test", action="store", dest="conn_rate_test", metavar="N[:max_rate]", type=str, default=None, help="perform a connection rate test (useful for collecting metrics related to susceptibility of the DHEat vuln). Testing is conducted with N concurrent sockets with an optional maximum rate of connections per second")
|
||||
parser.add_argument("--dheat", action="store", dest="dheat", metavar="N[:kex[:e_len]]", type=str, default=None, help="continuously perform the DHEat DoS attack (CVE-2002-20001) against the target using N concurrent sockets. Optionally, a specific key exchange algorithm can be specified instead of allowing it to be automatically chosen. Additionally, a small length of the fake e value sent to the server can be chosen for a more efficient attack (such as 4).")
|
||||
parser.add_argument("--lookup", action="store", dest="lookup", metavar="alg1[,alg2,...]", type=str, default=None, help="looks up an algorithm(s) without connecting to a server.")
|
||||
parser.add_argument("--skip-rate-test", action="store_true", dest="skip_rate_test", default=False, help="skip the connection rate test during standard audits (used to safely infer whether the DHEat attack is viable)")
|
||||
parser.add_argument("--threads", action="store", dest="threads", metavar="N", type=int, default=32, help="number of threads to use when scanning multiple targets (-T/--targets) (default: %(default)s)")
|
||||
|
||||
# The mandatory target option. Or rather, mandatory when -L, -T, or --lookup are not used.
|
||||
parser.add_argument("host", nargs="?", action="store", type=str, default="", help="target hostname or IPv4/IPv6 address")
|
||||
|
||||
# If no arguments were given, print the help and exit.
|
||||
if len(args) < 1:
|
||||
parser.print_help()
|
||||
sys.exit(exitcodes.UNKNOWN_ERROR)
|
||||
|
||||
oport: Optional[int] = None
|
||||
try:
|
||||
argument = parser.parse_args(args=args)
|
||||
|
||||
# Set simple flags.
|
||||
aconf.client_audit = argument.client_audit
|
||||
aconf.ipv4 = argument.ipv4
|
||||
aconf.ipv6 = argument.ipv6
|
||||
aconf.level = argument.level
|
||||
aconf.list_policies = argument.list_policies
|
||||
aconf.manual = argument.manual
|
||||
aconf.skip_rate_test = argument.skip_rate_test
|
||||
aconf.ssh1 = argument.ssh1
|
||||
aconf.ssh2 = argument.ssh2
|
||||
oport = argument.oport
|
||||
|
||||
if argument.batch is True:
|
||||
aconf.batch = True
|
||||
|
||||
# If one -j was given, turn on JSON output. If -jj was given, enable indentation.
|
||||
aconf.json = argument.json > 0
|
||||
if argument.json > 1:
|
||||
aconf.json_print_indent = True
|
||||
|
||||
if argument.conn_rate_test is not None:
|
||||
aconf.conn_rate_test = argument.conn_rate_test
|
||||
|
||||
if argument.debug is True:
|
||||
aconf.debug = True
|
||||
out.debug = True
|
||||
elif o in ('-g', '--gex-test'):
|
||||
|
||||
if argument.dheat is not None:
|
||||
aconf.dheat = argument.dheat
|
||||
|
||||
if argument.gex_test is not None:
|
||||
dh_gex = argument.gex_test
|
||||
permitted_syntax = get_permitted_syntax_for_gex_test()
|
||||
|
||||
if not any(re.search(regex_str, a) for regex_str in permitted_syntax.values()):
|
||||
usage_cb(out, '{} {} is not valid'.format(o, a))
|
||||
if not any(re.search(regex_str, dh_gex) for regex_str in permitted_syntax.values()):
|
||||
out.fail('{} is not valid'.format(dh_gex), write_now=True)
|
||||
sys.exit(exitcodes.UNKNOWN_ERROR)
|
||||
|
||||
if re.search(permitted_syntax['RANGE'], a):
|
||||
extracted_digits = re.findall(r'\d+', a)
|
||||
if re.search(permitted_syntax['RANGE'], dh_gex):
|
||||
extracted_digits = re.findall(r'\d+', dh_gex)
|
||||
bits_left_bound = int(extracted_digits[0])
|
||||
bits_right_bound = int(extracted_digits[1])
|
||||
|
||||
@ -973,27 +876,52 @@ def process_commandline(out: OutputBuffer, args: List[str], usage_cb: Callable[.
|
||||
bits_step = int(extracted_digits[2])
|
||||
|
||||
if bits_step <= 0:
|
||||
usage_cb(out, '{} {} is not valid'.format(o, bits_step))
|
||||
out.fail('the step field cannot be 0 or less: {}'.format(bits_step), write_now=True)
|
||||
sys.exit(exitcodes.UNKNOWN_ERROR)
|
||||
|
||||
if all(x < 0 for x in (bits_left_bound, bits_right_bound)):
|
||||
usage_cb(out, '{} {} {} is not valid'.format(o, bits_left_bound, bits_right_bound))
|
||||
out.fail('{} {} {} is not valid'.format(dh_gex, bits_left_bound, bits_right_bound), write_now=True)
|
||||
sys.exit(exitcodes.UNKNOWN_ERROR)
|
||||
|
||||
aconf.gex_test = a
|
||||
elif o == '--dheat':
|
||||
aconf.dheat = a
|
||||
elif o == '--skip-rate-test':
|
||||
aconf.skip_rate_test = True
|
||||
elif o == '--conn-rate-test':
|
||||
aconf.conn_rate_test = a
|
||||
aconf.gex_test = dh_gex
|
||||
|
||||
if argument.lookup is not None:
|
||||
aconf.lookup = argument.lookup
|
||||
|
||||
if len(args) == 0 and aconf.client_audit is False and aconf.target_file is None and aconf.list_policies is False and aconf.lookup == '' and aconf.manual is False:
|
||||
usage_cb(out)
|
||||
if argument.make_policy is not None:
|
||||
aconf.make_policy = True
|
||||
aconf.policy_file = argument.make_policy
|
||||
|
||||
if argument.policy is not None:
|
||||
aconf.policy_file = argument.policy
|
||||
|
||||
if argument.targets is not None:
|
||||
aconf.target_file = argument.targets
|
||||
|
||||
if argument.threads is not None:
|
||||
aconf.threads = argument.threads
|
||||
|
||||
if argument.timeout is not None:
|
||||
aconf.timeout = float(argument.timeout)
|
||||
aconf.timeout_set = True
|
||||
|
||||
if argument.verbose is True:
|
||||
aconf.verbose = True
|
||||
out.verbose = True
|
||||
|
||||
except argparse.ArgumentError as err:
|
||||
out.fail(str(err), write_now=True)
|
||||
parser.print_help()
|
||||
sys.exit(exitcodes.UNKNOWN_ERROR)
|
||||
|
||||
if argument.host == "" and argument.client_audit is False and argument.targets is None and argument.list_policies is False and argument.lookup is None and argument.manual is False:
|
||||
out.fail("target host must be specified, unless -c, -m, -L, -T, or --lookup are used", write_now=True)
|
||||
sys.exit(exitcodes.UNKNOWN_ERROR)
|
||||
|
||||
if aconf.manual:
|
||||
return aconf
|
||||
|
||||
if aconf.lookup != '':
|
||||
if aconf.lookup != "":
|
||||
return aconf
|
||||
|
||||
if aconf.list_policies:
|
||||
@ -1002,25 +930,26 @@ def process_commandline(out: OutputBuffer, args: List[str], usage_cb: Callable[.
|
||||
|
||||
if aconf.client_audit is False and aconf.target_file is None:
|
||||
if oport is not None:
|
||||
host = args[0]
|
||||
host = argument.host
|
||||
else:
|
||||
host, port = Utils.parse_host_and_port(args[0])
|
||||
if not host and aconf.target_file is None:
|
||||
usage_cb(out, 'host is empty')
|
||||
host, port = Utils.parse_host_and_port(argument.host)
|
||||
|
||||
if port == 0 and oport is None:
|
||||
if aconf.client_audit: # The default port to listen on during a client audit is 2222.
|
||||
port = 2222
|
||||
else:
|
||||
port = 22
|
||||
if not host and aconf.target_file is None:
|
||||
out.fail("target host is not specified", write_now=True)
|
||||
sys.exit(exitcodes.UNKNOWN_ERROR)
|
||||
|
||||
if oport is None and aconf.client_audit: # The default port to listen on during a client audit is 2222.
|
||||
port = 2222
|
||||
|
||||
if oport is not None:
|
||||
port = Utils.parse_int(oport)
|
||||
if port <= 0 or port > 65535:
|
||||
usage_cb(out, 'port {} is not valid'.format(oport))
|
||||
if port < 1 or port > 65535:
|
||||
out.fail("port must be greater than 0 and less than 65535: {}".format(oport), write_now=True)
|
||||
sys.exit(exitcodes.UNKNOWN_ERROR)
|
||||
|
||||
aconf.host = host
|
||||
aconf.port = port
|
||||
|
||||
if not (aconf.ssh1 or aconf.ssh2):
|
||||
aconf.ssh1, aconf.ssh2 = True, True
|
||||
|
||||
@ -1049,26 +978,23 @@ def process_commandline(out: OutputBuffer, args: List[str], usage_cb: Callable[.
|
||||
try:
|
||||
aconf.policy = Policy(policy_file=aconf.policy_file, json_output=aconf.json)
|
||||
except Exception as e:
|
||||
out.fail("Error while loading policy file: %s: %s" % (str(e), traceback.format_exc()))
|
||||
out.write()
|
||||
out.fail("Error while loading policy file: %s: %s" % (str(e), traceback.format_exc()), write_now=True)
|
||||
sys.exit(exitcodes.UNKNOWN_ERROR)
|
||||
|
||||
# If the user wants to do a client audit, but provided a server policy, terminate.
|
||||
if aconf.client_audit and aconf.policy.is_server_policy():
|
||||
out.fail("Error: client audit selected, but server policy provided.")
|
||||
out.write()
|
||||
out.fail("Error: client audit selected, but server policy provided.", write_now=True)
|
||||
sys.exit(exitcodes.UNKNOWN_ERROR)
|
||||
|
||||
# If the user wants to do a server audit, but provided a client policy, terminate.
|
||||
if aconf.client_audit is False and aconf.policy.is_server_policy() is False:
|
||||
out.fail("Error: server audit selected, but client policy provided.")
|
||||
out.write()
|
||||
out.fail("Error: server audit selected, but client policy provided.", write_now=True)
|
||||
sys.exit(exitcodes.UNKNOWN_ERROR)
|
||||
|
||||
return aconf
|
||||
|
||||
|
||||
def build_struct(target_host: str, banner: Optional['Banner'], cves: List[Dict[str, Union[str, float]]], kex: Optional['SSH2_Kex'] = None, pkm: Optional['SSH1_PublicKeyMessage'] = None, client_host: Optional[str] = None, software: Optional[Software] = None, algorithms: Optional[Algorithms] = None, algorithm_recommendation_suppress_list: Optional[List[str]] = None, additional_notes: List[str] = []) -> Any: # pylint: disable=dangerous-default-value
|
||||
def build_struct(target_host: str, banner: Optional['Banner'], kex: Optional['SSH2_Kex'] = None, pkm: Optional['SSH1_PublicKeyMessage'] = None, client_host: Optional[str] = None, software: Optional[Software] = None, algorithms: Optional[Algorithms] = None, algorithm_recommendation_suppress_list: Optional[List[str]] = None, additional_notes: List[str] = []) -> Any: # pylint: disable=dangerous-default-value
|
||||
|
||||
def fetch_notes(algorithm: str, alg_type: str) -> Dict[str, List[Optional[str]]]:
|
||||
'''Returns a dictionary containing the messages in the "fail", "warn", and "info" levels for this algorithm.'''
|
||||
@ -1230,8 +1156,8 @@ def build_struct(target_host: str, banner: Optional['Banner'], cves: List[Dict[s
|
||||
'fp': pkm_fp,
|
||||
}]
|
||||
|
||||
# Add in the CVE information.
|
||||
res['cves'] = cves
|
||||
# Historically, CVE information was returned. Now we'll just return an empty dictionary so as to not break any legacy clients.
|
||||
res['cves'] = []
|
||||
|
||||
# Add in the recommendations.
|
||||
res['recommendations'] = get_algorithm_recommendations(algorithms, algorithm_recommendation_suppress_list, software, for_server=True)
|
||||
@ -1315,6 +1241,7 @@ def audit(out: OutputBuffer, aconf: AuditConf, sshv: Optional[int] = None, print
|
||||
elif sshv == 2:
|
||||
try:
|
||||
kex = SSH2_Kex.parse(out, payload)
|
||||
out.d(str(kex))
|
||||
except Exception:
|
||||
out.fail("Failed to parse server's kex. Stack trace:\n%s" % str(traceback.format_exc()))
|
||||
return exitcodes.CONNECTION_ERROR
|
||||
@ -1551,7 +1478,7 @@ def run_gex_granular_modulus_size_test(out: OutputBuffer, s: 'SSH_Socket', kex:
|
||||
|
||||
def main() -> int:
|
||||
out = OutputBuffer()
|
||||
aconf = process_commandline(out, sys.argv[1:], usage)
|
||||
aconf = process_commandline(out, sys.argv[1:])
|
||||
|
||||
# If we're on Windows, but the colorama module could not be imported, print a warning if we're in verbose mode.
|
||||
if (sys.platform == 'win32') and ('colorama' not in sys.modules):
|
||||
@ -1584,10 +1511,10 @@ def main() -> int:
|
||||
if aconf.json:
|
||||
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 = []
|
||||
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))
|
||||
|
||||
# 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()
|
||||
self.__sock_map[s.fileno()] = s
|
||||
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:
|
||||
# Socket to listen on all IPv6 addresses.
|
||||
@ -119,11 +119,11 @@ class SSH_Socket(ReadBuf, WriteBuf):
|
||||
s.listen()
|
||||
self.__sock_map[s.fileno()] = s
|
||||
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 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)
|
||||
|
||||
# Wait for an incoming connection. If a timeout was explicitly
|
||||
|
@ -129,7 +129,7 @@ class Utils:
|
||||
return -1.0
|
||||
|
||||
@staticmethod
|
||||
def parse_host_and_port(host_and_port: str, default_port: int = 0) -> Tuple[str, int]:
|
||||
def parse_host_and_port(host_and_port: str, default_port: int = 22) -> Tuple[str, int]:
|
||||
'''Parses a string into a tuple of its host and port. The port is 0 if not specified.'''
|
||||
host = host_and_port
|
||||
port = default_port
|
||||
|
@ -1,170 +0,0 @@
|
||||
"""
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (C) 2017-2020 Joe Testa (jtesta@positronsecurity.com)
|
||||
Copyright (C) 2017 Andris Raugulis (moo@arthepsy.eu)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
# pylint: disable=unused-import
|
||||
from typing import Dict, List, Set, Sequence, Tuple, Iterable # noqa: F401
|
||||
from typing import Callable, Optional, Union, Any # noqa: F401
|
||||
|
||||
|
||||
class VersionVulnerabilityDB: # pylint: disable=too-few-public-methods
|
||||
# Format: [starting_vuln_version, last_vuln_version, affected, CVE_ID, CVSSv2, description]
|
||||
# affected: 1 = server, 2 = client, 4 = local
|
||||
# Example: if it affects servers, both remote & local, then affected
|
||||
# = 1. If it affects servers, but is a local issue only,
|
||||
# then affected = 1 + 4 = 5.
|
||||
CVE: Dict[str, List[List[Any]]] = {
|
||||
'Dropbear SSH': [
|
||||
['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', '2017.74', 5, 'CVE-2017-9079', 4.7, 'local users can read certain files as root'],
|
||||
['0.0', '2017.74', 5, 'CVE-2017-9078', 9.3, 'local users may elevate privileges to root under certain conditions'],
|
||||
['0.0', '2016.73', 5, 'CVE-2016-7409', 2.1, 'local users can read process memory under limited conditions'],
|
||||
['0.0', '2016.73', 1, 'CVE-2016-7408', 6.5, 'remote users can execute arbitrary code'],
|
||||
['0.0', '2016.73', 5, 'CVE-2016-7407', 10.0, 'local users can execute arbitrary code'],
|
||||
['0.0', '2016.73', 1, 'CVE-2016-7406', 10.0, 'remote users can execute arbitrary code'],
|
||||
['0.44', '2015.71', 1, 'CVE-2016-3116', 5.5, 'bypass command restrictions via xauth command injection'],
|
||||
['0.28', '2013.58', 1, 'CVE-2013-4434', 5.0, 'discover valid usernames through different time delays'],
|
||||
['0.28', '2013.58', 1, 'CVE-2013-4421', 5.0, 'cause DoS via a compressed packet (memory consumption)'],
|
||||
['0.52', '2011.54', 1, 'CVE-2012-0920', 7.1, 'execute arbitrary code or bypass command restrictions'],
|
||||
['0.40', '0.48.1', 1, 'CVE-2007-1099', 7.5, 'conduct a MitM attack (no warning for hostkey mismatch)'],
|
||||
['0.28', '0.47', 1, 'CVE-2006-1206', 7.5, 'cause DoS via large number of connections (slot exhaustion)'],
|
||||
['0.39', '0.47', 1, 'CVE-2006-0225', 4.6, 'execute arbitrary commands via scp with crafted filenames'],
|
||||
['0.28', '0.46', 1, 'CVE-2005-4178', 6.5, 'execute arbitrary code via buffer overflow vulnerability'],
|
||||
['0.28', '0.42', 1, 'CVE-2004-2486', 7.5, 'execute arbitrary code via DSS verification code']],
|
||||
'libssh': [
|
||||
['0.6.4', '0.6.4', 1, 'CVE-2018-10933', 6.4, 'authentication bypass'],
|
||||
['0.7.0', '0.7.5', 1, 'CVE-2018-10933', 6.4, 'authentication bypass'],
|
||||
['0.8.0', '0.8.3', 1, 'CVE-2018-10933', 6.4, 'authentication bypass'],
|
||||
['0.1', '0.7.2', 1, 'CVE-2016-0739', 4.3, 'conduct a MitM attack (weakness in DH key generation)'],
|
||||
['0.5.1', '0.6.4', 1, 'CVE-2015-3146', 5.0, 'cause DoS via kex packets (null pointer dereference)'],
|
||||
['0.5.1', '0.6.3', 1, 'CVE-2014-8132', 5.0, 'cause DoS via kex init packet (dangling pointer)'],
|
||||
['0.4.7', '0.6.2', 1, 'CVE-2014-0017', 1.9, 'leak data via PRNG state reuse on forking servers'],
|
||||
['0.4.7', '0.5.3', 1, 'CVE-2013-0176', 4.3, 'cause DoS via kex packet (null pointer dereference)'],
|
||||
['0.4.7', '0.5.2', 1, 'CVE-2012-6063', 7.5, 'cause DoS or execute arbitrary code via sftp (double free)'],
|
||||
['0.4.7', '0.5.2', 1, 'CVE-2012-4562', 7.5, 'cause DoS or execute arbitrary code (overflow check)'],
|
||||
['0.4.7', '0.5.2', 1, 'CVE-2012-4561', 5.0, 'cause DoS via unspecified vectors (invalid pointer)'],
|
||||
['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)']],
|
||||
'OpenSSH': [
|
||||
['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'],
|
||||
['8.2', '8.4', 2, 'CVE-2021-28041', 7.1, 'double free via ssh-agent'],
|
||||
['1.0', '8.3', 5, 'CVE-2020-15778', 7.8, 'command injection via anomalous argument transfers'],
|
||||
['5.7', '8.3', 2, 'CVE-2020-14145', 5.9, 'information leak via algorithm negotiation'],
|
||||
['8.2', '8.2', 2, 'CVE-2020-12062', 7.5, 'arbitrary files overwrite via scp'],
|
||||
['7.7', '8.0', 7, 'CVE-2019-16905', 7.8, 'memory corruption and local code execution via pre-authentication integer overflow'],
|
||||
['1.0', '7.9', 2, 'CVE-2019-6111', 5.9, 'arbitrary files overwrite via scp'],
|
||||
['1.0', '7.9', 2, 'CVE-2019-6110', 6.8, 'output manipulation'],
|
||||
['1.0', '7.9', 2, 'CVE-2019-6109', 6.8, 'output manipulation'],
|
||||
['1.0', '7.9', 2, 'CVE-2018-20685', 5.3, 'directory permissions modification via scp'],
|
||||
['5.9', '7.8', 1, 'CVE-2018-15919', 5.3, 'username enumeration via GS2'],
|
||||
['1.0', '7.7', 1, 'CVE-2018-15473', 5.3, 'enumerate usernames due to timing discrepancies'],
|
||||
['1.2', '6.292', 1, 'CVE-2017-15906', 5.3, 'readonly bypass via sftp'],
|
||||
['1.0', '8.7', 1, 'CVE-2016-20012', 5.3, 'enumerate usernames via challenge response'],
|
||||
['7.2', '7.2p2', 1, 'CVE-2016-6515', 7.8, 'cause DoS via long password string (crypt CPU consumption)'],
|
||||
['1.2.2', '7.2', 1, 'CVE-2016-3115', 5.5, 'bypass command restrictions via crafted X11 forwarding data'],
|
||||
['5.4', '7.1', 1, 'CVE-2016-1907', 5.0, 'cause DoS via crafted network traffic (out of bounds read)'],
|
||||
['5.4', '7.1p1', 2, 'CVE-2016-0778', 4.6, 'cause DoS via requesting many forwardings (heap based buffer overflow)'],
|
||||
['5.0', '7.1p1', 2, 'CVE-2016-0777', 4.0, 'leak data via allowing transfer of entire buffer'],
|
||||
['6.0', '7.2p2', 5, 'CVE-2015-8325', 7.2, 'privilege escalation via triggering crafted environment'],
|
||||
['6.8', '6.9', 5, 'CVE-2015-6565', 7.2, 'cause DoS via writing to a device (terminal disruption)'],
|
||||
['5.0', '6.9', 5, 'CVE-2015-6564', 6.9, 'privilege escalation via leveraging sshd uid'],
|
||||
['5.0', '6.9', 5, 'CVE-2015-6563', 1.9, 'conduct impersonation attack'],
|
||||
['6.9p1', '6.9p1', 1, 'CVE-2015-5600', 8.5, 'cause Dos or aid in conduct brute force attack (CPU consumption)'],
|
||||
['6.0', '6.6', 1, 'CVE-2015-5352', 4.3, 'bypass access restrictions via a specific connection'],
|
||||
['6.0', '6.6', 2, 'CVE-2014-2653', 5.8, 'bypass SSHFP DNS RR check via unacceptable host certificate'],
|
||||
['5.0', '6.5', 1, 'CVE-2014-2532', 5.8, 'bypass environment restrictions via specific string before wildcard'],
|
||||
['1.2', '6.4', 1, 'CVE-2014-1692', 7.5, 'cause DoS via triggering error condition (memory corruption)'],
|
||||
['6.2', '6.3', 1, 'CVE-2013-4548', 6.0, 'bypass command restrictions via crafted packet data'],
|
||||
['1.2', '5.6', 1, 'CVE-2012-0814', 3.5, 'leak data via debug messages'],
|
||||
['1.2', '5.8', 1, 'CVE-2011-5000', 3.5, 'cause DoS via large value in certain length field (memory consumption)'],
|
||||
['5.6', '5.7', 2, 'CVE-2011-0539', 5.0, 'leak data or conduct hash collision attack'],
|
||||
['1.2', '6.1', 1, 'CVE-2010-5107', 5.0, 'cause DoS via large number of connections (slot exhaustion)'],
|
||||
['1.2', '5.8', 1, 'CVE-2010-4755', 4.0, 'cause DoS via crafted glob expression (CPU and memory consumption)'],
|
||||
['1.2', '5.6', 1, 'CVE-2010-4478', 7.5, 'bypass authentication check via crafted values'],
|
||||
['4.3', '4.8', 1, 'CVE-2009-2904', 6.9, 'privilege escalation via hard links to setuid programs'],
|
||||
['4.0', '5.1', 1, 'CVE-2008-5161', 2.6, 'recover plaintext data from ciphertext'],
|
||||
['1.2', '4.6', 1, 'CVE-2008-4109', 5.0, 'cause DoS via multiple login attempts (slot exhaustion)'],
|
||||
['1.2', '4.8', 1, 'CVE-2008-1657', 6.5, 'bypass command restrictions via modifying session file'],
|
||||
['1.2.2', '4.9', 1, 'CVE-2008-1483', 6.9, 'hijack forwarded X11 connections'],
|
||||
['4.0', '4.6', 1, 'CVE-2007-4752', 7.5, 'privilege escalation via causing an X client to be trusted'],
|
||||
['4.3p2', '4.3p2', 1, 'CVE-2007-3102', 4.3, 'allow attacker to write random data to audit log'],
|
||||
['1.2', '4.6', 1, 'CVE-2007-2243', 5.0, 'discover valid usernames through different responses'],
|
||||
['4.4', '4.4', 1, 'CVE-2006-5794', 7.5, 'bypass authentication'],
|
||||
['4.1', '4.1p1', 1, 'CVE-2006-5229', 2.6, 'discover valid usernames through different time delays'],
|
||||
['1.2', '4.3p2', 1, 'CVE-2006-5052', 5.0, 'discover valid usernames through different responses'],
|
||||
['1.2', '4.3p2', 1, 'CVE-2006-5051', 9.3, 'cause DoS or execute arbitrary code (double free)'],
|
||||
['4.5', '4.5', 1, 'CVE-2006-4925', 5.0, 'cause DoS via invalid protocol sequence (crash)'],
|
||||
['1.2', '4.3p2', 1, 'CVE-2006-4924', 7.8, 'cause DoS via crafted packet (CPU consumption)'],
|
||||
['3.8.1p1', '3.8.1p1', 1, 'CVE-2006-0883', 5.0, 'cause DoS via connecting multiple times (client connection refusal)'],
|
||||
['3.0', '4.2p1', 1, 'CVE-2006-0225', 4.6, 'execute arbitrary code'],
|
||||
['2.1', '4.1p1', 1, 'CVE-2005-2798', 5.0, 'leak data about authentication credentials'],
|
||||
['3.5', '3.5p1', 1, 'CVE-2004-2760', 6.8, 'leak data through different connection states'],
|
||||
['2.3', '3.7.1p2', 1, 'CVE-2004-2069', 5.0, 'cause DoS via large number of connections (slot exhaustion)'],
|
||||
['3.0', '3.4p1', 1, 'CVE-2004-0175', 4.3, 'leak data through directory traversal'],
|
||||
['1.2', '3.9p1', 1, 'CVE-2003-1562', 7.6, 'leak data about authentication credentials'],
|
||||
['3.1p1', '3.7.1p1', 1, 'CVE-2003-0787', 7.5, 'privilege escalation via modifying stack'],
|
||||
['3.1p1', '3.7.1p1', 1, 'CVE-2003-0786', 10.0, 'privilege escalation via bypassing authentication'],
|
||||
['1.0', '3.7.1', 1, 'CVE-2003-0695', 7.5, 'cause DoS or execute arbitrary code'],
|
||||
['1.0', '3.7', 1, 'CVE-2003-0693', 10.0, 'execute arbitrary code'],
|
||||
['3.0', '3.6.1p2', 1, 'CVE-2003-0386', 7.5, 'bypass address restrictions for connection'],
|
||||
['3.1p1', '3.6.1p1', 1, 'CVE-2003-0190', 5.0, 'discover valid usernames through different time delays'],
|
||||
['3.2.2', '3.2.2', 1, 'CVE-2002-0765', 7.5, 'bypass authentication'],
|
||||
['1.2.2', '3.3p1', 1, 'CVE-2002-0640', 10.0, 'execute arbitrary code'],
|
||||
['1.2.2', '3.3p1', 1, 'CVE-2002-0639', 10.0, 'execute arbitrary code'],
|
||||
['2.1', '3.2', 1, 'CVE-2002-0575', 7.5, 'privilege escalation'],
|
||||
['2.1', '3.0.2p1', 2, 'CVE-2002-0083', 10.0, 'privilege escalation'],
|
||||
['3.0', '3.0p1', 1, 'CVE-2001-1507', 7.5, 'bypass authentication'],
|
||||
['1.2.3', '3.0.1p1', 5, 'CVE-2001-0872', 7.2, 'privilege escalation via crafted environment variables'],
|
||||
['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)']],
|
||||
'PuTTY': [
|
||||
# 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.74', 2, 'CVE-2021-33500', 5.0, 'denial of service of the complete windows desktop'],
|
||||
['0.68', '0.73', 2, 'CVE-2020-14002', 4.3, 'Observable Discrepancy which allows man-in-the-middle attackers to target initial connection attempts'],
|
||||
['0.54', '0.73', 2, 'CVE-2020-XXXX', 5.0, 'out of bounds memory read'],
|
||||
['0.0', '0.72', 2, 'CVE-2019-17069', 5.0, 'potential DOS by remote SSHv1 server'],
|
||||
['0.71', '0.72', 2, 'CVE-2019-17068', 5.0, 'xterm bracketed paste mode command injection'],
|
||||
['0.52', '0.72', 2, 'CVE-2019-17067', 7.5, 'port rebinding weakness in port forward tunnel handling'],
|
||||
['0.0', '0.71', 2, 'CVE-2019-XXXX', 5.0, 'undefined vulnerability in obsolete SSHv1 protocol handling'],
|
||||
['0.0', '0.71', 6, 'CVE-2019-XXXX', 5.0, 'local privilege escalation in Pageant'],
|
||||
['0.0', '0.70', 2, 'CVE-2019-9898', 7.5, 'potential recycling of random numbers'],
|
||||
['0.0', '0.70', 2, 'CVE-2019-9897', 5.0, 'multiple denial-of-service issues from writing to the terminal'],
|
||||
['0.0', '0.70', 6, 'CVE-2019-9896', 4.6, 'local application hijacking through malicious Windows help file'],
|
||||
['0.0', '0.70', 2, 'CVE-2019-9894', 6.4, 'buffer overflow in RSA key exchange'],
|
||||
['0.0', '0.69', 6, 'CVE-2016-6167', 4.4, 'local application hijacking through untrusted DLL loading'],
|
||||
['0.0', '0.67', 2, 'CVE-2017-6542', 7.5, 'buffer overflow in UNIX client that can result in privilege escalation or denial-of-service'],
|
||||
['0.0', '0.66', 2, 'CVE-2016-2563', 7.5, 'buffer overflow in SCP command-line utility'],
|
||||
['0.0', '0.65', 2, 'CVE-2015-5309', 4.3, 'integer overflow in terminal-handling code'],
|
||||
]
|
||||
}
|
||||
TXT: Dict[str, List[List[Any]]] = {
|
||||
'Dropbear SSH': [
|
||||
['0.28', '0.34', 1, 'remote root exploit', 'remote format string buffer overflow exploit (exploit-db#387)']],
|
||||
'libssh': [
|
||||
['0.3.3', '0.3.3', 1, 'null pointer check', 'missing null pointer check in "crypt_set_algorithms_server"'],
|
||||
['0.3.3', '0.3.3', 1, 'integer overflow', 'integer overflow in "buffer_get_data"'],
|
||||
['0.3.3', '0.3.3', 3, 'heap overflow', 'heap overflow in "packet_decrypt"']]
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
.TH SSH-AUDIT 1 "April 18, 2024"
|
||||
.TH SSH-AUDIT 1 "September 24, 2024"
|
||||
.SH NAME
|
||||
\fBssh-audit\fP \- SSH server & client configuration auditor
|
||||
.SH SYNOPSIS
|
||||
@ -149,7 +149,7 @@ The timeout, in seconds, for creating connections and reading data from the sock
|
||||
.TP
|
||||
.B -T, \-\-targets=<hosts.txt>
|
||||
.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
|
||||
.B \-\-threads=<threads>
|
||||
|
@ -78,6 +78,26 @@
|
||||
}
|
||||
],
|
||||
"fingerprints": [
|
||||
{
|
||||
"hash": "jdUfqoGCDOY1drQcoqIJm/pEix2r09hqwOs9E9GimZQ",
|
||||
"hash_alg": "SHA256",
|
||||
"hostkey": "ecdsa-sha2-nistp256"
|
||||
},
|
||||
{
|
||||
"hash": "98:27:f3:12:20:f6:23:6d:1a:00:2a:6c:71:7c:1e:6b",
|
||||
"hash_alg": "MD5",
|
||||
"hostkey": "ecdsa-sha2-nistp256"
|
||||
},
|
||||
{
|
||||
"hash": "NBzry0uMAX8BRsn4mv9CHpeivMOdwzGFEKrf6Hg7tIQ",
|
||||
"hash_alg": "SHA256",
|
||||
"hostkey": "ssh-dss"
|
||||
},
|
||||
{
|
||||
"hash": "16:60:9e:54:d7:1e:b3:0d:97:60:12:ad:fe:83:a2:40",
|
||||
"hash_alg": "MD5",
|
||||
"hostkey": "ssh-dss"
|
||||
},
|
||||
{
|
||||
"hash": "CDfAU12pjQS7/91kg7gYacza0U/6PDbE04Ic3IpYxkM",
|
||||
"hash_alg": "SHA256",
|
||||
@ -96,6 +116,9 @@
|
||||
"info": [
|
||||
"default key exchange from OpenSSH 7.4 to 8.9",
|
||||
"available since OpenSSH 7.4, Dropbear SSH 2018.76"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -105,6 +128,9 @@
|
||||
"info": [
|
||||
"default key exchange from OpenSSH 6.5 to 7.3",
|
||||
"available since OpenSSH 6.4, Dropbear SSH 2013.62"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -116,6 +142,9 @@
|
||||
],
|
||||
"info": [
|
||||
"available since OpenSSH 5.7, Dropbear SSH 2013.62"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -127,6 +156,9 @@
|
||||
],
|
||||
"info": [
|
||||
"available since OpenSSH 5.7, Dropbear SSH 2013.62"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -138,6 +170,9 @@
|
||||
],
|
||||
"info": [
|
||||
"available since OpenSSH 5.7, Dropbear SSH 2013.62"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -148,7 +183,8 @@
|
||||
"available since OpenSSH 7.3, Dropbear SSH 2016.73"
|
||||
],
|
||||
"warn": [
|
||||
"2048-bit modulus only provides 112-bits of symmetric strength"
|
||||
"2048-bit modulus only provides 112-bits of symmetric strength",
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -162,7 +198,8 @@
|
||||
"available since OpenSSH 3.9, Dropbear SSH 0.53"
|
||||
],
|
||||
"warn": [
|
||||
"2048-bit modulus only provides 112-bits of symmetric strength"
|
||||
"2048-bit modulus only provides 112-bits of symmetric strength",
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -171,6 +208,9 @@
|
||||
"notes": {
|
||||
"info": [
|
||||
"available since Dropbear SSH 2013.57"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -329,12 +369,6 @@
|
||||
"name": "twofish256-ctr",
|
||||
"notes": ""
|
||||
}
|
||||
],
|
||||
"kex": [
|
||||
{
|
||||
"name": "diffie-hellman-group16-sha512",
|
||||
"notes": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -351,9 +385,21 @@
|
||||
}
|
||||
],
|
||||
"kex": [
|
||||
{
|
||||
"name": "curve25519-sha256",
|
||||
"notes": ""
|
||||
},
|
||||
{
|
||||
"name": "curve25519-sha256@libssh.org",
|
||||
"notes": ""
|
||||
},
|
||||
{
|
||||
"name": "diffie-hellman-group14-sha256",
|
||||
"notes": ""
|
||||
},
|
||||
{
|
||||
"name": "kexguess2@matt.ucc.asn.au",
|
||||
"notes": ""
|
||||
}
|
||||
],
|
||||
"mac": [
|
||||
|
@ -5,22 +5,30 @@
|
||||
[0;32m(gen) compression: enabled (zlib@openssh.com)[0m
|
||||
|
||||
[0;36m# key exchange algorithms[0m
|
||||
[0;32m(kex) curve25519-sha256 -- [info] available since OpenSSH 7.4, Dropbear SSH 2018.76[0m
|
||||
[0;32m `- [info] default key exchange from OpenSSH 7.4 to 8.9[0m
|
||||
[0;32m(kex) curve25519-sha256@libssh.org -- [info] available since OpenSSH 6.4, Dropbear SSH 2013.62[0m
|
||||
[0;32m `- [info] default key exchange from OpenSSH 6.5 to 7.3[0m
|
||||
[0;33m(kex) curve25519-sha256 -- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 7.4, Dropbear SSH 2018.76
|
||||
`- [info] default key exchange from OpenSSH 7.4 to 8.9
|
||||
[0;33m(kex) curve25519-sha256@libssh.org -- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 6.4, Dropbear SSH 2013.62
|
||||
`- [info] default key exchange from OpenSSH 6.5 to 7.3
|
||||
[0;31m(kex) ecdh-sha2-nistp521 -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
|
||||
[0;31m(kex) ecdh-sha2-nistp384 -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
|
||||
[0;31m(kex) ecdh-sha2-nistp256 -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
|
||||
[0;33m(kex) diffie-hellman-group14-sha256 -- [warn] 2048-bit modulus only provides 112-bits of symmetric strength[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73
|
||||
[0;31m(kex) diffie-hellman-group14-sha1 -- [fail] using broken SHA-1 hash algorithm[0m
|
||||
[0;33m `- [warn] 2048-bit modulus only provides 112-bits of symmetric strength[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
|
||||
[0;32m(kex) kexguess2@matt.ucc.asn.au -- [info] available since Dropbear SSH 2013.57[0m
|
||||
[0;33m(kex) kexguess2@matt.ucc.asn.au -- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since Dropbear SSH 2013.57
|
||||
|
||||
[0;36m# host-key algorithms[0m
|
||||
[0;31m(key) ecdsa-sha2-nistp256 -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency[0m
|
||||
@ -74,13 +82,15 @@
|
||||
[0;31m(rec) -hmac-sha1-96 -- mac algorithm to remove [0m
|
||||
[0;31m(rec) -ssh-dss -- key algorithm to remove [0m
|
||||
[0;31m(rec) -ssh-rsa -- key algorithm to remove [0m
|
||||
[0;32m(rec) +diffie-hellman-group16-sha512 -- kex algorithm to append [0m
|
||||
[0;32m(rec) +twofish128-ctr -- enc algorithm to append [0m
|
||||
[0;32m(rec) +twofish256-ctr -- enc algorithm to append [0m
|
||||
[0;33m(rec) -aes128-cbc -- enc algorithm to remove [0m
|
||||
[0;33m(rec) -aes256-cbc -- enc algorithm to remove [0m
|
||||
[0;33m(rec) -curve25519-sha256 -- kex algorithm to remove [0m
|
||||
[0;33m(rec) -curve25519-sha256@libssh.org -- kex algorithm to remove [0m
|
||||
[0;33m(rec) -diffie-hellman-group14-sha256 -- kex algorithm to remove [0m
|
||||
[0;33m(rec) -hmac-sha2-256 -- mac algorithm to remove [0m
|
||||
[0;33m(rec) -kexguess2@matt.ucc.asn.au -- kex algorithm to remove [0m
|
||||
|
||||
[0;36m# additional info[0m
|
||||
[0;33m(nfo) For hardening guides on common OSes, please see: <https://www.ssh-audit.com/hardening_guides.html>[0m
|
||||
|
@ -10,118 +10,7 @@
|
||||
"none",
|
||||
"zlib"
|
||||
],
|
||||
"cves": [
|
||||
{
|
||||
"cvssv2": 7.8,
|
||||
"description": "command injection via anomalous argument transfers",
|
||||
"name": "CVE-2020-15778"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.3,
|
||||
"description": "enumerate usernames due to timing discrepancies",
|
||||
"name": "CVE-2018-15473"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.3,
|
||||
"description": "readonly bypass via sftp",
|
||||
"name": "CVE-2017-15906"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.3,
|
||||
"description": "enumerate usernames via challenge response",
|
||||
"name": "CVE-2016-20012"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.5,
|
||||
"description": "bypass command restrictions via crafted X11 forwarding data",
|
||||
"name": "CVE-2016-3115"
|
||||
},
|
||||
{
|
||||
"cvssv2": 7.5,
|
||||
"description": "cause DoS via triggering error condition (memory corruption)",
|
||||
"name": "CVE-2014-1692"
|
||||
},
|
||||
{
|
||||
"cvssv2": 3.5,
|
||||
"description": "leak data via debug messages",
|
||||
"name": "CVE-2012-0814"
|
||||
},
|
||||
{
|
||||
"cvssv2": 3.5,
|
||||
"description": "cause DoS via large value in certain length field (memory consumption)",
|
||||
"name": "CVE-2011-5000"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.0,
|
||||
"description": "cause DoS via large number of connections (slot exhaustion)",
|
||||
"name": "CVE-2010-5107"
|
||||
},
|
||||
{
|
||||
"cvssv2": 4.0,
|
||||
"description": "cause DoS via crafted glob expression (CPU and memory consumption)",
|
||||
"name": "CVE-2010-4755"
|
||||
},
|
||||
{
|
||||
"cvssv2": 7.5,
|
||||
"description": "bypass authentication check via crafted values",
|
||||
"name": "CVE-2010-4478"
|
||||
},
|
||||
{
|
||||
"cvssv2": 2.6,
|
||||
"description": "recover plaintext data from ciphertext",
|
||||
"name": "CVE-2008-5161"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.0,
|
||||
"description": "cause DoS via multiple login attempts (slot exhaustion)",
|
||||
"name": "CVE-2008-4109"
|
||||
},
|
||||
{
|
||||
"cvssv2": 6.5,
|
||||
"description": "bypass command restrictions via modifying session file",
|
||||
"name": "CVE-2008-1657"
|
||||
},
|
||||
{
|
||||
"cvssv2": 6.9,
|
||||
"description": "hijack forwarded X11 connections",
|
||||
"name": "CVE-2008-1483"
|
||||
},
|
||||
{
|
||||
"cvssv2": 7.5,
|
||||
"description": "privilege escalation via causing an X client to be trusted",
|
||||
"name": "CVE-2007-4752"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.0,
|
||||
"description": "discover valid usernames through different responses",
|
||||
"name": "CVE-2007-2243"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.0,
|
||||
"description": "discover valid usernames through different responses",
|
||||
"name": "CVE-2006-5052"
|
||||
},
|
||||
{
|
||||
"cvssv2": 9.3,
|
||||
"description": "cause DoS or execute arbitrary code (double free)",
|
||||
"name": "CVE-2006-5051"
|
||||
},
|
||||
{
|
||||
"cvssv2": 7.8,
|
||||
"description": "cause DoS via crafted packet (CPU consumption)",
|
||||
"name": "CVE-2006-4924"
|
||||
},
|
||||
{
|
||||
"cvssv2": 4.6,
|
||||
"description": "execute arbitrary code",
|
||||
"name": "CVE-2006-0225"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.0,
|
||||
"description": "leak data about authentication credentials",
|
||||
"name": "CVE-2005-2798"
|
||||
}
|
||||
],
|
||||
"cves": [],
|
||||
"enc": [
|
||||
{
|
||||
"algorithm": "aes128-cbc",
|
||||
@ -253,6 +142,16 @@
|
||||
}
|
||||
],
|
||||
"fingerprints": [
|
||||
{
|
||||
"hash": "sqDDYhzYz7YIQeFDc0WF8SeXtrEz+iwsV7d/FdIgztM",
|
||||
"hash_alg": "SHA256",
|
||||
"hostkey": "ssh-dss"
|
||||
},
|
||||
{
|
||||
"hash": "5c:de:62:f0:60:c8:93:13:87:71:78:95:56:3f:61:51",
|
||||
"hash_alg": "MD5",
|
||||
"hostkey": "ssh-dss"
|
||||
},
|
||||
{
|
||||
"hash": "YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4",
|
||||
"hash_alg": "SHA256",
|
||||
@ -274,6 +173,9 @@
|
||||
],
|
||||
"info": [
|
||||
"available since OpenSSH 2.3.0"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -287,7 +189,8 @@
|
||||
"available since OpenSSH 3.9, Dropbear SSH 0.53"
|
||||
],
|
||||
"warn": [
|
||||
"2048-bit modulus only provides 112-bits of symmetric strength"
|
||||
"2048-bit modulus only provides 112-bits of symmetric strength",
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -302,6 +205,9 @@
|
||||
"info": [
|
||||
"removed in OpenSSH 6.9: https://www.openssh.com/txt/release-6.9",
|
||||
"available since OpenSSH 2.3.0, Dropbear SSH 0.28"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -6,39 +6,20 @@
|
||||
[0;32m(gen) compression: enabled (zlib)[0m
|
||||
|
||||
[0;36m# security[0m
|
||||
[0;33m(cve) CVE-2020-15778 -- (CVSSv2: 7.8) command injection via anomalous argument transfers[0m
|
||||
[0;33m(cve) CVE-2018-15473 -- (CVSSv2: 5.3) enumerate usernames due to timing discrepancies[0m
|
||||
[0;33m(cve) CVE-2017-15906 -- (CVSSv2: 5.3) readonly bypass via sftp[0m
|
||||
[0;33m(cve) CVE-2016-20012 -- (CVSSv2: 5.3) enumerate usernames via challenge response[0m
|
||||
[0;33m(cve) CVE-2016-3115 -- (CVSSv2: 5.5) bypass command restrictions via crafted X11 forwarding data[0m
|
||||
[0;33m(cve) CVE-2014-1692 -- (CVSSv2: 7.5) cause DoS via triggering error condition (memory corruption)[0m
|
||||
[0;33m(cve) CVE-2012-0814 -- (CVSSv2: 3.5) leak data via debug messages[0m
|
||||
[0;33m(cve) CVE-2011-5000 -- (CVSSv2: 3.5) cause DoS via large value in certain length field (memory consumption)[0m
|
||||
[0;33m(cve) CVE-2010-5107 -- (CVSSv2: 5.0) cause DoS via large number of connections (slot exhaustion)[0m
|
||||
[0;33m(cve) CVE-2010-4755 -- (CVSSv2: 4.0) cause DoS via crafted glob expression (CPU and memory consumption)[0m
|
||||
[0;33m(cve) CVE-2010-4478 -- (CVSSv2: 7.5) bypass authentication check via crafted values[0m
|
||||
[0;33m(cve) CVE-2008-5161 -- (CVSSv2: 2.6) recover plaintext data from ciphertext[0m
|
||||
[0;33m(cve) CVE-2008-4109 -- (CVSSv2: 5.0) cause DoS via multiple login attempts (slot exhaustion)[0m
|
||||
[0;33m(cve) CVE-2008-1657 -- (CVSSv2: 6.5) bypass command restrictions via modifying session file[0m
|
||||
[0;33m(cve) CVE-2008-1483 -- (CVSSv2: 6.9) hijack forwarded X11 connections[0m
|
||||
[0;33m(cve) CVE-2007-4752 -- (CVSSv2: 7.5) privilege escalation via causing an X client to be trusted[0m
|
||||
[0;33m(cve) CVE-2007-2243 -- (CVSSv2: 5.0) discover valid usernames through different responses[0m
|
||||
[0;33m(cve) CVE-2006-5052 -- (CVSSv2: 5.0) discover valid usernames through different responses[0m
|
||||
[0;31m(cve) CVE-2006-5051 -- (CVSSv2: 9.3) cause DoS or execute arbitrary code (double free)[0m
|
||||
[0;33m(cve) CVE-2006-4924 -- (CVSSv2: 7.8) cause DoS via crafted packet (CPU consumption)[0m
|
||||
[0;33m(cve) CVE-2006-0225 -- (CVSSv2: 4.6) execute arbitrary code[0m
|
||||
[0;33m(cve) CVE-2005-2798 -- (CVSSv2: 5.0) leak data about authentication credentials[0m
|
||||
[0;31m(sec) SSH v1 enabled -- SSH v1 can be exploited to recover plaintext passwords[0m
|
||||
|
||||
[0;36m# key exchange algorithms[0m
|
||||
[0;31m(kex) diffie-hellman-group-exchange-sha1 (1024-bit) -- [fail] using small 1024-bit modulus[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 2.3.0
|
||||
[0;31m(kex) diffie-hellman-group14-sha1 -- [fail] using broken SHA-1 hash algorithm[0m
|
||||
[0;33m `- [warn] 2048-bit modulus only provides 112-bits of symmetric strength[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
|
||||
[0;31m(kex) diffie-hellman-group1-sha1 -- [fail] using small 1024-bit modulus[0m
|
||||
[0;31m `- [fail] vulnerable to the Logjam attack: https://en.wikipedia.org/wiki/Logjam_(computer_security)[0m
|
||||
[0;31m `- [fail] using broken SHA-1 hash algorithm[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
|
||||
`- [info] removed in OpenSSH 6.9: https://www.openssh.com/txt/release-6.9
|
||||
|
||||
|
@ -2,5 +2,7 @@
|
||||
"errors": [],
|
||||
"host": "localhost",
|
||||
"passed": true,
|
||||
"policy": "Docker policy: test1 (version 1)"
|
||||
"policy": "Docker policy: test1 (version 1)",
|
||||
"port": 2222,
|
||||
"warnings": []
|
||||
}
|
||||
|
@ -27,5 +27,7 @@
|
||||
],
|
||||
"host": "localhost",
|
||||
"passed": false,
|
||||
"policy": "Docker poliicy: test10 (version 1)"
|
||||
"policy": "Docker poliicy: test10 (version 1)",
|
||||
"port": 2222,
|
||||
"warnings": []
|
||||
}
|
||||
|
@ -19,5 +19,7 @@
|
||||
],
|
||||
"host": "localhost",
|
||||
"passed": false,
|
||||
"policy": "Docker policy: test2 (version 1)"
|
||||
"policy": "Docker policy: test2 (version 1)",
|
||||
"port": 2222,
|
||||
"warnings": []
|
||||
}
|
||||
|
@ -18,5 +18,7 @@
|
||||
],
|
||||
"host": "localhost",
|
||||
"passed": false,
|
||||
"policy": "Docker policy: test3 (version 1)"
|
||||
"policy": "Docker policy: test3 (version 1)",
|
||||
"port": 2222,
|
||||
"warnings": []
|
||||
}
|
||||
|
@ -28,5 +28,7 @@
|
||||
],
|
||||
"host": "localhost",
|
||||
"passed": false,
|
||||
"policy": "Docker policy: test4 (version 1)"
|
||||
"policy": "Docker policy: test4 (version 1)",
|
||||
"port": 2222,
|
||||
"warnings": []
|
||||
}
|
||||
|
@ -27,5 +27,7 @@
|
||||
],
|
||||
"host": "localhost",
|
||||
"passed": false,
|
||||
"policy": "Docker policy: test5 (version 1)"
|
||||
"policy": "Docker policy: test5 (version 1)",
|
||||
"port": 2222,
|
||||
"warnings": []
|
||||
}
|
||||
|
@ -2,5 +2,7 @@
|
||||
"errors": [],
|
||||
"host": "localhost",
|
||||
"passed": true,
|
||||
"policy": "Docker poliicy: test7 (version 1)"
|
||||
"policy": "Docker poliicy: test7 (version 1)",
|
||||
"port": 2222,
|
||||
"warnings": []
|
||||
}
|
||||
|
@ -15,5 +15,7 @@
|
||||
],
|
||||
"host": "localhost",
|
||||
"passed": false,
|
||||
"policy": "Docker poliicy: test8 (version 1)"
|
||||
"policy": "Docker poliicy: test8 (version 1)",
|
||||
"port": 2222,
|
||||
"warnings": []
|
||||
}
|
||||
|
@ -15,5 +15,7 @@
|
||||
],
|
||||
"host": "localhost",
|
||||
"passed": false,
|
||||
"policy": "Docker poliicy: test9 (version 1)"
|
||||
"policy": "Docker poliicy: test9 (version 1)",
|
||||
"port": 2222,
|
||||
"warnings": []
|
||||
}
|
||||
|
@ -10,83 +10,7 @@
|
||||
"none",
|
||||
"zlib@openssh.com"
|
||||
],
|
||||
"cves": [
|
||||
{
|
||||
"cvssv2": 7.8,
|
||||
"description": "command injection via anomalous argument transfers",
|
||||
"name": "CVE-2020-15778"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.3,
|
||||
"description": "enumerate usernames due to timing discrepancies",
|
||||
"name": "CVE-2018-15473"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.3,
|
||||
"description": "readonly bypass via sftp",
|
||||
"name": "CVE-2017-15906"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.3,
|
||||
"description": "enumerate usernames via challenge response",
|
||||
"name": "CVE-2016-20012"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.5,
|
||||
"description": "bypass command restrictions via crafted X11 forwarding data",
|
||||
"name": "CVE-2016-3115"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.0,
|
||||
"description": "cause DoS via crafted network traffic (out of bounds read)",
|
||||
"name": "CVE-2016-1907"
|
||||
},
|
||||
{
|
||||
"cvssv2": 6.9,
|
||||
"description": "privilege escalation via leveraging sshd uid",
|
||||
"name": "CVE-2015-6564"
|
||||
},
|
||||
{
|
||||
"cvssv2": 1.9,
|
||||
"description": "conduct impersonation attack",
|
||||
"name": "CVE-2015-6563"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.8,
|
||||
"description": "bypass environment restrictions via specific string before wildcard",
|
||||
"name": "CVE-2014-2532"
|
||||
},
|
||||
{
|
||||
"cvssv2": 7.5,
|
||||
"description": "cause DoS via triggering error condition (memory corruption)",
|
||||
"name": "CVE-2014-1692"
|
||||
},
|
||||
{
|
||||
"cvssv2": 3.5,
|
||||
"description": "leak data via debug messages",
|
||||
"name": "CVE-2012-0814"
|
||||
},
|
||||
{
|
||||
"cvssv2": 3.5,
|
||||
"description": "cause DoS via large value in certain length field (memory consumption)",
|
||||
"name": "CVE-2011-5000"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.0,
|
||||
"description": "cause DoS via large number of connections (slot exhaustion)",
|
||||
"name": "CVE-2010-5107"
|
||||
},
|
||||
{
|
||||
"cvssv2": 4.0,
|
||||
"description": "cause DoS via crafted glob expression (CPU and memory consumption)",
|
||||
"name": "CVE-2010-4755"
|
||||
},
|
||||
{
|
||||
"cvssv2": 7.5,
|
||||
"description": "bypass authentication check via crafted values",
|
||||
"name": "CVE-2010-4478"
|
||||
}
|
||||
],
|
||||
"cves": [],
|
||||
"enc": [
|
||||
{
|
||||
"algorithm": "aes128-ctr",
|
||||
@ -240,6 +164,16 @@
|
||||
}
|
||||
],
|
||||
"fingerprints": [
|
||||
{
|
||||
"hash": "sqDDYhzYz7YIQeFDc0WF8SeXtrEz+iwsV7d/FdIgztM",
|
||||
"hash_alg": "SHA256",
|
||||
"hostkey": "ssh-dss"
|
||||
},
|
||||
{
|
||||
"hash": "5c:de:62:f0:60:c8:93:13:87:71:78:95:56:3f:61:51",
|
||||
"hash_alg": "MD5",
|
||||
"hostkey": "ssh-dss"
|
||||
},
|
||||
{
|
||||
"hash": "YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4",
|
||||
"hash_alg": "SHA256",
|
||||
@ -261,6 +195,9 @@
|
||||
],
|
||||
"info": [
|
||||
"available since OpenSSH 4.4"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -273,6 +210,9 @@
|
||||
],
|
||||
"info": [
|
||||
"available since OpenSSH 2.3.0"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -286,7 +226,8 @@
|
||||
"available since OpenSSH 3.9, Dropbear SSH 0.53"
|
||||
],
|
||||
"warn": [
|
||||
"2048-bit modulus only provides 112-bits of symmetric strength"
|
||||
"2048-bit modulus only provides 112-bits of symmetric strength",
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -301,6 +242,9 @@
|
||||
"info": [
|
||||
"removed in OpenSSH 6.9: https://www.openssh.com/txt/release-6.9",
|
||||
"available since OpenSSH 2.3.0, Dropbear SSH 0.28"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -4,34 +4,21 @@
|
||||
[0;32m(gen) compatibility: OpenSSH 4.7-6.6, Dropbear SSH 0.53+ (some functionality from 0.52)[0m
|
||||
[0;32m(gen) compression: enabled (zlib@openssh.com)[0m
|
||||
|
||||
[0;36m# security[0m
|
||||
[0;33m(cve) CVE-2020-15778 -- (CVSSv2: 7.8) command injection via anomalous argument transfers[0m
|
||||
[0;33m(cve) CVE-2018-15473 -- (CVSSv2: 5.3) enumerate usernames due to timing discrepancies[0m
|
||||
[0;33m(cve) CVE-2017-15906 -- (CVSSv2: 5.3) readonly bypass via sftp[0m
|
||||
[0;33m(cve) CVE-2016-20012 -- (CVSSv2: 5.3) enumerate usernames via challenge response[0m
|
||||
[0;33m(cve) CVE-2016-3115 -- (CVSSv2: 5.5) bypass command restrictions via crafted X11 forwarding data[0m
|
||||
[0;33m(cve) CVE-2016-1907 -- (CVSSv2: 5.0) cause DoS via crafted network traffic (out of bounds read)[0m
|
||||
[0;33m(cve) CVE-2015-6564 -- (CVSSv2: 6.9) privilege escalation via leveraging sshd uid[0m
|
||||
[0;33m(cve) CVE-2015-6563 -- (CVSSv2: 1.9) conduct impersonation attack[0m
|
||||
[0;33m(cve) CVE-2014-2532 -- (CVSSv2: 5.8) bypass environment restrictions via specific string before wildcard[0m
|
||||
[0;33m(cve) CVE-2014-1692 -- (CVSSv2: 7.5) cause DoS via triggering error condition (memory corruption)[0m
|
||||
[0;33m(cve) CVE-2012-0814 -- (CVSSv2: 3.5) leak data via debug messages[0m
|
||||
[0;33m(cve) CVE-2011-5000 -- (CVSSv2: 3.5) cause DoS via large value in certain length field (memory consumption)[0m
|
||||
[0;33m(cve) CVE-2010-5107 -- (CVSSv2: 5.0) cause DoS via large number of connections (slot exhaustion)[0m
|
||||
[0;33m(cve) CVE-2010-4755 -- (CVSSv2: 4.0) cause DoS via crafted glob expression (CPU and memory consumption)[0m
|
||||
[0;33m(cve) CVE-2010-4478 -- (CVSSv2: 7.5) bypass authentication check via crafted values[0m
|
||||
|
||||
[0;36m# key exchange algorithms[0m
|
||||
[0;31m(kex) diffie-hellman-group-exchange-sha256 (1024-bit) -- [fail] using small 1024-bit modulus[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 4.4
|
||||
[0;31m(kex) diffie-hellman-group-exchange-sha1 (1024-bit) -- [fail] using small 1024-bit modulus[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 2.3.0
|
||||
[0;31m(kex) diffie-hellman-group14-sha1 -- [fail] using broken SHA-1 hash algorithm[0m
|
||||
[0;33m `- [warn] 2048-bit modulus only provides 112-bits of symmetric strength[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
|
||||
[0;31m(kex) diffie-hellman-group1-sha1 -- [fail] using small 1024-bit modulus[0m
|
||||
[0;31m `- [fail] vulnerable to the Logjam attack: https://en.wikipedia.org/wiki/Logjam_(computer_security)[0m
|
||||
[0;31m `- [fail] using broken SHA-1 hash algorithm[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
|
||||
`- [info] removed in OpenSSH 6.9: https://www.openssh.com/txt/release-6.9
|
||||
|
||||
|
@ -10,83 +10,7 @@
|
||||
"none",
|
||||
"zlib@openssh.com"
|
||||
],
|
||||
"cves": [
|
||||
{
|
||||
"cvssv2": 7.8,
|
||||
"description": "command injection via anomalous argument transfers",
|
||||
"name": "CVE-2020-15778"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.3,
|
||||
"description": "enumerate usernames due to timing discrepancies",
|
||||
"name": "CVE-2018-15473"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.3,
|
||||
"description": "readonly bypass via sftp",
|
||||
"name": "CVE-2017-15906"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.3,
|
||||
"description": "enumerate usernames via challenge response",
|
||||
"name": "CVE-2016-20012"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.5,
|
||||
"description": "bypass command restrictions via crafted X11 forwarding data",
|
||||
"name": "CVE-2016-3115"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.0,
|
||||
"description": "cause DoS via crafted network traffic (out of bounds read)",
|
||||
"name": "CVE-2016-1907"
|
||||
},
|
||||
{
|
||||
"cvssv2": 6.9,
|
||||
"description": "privilege escalation via leveraging sshd uid",
|
||||
"name": "CVE-2015-6564"
|
||||
},
|
||||
{
|
||||
"cvssv2": 1.9,
|
||||
"description": "conduct impersonation attack",
|
||||
"name": "CVE-2015-6563"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.8,
|
||||
"description": "bypass environment restrictions via specific string before wildcard",
|
||||
"name": "CVE-2014-2532"
|
||||
},
|
||||
{
|
||||
"cvssv2": 7.5,
|
||||
"description": "cause DoS via triggering error condition (memory corruption)",
|
||||
"name": "CVE-2014-1692"
|
||||
},
|
||||
{
|
||||
"cvssv2": 3.5,
|
||||
"description": "leak data via debug messages",
|
||||
"name": "CVE-2012-0814"
|
||||
},
|
||||
{
|
||||
"cvssv2": 3.5,
|
||||
"description": "cause DoS via large value in certain length field (memory consumption)",
|
||||
"name": "CVE-2011-5000"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.0,
|
||||
"description": "cause DoS via large number of connections (slot exhaustion)",
|
||||
"name": "CVE-2010-5107"
|
||||
},
|
||||
{
|
||||
"cvssv2": 4.0,
|
||||
"description": "cause DoS via crafted glob expression (CPU and memory consumption)",
|
||||
"name": "CVE-2010-4755"
|
||||
},
|
||||
{
|
||||
"cvssv2": 7.5,
|
||||
"description": "bypass authentication check via crafted values",
|
||||
"name": "CVE-2010-4478"
|
||||
}
|
||||
],
|
||||
"cves": [],
|
||||
"enc": [
|
||||
{
|
||||
"algorithm": "aes128-ctr",
|
||||
@ -261,6 +185,9 @@
|
||||
],
|
||||
"info": [
|
||||
"available since OpenSSH 4.4"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -273,6 +200,9 @@
|
||||
],
|
||||
"info": [
|
||||
"available since OpenSSH 2.3.0"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -286,7 +216,8 @@
|
||||
"available since OpenSSH 3.9, Dropbear SSH 0.53"
|
||||
],
|
||||
"warn": [
|
||||
"2048-bit modulus only provides 112-bits of symmetric strength"
|
||||
"2048-bit modulus only provides 112-bits of symmetric strength",
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -301,6 +232,9 @@
|
||||
"info": [
|
||||
"removed in OpenSSH 6.9: https://www.openssh.com/txt/release-6.9",
|
||||
"available since OpenSSH 2.3.0, Dropbear SSH 0.28"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -4,34 +4,21 @@
|
||||
[0;32m(gen) compatibility: OpenSSH 5.6-6.6, Dropbear SSH 0.53+ (some functionality from 0.52)[0m
|
||||
[0;32m(gen) compression: enabled (zlib@openssh.com)[0m
|
||||
|
||||
[0;36m# security[0m
|
||||
[0;33m(cve) CVE-2020-15778 -- (CVSSv2: 7.8) command injection via anomalous argument transfers[0m
|
||||
[0;33m(cve) CVE-2018-15473 -- (CVSSv2: 5.3) enumerate usernames due to timing discrepancies[0m
|
||||
[0;33m(cve) CVE-2017-15906 -- (CVSSv2: 5.3) readonly bypass via sftp[0m
|
||||
[0;33m(cve) CVE-2016-20012 -- (CVSSv2: 5.3) enumerate usernames via challenge response[0m
|
||||
[0;33m(cve) CVE-2016-3115 -- (CVSSv2: 5.5) bypass command restrictions via crafted X11 forwarding data[0m
|
||||
[0;33m(cve) CVE-2016-1907 -- (CVSSv2: 5.0) cause DoS via crafted network traffic (out of bounds read)[0m
|
||||
[0;33m(cve) CVE-2015-6564 -- (CVSSv2: 6.9) privilege escalation via leveraging sshd uid[0m
|
||||
[0;33m(cve) CVE-2015-6563 -- (CVSSv2: 1.9) conduct impersonation attack[0m
|
||||
[0;33m(cve) CVE-2014-2532 -- (CVSSv2: 5.8) bypass environment restrictions via specific string before wildcard[0m
|
||||
[0;33m(cve) CVE-2014-1692 -- (CVSSv2: 7.5) cause DoS via triggering error condition (memory corruption)[0m
|
||||
[0;33m(cve) CVE-2012-0814 -- (CVSSv2: 3.5) leak data via debug messages[0m
|
||||
[0;33m(cve) CVE-2011-5000 -- (CVSSv2: 3.5) cause DoS via large value in certain length field (memory consumption)[0m
|
||||
[0;33m(cve) CVE-2010-5107 -- (CVSSv2: 5.0) cause DoS via large number of connections (slot exhaustion)[0m
|
||||
[0;33m(cve) CVE-2010-4755 -- (CVSSv2: 4.0) cause DoS via crafted glob expression (CPU and memory consumption)[0m
|
||||
[0;33m(cve) CVE-2010-4478 -- (CVSSv2: 7.5) bypass authentication check via crafted values[0m
|
||||
|
||||
[0;36m# key exchange algorithms[0m
|
||||
[0;31m(kex) diffie-hellman-group-exchange-sha256 (1024-bit) -- [fail] using small 1024-bit modulus[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 4.4
|
||||
[0;31m(kex) diffie-hellman-group-exchange-sha1 (1024-bit) -- [fail] using small 1024-bit modulus[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 2.3.0
|
||||
[0;31m(kex) diffie-hellman-group14-sha1 -- [fail] using broken SHA-1 hash algorithm[0m
|
||||
[0;33m `- [warn] 2048-bit modulus only provides 112-bits of symmetric strength[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
|
||||
[0;31m(kex) diffie-hellman-group1-sha1 -- [fail] using small 1024-bit modulus[0m
|
||||
[0;31m `- [fail] vulnerable to the Logjam attack: https://en.wikipedia.org/wiki/Logjam_(computer_security)[0m
|
||||
[0;31m `- [fail] using broken SHA-1 hash algorithm[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
|
||||
`- [info] removed in OpenSSH 6.9: https://www.openssh.com/txt/release-6.9
|
||||
|
||||
|
@ -10,83 +10,7 @@
|
||||
"none",
|
||||
"zlib@openssh.com"
|
||||
],
|
||||
"cves": [
|
||||
{
|
||||
"cvssv2": 7.8,
|
||||
"description": "command injection via anomalous argument transfers",
|
||||
"name": "CVE-2020-15778"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.3,
|
||||
"description": "enumerate usernames due to timing discrepancies",
|
||||
"name": "CVE-2018-15473"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.3,
|
||||
"description": "readonly bypass via sftp",
|
||||
"name": "CVE-2017-15906"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.3,
|
||||
"description": "enumerate usernames via challenge response",
|
||||
"name": "CVE-2016-20012"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.5,
|
||||
"description": "bypass command restrictions via crafted X11 forwarding data",
|
||||
"name": "CVE-2016-3115"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.0,
|
||||
"description": "cause DoS via crafted network traffic (out of bounds read)",
|
||||
"name": "CVE-2016-1907"
|
||||
},
|
||||
{
|
||||
"cvssv2": 6.9,
|
||||
"description": "privilege escalation via leveraging sshd uid",
|
||||
"name": "CVE-2015-6564"
|
||||
},
|
||||
{
|
||||
"cvssv2": 1.9,
|
||||
"description": "conduct impersonation attack",
|
||||
"name": "CVE-2015-6563"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.8,
|
||||
"description": "bypass environment restrictions via specific string before wildcard",
|
||||
"name": "CVE-2014-2532"
|
||||
},
|
||||
{
|
||||
"cvssv2": 7.5,
|
||||
"description": "cause DoS via triggering error condition (memory corruption)",
|
||||
"name": "CVE-2014-1692"
|
||||
},
|
||||
{
|
||||
"cvssv2": 3.5,
|
||||
"description": "leak data via debug messages",
|
||||
"name": "CVE-2012-0814"
|
||||
},
|
||||
{
|
||||
"cvssv2": 3.5,
|
||||
"description": "cause DoS via large value in certain length field (memory consumption)",
|
||||
"name": "CVE-2011-5000"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.0,
|
||||
"description": "cause DoS via large number of connections (slot exhaustion)",
|
||||
"name": "CVE-2010-5107"
|
||||
},
|
||||
{
|
||||
"cvssv2": 4.0,
|
||||
"description": "cause DoS via crafted glob expression (CPU and memory consumption)",
|
||||
"name": "CVE-2010-4755"
|
||||
},
|
||||
{
|
||||
"cvssv2": 7.5,
|
||||
"description": "bypass authentication check via crafted values",
|
||||
"name": "CVE-2010-4478"
|
||||
}
|
||||
],
|
||||
"cves": [],
|
||||
"enc": [
|
||||
{
|
||||
"algorithm": "aes128-ctr",
|
||||
@ -261,6 +185,9 @@
|
||||
],
|
||||
"info": [
|
||||
"available since OpenSSH 4.4"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -273,6 +200,9 @@
|
||||
],
|
||||
"info": [
|
||||
"available since OpenSSH 2.3.0"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -286,7 +216,8 @@
|
||||
"available since OpenSSH 3.9, Dropbear SSH 0.53"
|
||||
],
|
||||
"warn": [
|
||||
"2048-bit modulus only provides 112-bits of symmetric strength"
|
||||
"2048-bit modulus only provides 112-bits of symmetric strength",
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -301,6 +232,9 @@
|
||||
"info": [
|
||||
"removed in OpenSSH 6.9: https://www.openssh.com/txt/release-6.9",
|
||||
"available since OpenSSH 2.3.0, Dropbear SSH 0.28"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -4,34 +4,21 @@
|
||||
[0;32m(gen) compatibility: OpenSSH 5.6-6.6, Dropbear SSH 0.53+ (some functionality from 0.52)[0m
|
||||
[0;32m(gen) compression: enabled (zlib@openssh.com)[0m
|
||||
|
||||
[0;36m# security[0m
|
||||
[0;33m(cve) CVE-2020-15778 -- (CVSSv2: 7.8) command injection via anomalous argument transfers[0m
|
||||
[0;33m(cve) CVE-2018-15473 -- (CVSSv2: 5.3) enumerate usernames due to timing discrepancies[0m
|
||||
[0;33m(cve) CVE-2017-15906 -- (CVSSv2: 5.3) readonly bypass via sftp[0m
|
||||
[0;33m(cve) CVE-2016-20012 -- (CVSSv2: 5.3) enumerate usernames via challenge response[0m
|
||||
[0;33m(cve) CVE-2016-3115 -- (CVSSv2: 5.5) bypass command restrictions via crafted X11 forwarding data[0m
|
||||
[0;33m(cve) CVE-2016-1907 -- (CVSSv2: 5.0) cause DoS via crafted network traffic (out of bounds read)[0m
|
||||
[0;33m(cve) CVE-2015-6564 -- (CVSSv2: 6.9) privilege escalation via leveraging sshd uid[0m
|
||||
[0;33m(cve) CVE-2015-6563 -- (CVSSv2: 1.9) conduct impersonation attack[0m
|
||||
[0;33m(cve) CVE-2014-2532 -- (CVSSv2: 5.8) bypass environment restrictions via specific string before wildcard[0m
|
||||
[0;33m(cve) CVE-2014-1692 -- (CVSSv2: 7.5) cause DoS via triggering error condition (memory corruption)[0m
|
||||
[0;33m(cve) CVE-2012-0814 -- (CVSSv2: 3.5) leak data via debug messages[0m
|
||||
[0;33m(cve) CVE-2011-5000 -- (CVSSv2: 3.5) cause DoS via large value in certain length field (memory consumption)[0m
|
||||
[0;33m(cve) CVE-2010-5107 -- (CVSSv2: 5.0) cause DoS via large number of connections (slot exhaustion)[0m
|
||||
[0;33m(cve) CVE-2010-4755 -- (CVSSv2: 4.0) cause DoS via crafted glob expression (CPU and memory consumption)[0m
|
||||
[0;33m(cve) CVE-2010-4478 -- (CVSSv2: 7.5) bypass authentication check via crafted values[0m
|
||||
|
||||
[0;36m# key exchange algorithms[0m
|
||||
[0;31m(kex) diffie-hellman-group-exchange-sha256 (1024-bit) -- [fail] using small 1024-bit modulus[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 4.4
|
||||
[0;31m(kex) diffie-hellman-group-exchange-sha1 (1024-bit) -- [fail] using small 1024-bit modulus[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 2.3.0
|
||||
[0;31m(kex) diffie-hellman-group14-sha1 -- [fail] using broken SHA-1 hash algorithm[0m
|
||||
[0;33m `- [warn] 2048-bit modulus only provides 112-bits of symmetric strength[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
|
||||
[0;31m(kex) diffie-hellman-group1-sha1 -- [fail] using small 1024-bit modulus[0m
|
||||
[0;31m `- [fail] vulnerable to the Logjam attack: https://en.wikipedia.org/wiki/Logjam_(computer_security)[0m
|
||||
[0;31m `- [fail] using broken SHA-1 hash algorithm[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
|
||||
`- [info] removed in OpenSSH 6.9: https://www.openssh.com/txt/release-6.9
|
||||
|
||||
|
@ -10,83 +10,7 @@
|
||||
"none",
|
||||
"zlib@openssh.com"
|
||||
],
|
||||
"cves": [
|
||||
{
|
||||
"cvssv2": 7.8,
|
||||
"description": "command injection via anomalous argument transfers",
|
||||
"name": "CVE-2020-15778"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.3,
|
||||
"description": "enumerate usernames due to timing discrepancies",
|
||||
"name": "CVE-2018-15473"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.3,
|
||||
"description": "readonly bypass via sftp",
|
||||
"name": "CVE-2017-15906"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.3,
|
||||
"description": "enumerate usernames via challenge response",
|
||||
"name": "CVE-2016-20012"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.5,
|
||||
"description": "bypass command restrictions via crafted X11 forwarding data",
|
||||
"name": "CVE-2016-3115"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.0,
|
||||
"description": "cause DoS via crafted network traffic (out of bounds read)",
|
||||
"name": "CVE-2016-1907"
|
||||
},
|
||||
{
|
||||
"cvssv2": 6.9,
|
||||
"description": "privilege escalation via leveraging sshd uid",
|
||||
"name": "CVE-2015-6564"
|
||||
},
|
||||
{
|
||||
"cvssv2": 1.9,
|
||||
"description": "conduct impersonation attack",
|
||||
"name": "CVE-2015-6563"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.8,
|
||||
"description": "bypass environment restrictions via specific string before wildcard",
|
||||
"name": "CVE-2014-2532"
|
||||
},
|
||||
{
|
||||
"cvssv2": 7.5,
|
||||
"description": "cause DoS via triggering error condition (memory corruption)",
|
||||
"name": "CVE-2014-1692"
|
||||
},
|
||||
{
|
||||
"cvssv2": 3.5,
|
||||
"description": "leak data via debug messages",
|
||||
"name": "CVE-2012-0814"
|
||||
},
|
||||
{
|
||||
"cvssv2": 3.5,
|
||||
"description": "cause DoS via large value in certain length field (memory consumption)",
|
||||
"name": "CVE-2011-5000"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.0,
|
||||
"description": "cause DoS via large number of connections (slot exhaustion)",
|
||||
"name": "CVE-2010-5107"
|
||||
},
|
||||
{
|
||||
"cvssv2": 4.0,
|
||||
"description": "cause DoS via crafted glob expression (CPU and memory consumption)",
|
||||
"name": "CVE-2010-4755"
|
||||
},
|
||||
{
|
||||
"cvssv2": 7.5,
|
||||
"description": "bypass authentication check via crafted values",
|
||||
"name": "CVE-2010-4478"
|
||||
}
|
||||
],
|
||||
"cves": [],
|
||||
"enc": [
|
||||
{
|
||||
"algorithm": "aes128-ctr",
|
||||
@ -261,6 +185,9 @@
|
||||
],
|
||||
"info": [
|
||||
"available since OpenSSH 4.4"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -273,6 +200,9 @@
|
||||
],
|
||||
"info": [
|
||||
"available since OpenSSH 2.3.0"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -286,7 +216,8 @@
|
||||
"available since OpenSSH 3.9, Dropbear SSH 0.53"
|
||||
],
|
||||
"warn": [
|
||||
"2048-bit modulus only provides 112-bits of symmetric strength"
|
||||
"2048-bit modulus only provides 112-bits of symmetric strength",
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -301,6 +232,9 @@
|
||||
"info": [
|
||||
"removed in OpenSSH 6.9: https://www.openssh.com/txt/release-6.9",
|
||||
"available since OpenSSH 2.3.0, Dropbear SSH 0.28"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -4,34 +4,21 @@
|
||||
[0;32m(gen) compatibility: OpenSSH 5.6-6.6, Dropbear SSH 0.53+ (some functionality from 0.52)[0m
|
||||
[0;32m(gen) compression: enabled (zlib@openssh.com)[0m
|
||||
|
||||
[0;36m# security[0m
|
||||
[0;33m(cve) CVE-2020-15778 -- (CVSSv2: 7.8) command injection via anomalous argument transfers[0m
|
||||
[0;33m(cve) CVE-2018-15473 -- (CVSSv2: 5.3) enumerate usernames due to timing discrepancies[0m
|
||||
[0;33m(cve) CVE-2017-15906 -- (CVSSv2: 5.3) readonly bypass via sftp[0m
|
||||
[0;33m(cve) CVE-2016-20012 -- (CVSSv2: 5.3) enumerate usernames via challenge response[0m
|
||||
[0;33m(cve) CVE-2016-3115 -- (CVSSv2: 5.5) bypass command restrictions via crafted X11 forwarding data[0m
|
||||
[0;33m(cve) CVE-2016-1907 -- (CVSSv2: 5.0) cause DoS via crafted network traffic (out of bounds read)[0m
|
||||
[0;33m(cve) CVE-2015-6564 -- (CVSSv2: 6.9) privilege escalation via leveraging sshd uid[0m
|
||||
[0;33m(cve) CVE-2015-6563 -- (CVSSv2: 1.9) conduct impersonation attack[0m
|
||||
[0;33m(cve) CVE-2014-2532 -- (CVSSv2: 5.8) bypass environment restrictions via specific string before wildcard[0m
|
||||
[0;33m(cve) CVE-2014-1692 -- (CVSSv2: 7.5) cause DoS via triggering error condition (memory corruption)[0m
|
||||
[0;33m(cve) CVE-2012-0814 -- (CVSSv2: 3.5) leak data via debug messages[0m
|
||||
[0;33m(cve) CVE-2011-5000 -- (CVSSv2: 3.5) cause DoS via large value in certain length field (memory consumption)[0m
|
||||
[0;33m(cve) CVE-2010-5107 -- (CVSSv2: 5.0) cause DoS via large number of connections (slot exhaustion)[0m
|
||||
[0;33m(cve) CVE-2010-4755 -- (CVSSv2: 4.0) cause DoS via crafted glob expression (CPU and memory consumption)[0m
|
||||
[0;33m(cve) CVE-2010-4478 -- (CVSSv2: 7.5) bypass authentication check via crafted values[0m
|
||||
|
||||
[0;36m# key exchange algorithms[0m
|
||||
[0;31m(kex) diffie-hellman-group-exchange-sha256 (1024-bit) -- [fail] using small 1024-bit modulus[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 4.4
|
||||
[0;31m(kex) diffie-hellman-group-exchange-sha1 (1024-bit) -- [fail] using small 1024-bit modulus[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 2.3.0
|
||||
[0;31m(kex) diffie-hellman-group14-sha1 -- [fail] using broken SHA-1 hash algorithm[0m
|
||||
[0;33m `- [warn] 2048-bit modulus only provides 112-bits of symmetric strength[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
|
||||
[0;31m(kex) diffie-hellman-group1-sha1 -- [fail] using small 1024-bit modulus[0m
|
||||
[0;31m `- [fail] vulnerable to the Logjam attack: https://en.wikipedia.org/wiki/Logjam_(computer_security)[0m
|
||||
[0;31m `- [fail] using broken SHA-1 hash algorithm[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
|
||||
`- [info] removed in OpenSSH 6.9: https://www.openssh.com/txt/release-6.9
|
||||
|
||||
|
@ -10,83 +10,7 @@
|
||||
"none",
|
||||
"zlib@openssh.com"
|
||||
],
|
||||
"cves": [
|
||||
{
|
||||
"cvssv2": 7.8,
|
||||
"description": "command injection via anomalous argument transfers",
|
||||
"name": "CVE-2020-15778"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.3,
|
||||
"description": "enumerate usernames due to timing discrepancies",
|
||||
"name": "CVE-2018-15473"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.3,
|
||||
"description": "readonly bypass via sftp",
|
||||
"name": "CVE-2017-15906"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.3,
|
||||
"description": "enumerate usernames via challenge response",
|
||||
"name": "CVE-2016-20012"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.5,
|
||||
"description": "bypass command restrictions via crafted X11 forwarding data",
|
||||
"name": "CVE-2016-3115"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.0,
|
||||
"description": "cause DoS via crafted network traffic (out of bounds read)",
|
||||
"name": "CVE-2016-1907"
|
||||
},
|
||||
{
|
||||
"cvssv2": 6.9,
|
||||
"description": "privilege escalation via leveraging sshd uid",
|
||||
"name": "CVE-2015-6564"
|
||||
},
|
||||
{
|
||||
"cvssv2": 1.9,
|
||||
"description": "conduct impersonation attack",
|
||||
"name": "CVE-2015-6563"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.8,
|
||||
"description": "bypass environment restrictions via specific string before wildcard",
|
||||
"name": "CVE-2014-2532"
|
||||
},
|
||||
{
|
||||
"cvssv2": 7.5,
|
||||
"description": "cause DoS via triggering error condition (memory corruption)",
|
||||
"name": "CVE-2014-1692"
|
||||
},
|
||||
{
|
||||
"cvssv2": 3.5,
|
||||
"description": "leak data via debug messages",
|
||||
"name": "CVE-2012-0814"
|
||||
},
|
||||
{
|
||||
"cvssv2": 3.5,
|
||||
"description": "cause DoS via large value in certain length field (memory consumption)",
|
||||
"name": "CVE-2011-5000"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.0,
|
||||
"description": "cause DoS via large number of connections (slot exhaustion)",
|
||||
"name": "CVE-2010-5107"
|
||||
},
|
||||
{
|
||||
"cvssv2": 4.0,
|
||||
"description": "cause DoS via crafted glob expression (CPU and memory consumption)",
|
||||
"name": "CVE-2010-4755"
|
||||
},
|
||||
{
|
||||
"cvssv2": 7.5,
|
||||
"description": "bypass authentication check via crafted values",
|
||||
"name": "CVE-2010-4478"
|
||||
}
|
||||
],
|
||||
"cves": [],
|
||||
"enc": [
|
||||
{
|
||||
"algorithm": "aes128-ctr",
|
||||
@ -261,6 +185,9 @@
|
||||
],
|
||||
"info": [
|
||||
"available since OpenSSH 4.4"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -273,6 +200,9 @@
|
||||
],
|
||||
"info": [
|
||||
"available since OpenSSH 2.3.0"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -286,7 +216,8 @@
|
||||
"available since OpenSSH 3.9, Dropbear SSH 0.53"
|
||||
],
|
||||
"warn": [
|
||||
"2048-bit modulus only provides 112-bits of symmetric strength"
|
||||
"2048-bit modulus only provides 112-bits of symmetric strength",
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -301,6 +232,9 @@
|
||||
"info": [
|
||||
"removed in OpenSSH 6.9: https://www.openssh.com/txt/release-6.9",
|
||||
"available since OpenSSH 2.3.0, Dropbear SSH 0.28"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -4,34 +4,21 @@
|
||||
[0;32m(gen) compatibility: OpenSSH 5.6-6.6, Dropbear SSH 0.53+ (some functionality from 0.52)[0m
|
||||
[0;32m(gen) compression: enabled (zlib@openssh.com)[0m
|
||||
|
||||
[0;36m# security[0m
|
||||
[0;33m(cve) CVE-2020-15778 -- (CVSSv2: 7.8) command injection via anomalous argument transfers[0m
|
||||
[0;33m(cve) CVE-2018-15473 -- (CVSSv2: 5.3) enumerate usernames due to timing discrepancies[0m
|
||||
[0;33m(cve) CVE-2017-15906 -- (CVSSv2: 5.3) readonly bypass via sftp[0m
|
||||
[0;33m(cve) CVE-2016-20012 -- (CVSSv2: 5.3) enumerate usernames via challenge response[0m
|
||||
[0;33m(cve) CVE-2016-3115 -- (CVSSv2: 5.5) bypass command restrictions via crafted X11 forwarding data[0m
|
||||
[0;33m(cve) CVE-2016-1907 -- (CVSSv2: 5.0) cause DoS via crafted network traffic (out of bounds read)[0m
|
||||
[0;33m(cve) CVE-2015-6564 -- (CVSSv2: 6.9) privilege escalation via leveraging sshd uid[0m
|
||||
[0;33m(cve) CVE-2015-6563 -- (CVSSv2: 1.9) conduct impersonation attack[0m
|
||||
[0;33m(cve) CVE-2014-2532 -- (CVSSv2: 5.8) bypass environment restrictions via specific string before wildcard[0m
|
||||
[0;33m(cve) CVE-2014-1692 -- (CVSSv2: 7.5) cause DoS via triggering error condition (memory corruption)[0m
|
||||
[0;33m(cve) CVE-2012-0814 -- (CVSSv2: 3.5) leak data via debug messages[0m
|
||||
[0;33m(cve) CVE-2011-5000 -- (CVSSv2: 3.5) cause DoS via large value in certain length field (memory consumption)[0m
|
||||
[0;33m(cve) CVE-2010-5107 -- (CVSSv2: 5.0) cause DoS via large number of connections (slot exhaustion)[0m
|
||||
[0;33m(cve) CVE-2010-4755 -- (CVSSv2: 4.0) cause DoS via crafted glob expression (CPU and memory consumption)[0m
|
||||
[0;33m(cve) CVE-2010-4478 -- (CVSSv2: 7.5) bypass authentication check via crafted values[0m
|
||||
|
||||
[0;36m# key exchange algorithms[0m
|
||||
[0;31m(kex) diffie-hellman-group-exchange-sha256 (1024-bit) -- [fail] using small 1024-bit modulus[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 4.4
|
||||
[0;31m(kex) diffie-hellman-group-exchange-sha1 (1024-bit) -- [fail] using small 1024-bit modulus[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 2.3.0
|
||||
[0;31m(kex) diffie-hellman-group14-sha1 -- [fail] using broken SHA-1 hash algorithm[0m
|
||||
[0;33m `- [warn] 2048-bit modulus only provides 112-bits of symmetric strength[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
|
||||
[0;31m(kex) diffie-hellman-group1-sha1 -- [fail] using small 1024-bit modulus[0m
|
||||
[0;31m `- [fail] vulnerable to the Logjam attack: https://en.wikipedia.org/wiki/Logjam_(computer_security)[0m
|
||||
[0;31m `- [fail] using broken SHA-1 hash algorithm[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
|
||||
`- [info] removed in OpenSSH 6.9: https://www.openssh.com/txt/release-6.9
|
||||
|
||||
|
@ -39,5 +39,7 @@
|
||||
],
|
||||
"host": "localhost",
|
||||
"passed": false,
|
||||
"policy": "Hardened OpenSSH Server v8.0 (version 4)"
|
||||
"policy": "Hardened OpenSSH Server v8.0 (version 4)",
|
||||
"port": 2222,
|
||||
"warnings": []
|
||||
}
|
||||
|
@ -62,5 +62,7 @@
|
||||
],
|
||||
"host": "localhost",
|
||||
"passed": false,
|
||||
"policy": "Hardened OpenSSH Server v8.0 (version 4)"
|
||||
"policy": "Hardened OpenSSH Server v8.0 (version 4)",
|
||||
"port": 2222,
|
||||
"warnings": []
|
||||
}
|
||||
|
@ -2,5 +2,7 @@
|
||||
"errors": [],
|
||||
"host": "localhost",
|
||||
"passed": true,
|
||||
"policy": "Docker policy: test11 (version 1)"
|
||||
"policy": "Docker policy: test11 (version 1)",
|
||||
"port": 2222,
|
||||
"warnings": []
|
||||
}
|
||||
|
@ -39,5 +39,7 @@
|
||||
],
|
||||
"host": "localhost",
|
||||
"passed": false,
|
||||
"policy": "Docker policy: test12 (version 1)"
|
||||
"policy": "Docker policy: test12 (version 1)",
|
||||
"port": 2222,
|
||||
"warnings": []
|
||||
}
|
||||
|
@ -2,5 +2,7 @@
|
||||
"errors": [],
|
||||
"host": "localhost",
|
||||
"passed": true,
|
||||
"policy": "Docker policy: test13 (version 1)"
|
||||
"policy": "Docker policy: test13 (version 1)",
|
||||
"port": 2222,
|
||||
"warnings": []
|
||||
}
|
||||
|
@ -15,5 +15,7 @@
|
||||
],
|
||||
"host": "localhost",
|
||||
"passed": false,
|
||||
"policy": "Docker policy: test14 (version 1)"
|
||||
"policy": "Docker policy: test14 (version 1)",
|
||||
"port": 2222,
|
||||
"warnings": []
|
||||
}
|
||||
|
@ -2,5 +2,7 @@
|
||||
"errors": [],
|
||||
"host": "localhost",
|
||||
"passed": true,
|
||||
"policy": "Docker policy: test15 (version 1)"
|
||||
"policy": "Docker policy: test15 (version 1)",
|
||||
"port": 2222,
|
||||
"warnings": []
|
||||
}
|
||||
|
@ -82,5 +82,7 @@
|
||||
],
|
||||
"host": "localhost",
|
||||
"passed": false,
|
||||
"policy": "Docker policy: test16 (version 1)"
|
||||
"policy": "Docker policy: test16 (version 1)",
|
||||
"port": 2222,
|
||||
"warnings": []
|
||||
}
|
||||
|
@ -2,5 +2,7 @@
|
||||
"errors": [],
|
||||
"host": "localhost",
|
||||
"passed": true,
|
||||
"policy": "Docker policy: test17 (version 1)"
|
||||
"policy": "Docker policy: test17 (version 1)",
|
||||
"port": 2222,
|
||||
"warnings": []
|
||||
}
|
||||
|
@ -2,5 +2,7 @@
|
||||
"errors": [],
|
||||
"host": "localhost",
|
||||
"passed": true,
|
||||
"policy": "Docker policy: test6 (version 1)"
|
||||
"policy": "Docker policy: test6 (version 1)",
|
||||
"port": 2222,
|
||||
"warnings": []
|
||||
}
|
||||
|
@ -10,28 +10,7 @@
|
||||
"none",
|
||||
"zlib@openssh.com"
|
||||
],
|
||||
"cves": [
|
||||
{
|
||||
"cvssv2": 7.0,
|
||||
"description": "privilege escalation via supplemental groups",
|
||||
"name": "CVE-2021-41617"
|
||||
},
|
||||
{
|
||||
"cvssv2": 7.8,
|
||||
"description": "command injection via anomalous argument transfers",
|
||||
"name": "CVE-2020-15778"
|
||||
},
|
||||
{
|
||||
"cvssv2": 7.8,
|
||||
"description": "memory corruption and local code execution via pre-authentication integer overflow",
|
||||
"name": "CVE-2019-16905"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.3,
|
||||
"description": "enumerate usernames via challenge response",
|
||||
"name": "CVE-2016-20012"
|
||||
}
|
||||
],
|
||||
"cves": [],
|
||||
"enc": [
|
||||
{
|
||||
"algorithm": "chacha20-poly1305@openssh.com",
|
||||
@ -87,6 +66,16 @@
|
||||
}
|
||||
],
|
||||
"fingerprints": [
|
||||
{
|
||||
"hash": "Q6Llm0o4TrcUen4tnT2h4BDf2f+ina6dIJmVH8c40bg",
|
||||
"hash_alg": "SHA256",
|
||||
"hostkey": "ecdsa-sha2-nistp256"
|
||||
},
|
||||
{
|
||||
"hash": "cc:e0:80:84:5b:05:98:64:24:43:52:3b:17:c8:94:89",
|
||||
"hash_alg": "MD5",
|
||||
"hostkey": "ecdsa-sha2-nistp256"
|
||||
},
|
||||
{
|
||||
"hash": "UrnXIVH+7dlw8UqYocl48yUEcKrthGDQG2CPCgp7MxU",
|
||||
"hash_alg": "SHA256",
|
||||
@ -115,6 +104,9 @@
|
||||
"info": [
|
||||
"default key exchange from OpenSSH 7.4 to 8.9",
|
||||
"available since OpenSSH 7.4, Dropbear SSH 2018.76"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -124,6 +116,9 @@
|
||||
"info": [
|
||||
"default key exchange from OpenSSH 6.5 to 7.3",
|
||||
"available since OpenSSH 6.4, Dropbear SSH 2013.62"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -135,6 +130,9 @@
|
||||
],
|
||||
"info": [
|
||||
"available since OpenSSH 5.7, Dropbear SSH 2013.62"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -146,6 +144,9 @@
|
||||
],
|
||||
"info": [
|
||||
"available since OpenSSH 5.7, Dropbear SSH 2013.62"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -157,6 +158,9 @@
|
||||
],
|
||||
"info": [
|
||||
"available since OpenSSH 5.7, Dropbear SSH 2013.62"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -167,6 +171,9 @@
|
||||
"info": [
|
||||
"OpenSSH's GEX fallback mechanism was triggered during testing. Very old SSH clients will still be able to create connections using a 2048-bit modulus, though modern clients will use 4096. This can only be disabled by recompiling the code (see https://github.com/openssh/openssh-portable/blob/V_9_4/dh.c#L477).",
|
||||
"available since OpenSSH 4.4"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -175,6 +182,9 @@
|
||||
"notes": {
|
||||
"info": [
|
||||
"available since OpenSSH 7.3, Dropbear SSH 2016.73"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -183,6 +193,9 @@
|
||||
"notes": {
|
||||
"info": [
|
||||
"available since OpenSSH 7.3"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -193,7 +206,8 @@
|
||||
"available since OpenSSH 7.3, Dropbear SSH 2016.73"
|
||||
],
|
||||
"warn": [
|
||||
"2048-bit modulus only provides 112-bits of symmetric strength"
|
||||
"2048-bit modulus only provides 112-bits of symmetric strength",
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -207,7 +221,8 @@
|
||||
"available since OpenSSH 3.9, Dropbear SSH 0.53"
|
||||
],
|
||||
"warn": [
|
||||
"2048-bit modulus only provides 112-bits of symmetric strength"
|
||||
"2048-bit modulus only provides 112-bits of symmetric strength",
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -418,6 +433,14 @@
|
||||
}
|
||||
},
|
||||
"warning": {
|
||||
"chg": {
|
||||
"kex": [
|
||||
{
|
||||
"name": "diffie-hellman-group-exchange-sha256",
|
||||
"notes": "increase modulus size to 3072 bits or larger"
|
||||
}
|
||||
]
|
||||
},
|
||||
"del": {
|
||||
"enc": [
|
||||
{
|
||||
@ -426,9 +449,25 @@
|
||||
}
|
||||
],
|
||||
"kex": [
|
||||
{
|
||||
"name": "curve25519-sha256",
|
||||
"notes": ""
|
||||
},
|
||||
{
|
||||
"name": "curve25519-sha256@libssh.org",
|
||||
"notes": ""
|
||||
},
|
||||
{
|
||||
"name": "diffie-hellman-group14-sha256",
|
||||
"notes": ""
|
||||
},
|
||||
{
|
||||
"name": "diffie-hellman-group16-sha512",
|
||||
"notes": ""
|
||||
},
|
||||
{
|
||||
"name": "diffie-hellman-group18-sha512",
|
||||
"notes": ""
|
||||
}
|
||||
],
|
||||
"mac": [
|
||||
|
@ -4,31 +4,35 @@
|
||||
[0;32m(gen) compatibility: OpenSSH 7.4+, Dropbear SSH 2020.79+[0m
|
||||
[0;32m(gen) compression: enabled (zlib@openssh.com)[0m
|
||||
|
||||
[0;36m# security[0m
|
||||
[0;33m(cve) CVE-2021-41617 -- (CVSSv2: 7.0) privilege escalation via supplemental groups[0m
|
||||
[0;33m(cve) CVE-2020-15778 -- (CVSSv2: 7.8) command injection via anomalous argument transfers[0m
|
||||
[0;33m(cve) CVE-2019-16905 -- (CVSSv2: 7.8) memory corruption and local code execution via pre-authentication integer overflow[0m
|
||||
[0;33m(cve) CVE-2016-20012 -- (CVSSv2: 5.3) enumerate usernames via challenge response[0m
|
||||
|
||||
[0;36m# key exchange algorithms[0m
|
||||
[0;32m(kex) curve25519-sha256 -- [info] available since OpenSSH 7.4, Dropbear SSH 2018.76[0m
|
||||
[0;32m `- [info] default key exchange from OpenSSH 7.4 to 8.9[0m
|
||||
[0;32m(kex) curve25519-sha256@libssh.org -- [info] available since OpenSSH 6.4, Dropbear SSH 2013.62[0m
|
||||
[0;32m `- [info] default key exchange from OpenSSH 6.5 to 7.3[0m
|
||||
[0;33m(kex) curve25519-sha256 -- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 7.4, Dropbear SSH 2018.76
|
||||
`- [info] default key exchange from OpenSSH 7.4 to 8.9
|
||||
[0;33m(kex) curve25519-sha256@libssh.org -- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 6.4, Dropbear SSH 2013.62
|
||||
`- [info] default key exchange from OpenSSH 6.5 to 7.3
|
||||
[0;31m(kex) ecdh-sha2-nistp256 -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
|
||||
[0;31m(kex) ecdh-sha2-nistp384 -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
|
||||
[0;31m(kex) ecdh-sha2-nistp521 -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
|
||||
[0;32m(kex) diffie-hellman-group-exchange-sha256 (4096-bit) -- [info] available since OpenSSH 4.4[0m
|
||||
[0;32m `- [info] OpenSSH's GEX fallback mechanism was triggered during testing. Very old SSH clients will still be able to create connections using a 2048-bit modulus, though modern clients will use 4096. This can only be disabled by recompiling the code (see https://github.com/openssh/openssh-portable/blob/V_9_4/dh.c#L477).[0m
|
||||
[0;32m(kex) diffie-hellman-group16-sha512 -- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73[0m
|
||||
[0;32m(kex) diffie-hellman-group18-sha512 -- [info] available since OpenSSH 7.3[0m
|
||||
[0;33m(kex) diffie-hellman-group-exchange-sha256 (4096-bit) -- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 4.4
|
||||
`- [info] OpenSSH's GEX fallback mechanism was triggered during testing. Very old SSH clients will still be able to create connections using a 2048-bit modulus, though modern clients will use 4096. This can only be disabled by recompiling the code (see https://github.com/openssh/openssh-portable/blob/V_9_4/dh.c#L477).
|
||||
[0;33m(kex) diffie-hellman-group16-sha512 -- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73
|
||||
[0;33m(kex) diffie-hellman-group18-sha512 -- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 7.3
|
||||
[0;33m(kex) diffie-hellman-group14-sha256 -- [warn] 2048-bit modulus only provides 112-bits of symmetric strength[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73
|
||||
[0;31m(kex) diffie-hellman-group14-sha1 -- [fail] using broken SHA-1 hash algorithm[0m
|
||||
[0;33m `- [warn] 2048-bit modulus only provides 112-bits of symmetric strength[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
|
||||
|
||||
[0;36m# host-key algorithms[0m
|
||||
@ -86,8 +90,13 @@
|
||||
[0;31m(rec) -hmac-sha1 -- mac algorithm to remove [0m
|
||||
[0;31m(rec) -hmac-sha1-etm@openssh.com -- mac algorithm to remove [0m
|
||||
[0;31m(rec) -ssh-rsa -- key algorithm to remove [0m
|
||||
[0;33m(rec) !diffie-hellman-group-exchange-sha256 -- kex algorithm to change (increase modulus size to 3072 bits or larger) [0m
|
||||
[0;33m(rec) -chacha20-poly1305@openssh.com -- enc algorithm to remove [0m
|
||||
[0;33m(rec) -curve25519-sha256 -- kex algorithm to remove [0m
|
||||
[0;33m(rec) -curve25519-sha256@libssh.org -- kex algorithm to remove [0m
|
||||
[0;33m(rec) -diffie-hellman-group14-sha256 -- kex algorithm to remove [0m
|
||||
[0;33m(rec) -diffie-hellman-group16-sha512 -- kex algorithm to remove [0m
|
||||
[0;33m(rec) -diffie-hellman-group18-sha512 -- kex algorithm to remove [0m
|
||||
[0;33m(rec) -hmac-sha2-256 -- mac algorithm to remove [0m
|
||||
[0;33m(rec) -hmac-sha2-512 -- mac algorithm to remove [0m
|
||||
[0;33m(rec) -umac-128@openssh.com -- mac algorithm to remove [0m
|
||||
|
@ -10,28 +10,7 @@
|
||||
"none",
|
||||
"zlib@openssh.com"
|
||||
],
|
||||
"cves": [
|
||||
{
|
||||
"cvssv2": 7.0,
|
||||
"description": "privilege escalation via supplemental groups",
|
||||
"name": "CVE-2021-41617"
|
||||
},
|
||||
{
|
||||
"cvssv2": 7.8,
|
||||
"description": "command injection via anomalous argument transfers",
|
||||
"name": "CVE-2020-15778"
|
||||
},
|
||||
{
|
||||
"cvssv2": 7.8,
|
||||
"description": "memory corruption and local code execution via pre-authentication integer overflow",
|
||||
"name": "CVE-2019-16905"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.3,
|
||||
"description": "enumerate usernames via challenge response",
|
||||
"name": "CVE-2016-20012"
|
||||
}
|
||||
],
|
||||
"cves": [],
|
||||
"enc": [
|
||||
{
|
||||
"algorithm": "chacha20-poly1305@openssh.com",
|
||||
@ -105,6 +84,9 @@
|
||||
"info": [
|
||||
"default key exchange from OpenSSH 7.4 to 8.9",
|
||||
"available since OpenSSH 7.4, Dropbear SSH 2018.76"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -114,6 +96,9 @@
|
||||
"info": [
|
||||
"default key exchange from OpenSSH 6.5 to 7.3",
|
||||
"available since OpenSSH 6.4, Dropbear SSH 2013.62"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -125,6 +110,9 @@
|
||||
],
|
||||
"info": [
|
||||
"available since OpenSSH 5.7, Dropbear SSH 2013.62"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -136,6 +124,9 @@
|
||||
],
|
||||
"info": [
|
||||
"available since OpenSSH 5.7, Dropbear SSH 2013.62"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -147,6 +138,9 @@
|
||||
],
|
||||
"info": [
|
||||
"available since OpenSSH 5.7, Dropbear SSH 2013.62"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -157,6 +151,9 @@
|
||||
"info": [
|
||||
"OpenSSH's GEX fallback mechanism was triggered during testing. Very old SSH clients will still be able to create connections using a 2048-bit modulus, though modern clients will use 4096. This can only be disabled by recompiling the code (see https://github.com/openssh/openssh-portable/blob/V_9_4/dh.c#L477).",
|
||||
"available since OpenSSH 4.4"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -165,6 +162,9 @@
|
||||
"notes": {
|
||||
"info": [
|
||||
"available since OpenSSH 7.3, Dropbear SSH 2016.73"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -173,6 +173,9 @@
|
||||
"notes": {
|
||||
"info": [
|
||||
"available since OpenSSH 7.3"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -183,7 +186,8 @@
|
||||
"available since OpenSSH 7.3, Dropbear SSH 2016.73"
|
||||
],
|
||||
"warn": [
|
||||
"2048-bit modulus only provides 112-bits of symmetric strength"
|
||||
"2048-bit modulus only provides 112-bits of symmetric strength",
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -197,7 +201,8 @@
|
||||
"available since OpenSSH 3.9, Dropbear SSH 0.53"
|
||||
],
|
||||
"warn": [
|
||||
"2048-bit modulus only provides 112-bits of symmetric strength"
|
||||
"2048-bit modulus only provides 112-bits of symmetric strength",
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -377,6 +382,14 @@
|
||||
}
|
||||
},
|
||||
"warning": {
|
||||
"chg": {
|
||||
"kex": [
|
||||
{
|
||||
"name": "diffie-hellman-group-exchange-sha256",
|
||||
"notes": "increase modulus size to 3072 bits or larger"
|
||||
}
|
||||
]
|
||||
},
|
||||
"del": {
|
||||
"enc": [
|
||||
{
|
||||
@ -385,9 +398,25 @@
|
||||
}
|
||||
],
|
||||
"kex": [
|
||||
{
|
||||
"name": "curve25519-sha256",
|
||||
"notes": ""
|
||||
},
|
||||
{
|
||||
"name": "curve25519-sha256@libssh.org",
|
||||
"notes": ""
|
||||
},
|
||||
{
|
||||
"name": "diffie-hellman-group14-sha256",
|
||||
"notes": ""
|
||||
},
|
||||
{
|
||||
"name": "diffie-hellman-group16-sha512",
|
||||
"notes": ""
|
||||
},
|
||||
{
|
||||
"name": "diffie-hellman-group18-sha512",
|
||||
"notes": ""
|
||||
}
|
||||
],
|
||||
"mac": [
|
||||
|
@ -4,31 +4,35 @@
|
||||
[0;32m(gen) compatibility: OpenSSH 7.4+, Dropbear SSH 2020.79+[0m
|
||||
[0;32m(gen) compression: enabled (zlib@openssh.com)[0m
|
||||
|
||||
[0;36m# security[0m
|
||||
[0;33m(cve) CVE-2021-41617 -- (CVSSv2: 7.0) privilege escalation via supplemental groups[0m
|
||||
[0;33m(cve) CVE-2020-15778 -- (CVSSv2: 7.8) command injection via anomalous argument transfers[0m
|
||||
[0;33m(cve) CVE-2019-16905 -- (CVSSv2: 7.8) memory corruption and local code execution via pre-authentication integer overflow[0m
|
||||
[0;33m(cve) CVE-2016-20012 -- (CVSSv2: 5.3) enumerate usernames via challenge response[0m
|
||||
|
||||
[0;36m# key exchange algorithms[0m
|
||||
[0;32m(kex) curve25519-sha256 -- [info] available since OpenSSH 7.4, Dropbear SSH 2018.76[0m
|
||||
[0;32m `- [info] default key exchange from OpenSSH 7.4 to 8.9[0m
|
||||
[0;32m(kex) curve25519-sha256@libssh.org -- [info] available since OpenSSH 6.4, Dropbear SSH 2013.62[0m
|
||||
[0;32m `- [info] default key exchange from OpenSSH 6.5 to 7.3[0m
|
||||
[0;33m(kex) curve25519-sha256 -- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 7.4, Dropbear SSH 2018.76
|
||||
`- [info] default key exchange from OpenSSH 7.4 to 8.9
|
||||
[0;33m(kex) curve25519-sha256@libssh.org -- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 6.4, Dropbear SSH 2013.62
|
||||
`- [info] default key exchange from OpenSSH 6.5 to 7.3
|
||||
[0;31m(kex) ecdh-sha2-nistp256 -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
|
||||
[0;31m(kex) ecdh-sha2-nistp384 -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
|
||||
[0;31m(kex) ecdh-sha2-nistp521 -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
|
||||
[0;32m(kex) diffie-hellman-group-exchange-sha256 (4096-bit) -- [info] available since OpenSSH 4.4[0m
|
||||
[0;32m `- [info] OpenSSH's GEX fallback mechanism was triggered during testing. Very old SSH clients will still be able to create connections using a 2048-bit modulus, though modern clients will use 4096. This can only be disabled by recompiling the code (see https://github.com/openssh/openssh-portable/blob/V_9_4/dh.c#L477).[0m
|
||||
[0;32m(kex) diffie-hellman-group16-sha512 -- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73[0m
|
||||
[0;32m(kex) diffie-hellman-group18-sha512 -- [info] available since OpenSSH 7.3[0m
|
||||
[0;33m(kex) diffie-hellman-group-exchange-sha256 (4096-bit) -- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 4.4
|
||||
`- [info] OpenSSH's GEX fallback mechanism was triggered during testing. Very old SSH clients will still be able to create connections using a 2048-bit modulus, though modern clients will use 4096. This can only be disabled by recompiling the code (see https://github.com/openssh/openssh-portable/blob/V_9_4/dh.c#L477).
|
||||
[0;33m(kex) diffie-hellman-group16-sha512 -- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73
|
||||
[0;33m(kex) diffie-hellman-group18-sha512 -- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 7.3
|
||||
[0;33m(kex) diffie-hellman-group14-sha256 -- [warn] 2048-bit modulus only provides 112-bits of symmetric strength[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73
|
||||
[0;31m(kex) diffie-hellman-group14-sha1 -- [fail] using broken SHA-1 hash algorithm[0m
|
||||
[0;33m `- [warn] 2048-bit modulus only provides 112-bits of symmetric strength[0m
|
||||
[0;33m `- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
|
||||
|
||||
[0;36m# host-key algorithms[0m
|
||||
@ -78,8 +82,13 @@
|
||||
[0;31m(rec) -hmac-sha1-etm@openssh.com -- mac algorithm to remove [0m
|
||||
[0;32m(rec) +rsa-sha2-256 -- key algorithm to append [0m
|
||||
[0;32m(rec) +rsa-sha2-512 -- key algorithm to append [0m
|
||||
[0;33m(rec) !diffie-hellman-group-exchange-sha256 -- kex algorithm to change (increase modulus size to 3072 bits or larger) [0m
|
||||
[0;33m(rec) -chacha20-poly1305@openssh.com -- enc algorithm to remove [0m
|
||||
[0;33m(rec) -curve25519-sha256 -- kex algorithm to remove [0m
|
||||
[0;33m(rec) -curve25519-sha256@libssh.org -- kex algorithm to remove [0m
|
||||
[0;33m(rec) -diffie-hellman-group14-sha256 -- kex algorithm to remove [0m
|
||||
[0;33m(rec) -diffie-hellman-group16-sha512 -- kex algorithm to remove [0m
|
||||
[0;33m(rec) -diffie-hellman-group18-sha512 -- kex algorithm to remove [0m
|
||||
[0;33m(rec) -hmac-sha2-256 -- mac algorithm to remove [0m
|
||||
[0;33m(rec) -hmac-sha2-512 -- mac algorithm to remove [0m
|
||||
[0;33m(rec) -umac-128@openssh.com -- mac algorithm to remove [0m
|
||||
|
@ -10,28 +10,7 @@
|
||||
"none",
|
||||
"zlib@openssh.com"
|
||||
],
|
||||
"cves": [
|
||||
{
|
||||
"cvssv2": 7.0,
|
||||
"description": "privilege escalation via supplemental groups",
|
||||
"name": "CVE-2021-41617"
|
||||
},
|
||||
{
|
||||
"cvssv2": 7.8,
|
||||
"description": "command injection via anomalous argument transfers",
|
||||
"name": "CVE-2020-15778"
|
||||
},
|
||||
{
|
||||
"cvssv2": 7.8,
|
||||
"description": "memory corruption and local code execution via pre-authentication integer overflow",
|
||||
"name": "CVE-2019-16905"
|
||||
},
|
||||
{
|
||||
"cvssv2": 5.3,
|
||||
"description": "enumerate usernames via challenge response",
|
||||
"name": "CVE-2016-20012"
|
||||
}
|
||||
],
|
||||
"cves": [],
|
||||
"enc": [
|
||||
{
|
||||
"algorithm": "chacha20-poly1305@openssh.com",
|
||||
@ -105,6 +84,9 @@
|
||||
"info": [
|
||||
"default key exchange from OpenSSH 7.4 to 8.9",
|
||||
"available since OpenSSH 7.4, Dropbear SSH 2018.76"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -114,6 +96,9 @@
|
||||
"info": [
|
||||
"default key exchange from OpenSSH 6.5 to 7.3",
|
||||
"available since OpenSSH 6.4, Dropbear SSH 2013.62"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -124,6 +109,9 @@
|
||||
"info": [
|
||||
"OpenSSH's GEX fallback mechanism was triggered during testing. Very old SSH clients will still be able to create connections using a 2048-bit modulus, though modern clients will use 4096. This can only be disabled by recompiling the code (see https://github.com/openssh/openssh-portable/blob/V_9_4/dh.c#L477).",
|
||||
"available since OpenSSH 4.4"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -167,16 +155,6 @@
|
||||
"recommendations": {
|
||||
"informational": {
|
||||
"add": {
|
||||
"kex": [
|
||||
{
|
||||
"name": "diffie-hellman-group16-sha512",
|
||||
"notes": ""
|
||||
},
|
||||
{
|
||||
"name": "diffie-hellman-group18-sha512",
|
||||
"notes": ""
|
||||
}
|
||||
],
|
||||
"key": [
|
||||
{
|
||||
"name": "rsa-sha2-256",
|
||||
@ -190,12 +168,30 @@
|
||||
}
|
||||
},
|
||||
"warning": {
|
||||
"chg": {
|
||||
"kex": [
|
||||
{
|
||||
"name": "diffie-hellman-group-exchange-sha256",
|
||||
"notes": "increase modulus size to 3072 bits or larger"
|
||||
}
|
||||
]
|
||||
},
|
||||
"del": {
|
||||
"enc": [
|
||||
{
|
||||
"name": "chacha20-poly1305@openssh.com",
|
||||
"notes": ""
|
||||
}
|
||||
],
|
||||
"kex": [
|
||||
{
|
||||
"name": "curve25519-sha256",
|
||||
"notes": ""
|
||||
},
|
||||
{
|
||||
"name": "curve25519-sha256@libssh.org",
|
||||
"notes": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -4,19 +4,16 @@
|
||||
[0;32m(gen) compatibility: OpenSSH 7.4+, Dropbear SSH 2020.79+[0m
|
||||
[0;32m(gen) compression: enabled (zlib@openssh.com)[0m
|
||||
|
||||
[0;36m# security[0m
|
||||
[0;33m(cve) CVE-2021-41617 -- (CVSSv2: 7.0) privilege escalation via supplemental groups[0m
|
||||
[0;33m(cve) CVE-2020-15778 -- (CVSSv2: 7.8) command injection via anomalous argument transfers[0m
|
||||
[0;33m(cve) CVE-2019-16905 -- (CVSSv2: 7.8) memory corruption and local code execution via pre-authentication integer overflow[0m
|
||||
[0;33m(cve) CVE-2016-20012 -- (CVSSv2: 5.3) enumerate usernames via challenge response[0m
|
||||
|
||||
[0;36m# key exchange algorithms[0m
|
||||
[0;32m(kex) curve25519-sha256 -- [info] available since OpenSSH 7.4, Dropbear SSH 2018.76[0m
|
||||
[0;32m `- [info] default key exchange from OpenSSH 7.4 to 8.9[0m
|
||||
[0;32m(kex) curve25519-sha256@libssh.org -- [info] available since OpenSSH 6.4, Dropbear SSH 2013.62[0m
|
||||
[0;32m `- [info] default key exchange from OpenSSH 6.5 to 7.3[0m
|
||||
[0;32m(kex) diffie-hellman-group-exchange-sha256 (4096-bit) -- [info] available since OpenSSH 4.4[0m
|
||||
[0;32m `- [info] OpenSSH's GEX fallback mechanism was triggered during testing. Very old SSH clients will still be able to create connections using a 2048-bit modulus, though modern clients will use 4096. This can only be disabled by recompiling the code (see https://github.com/openssh/openssh-portable/blob/V_9_4/dh.c#L477).[0m
|
||||
[0;33m(kex) curve25519-sha256 -- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 7.4, Dropbear SSH 2018.76
|
||||
`- [info] default key exchange from OpenSSH 7.4 to 8.9
|
||||
[0;33m(kex) curve25519-sha256@libssh.org -- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 6.4, Dropbear SSH 2013.62
|
||||
`- [info] default key exchange from OpenSSH 6.5 to 7.3
|
||||
[0;33m(kex) diffie-hellman-group-exchange-sha256 (4096-bit) -- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 4.4
|
||||
`- [info] OpenSSH's GEX fallback mechanism was triggered during testing. Very old SSH clients will still be able to create connections using a 2048-bit modulus, though modern clients will use 4096. This can only be disabled by recompiling the code (see https://github.com/openssh/openssh-portable/blob/V_9_4/dh.c#L477).
|
||||
|
||||
[0;36m# host-key algorithms[0m
|
||||
[0;32m(key) ssh-ed25519 -- [info] available since OpenSSH 6.5, Dropbear SSH 2020.79[0m
|
||||
@ -40,11 +37,12 @@
|
||||
[0;32m(fin) ssh-ed25519: SHA256:UrnXIVH+7dlw8UqYocl48yUEcKrthGDQG2CPCgp7MxU[0m
|
||||
|
||||
[0;36m# algorithm recommendations (for OpenSSH 8.0)[0m
|
||||
[0;32m(rec) +diffie-hellman-group16-sha512 -- kex algorithm to append [0m
|
||||
[0;32m(rec) +diffie-hellman-group18-sha512 -- kex algorithm to append [0m
|
||||
[0;32m(rec) +rsa-sha2-256 -- key algorithm to append [0m
|
||||
[0;32m(rec) +rsa-sha2-512 -- key algorithm to append [0m
|
||||
[0;33m(rec) !diffie-hellman-group-exchange-sha256 -- kex algorithm to change (increase modulus size to 3072 bits or larger) [0m
|
||||
[0;33m(rec) -chacha20-poly1305@openssh.com -- enc algorithm to remove [0m
|
||||
[0;33m(rec) -curve25519-sha256 -- kex algorithm to remove [0m
|
||||
[0;33m(rec) -curve25519-sha256@libssh.org -- kex algorithm to remove [0m
|
||||
|
||||
[0;36m# additional info[0m
|
||||
[0;33m(nfo) For hardening guides on common OSes, please see: <https://www.ssh-audit.com/hardening_guides.html>[0m
|
||||
|
@ -43,6 +43,9 @@
|
||||
"info": [
|
||||
"default key exchange from OpenSSH 7.4 to 8.9",
|
||||
"available since OpenSSH 7.4, Dropbear SSH 2018.76"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -52,6 +55,9 @@
|
||||
"info": [
|
||||
"default key exchange from OpenSSH 6.5 to 7.3",
|
||||
"available since OpenSSH 6.4, Dropbear SSH 2013.62"
|
||||
],
|
||||
"warn": [
|
||||
"does not provide protection against post-quantum attacks"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
@ -4,10 +4,12 @@
|
||||
[0;32m(gen) compression: disabled[0m
|
||||
|
||||
[0;36m# key exchange algorithms[0m
|
||||
[0;32m(kex) curve25519-sha256 -- [info] available since OpenSSH 7.4, Dropbear SSH 2018.76[0m
|
||||
[0;32m `- [info] default key exchange from OpenSSH 7.4 to 8.9[0m
|
||||
[0;32m(kex) curve25519-sha256@libssh.org -- [info] available since OpenSSH 6.4, Dropbear SSH 2013.62[0m
|
||||
[0;32m `- [info] default key exchange from OpenSSH 6.5 to 7.3[0m
|
||||
[0;33m(kex) curve25519-sha256 -- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 7.4, Dropbear SSH 2018.76
|
||||
`- [info] default key exchange from OpenSSH 7.4 to 8.9
|
||||
[0;33m(kex) curve25519-sha256@libssh.org -- [warn] does not provide protection against post-quantum attacks[0m
|
||||
`- [info] available since OpenSSH 6.4, Dropbear SSH 2013.62
|
||||
`- [info] default key exchange from OpenSSH 6.5 to 7.3
|
||||
[0;33m(kex) sntrup4591761x25519-sha512@tinyssh.org -- [warn] using experimental algorithm[0m
|
||||
`- [info] available since OpenSSH 8.0
|
||||
`- [info] the sntrup4591761 algorithm was withdrawn, as it may not provide strong post-quantum security
|
||||
|
@ -8,7 +8,6 @@ class TestAuditConf:
|
||||
def init(self, ssh_audit):
|
||||
self.AuditConf = ssh_audit.AuditConf
|
||||
self.OutputBuffer = ssh_audit.OutputBuffer()
|
||||
self.usage = ssh_audit.usage
|
||||
self.process_commandline = process_commandline
|
||||
|
||||
@staticmethod
|
||||
@ -107,7 +106,7 @@ class TestAuditConf:
|
||||
|
||||
def test_audit_conf_process_commandline(self):
|
||||
# pylint: disable=too-many-statements
|
||||
c = lambda x: self.process_commandline(self.OutputBuffer, x.split(), self.usage) # noqa
|
||||
c = lambda x: self.process_commandline(self.OutputBuffer, x.split()) # noqa
|
||||
with pytest.raises(SystemExit):
|
||||
conf = c('')
|
||||
with pytest.raises(SystemExit):
|
||||
@ -163,7 +162,7 @@ class TestAuditConf:
|
||||
conf = c('-64 localhost')
|
||||
self._test_conf(conf, host='localhost', ipv4=True, ipv6=True, ipvo=(6, 4))
|
||||
conf = c('-b localhost')
|
||||
self._test_conf(conf, host='localhost', batch=True, verbose=True)
|
||||
self._test_conf(conf, host='localhost', batch=True)
|
||||
conf = c('-n localhost')
|
||||
self._test_conf(conf, host='localhost', colors=False)
|
||||
conf = c('-v localhost')
|
||||
|
@ -36,7 +36,7 @@ def test_prevent_runtime_error_regression(ssh_audit, kex):
|
||||
kex.set_host_key("ssh-rsa7", b"\x00\x00\x00\x07ssh-rsa\x00\x00\x00", 1024, '', 0)
|
||||
kex.set_host_key("ssh-rsa8", b"\x00\x00\x00\x07ssh-rsa\x00\x00\x00", 1024, '', 0)
|
||||
|
||||
rv = ssh_audit.build_struct('localhost', None, [], kex=kex)
|
||||
rv = ssh_audit.build_struct('localhost', None, kex=kex)
|
||||
|
||||
assert len(rv["fingerprints"]) == (9 * 2) # Each host key generates two hash fingerprints: one using SHA256, and one using MD5.
|
||||
|
||||
|
@ -52,6 +52,14 @@ class TestPolicy:
|
||||
version_str = " (version %s)" % BUILTIN_POLICIES[policy_name]['version']
|
||||
assert policy_name.endswith(version_str)
|
||||
|
||||
# Ensure version field is a string, but can be parsed as an integer.
|
||||
version_field = BUILTIN_POLICIES[policy_name]['version']
|
||||
assert type(version_field) is str
|
||||
try:
|
||||
int(version_field)
|
||||
except ValueError:
|
||||
assert False, "version field of %s policy is not parseable as an integer." % policy_name
|
||||
|
||||
# Ensure no extra fields are present.
|
||||
assert len(required_fields) == len(BUILTIN_POLICIES[policy_name])
|
||||
|
||||
|
@ -139,7 +139,7 @@ class TestSSH1:
|
||||
self.audit(out, self._conf())
|
||||
out.write()
|
||||
lines = output_spy.flush()
|
||||
assert len(lines) == 21
|
||||
assert len(lines) == 13
|
||||
|
||||
def test_ssh1_server_invalid_first_packet(self, output_spy, virtual_socket):
|
||||
vsocket = virtual_socket
|
||||
@ -154,7 +154,7 @@ class TestSSH1:
|
||||
out.write()
|
||||
assert ret != 0
|
||||
lines = output_spy.flush()
|
||||
assert len(lines) == 14
|
||||
assert len(lines) == 6
|
||||
assert 'unknown message' in lines[-1]
|
||||
|
||||
def test_ssh1_server_invalid_checksum(self, output_spy, virtual_socket):
|
||||
|
@ -165,7 +165,7 @@ class TestSSH2:
|
||||
self.audit(out, self._conf())
|
||||
out.write()
|
||||
lines = output_spy.flush()
|
||||
assert len(lines) == 83
|
||||
assert len(lines) == 74
|
||||
|
||||
def test_ssh2_server_invalid_first_packet(self, output_spy, virtual_socket):
|
||||
vsocket = virtual_socket
|
||||
@ -179,7 +179,7 @@ class TestSSH2:
|
||||
out.write()
|
||||
assert ret != 0
|
||||
lines = output_spy.flush()
|
||||
assert len(lines) == 9
|
||||
assert len(lines) == 4
|
||||
assert 'unknown message' in lines[-1]
|
||||
|
||||
def test_ssh2_gss_kex(self, output_spy, virtual_socket):
|
||||
|
@ -8,6 +8,7 @@ class Test_SSH2_KexDB:
|
||||
@pytest.fixture(autouse=True)
|
||||
def init(self):
|
||||
self.db = SSH2_KexDB.get_db()
|
||||
self.pq_warning = SSH2_KexDB.WARN_NOT_PQ_SAFE
|
||||
|
||||
def test_ssh2_kexdb(self):
|
||||
'''Ensures that the SSH2_KexDB.ALGORITHMS dictionary is in the right format.'''
|
||||
@ -33,3 +34,38 @@ class Test_SSH2_KexDB:
|
||||
# The first entry denotes the versions when this algorithm was added to OpenSSH, Dropbear, and/or libssh, followed by when it was deprecated, and finally when it was removed. Hence it must have between 0 and 3 entries.
|
||||
added_entry = alg_data[0]
|
||||
assert 0 <= len(added_entry) <= 3
|
||||
|
||||
|
||||
def test_kex_pq_unsafe(self):
|
||||
'''Ensures that all key exchange algorithms are marked as post-quantum unsafe, unless they appear in a whitelist.'''
|
||||
|
||||
# These algorithms include protections against quantum attacks.
|
||||
kex_pq_safe = [
|
||||
"ecdh-nistp256-kyber-512r3-sha256-d00@openquantumsafe.org",
|
||||
"ecdh-nistp384-kyber-768r3-sha384-d00@openquantumsafe.org",
|
||||
"ecdh-nistp521-kyber-1024r3-sha512-d00@openquantumsafe.org",
|
||||
"ext-info-c",
|
||||
"ext-info-s",
|
||||
"kex-strict-c-v00@openssh.com",
|
||||
"kex-strict-s-v00@openssh.com",
|
||||
"mlkem768x25519-sha256",
|
||||
"sntrup4591761x25519-sha512@tinyssh.org",
|
||||
"sntrup761x25519-sha512@openssh.com",
|
||||
"sntrup761x25519-sha512",
|
||||
"x25519-kyber-512r3-sha256-d00@amazon.com",
|
||||
"x25519-kyber512-sha512@aws.amazon.com"
|
||||
]
|
||||
|
||||
failures = []
|
||||
for kex_name in self.db['kex']:
|
||||
|
||||
# Skip key exchanges that are PQ safe.
|
||||
if kex_name in kex_pq_safe:
|
||||
continue
|
||||
|
||||
# Ensure all other kex exchanges have the proper PQ unsafe flag set in their warnings list.
|
||||
alg_data = self.db['kex'][kex_name]
|
||||
if len(alg_data) < 3 or self.pq_warning not in alg_data[2]:
|
||||
failures.append(kex_name)
|
||||
|
||||
assert failures == []
|
||||
|
17
tox.ini
17
tox.ini
@ -1,7 +1,7 @@
|
||||
[tox]
|
||||
envlist =
|
||||
py{py3}-{test,pylint,flake8}
|
||||
py{38,39,310,311,312}-{test,mypy,pylint,flake8}
|
||||
py{38,39,310,311,312,313}-{test,mypy,pylint,flake8}
|
||||
cov
|
||||
skip_missing_interpreters = true
|
||||
|
||||
@ -9,10 +9,10 @@ skip_missing_interpreters = true
|
||||
deps =
|
||||
test: pytest
|
||||
test,cov: {[testenv:cov]deps}
|
||||
test,py{38,39,310,311,312}-{type,mypy}: colorama
|
||||
py{38,39,310,311,312}-{type,mypy}: {[testenv:mypy]deps}
|
||||
py{py3,38,39,310,311,312}-{lint,pylint},lint: {[testenv:pylint]deps}
|
||||
py{py3,38,39,310,311,312}-{lint,flake8},lint: {[testenv:flake8]deps}
|
||||
test,py{38,39,310,311,312,313}-{type,mypy}: colorama
|
||||
py{38,39,310,311,312,313}-{type,mypy}: {[testenv:mypy]deps}
|
||||
py{py3,38,39,310,311,312,313}-{lint,pylint},lint: {[testenv:pylint]deps}
|
||||
py{py3,38,39,310,311,312,313}-{lint,flake8},lint: {[testenv:flake8]deps}
|
||||
setenv =
|
||||
SSHAUDIT = {toxinidir}/src
|
||||
test: COVERAGE_FILE = {toxinidir}/.coverage.{envname}
|
||||
@ -24,9 +24,9 @@ commands =
|
||||
test: coverage combine
|
||||
test: coverage report --show-missing
|
||||
test: coverage html -d {toxinidir}/reports/html/coverage.{envname}
|
||||
py{38,39,310,311,312}-{type,mypy}: {[testenv:mypy]commands}
|
||||
py{py3,38,39,310,311,312}-{lint,pylint},lint: {[testenv:pylint]commands}
|
||||
py{py3,38,39,310,311,312}-{lint,flake8},lint: {[testenv:flake8]commands}
|
||||
py{38,39,310,311,312,313}-{type,mypy}: {[testenv:mypy]commands}
|
||||
py{py3,38,39,310,311,312,313}-{lint,pylint},lint: {[testenv:pylint]commands}
|
||||
py{py3,38,39,310,311,312,313}-{lint,flake8},lint: {[testenv:flake8]commands}
|
||||
|
||||
#ignore_outcome =
|
||||
# type: true
|
||||
@ -96,6 +96,7 @@ disable =
|
||||
too-many-lines,
|
||||
too-many-locals,
|
||||
too-many-nested-blocks,
|
||||
too-many-positional-arguments,
|
||||
too-many-return-statements,
|
||||
too-many-statements,
|
||||
consider-using-f-string
|
||||
|
Loading…
x
Reference in New Issue
Block a user