mirror of
https://github.com/jtesta/ssh-audit.git
synced 2025-07-06 14:02:49 -05:00
Compare commits
73 Commits
Author | SHA1 | Date | |
---|---|---|---|
3ba28b01e9 | |||
3c1451cfdc | |||
929652c9b7 | |||
e172932977 | |||
c33e7d9b72 | |||
0074fcc1af | |||
1eab4ab0e6 | |||
7f8d6b4d5b | |||
4c098b7d12 | |||
0bfb5d6979 | |||
a5f5e0dab2 | |||
05f159a152 | |||
263267c5ad | |||
4f31304b66 | |||
6f05a2c6b5 | |||
784d412148 | |||
dc083de87e | |||
7d5eb37a0f | |||
5c1c447755 | |||
cbb7d43006 | |||
cc9e4fbc4a | |||
992aa1b961 | |||
413dea60ae | |||
e2a9896397 | |||
71feaa191e | |||
c02ab8f170 | |||
cdaee69642 | |||
7bbf4cdff0 | |||
e4d864c6c1 | |||
1663e5bdcf | |||
5ecad8fac9 | |||
38ff225ed8 | |||
c9dc9a9c10 | |||
f9e00b6f2d | |||
433c7e779d | |||
984ea1eee3 | |||
0b905a7fdd | |||
6e9283e643 | |||
32ff04c2cc | |||
e50ac5c84d | |||
29496b43d5 | |||
3300c60aaa | |||
78a9475a32 | |||
8d861dcdc6 | |||
c50cc040c2 | |||
93f0692444 | |||
6e9945337e | |||
d429b543d0 | |||
b9520cbc25 | |||
0b8ecf2fb5 | |||
eb4ae65b0a | |||
113d1de443 | |||
4d89f9b30b | |||
11905ed44a | |||
19f192d21f | |||
5ac0ffa8f1 | |||
0a6ac5de54 | |||
c6b8dc97e1 | |||
1bdf7029b4 | |||
5fbcb1b90f | |||
b04acc3737 | |||
4ace52a190 | |||
22a9559a82 | |||
57e6c0246d | |||
80a718a5af | |||
1f0b3acff2 | |||
cdc379d6df | |||
9f87acfc74 | |||
597b500eba | |||
96efb3efb4 | |||
ce5939856c | |||
7f74731351 | |||
8c4855ffa2 |
@ -1,33 +0,0 @@
|
|||||||
version: 'v2.2.1-dev.{build}'
|
|
||||||
|
|
||||||
build: off
|
|
||||||
branches:
|
|
||||||
only:
|
|
||||||
- master
|
|
||||||
- develop
|
|
||||||
|
|
||||||
environment:
|
|
||||||
matrix:
|
|
||||||
- PYTHON: "C:\\Python35"
|
|
||||||
- PYTHON: "C:\\Python35-x64"
|
|
||||||
- PYTHON: "C:\\Python36"
|
|
||||||
- PYTHON: "C:\\Python36-x64"
|
|
||||||
- PYTHON: "C:\\Python37"
|
|
||||||
- PYTHON: "C:\\Python37-x64"
|
|
||||||
- PYTHON: "C:\\Python38"
|
|
||||||
- PYTHON: "C:\\Python38-x64"
|
|
||||||
matrix:
|
|
||||||
fast_finish: true
|
|
||||||
|
|
||||||
cache:
|
|
||||||
- '%LOCALAPPDATA%\pip\Cache'
|
|
||||||
- .downloads -> .appveyor.yml
|
|
||||||
|
|
||||||
install:
|
|
||||||
- "cmd /c .\\test\\tools\\ci-win.cmd install"
|
|
||||||
|
|
||||||
test_script:
|
|
||||||
- "cmd /c .\\test\\tools\\ci-win.cmd test"
|
|
||||||
|
|
||||||
on_failure:
|
|
||||||
- ps: get-content .tox\*\log\*
|
|
4
.github/workflows/tox.yaml
vendored
4
.github/workflows/tox.yaml
vendored
@ -7,7 +7,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
python-version: [3.6, 3.7, 3.8, 3.9]
|
python-version: [3.7, 3.8, 3.9, "3.10", 3.11]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
@ -18,7 +18,7 @@ jobs:
|
|||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
python -m pip install --upgrade pip
|
python -m pip install --upgrade pip
|
||||||
pip install codecov coveralls flake8 mypy pylint tox vulture
|
pip install -U codecov coveralls flake8 mypy pylint pytest tox vulture
|
||||||
- name: Run Tox
|
- name: Run Tox
|
||||||
run: |
|
run: |
|
||||||
tox
|
tox
|
||||||
|
25
.travis.yml
25
.travis.yml
@ -1,25 +0,0 @@
|
|||||||
language: python
|
|
||||||
|
|
||||||
arch:
|
|
||||||
- arm64
|
|
||||||
- amd64
|
|
||||||
- ppc64le
|
|
||||||
|
|
||||||
python:
|
|
||||||
- "3.6"
|
|
||||||
- "3.7"
|
|
||||||
- "3.8"
|
|
||||||
- "3.9"
|
|
||||||
- "3.10"
|
|
||||||
|
|
||||||
cache:
|
|
||||||
- pip
|
|
||||||
|
|
||||||
install:
|
|
||||||
- pip install -U pip tox tox-travis coveralls codecov
|
|
||||||
|
|
||||||
script:
|
|
||||||
- tox
|
|
||||||
|
|
||||||
after_success:
|
|
||||||
- codecov
|
|
@ -1,6 +1,6 @@
|
|||||||
# Contributing to ssh-audit
|
# Contributing to ssh-audit
|
||||||
|
|
||||||
We are very much open to receiving patches from the community! To encourage participation, passing Travis tests, unit tests, etc., *is OPTIONAL*. As long as the patch works properly, it can be merged.
|
We are very much open to receiving patches from the community! To encourage participation, passing CI tests, unit tests, etc., *is OPTIONAL*. As long as the patch works properly, it can be merged.
|
||||||
|
|
||||||
However, if you can submit patches that pass all of our automated tests, then you'll lighten the load for the project maintainer (who already has enough to do!). This document describes what tests are done and what documentation is maintained.
|
However, if you can submit patches that pass all of our automated tests, then you'll lighten the load for the project maintainer (who already has enough to do!). This document describes what tests are done and what documentation is maintained.
|
||||||
|
|
||||||
@ -9,16 +9,16 @@ However, if you can submit patches that pass all of our automated tests, then yo
|
|||||||
|
|
||||||
## Tox Tests
|
## Tox Tests
|
||||||
|
|
||||||
Tox is used to do unit testing, linting with [pylint](http://pylint.pycqa.org/en/latest/) & [flake8](https://flake8.pycqa.org/en/latest/), and static type-checking with [mypy](https://mypy.readthedocs.io/en/stable/).
|
[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 18.04 or later, install tox with `apt install tox`, then simply run `tox` in the top-level directory. Look for any error messages in the (verbose) output.
|
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.
|
||||||
|
|
||||||
|
|
||||||
## Docker Tests
|
## Docker Tests
|
||||||
|
|
||||||
Docker is used to run ssh-audit against various real SSH servers (OpenSSH, Dropbear, and TinySSH). The output is then diff'ed against the expected result. Any differences result in failure.
|
Docker is used to run ssh-audit against various real SSH servers (OpenSSH, Dropbear, and TinySSH). The output is then diff'ed against the expected result. Any differences result in failure.
|
||||||
|
|
||||||
The docker tests are run with `./docker_test.sh`. The first time it is run, it will download and compile the SSH servers; this may take awhile. Subsequent runs, however, will take only a minute to complete, as the docker image will already be up-to-date.
|
The docker tests are run with `./docker_test.sh`.
|
||||||
|
|
||||||
|
|
||||||
## Man Page
|
## Man Page
|
||||||
|
14
Dockerfile
14
Dockerfile
@ -1,10 +1,18 @@
|
|||||||
FROM python:3.9-slim
|
FROM python:3-slim
|
||||||
|
|
||||||
WORKDIR /
|
WORKDIR /
|
||||||
|
|
||||||
|
# Remove suid & sgid bits from all files.
|
||||||
|
RUN find / -xdev -perm /6000 -exec chmod ug-s {} \; 2> /dev/null || true
|
||||||
|
|
||||||
|
# Copy the ssh-audit code.
|
||||||
COPY ssh-audit.py .
|
COPY ssh-audit.py .
|
||||||
COPY src/ .
|
COPY src/ .
|
||||||
|
|
||||||
ENTRYPOINT ["python3", "/ssh-audit.py"]
|
# Allow listening on 2222/tcp for client auditing.
|
||||||
|
|
||||||
EXPOSE 2222
|
EXPOSE 2222
|
||||||
|
|
||||||
|
# Drop root privileges.
|
||||||
|
USER nobody:nogroup
|
||||||
|
|
||||||
|
ENTRYPOINT ["python3", "/ssh-audit.py"]
|
||||||
|
2
LICENSE
2
LICENSE
@ -1,6 +1,6 @@
|
|||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (C) 2017-2020 Joe Testa (jtesta@positronsecurity.com)
|
Copyright (C) 2017-2023 Joe Testa (jtesta@positronsecurity.com)
|
||||||
Copyright (C) 2017 Andris Raugulis (moo@arthepsy.eu)
|
Copyright (C) 2017 Andris Raugulis (moo@arthepsy.eu)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
all:
|
|
||||||
echo -e "\n\nDid you remember to bump the version number in snapcraft.yaml?\n\n"
|
|
||||||
snapcraft --use-lxd
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf parts/ prime/ snap/ stage/ build/ dist/ src/*.egg-info/ ssh-audit*.snap
|
|
33
PACKAGING.md
33
PACKAGING.md
@ -2,17 +2,11 @@
|
|||||||
|
|
||||||
An executable can only be made on a Windows host because the PyInstaller tool (https://www.pyinstaller.org/) does not support cross-compilation.
|
An executable can only be made on a Windows host because the PyInstaller tool (https://www.pyinstaller.org/) does not support cross-compilation.
|
||||||
|
|
||||||
1.) Install Python v3.9.x from https://www.python.org/. To make life easier, check the option to add Python to the PATH environment variable.
|
1.) Install Python v3.11.x from https://www.python.org/. To make life easier, check the option to add Python to the PATH environment variable.
|
||||||
|
|
||||||
2.) Using pip, install pyinstaller and colorama:
|
2.) Install Cygwin (https://www.cygwin.com/).
|
||||||
|
|
||||||
```
|
3.) Install/update package dependencies and create the executable with:
|
||||||
pip install pyinstaller colorama
|
|
||||||
```
|
|
||||||
|
|
||||||
3.) Install Cygwin (https://www.cygwin.com/).
|
|
||||||
|
|
||||||
4.) Create the executable with:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
$ ./build_windows_executable.sh
|
$ ./build_windows_executable.sh
|
||||||
@ -51,27 +45,14 @@ To download from production server and verify:
|
|||||||
$ pip3 install ssh-audit
|
$ pip3 install ssh-audit
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
# Snap
|
# Snap
|
||||||
|
|
||||||
To create the snap package, run a fully-updated Ubuntu Server 20.04 VM.
|
To create the snap package, run a fully-updated Ubuntu Server 22.04 VM.
|
||||||
|
|
||||||
Install pre-requisites with:
|
|
||||||
|
|
||||||
|
Create the snap package with:
|
||||||
```
|
```
|
||||||
$ sudo apt install make snapcraft
|
$ ./build_snap.sh
|
||||||
$ sudo snap install review-tools lxd
|
|
||||||
```
|
|
||||||
|
|
||||||
Initialize LXD (leave all options default):
|
|
||||||
|
|
||||||
```
|
|
||||||
$ sudo lxd init
|
|
||||||
```
|
|
||||||
|
|
||||||
Bump the version number in snapcraft.yaml. Then run:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ make -f Makefile.snap
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Upload the snap with:
|
Upload the snap with:
|
||||||
|
38
README.md
38
README.md
@ -32,7 +32,7 @@
|
|||||||
- historical information from OpenSSH, Dropbear SSH and libssh;
|
- historical information from OpenSSH, Dropbear SSH and libssh;
|
||||||
- policy scans to ensure adherence to a hardened/standard configuration;
|
- policy scans to ensure adherence to a hardened/standard configuration;
|
||||||
- runs on Linux and Windows;
|
- runs on Linux and Windows;
|
||||||
- supports Python 3.6 - 3.9;
|
- supports Python 3.7 - 3.11;
|
||||||
- no dependencies
|
- no dependencies
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
@ -49,6 +49,9 @@ usage: ssh-audit.py [options] <host>
|
|||||||
software config (use -p to change port;
|
software config (use -p to change port;
|
||||||
use -t to change timeout)
|
use -t to change timeout)
|
||||||
-d, --debug Enable debug output.
|
-d, --debug Enable debug output.
|
||||||
|
-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)
|
-j, --json JSON output (use -jj to enable indents)
|
||||||
-l, --level=<level> minimum output level (info|warn|fail)
|
-l, --level=<level> minimum output level (info|warn|fail)
|
||||||
-L, --list-policies list all the official, built-in policies
|
-L, --list-policies list all the official, built-in policies
|
||||||
@ -148,7 +151,7 @@ Below is a screen shot of the client-auditing output when an unhardened OpenSSH
|
|||||||
Guides to harden server & client configuration can be found here: [https://www.ssh-audit.com/hardening_guides.html](https://www.ssh-audit.com/hardening_guides.html)
|
Guides to harden server & client configuration can be found here: [https://www.ssh-audit.com/hardening_guides.html](https://www.ssh-audit.com/hardening_guides.html)
|
||||||
|
|
||||||
## Pre-Built Packages
|
## Pre-Built Packages
|
||||||
Pre-built packages are available for Windows (see the releases page), on PyPI, Snap, and Homebrew.
|
Pre-built packages are available for Windows (see the releases page), PyPI, Snap, and Docker:
|
||||||
|
|
||||||
To install from PyPI:
|
To install from PyPI:
|
||||||
```
|
```
|
||||||
@ -160,21 +163,42 @@ To install the Snap package:
|
|||||||
$ snap install ssh-audit
|
$ snap install ssh-audit
|
||||||
```
|
```
|
||||||
|
|
||||||
To install on Homebrew:
|
|
||||||
```
|
|
||||||
$ brew install ssh-audit
|
|
||||||
```
|
|
||||||
|
|
||||||
To install from Dockerhub:
|
To install from Dockerhub:
|
||||||
```
|
```
|
||||||
$ docker pull positronsecurity/ssh-audit
|
$ 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 -p 2222:2222 positronsecurity/ssh-audit 10.1.1.1`)
|
||||||
|
|
||||||
|
The status of various other platform packages can be found below (via Repology):
|
||||||
|
|
||||||
|
<a href="https://repology.org/project/ssh-audit/versions"><img src="https://repology.org/badge/vertical-allrepos/ssh-audit.svg?columns=4" alt="Packaging status" align="center"></a>
|
||||||
|
|
||||||
## Web Front-End
|
## Web Front-End
|
||||||
For convenience, a web front-end on top of the command-line tool is available at [https://www.ssh-audit.com/](https://www.ssh-audit.com/).
|
For convenience, a web front-end on top of the command-line tool is available at [https://www.ssh-audit.com/](https://www.ssh-audit.com/).
|
||||||
|
|
||||||
## ChangeLog
|
## ChangeLog
|
||||||
|
|
||||||
|
### v2.9.0 (2023-04-29)
|
||||||
|
- Dropped support for Python 3.6, as it reached EOL at the end of 2021.
|
||||||
|
- Added Ubuntu Server & Client 22.04 hardening policies.
|
||||||
|
- Removed experimental warning tag from `sntrup761x25519-sha512@openssh.com`.
|
||||||
|
- Updated CVE database; credit [Alexandre Zanni](https://github.com/noraj).
|
||||||
|
- Added `-g` and `--gex-test` for granular GEX modulus size tests; credit [Adam Russell](https://github.com/thecliguy).
|
||||||
|
- Snap packages now print more user-friendly error messages when permission errors are encountered.
|
||||||
|
- JSON 'target' field now always includes port number; credit [tomatohater1337](https://github.com/tomatohater1337).
|
||||||
|
- JSON output now includes recommendations and CVE data.
|
||||||
|
- Mixed host key/CA key types (i.e.: RSA host keys signed with ED25519 CAs, etc.) are now properly handled.
|
||||||
|
- Warnings are now printed for 2048-bit moduli; partial credit [Adam Russell](https://github.com/thecliguy).
|
||||||
|
- SHA-1 algorithms now cause failures.
|
||||||
|
- CBC mode ciphers are now warnings instead of failures.
|
||||||
|
- Generic failure/warning messages replaced with more specific reasons (i.e.: 'using weak cipher' => 'using broken RC4 cipher').
|
||||||
|
- Updated built-in policies to include missing host key size information.
|
||||||
|
- Added built-in policies for OpenSSH 8.8, 8.9, 9.0, 9.1, 9.2, and 9.3.
|
||||||
|
- Added 33 new host keys: `dsa2048-sha224@libassh.org`, `dsa2048-sha256@libassh.org`, `dsa3072-sha256@libassh.org`, `ecdsa-sha2-1.3.132.0.10-cert-v01@openssh.com`, `eddsa-e382-shake256@libassh.org`, `eddsa-e521-shake256@libassh.org`, `null`, `pgp-sign-dss`, `pgp-sign-rsa`, `spki-sign-dss`, `spki-sign-rsa`, `ssh-dss-sha224@ssh.com`, `ssh-dss-sha384@ssh.com`, `ssh-dss-sha512@ssh.com`, `ssh-ed448-cert-v01@openssh.com`, `ssh-rsa-sha224@ssh.com`, `ssh-rsa-sha2-256`, `ssh-rsa-sha2-512`, `ssh-rsa-sha384@ssh.com`, `ssh-rsa-sha512@ssh.com`, `ssh-xmss-cert-v01@openssh.com`, `ssh-xmss@openssh.com`, `webauthn-sk-ecdsa-sha2-nistp256@openssh.com`, `x509v3-ecdsa-sha2-1.3.132.0.10`, `x509v3-sign-dss-sha1`, `x509v3-sign-dss-sha224@ssh.com`, `x509v3-sign-dss-sha256@ssh.com`, `x509v3-sign-dss-sha384@ssh.com`, `x509v3-sign-dss-sha512@ssh.com`, `x509v3-sign-rsa-sha1`, `x509v3-sign-rsa-sha224@ssh.com`, `x509v3-sign-rsa-sha384@ssh.com`, `x509v3-sign-rsa-sha512@ssh.com`.
|
||||||
|
- Added 46 new key exchanges: `diffie-hellman-group14-sha224@ssh.com`, `diffie-hellman_group17-sha512`, `diffie-hellman-group-exchange-sha224@ssh.com`, `diffie-hellman-group-exchange-sha384@ssh.com`, `ecdh-sha2-1.2.840.10045.3.1.1`, `ecdh-sha2-1.2.840.10045.3.1.7`, `ecdh-sha2-1.3.132.0.1`, `ecdh-sha2-1.3.132.0.16`, `ecdh-sha2-1.3.132.0.26`, `ecdh-sha2-1.3.132.0.27`, `ecdh-sha2-1.3.132.0.33`, `ecdh-sha2-1.3.132.0.34`, `ecdh-sha2-1.3.132.0.35`, `ecdh-sha2-1.3.132.0.36`, `ecdh-sha2-1.3.132.0.37`, `ecdh-sha2-1.3.132.0.38`, `ecdh-sha2-4MHB+NBt3AlaSRQ7MnB4cg==`, `ecdh-sha2-5pPrSUQtIaTjUSt5VZNBjg==`, `ecdh-sha2-9UzNcgwTlEnSCECZa7V1mw==`, `ecdh-sha2-D3FefCjYoJ/kfXgAyLddYA==`, `ecdh-sha2-h/SsxnLCtRBh7I9ATyeB3A==`, `ecdh-sha2-m/FtSAmrV4j/Wy6RVUaK7A==`, `ecdh-sha2-mNVwCXAoS1HGmHpLvBC94w==`, `ecdh-sha2-qCbG5Cn/jjsZ7nBeR7EnOA==`, `ecdh-sha2-qcFQaMAMGhTziMT0z+Tuzw==`, `ecdh-sha2-VqBg4QRPjxx1EXZdV0GdWQ==`, `ecdh-sha2-wiRIU8TKjMZ418sMqlqtvQ==`, `ecdh-sha2-zD/b3hu/71952ArpUG4OjQ==`, `ecmqv-sha2`, `gss-13.3.132.0.10-sha256-*`, `gss-curve25519-sha256-*`, `gss-curve448-sha512-*`, `gss-gex-sha1-*`, `gss-gex-sha256-*`, `gss-group14-sha1-*`, `gss-group14-sha256-*`, `gss-group15-sha512-*`, `gss-group16-sha512-*`, `gss-group17-sha512-*`, `gss-group18-sha512-*`, `gss-group1-sha1-*`, `gss-nistp256-sha256-*`, `gss-nistp384-sha256-*`, `gss-nistp521-sha512-*`, `m383-sha384@libassh.org`, `m511-sha512@libassh.org`.
|
||||||
|
- Added 28 new ciphers: `3des-cfb`, `3des-ecb`, `3des-ofb`, `blowfish-cfb`, `blowfish-ecb`, `blowfish-ofb`, `camellia128-cbc@openssh.org`, `camellia128-ctr@openssh.org`, `camellia192-cbc@openssh.org`, `camellia192-ctr@openssh.org`, `camellia256-cbc@openssh.org`, `camellia256-ctr@openssh.org`, `cast128-cfb`, `cast128-ecb`, `cast128-ofb`, `cast128-12-cbc@ssh.com`, `idea-cfb`, `idea-ecb`, `idea-ofb`, `rijndael-cbc@ssh.com`, `seed-ctr@ssh.com`, `serpent128-gcm@libassh.org`, `serpent256-gcm@libassh.org`, `twofish128-gcm@libassh.org`, `twofish256-gcm@libassh.org`, `twofish-cfb`, `twofish-ecb`, `twofish-ofb`
|
||||||
|
- Added 5 new MACs: `hmac-sha1-96@openssh.com`, `hmac-sha224@ssh.com`, `hmac-sha256-2@ssh.com`, `hmac-sha384@ssh.com`, `hmac-whirlpool`.
|
||||||
|
|
||||||
### v2.5.0 (2021-08-26)
|
### v2.5.0 (2021-08-26)
|
||||||
- Fixed crash when running host key tests.
|
- Fixed crash when running host key tests.
|
||||||
- Handles server connection failures more gracefully.
|
- Handles server connection failures more gracefully.
|
||||||
|
73
build_snap.sh
Executable file
73
build_snap.sh
Executable file
@ -0,0 +1,73 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
#
|
||||||
|
# The MIT License (MIT)
|
||||||
|
#
|
||||||
|
# Copyright (C) 2021 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
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# build_snap.sh
|
||||||
|
#
|
||||||
|
# Builds a Snap package.
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
|
||||||
|
# Pre-requisites
|
||||||
|
sudo apt install -y make
|
||||||
|
sudo snap install snapcraft --classic
|
||||||
|
sudo snap install review-tools lxd
|
||||||
|
|
||||||
|
# Initialize LXD.
|
||||||
|
sudo lxd init --auto
|
||||||
|
|
||||||
|
# Reset the filesystem from any previous runs.
|
||||||
|
rm -rf parts/ prime/ snap/ stage/ build/ dist/ src/*.egg-info/ ssh-audit*.snap
|
||||||
|
git checkout snapcraft.yaml 2> /dev/null
|
||||||
|
git checkout src/ssh_audit/globals.py 2> /dev/null
|
||||||
|
|
||||||
|
# Get the version from the globals.py file.
|
||||||
|
version=$(grep VERSION src/ssh_audit/globals.py | awk 'BEGIN {FS="="} ; {print $2}' | tr -d '[:space:]')
|
||||||
|
|
||||||
|
# Strip the quotes around the version (along with the initial 'v' character) and append "-1" to make the default Snap version (i.e.: 'v2.5.0' => '2.5.0-1')
|
||||||
|
default_snap_version="${version:2:-1}-1"
|
||||||
|
echo -e -n "\nEnter Snap package version [default: ${default_snap_version}]: "
|
||||||
|
read -r snap_version
|
||||||
|
|
||||||
|
# If no version was specified, use the default version.
|
||||||
|
if [[ $snap_version == '' ]]; then
|
||||||
|
snap_version=$default_snap_version
|
||||||
|
echo -e "Using default snap version: ${snap_version}\n"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Ensure that the snap version fits the format of X.X.X-X.
|
||||||
|
if [[ ! $snap_version =~ ^[0-9]\.[0-9]\.[0-9]\-[0-9]$ ]]; then
|
||||||
|
echo "Error: version string does not match format X.X.X-X!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Append the version field to the end of the file. Not pretty, but it works.
|
||||||
|
echo -e "\nversion: '${snap_version}'" >> snapcraft.yaml
|
||||||
|
|
||||||
|
# Set the SNAP_PACKAGE variable to True so that file permission errors give more user-friendly
|
||||||
|
sed -i 's/SNAP_PACKAGE = False/SNAP_PACKAGE = True/' src/ssh_audit/globals.py
|
||||||
|
|
||||||
|
snapcraft --use-lxd && echo -e "\nDone.\n"
|
@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
#
|
#
|
||||||
# The MIT License (MIT)
|
# The MIT License (MIT)
|
||||||
@ -48,15 +48,10 @@ if [[ "$(python -V)" != "Python 3."* ]]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Ensure that pyinstaller is installed.
|
# Install/update package dependencies.
|
||||||
command -v pyinstaller >/dev/null 2>&1 || { echo >&2 "pyinstaller not found. Install with: 'pip install pyinstaller'"; exit 1; }
|
echo "Installing/updating pyinstaller and colorama packages..."
|
||||||
|
pip install -U pyinstaller colorama
|
||||||
# Ensure that the colorama module is installed.
|
echo
|
||||||
X=`pip show colorama` 2> /dev/null
|
|
||||||
if [[ $? != 0 ]]; then
|
|
||||||
echo "Colorama module not found. Install with: 'pip install colorama'"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Prompt for the version to release.
|
# Prompt for the version to release.
|
||||||
echo -n "Enter the version to release, using format 'vX.X.X': "
|
echo -n "Enter the version to release, using format 'vX.X.X': "
|
||||||
|
234
docker_test.sh
234
docker_test.sh
@ -4,6 +4,11 @@
|
|||||||
# This script will set up a docker image with multiple versions of OpenSSH, then
|
# This script will set up a docker image with multiple versions of OpenSSH, then
|
||||||
# use it to run tests.
|
# use it to run tests.
|
||||||
#
|
#
|
||||||
|
# Optional arguments:
|
||||||
|
# --accept: accepts test failures and overwrites expected results with actual results (useful for updating the tests themselves).
|
||||||
|
# --create: attempts to create a new docker image.
|
||||||
|
#
|
||||||
|
#
|
||||||
# For debugging purposes, here is a cheat sheet for manually running the docker image:
|
# For debugging purposes, here is a cheat sheet for manually running the docker image:
|
||||||
#
|
#
|
||||||
# docker run -p 2222:22 -it ssh-audit-test:X /bin/bash
|
# docker run -p 2222:22 -it ssh-audit-test:X /bin/bash
|
||||||
@ -27,6 +32,7 @@ RED="\033[0;31m"
|
|||||||
YELLOW="\033[0;33m"
|
YELLOW="\033[0;33m"
|
||||||
GREEN="\033[0;32m"
|
GREEN="\033[0;32m"
|
||||||
REDB="\033[1;31m" # Red + bold
|
REDB="\033[1;31m" # Red + bold
|
||||||
|
YELLOWB="\033[1;33m" # Yellow + bold
|
||||||
GREENB="\033[1;32m" # Green + bold
|
GREENB="\033[1;32m" # Green + bold
|
||||||
|
|
||||||
# Program return values.
|
# Program return values.
|
||||||
@ -39,35 +45,38 @@ PROGRAM_RETVAL_GOOD=0
|
|||||||
# Counts the number of test failures.
|
# Counts the number of test failures.
|
||||||
num_failures=0
|
num_failures=0
|
||||||
|
|
||||||
|
# When set, if a failure is encountered, overwrite the expected output with the actual value (i.e.: the user validated the failures already and wants to update the tests themselves).
|
||||||
|
accept=0
|
||||||
|
|
||||||
|
|
||||||
# Returns 0 if current docker image exists.
|
# Returns 0 if current docker image exists.
|
||||||
function check_if_docker_image_exists {
|
check_if_docker_image_exists() {
|
||||||
images=`docker image ls | egrep "$IMAGE_NAME[[:space:]]+$IMAGE_VERSION"`
|
images=$(docker image ls | grep -E "$IMAGE_NAME[[:space:]]+$IMAGE_VERSION")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Uncompresses and compiles the specified version of Dropbear.
|
# Uncompresses and compiles the specified version of Dropbear.
|
||||||
function compile_dropbear {
|
compile_dropbear() {
|
||||||
version=$1
|
version=$1
|
||||||
compile 'Dropbear' $version
|
compile 'Dropbear' "$version"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Uncompresses and compiles the specified version of OpenSSH.
|
# Uncompresses and compiles the specified version of OpenSSH.
|
||||||
function compile_openssh {
|
compile_openssh() {
|
||||||
version=$1
|
version=$1
|
||||||
compile 'OpenSSH' $version
|
compile 'OpenSSH' "$version"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Uncompresses and compiles the specified version of TinySSH.
|
# Uncompresses and compiles the specified version of TinySSH.
|
||||||
function compile_tinyssh {
|
compile_tinyssh() {
|
||||||
version=$1
|
version=$1
|
||||||
compile 'TinySSH' $version
|
compile 'TinySSH' "$version"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function compile {
|
compile() {
|
||||||
project=$1
|
project=$1
|
||||||
version=$2
|
version=$2
|
||||||
|
|
||||||
@ -93,10 +102,10 @@ function compile {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Uncompressing ${project} ${version}..."
|
echo "Uncompressing ${project} ${version}..."
|
||||||
tar $uncompress_options $tarball
|
tar $uncompress_options "$tarball"
|
||||||
|
|
||||||
echo "Compiling ${project} ${version}..."
|
echo "Compiling ${project} ${version}..."
|
||||||
pushd $source_dir > /dev/null
|
pushd "$source_dir" > /dev/null
|
||||||
|
|
||||||
# TinySSH has no configure script... only a Makefile.
|
# TinySSH has no configure script... only a Makefile.
|
||||||
if [[ $project == 'TinySSH' ]]; then
|
if [[ $project == 'TinySSH' ]]; then
|
||||||
@ -116,16 +125,16 @@ function compile {
|
|||||||
|
|
||||||
|
|
||||||
# Creates a new docker image.
|
# Creates a new docker image.
|
||||||
function create_docker_image {
|
create_docker_image() {
|
||||||
# Create a new temporary directory.
|
# Create a new temporary directory.
|
||||||
TMP_DIR=`mktemp -d /tmp/sshaudit-docker-XXXXXXXXXX`
|
TMP_DIR=$(mktemp -d /tmp/sshaudit-docker-XXXXXXXXXX)
|
||||||
|
|
||||||
# Copy the Dockerfile and all files in the test/docker/ dir to our new temp directory.
|
# Copy the Dockerfile and all files in the test/docker/ dir to our new temp directory.
|
||||||
find test/docker/ -maxdepth 1 -type f | xargs cp -t $TMP_DIR
|
find test/docker/ -maxdepth 1 -type f -exec cp -t "$TMP_DIR" '{}' +
|
||||||
|
|
||||||
# Make the temp directory our working directory for the duration of the build
|
# Make the temp directory our working directory for the duration of the build
|
||||||
# process.
|
# process.
|
||||||
pushd $TMP_DIR > /dev/null
|
pushd "$TMP_DIR" > /dev/null
|
||||||
|
|
||||||
# Get the release keys.
|
# Get the release keys.
|
||||||
get_dropbear_release_key
|
get_dropbear_release_key
|
||||||
@ -204,43 +213,43 @@ function create_docker_image {
|
|||||||
|
|
||||||
|
|
||||||
# Now build the docker image!
|
# Now build the docker image!
|
||||||
docker build --tag $IMAGE_NAME:$IMAGE_VERSION .
|
docker build --tag "$IMAGE_NAME:$IMAGE_VERSION" .
|
||||||
|
|
||||||
popd > /dev/null
|
popd > /dev/null
|
||||||
rm -rf $TMP_DIR
|
rm -rf -- "$TMP_DIR"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Creates an OpenSSH configuration file for a specific test.
|
# Creates an OpenSSH configuration file for a specific test.
|
||||||
function create_openssh_config {
|
create_openssh_config() {
|
||||||
openssh_version=$1
|
openssh_version=$1
|
||||||
test_number=$2
|
test_number=$2
|
||||||
config_text=$3
|
config_text=$3
|
||||||
|
|
||||||
cp sshd_config-${openssh_version}_orig sshd_config-${openssh_version}_${test_number}
|
cp "sshd_config-${openssh_version}_orig" "sshd_config-${openssh_version}_${test_number}"
|
||||||
echo -e "${config_text}" >> sshd_config-${openssh_version}_${test_number}
|
echo -e "${config_text}" >> "sshd_config-${openssh_version}_${test_number}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Downloads the Dropbear release key and adds it to the local keyring.
|
# Downloads the Dropbear release key and adds it to the local keyring.
|
||||||
function get_dropbear_release_key {
|
get_dropbear_release_key() {
|
||||||
get_release_key 'Dropbear' 'https://matt.ucc.asn.au/dropbear/releases/dropbear-key-2015.asc' 'F29C6773' 'F734 7EF2 EE2E 07A2 6762 8CA9 4493 1494 F29C 6773'
|
get_release_key 'Dropbear' 'https://matt.ucc.asn.au/dropbear/releases/dropbear-key-2015.asc' 'F29C6773' 'F734 7EF2 EE2E 07A2 6762 8CA9 4493 1494 F29C 6773'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Downloads the OpenSSH release key and adds it to the local keyring.
|
# Downloads the OpenSSH release key and adds it to the local keyring.
|
||||||
function get_openssh_release_key {
|
get_openssh_release_key() {
|
||||||
get_release_key 'OpenSSH' 'https://ftp.openbsd.org/pub/OpenBSD/OpenSSH/RELEASE_KEY.asc' '6D920D30' '59C2 118E D206 D927 E667 EBE3 D3E5 F56B 6D92 0D30'
|
get_release_key 'OpenSSH' 'https://ftp.openbsd.org/pub/OpenBSD/OpenSSH/RELEASE_KEY.asc' '6D920D30' '59C2 118E D206 D927 E667 EBE3 D3E5 F56B 6D92 0D30'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Downloads the TinySSH release key and adds it to the local keyring.
|
# Downloads the TinySSH release key and adds it to the local keyring.
|
||||||
function get_tinyssh_release_key {
|
get_tinyssh_release_key() {
|
||||||
get_release_key 'TinySSH' '' '96939FF9' 'AADF 2EDF 5529 F170 2772 C8A2 DEC4 D246 931E F49B'
|
get_release_key 'TinySSH' '' '96939FF9' 'AADF 2EDF 5529 F170 2772 C8A2 DEC4 D246 931E F49B'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function get_release_key {
|
get_release_key() {
|
||||||
project=$1
|
project=$1
|
||||||
key_url=$2
|
key_url=$2
|
||||||
key_id=$3
|
key_id=$3
|
||||||
@ -248,10 +257,10 @@ function get_release_key {
|
|||||||
|
|
||||||
# The TinySSH release key isn't on any website, apparently.
|
# The TinySSH release key isn't on any website, apparently.
|
||||||
if [[ $project == 'TinySSH' ]]; then
|
if [[ $project == 'TinySSH' ]]; then
|
||||||
gpg --keyserver keys.gnupg.net --recv-key $key_id
|
gpg --keyserver keys.gnupg.net --recv-key "$key_id"
|
||||||
else
|
else
|
||||||
echo -e "\nGetting ${project} release key...\n"
|
echo -e "\nGetting ${project} release key...\n"
|
||||||
wget -O key.asc $2
|
wget -O key.asc "$2"
|
||||||
|
|
||||||
echo -e "\nImporting ${project} release key...\n"
|
echo -e "\nImporting ${project} release key...\n"
|
||||||
gpg --import key.asc
|
gpg --import key.asc
|
||||||
@ -259,40 +268,40 @@ function get_release_key {
|
|||||||
rm key.asc
|
rm key.asc
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local release_key_fingerprint_actual=`gpg --fingerprint ${key_id}`
|
local release_key_fingerprint_actual=$(gpg --fingerprint "$key_id")
|
||||||
if [[ $release_key_fingerprint_actual != *"$release_key_fingerprint_expected"* ]]; then
|
if [[ $release_key_fingerprint_actual != *"$release_key_fingerprint_expected"* ]]; then
|
||||||
echo -e "\n${REDB}Error: ${project} release key fingerprint does not match expected value!\n\tExpected: $release_key_fingerprint_expected\n\tActual: $release_key_fingerprint_actual\n\nTerminating.${CLR}"
|
echo -e "\n${REDB}Error: ${project} release key fingerprint does not match expected value!\n\tExpected: $release_key_fingerprint_expected\n\tActual: $release_key_fingerprint_actual\n\nTerminating.${CLR}"
|
||||||
exit -1
|
exit 1
|
||||||
fi
|
fi
|
||||||
echo -e "\n\n${GREEN}${project} release key matches expected value.${CLR}\n"
|
echo -e "\n\n${GREEN}${project} release key matches expected value.${CLR}\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Downloads the specified version of Dropbear.
|
# Downloads the specified version of Dropbear.
|
||||||
function get_dropbear {
|
get_dropbear() {
|
||||||
version=$1
|
version=$1
|
||||||
tarball_checksum_expected=$2
|
tarball_checksum_expected=$2
|
||||||
get_source 'Dropbear' $version $tarball_checksum_expected
|
get_source 'Dropbear' "$version" "$tarball_checksum_expected"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Downloads the specified version of OpenSSH.
|
# Downloads the specified version of OpenSSH.
|
||||||
function get_openssh {
|
get_openssh() {
|
||||||
version=$1
|
version=$1
|
||||||
tarball_checksum_expected=$2
|
tarball_checksum_expected=$2
|
||||||
get_source 'OpenSSH' $version $tarball_checksum_expected
|
get_source 'OpenSSH' "$version" "$tarball_checksum_expected"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Downloads the specified version of TinySSH.
|
# Downloads the specified version of TinySSH.
|
||||||
function get_tinyssh {
|
get_tinyssh() {
|
||||||
version=$1
|
version=$1
|
||||||
tarball_checksum_expected=$2
|
tarball_checksum_expected=$2
|
||||||
get_source 'TinySSH' $version $tarball_checksum_expected
|
get_source 'TinySSH' "$version" "$tarball_checksum_expected"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function get_source {
|
get_source() {
|
||||||
project=$1
|
project=$1
|
||||||
version=$2
|
version=$2
|
||||||
tarball_checksum_expected=$3
|
tarball_checksum_expected=$3
|
||||||
@ -331,48 +340,48 @@ function get_source {
|
|||||||
|
|
||||||
# Older OpenSSH releases were .sigs.
|
# Older OpenSSH releases were .sigs.
|
||||||
if [[ ($project == 'OpenSSH') && (! -f $sig) ]]; then
|
if [[ ($project == 'OpenSSH') && (! -f $sig) ]]; then
|
||||||
wget ${base_url_sig}openssh-${version}.tar.gz.sig
|
wget "${base_url_sig}openssh-${version}.tar.gz.sig"
|
||||||
sig=openssh-${version}.tar.gz.sig
|
sig=openssh-${version}.tar.gz.sig
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local gpg_verify=`gpg --verify ${sig} ${tarball} 2>&1`
|
local gpg_verify=$(gpg --verify "${sig}" "${tarball}" 2>&1)
|
||||||
if [[ $gpg_verify != *"Good signature from \"${signer}"* ]]; then
|
if [[ $gpg_verify != *"Good signature from \"${signer}"* ]]; then
|
||||||
echo -e "\n\n${REDB}Error: ${project} signature invalid!\n$gpg_verify\n\nTerminating.${CLR}"
|
echo -e "\n\n${REDB}Error: ${project} signature invalid!\n$gpg_verify\n\nTerminating.${CLR}"
|
||||||
exit -1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check GPG's return value. 0 denotes a valid signature, and 1 is returned
|
# Check GPG's return value. 0 denotes a valid signature, and 1 is returned
|
||||||
# on invalid signatures.
|
# on invalid signatures.
|
||||||
if [[ $? != 0 ]]; then
|
if [[ $? != 0 ]]; then
|
||||||
echo -e "\n\n${REDB}Error: ${project} signature invalid! Verification returned code: $?\n\nTerminating.${CLR}"
|
echo -e "\n\n${REDB}Error: ${project} signature invalid! Verification returned code: $?\n\nTerminating.${CLR}"
|
||||||
exit -1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo -e "${GREEN}Signature on ${project} sources verified.${CLR}\n"
|
echo -e "${GREEN}Signature on ${project} sources verified.${CLR}\n"
|
||||||
|
|
||||||
local checksum_actual=`sha256sum ${tarball} | cut -f1 -d" "`
|
local checksum_actual=$(sha256sum "${tarball}" | cut -f1 -d" ")
|
||||||
if [[ $checksum_actual != $tarball_checksum_expected ]]; then
|
if [[ $checksum_actual != "$tarball_checksum_expected" ]]; then
|
||||||
echo -e "${REDB}Error: ${project} checksum is invalid!\n Expected: ${tarball_checksum_expected}\n Actual: ${checksum_actual}\n\n Terminating.${CLR}"
|
echo -e "${REDB}Error: ${project} checksum is invalid!\n Expected: ${tarball_checksum_expected}\n Actual: ${checksum_actual}\n\n Terminating.${CLR}"
|
||||||
exit -1
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Pulls the defined image from Dockerhub.
|
# Pulls the defined image from Dockerhub.
|
||||||
function pull_docker_image {
|
pull_docker_image() {
|
||||||
docker pull $IMAGE_NAME:$IMAGE_VERSION
|
docker pull "$IMAGE_NAME:$IMAGE_VERSION"
|
||||||
if [[ $? == 0 ]]; then
|
if [[ $? == 0 ]]; then
|
||||||
echo -e "${GREEN}Successfully downloaded image ${IMAGE_NAME}:${IMAGE_VERSION} from Dockerhub.${CLR}\n"
|
echo -e "${GREEN}Successfully downloaded image $IMAGE_NAME:$IMAGE_VERSION from Dockerhub.${CLR}\n"
|
||||||
else
|
else
|
||||||
echo -e "${REDB}Failed to pull image ${IMAGE_NAME}:${IMAGE_VERSION} from Dockerhub! Error code: $?${CLR}\n"
|
echo -e "${REDB}Failed to pull image $IMAGE_NAME:$IMAGE_VERSION from Dockerhub! Error code: $?${CLR}\n"
|
||||||
exit -1
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Runs a Dropbear test. Upon failure, a diff between the expected and actual results
|
# Runs a Dropbear test. Upon failure, a diff between the expected and actual results
|
||||||
# is shown, then the script immediately terminates.
|
# is shown, then the script immediately terminates.
|
||||||
function run_dropbear_test {
|
run_dropbear_test() {
|
||||||
dropbear_version=$1
|
dropbear_version=$1
|
||||||
test_number=$2
|
test_number=$2
|
||||||
options=$3
|
options=$3
|
||||||
@ -384,7 +393,7 @@ function run_dropbear_test {
|
|||||||
|
|
||||||
# Runs an OpenSSH test. Upon failure, a diff between the expected and actual results
|
# Runs an OpenSSH test. Upon failure, a diff between the expected and actual results
|
||||||
# is shown, then the script immediately terminates.
|
# is shown, then the script immediately terminates.
|
||||||
function run_openssh_test {
|
run_openssh_test() {
|
||||||
openssh_version=$1
|
openssh_version=$1
|
||||||
test_number=$2
|
test_number=$2
|
||||||
expected_retval=$3
|
expected_retval=$3
|
||||||
@ -395,7 +404,7 @@ function run_openssh_test {
|
|||||||
|
|
||||||
# Runs a TinySSH test. Upon failure, a diff between the expected and actual results
|
# Runs a TinySSH test. Upon failure, a diff between the expected and actual results
|
||||||
# is shown, then the script immediately terminates.
|
# is shown, then the script immediately terminates.
|
||||||
function run_tinyssh_test {
|
run_tinyssh_test() {
|
||||||
tinyssh_version=$1
|
tinyssh_version=$1
|
||||||
test_number=$2
|
test_number=$2
|
||||||
expected_retval=$3
|
expected_retval=$3
|
||||||
@ -404,7 +413,7 @@ function run_tinyssh_test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function run_test {
|
run_test() {
|
||||||
server_type=$1
|
server_type=$1
|
||||||
version=$2
|
version=$2
|
||||||
test_number=$3
|
test_number=$3
|
||||||
@ -442,25 +451,37 @@ function run_test {
|
|||||||
test_name="TinySSH ${version} ${test_number}"
|
test_name="TinySSH ${version} ${test_number}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cid=`docker run -d -p 2222:22 ${IMAGE_NAME}:${IMAGE_VERSION} ${server_exec}`
|
cid=$(docker run -d -p 2222:22 "$IMAGE_NAME:$IMAGE_VERSION" ${server_exec})
|
||||||
#echo "Running: docker run -d -p 2222:22 ${IMAGE_NAME}:${IMAGE_VERSION} ${server_exec}"
|
#echo "Running: docker run -d -p 2222:22 $IMAGE_NAME:$IMAGE_VERSION ${server_exec}"
|
||||||
if [[ $? != 0 ]]; then
|
if [[ $? != 0 ]]; then
|
||||||
echo -e "${REDB}Failed to run docker image! (exit code: $?)${CLR}"
|
echo -e "${REDB}Failed to run docker image! (exit code: $?)${CLR}"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
./ssh-audit.py localhost:2222 > $test_result_stdout
|
./ssh-audit.py localhost:2222 > "$test_result_stdout"
|
||||||
actual_retval=$?
|
actual_retval=$?
|
||||||
if [[ $actual_retval != $expected_retval ]]; then
|
if [[ $actual_retval != "$expected_retval" ]]; then
|
||||||
echo -e "${REDB}Unexpected return value. Expected: ${expected_retval}; Actual: ${actual_retval}${CLR}"
|
echo -e "${REDB}Unexpected return value. Expected: ${expected_retval}; Actual: ${actual_retval}${CLR}"
|
||||||
|
|
||||||
|
if [[ $accept == 1 ]]; then
|
||||||
|
echo -e "\n${REDB}This failure cannot be automatically fixed; this script must be manually updated with the new expected return value.${CLR}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat ${test_result_stdout}
|
||||||
docker container stop -t 0 $cid > /dev/null
|
docker container stop -t 0 $cid > /dev/null
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
./ssh-audit.py -j localhost:2222 > $test_result_json
|
./ssh-audit.py -jj localhost:2222 > "$test_result_json"
|
||||||
actual_retval=$?
|
actual_retval=$?
|
||||||
if [[ $actual_retval != $expected_retval ]]; then
|
if [[ $actual_retval != "$expected_retval" ]]; then
|
||||||
echo -e "${REDB}Unexpected return value. Expected: ${expected_retval}; Actual: ${actual_retval}${CLR}"
|
echo -e "${REDB}Unexpected return value. Expected: ${expected_retval}; Actual: ${actual_retval}${CLR}"
|
||||||
|
|
||||||
|
if [[ $accept == 1 ]]; then
|
||||||
|
echo -e "\n${REDB}This failure cannot be automatically fixed; this script must be manually updated with the new expected return value.${CLR}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat ${test_result_json}
|
||||||
docker container stop -t 0 $cid > /dev/null
|
docker container stop -t 0 $cid > /dev/null
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
@ -475,32 +496,48 @@ function run_test {
|
|||||||
# we need to filter out the banner part of the output so we get stable, repeatable
|
# we need to filter out the banner part of the output so we get stable, repeatable
|
||||||
# results.
|
# results.
|
||||||
if [[ $server_type == 'TinySSH' ]]; then
|
if [[ $server_type == 'TinySSH' ]]; then
|
||||||
grep -v "(gen) banner: " ${test_result_stdout} > "${test_result_stdout}.tmp"
|
grep -v "(gen) banner: " "${test_result_stdout}" > "${test_result_stdout}.tmp"
|
||||||
mv "${test_result_stdout}.tmp" ${test_result_stdout}
|
mv "${test_result_stdout}.tmp" "${test_result_stdout}"
|
||||||
cat "${test_result_json}" | perl -pe 's/"comments": ".*?"/"comments": ""/' | perl -pe 's/"raw": ".+?"/"raw": ""/' > "${test_result_json}.tmp"
|
cat "${test_result_json}" | perl -pe 's/"comments": ".*?"/"comments": ""/' | perl -pe 's/"raw": ".+?"/"raw": ""/' > "${test_result_json}.tmp"
|
||||||
mv "${test_result_json}.tmp" ${test_result_json}
|
mv "${test_result_json}.tmp" "${test_result_json}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
diff=`diff -u ${expected_result_stdout} ${test_result_stdout}`
|
diff=$(diff -u "${expected_result_stdout}" "${test_result_stdout}")
|
||||||
if [[ $? != 0 ]]; then
|
if [[ $? != 0 ]]; then
|
||||||
|
|
||||||
|
# If the user wants to update the tests, then overwrite the expected results with the actual results.
|
||||||
|
if [[ $accept == 1 ]]; then
|
||||||
|
cp "${test_result_stdout}" "${expected_result_stdout}"
|
||||||
|
echo -e "${test_name} ${YELLOWB}UPDATED${CLR}\n"
|
||||||
|
else
|
||||||
echo -e "${test_name} ${REDB}FAILED${CLR}.\n\n${diff}\n"
|
echo -e "${test_name} ${REDB}FAILED${CLR}.\n\n${diff}\n"
|
||||||
failed=1
|
failed=1
|
||||||
num_failures=$((num_failures+1))
|
num_failures=$((num_failures+1))
|
||||||
fi
|
fi
|
||||||
|
|
||||||
diff=`diff -u ${expected_result_json} ${test_result_json}`
|
fi
|
||||||
|
|
||||||
|
diff=$(diff -u "${expected_result_json}" "${test_result_json}")
|
||||||
if [[ $? != 0 ]]; then
|
if [[ $? != 0 ]]; then
|
||||||
|
|
||||||
|
# If the user wants to update the tests, then overwrite the expected results with the actual results.
|
||||||
|
if [[ $accept == 1 ]]; then
|
||||||
|
cp "${test_result_json}" "${expected_result_json}"
|
||||||
|
echo -e "${test_name} ${YELLOWB}UPDATED${CLR}\n"
|
||||||
|
else
|
||||||
echo -e "${test_name} ${REDB}FAILED${CLR}.\n\n${diff}\n"
|
echo -e "${test_name} ${REDB}FAILED${CLR}.\n\n${diff}\n"
|
||||||
failed=1
|
failed=1
|
||||||
num_failures=$((num_failures+1))
|
num_failures=$((num_failures+1))
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ $failed == 0 ]]; then
|
if [[ $failed == 0 ]]; then
|
||||||
echo -e "${test_name} ${GREEN}passed${CLR}."
|
echo -e "${test_name} ${GREEN}passed${CLR}."
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function run_builtin_policy_test {
|
run_builtin_policy_test() {
|
||||||
policy_name=$1 # The built-in policy name to use.
|
policy_name=$1 # The built-in policy name to use.
|
||||||
version=$2 # Version of OpenSSH to test with.
|
version=$2 # Version of OpenSSH to test with.
|
||||||
test_number=$3 # The test number to run.
|
test_number=$3 # The test number to run.
|
||||||
@ -518,7 +555,7 @@ function run_builtin_policy_test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function run_custom_policy_test {
|
run_custom_policy_test() {
|
||||||
config_number=$1 # The configuration number to use.
|
config_number=$1 # The configuration number to use.
|
||||||
test_number=$2 # The policy test number to run.
|
test_number=$2 # The policy test number to run.
|
||||||
expected_exit_code=$3 # The expected exit code of ssh-audit.py.
|
expected_exit_code=$3 # The expected exit code of ssh-audit.py.
|
||||||
@ -548,7 +585,7 @@ function run_custom_policy_test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function run_policy_test {
|
run_policy_test() {
|
||||||
test_name=$1
|
test_name=$1
|
||||||
server_exec=$2
|
server_exec=$2
|
||||||
policy_path=$3
|
policy_path=$3
|
||||||
@ -557,29 +594,39 @@ function run_policy_test {
|
|||||||
expected_exit_code=$6
|
expected_exit_code=$6
|
||||||
|
|
||||||
|
|
||||||
#echo "Running: docker run -d -p 2222:22 ${IMAGE_NAME}:${IMAGE_VERSION} ${server_exec}"
|
#echo "Running: docker run -d -p 2222:22 $IMAGE_NAME:$IMAGE_VERSION ${server_exec}"
|
||||||
cid=`docker run -d -p 2222:22 ${IMAGE_NAME}:${IMAGE_VERSION} ${server_exec}`
|
cid=$(docker run -d -p 2222:22 "$IMAGE_NAME:$IMAGE_VERSION" ${server_exec})
|
||||||
if [[ $? != 0 ]]; then
|
if [[ $? != 0 ]]; then
|
||||||
echo -e "${REDB}Failed to run docker image! (exit code: $?)${CLR}"
|
echo -e "${REDB}Failed to run docker image! (exit code: $?)${CLR}"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#echo "Running: ./ssh-audit.py -P \"${policy_path}\" localhost:2222 > ${test_result_stdout}"
|
#echo "Running: ./ssh-audit.py -P \"${policy_path}\" localhost:2222 > ${test_result_stdout}"
|
||||||
./ssh-audit.py -P "${policy_path}" localhost:2222 > ${test_result_stdout}
|
./ssh-audit.py -P "${policy_path}" localhost:2222 > "${test_result_stdout}"
|
||||||
actual_exit_code=$?
|
actual_exit_code=$?
|
||||||
if [[ ${actual_exit_code} != ${expected_exit_code} ]]; then
|
if [[ ${actual_exit_code} != "${expected_exit_code}" ]]; then
|
||||||
echo -e "${test_name} ${REDB}FAILED${CLR} (expected exit code: ${expected_exit_code}; actual exit code: ${actual_exit_code}\n"
|
echo -e "${test_name} ${REDB}FAILED${CLR} (expected exit code: ${expected_exit_code}; actual exit code: ${actual_exit_code}\n"
|
||||||
cat ${test_result_stdout}
|
|
||||||
|
if [[ $accept == 1 ]]; then
|
||||||
|
echo -e "\n${REDB}This failure cannot be automatically fixed; this script must be manually updated with the new expected return value.${CLR}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat "${test_result_stdout}"
|
||||||
docker container stop -t 0 $cid > /dev/null
|
docker container stop -t 0 $cid > /dev/null
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#echo "Running: ./ssh-audit.py -P \"${policy_path}\" -j localhost:2222 > ${test_result_json}"
|
#echo "Running: ./ssh-audit.py -P \"${policy_path}\" -jj localhost:2222 > ${test_result_json} 2> /dev/null"
|
||||||
./ssh-audit.py -P "${policy_path}" -j localhost:2222 > ${test_result_json}
|
./ssh-audit.py -P "${policy_path}" -jj localhost:2222 > "${test_result_json}" 2> /dev/null
|
||||||
actual_exit_code=$?
|
actual_exit_code=$?
|
||||||
if [[ ${actual_exit_code} != ${expected_exit_code} ]]; then
|
if [[ ${actual_exit_code} != "${expected_exit_code}" ]]; then
|
||||||
echo -e "${test_name} ${REDB}FAILED${CLR} (expected exit code: ${expected_exit_code}; actual exit code: ${actual_exit_code}\n"
|
echo -e "${test_name} ${REDB}FAILED${CLR} (expected exit code: ${expected_exit_code}; actual exit code: ${actual_exit_code}\n"
|
||||||
cat ${test_result_json}
|
|
||||||
|
if [[ $accept == 1 ]]; then
|
||||||
|
echo -e "\n${REDB}This failure cannot be automatically fixed; this script must be manually updated with the new expected return value.${CLR}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat "${test_result_json}"
|
||||||
docker container stop -t 0 $cid > /dev/null
|
docker container stop -t 0 $cid > /dev/null
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
@ -590,18 +637,34 @@ function run_policy_test {
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
diff=`diff -u ${expected_result_stdout} ${test_result_stdout}`
|
diff=$(diff -u "${expected_result_stdout}" "${test_result_stdout}")
|
||||||
if [[ $? != 0 ]]; then
|
if [[ $? != 0 ]]; then
|
||||||
|
|
||||||
|
# If the user wants to update the tests, then overwrite the expected results with the actual results.
|
||||||
|
if [[ $accept == 1 ]]; then
|
||||||
|
cp "${test_result_stdout}" "${expected_result_stdout}"
|
||||||
|
echo -e "${test_name} ${YELLOWB}UPDATED${CLR}\n"
|
||||||
|
else
|
||||||
echo -e "${test_name} ${REDB}FAILED${CLR}.\n\n${diff}\n"
|
echo -e "${test_name} ${REDB}FAILED${CLR}.\n\n${diff}\n"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
diff=`diff -u ${expected_result_json} ${test_result_json}`
|
fi
|
||||||
|
|
||||||
|
diff=$(diff -u "${expected_result_json}" "${test_result_json}")
|
||||||
if [[ $? != 0 ]]; then
|
if [[ $? != 0 ]]; then
|
||||||
|
|
||||||
|
# If the user wants to update the tests, then overwrite the expected results with the actual results.
|
||||||
|
if [[ $accept == 1 ]]; then
|
||||||
|
cp "${test_result_json}" "${expected_result_json}"
|
||||||
|
echo -e "${test_name} ${YELLOWB}UPDATED${CLR}\n"
|
||||||
|
else
|
||||||
echo -e "${test_name} ${REDB}FAILED${CLR}.\n\n${diff}\n"
|
echo -e "${test_name} ${REDB}FAILED${CLR}.\n\n${diff}\n"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
echo -e "${test_name} ${GREEN}passed${CLR}."
|
echo -e "${test_name} ${GREEN}passed${CLR}."
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -637,6 +700,13 @@ if [[ ($# == 1) && ($1 == "--create") ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# If the user passes --accept, then the actual results will replace the expected results (meaning the user wants to update the tests themselves due to new functionality).
|
||||||
|
if [[ ($# == 1) && ($1 == "--accept") ]]; then
|
||||||
|
accept=1
|
||||||
|
echo -e "\n${YELLOWB}Expected test results will be replaced with actual results.${CLR}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
# If we weren't explicitly told to create a new image, and it doesn't exist, then pull it from Dockerhub.
|
# If we weren't explicitly told to create a new image, and it doesn't exist, then pull it from Dockerhub.
|
||||||
if [[ $docker_image_exists == 0 ]]; then
|
if [[ $docker_image_exists == 0 ]]; then
|
||||||
echo -e "\nPulling docker image $IMAGE_NAME:$IMAGE_VERSION..."
|
echo -e "\nPulling docker image $IMAGE_NAME:$IMAGE_VERSION..."
|
||||||
@ -647,7 +717,7 @@ fi
|
|||||||
echo -e "\n${GREEN}Starting tests...${CLR}"
|
echo -e "\n${GREEN}Starting tests...${CLR}"
|
||||||
|
|
||||||
# Create a temporary directory to write test results to.
|
# Create a temporary directory to write test results to.
|
||||||
TEST_RESULT_DIR=`mktemp -d /tmp/ssh-audit_test-results_XXXXXXXXXX`
|
TEST_RESULT_DIR=$(mktemp -d /tmp/ssh-audit_test-results_XXXXXXXXXX)
|
||||||
|
|
||||||
# Now run all the tests.
|
# Now run all the tests.
|
||||||
echo -e "\nRunning tests..."
|
echo -e "\nRunning tests..."
|
||||||
@ -661,7 +731,7 @@ run_openssh_test '5.6p1' 'test5' $PROGRAM_RETVAL_FAILURE
|
|||||||
echo
|
echo
|
||||||
run_openssh_test '8.0p1' 'test1' $PROGRAM_RETVAL_FAILURE
|
run_openssh_test '8.0p1' 'test1' $PROGRAM_RETVAL_FAILURE
|
||||||
run_openssh_test '8.0p1' 'test2' $PROGRAM_RETVAL_FAILURE
|
run_openssh_test '8.0p1' 'test2' $PROGRAM_RETVAL_FAILURE
|
||||||
run_openssh_test '8.0p1' 'test3' $PROGRAM_RETVAL_GOOD
|
run_openssh_test '8.0p1' 'test3' $PROGRAM_RETVAL_WARNING
|
||||||
echo
|
echo
|
||||||
run_dropbear_test '2019.78' 'test1' '-r /etc/dropbear/dropbear_rsa_host_key_1024 -r /etc/dropbear/dropbear_dss_host_key -r /etc/dropbear/dropbear_ecdsa_host_key' 3
|
run_dropbear_test '2019.78' 'test1' '-r /etc/dropbear/dropbear_rsa_host_key_1024 -r /etc/dropbear/dropbear_dss_host_key -r /etc/dropbear/dropbear_ecdsa_host_key' 3
|
||||||
echo
|
echo
|
||||||
@ -699,16 +769,16 @@ run_custom_policy_test 'config2' 'test13' $PROGRAM_RETVAL_GOOD
|
|||||||
# Failing test with DH modulus test.
|
# Failing test with DH modulus test.
|
||||||
run_custom_policy_test 'config2' 'test14' $PROGRAM_RETVAL_FAILURE
|
run_custom_policy_test 'config2' 'test14' $PROGRAM_RETVAL_FAILURE
|
||||||
|
|
||||||
# Passing test for built-in OpenSSH 8.0p1 server policy.
|
# Failing test for built-in OpenSSH 8.0p1 server policy (RSA host key size is 3072 instead of 4096).
|
||||||
run_builtin_policy_test "Hardened OpenSSH Server v8.0 (version 1)" "8.0p1" "test1" "-o HostKeyAlgorithms=rsa-sha2-512,rsa-sha2-256,ssh-ed25519 -o KexAlgorithms=curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha256 -o Ciphers=chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr -o MACs=hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,umac-128-etm@openssh.com" $PROGRAM_RETVAL_GOOD
|
run_builtin_policy_test "Hardened OpenSSH Server v8.0 (version 2)" "8.0p1" "test1" "-o HostKeyAlgorithms=rsa-sha2-512,rsa-sha2-256,ssh-ed25519 -o KexAlgorithms=curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha256 -o Ciphers=chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr -o MACs=hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,umac-128-etm@openssh.com" $PROGRAM_RETVAL_FAILURE
|
||||||
|
|
||||||
# Failing test for built-in OpenSSH 8.0p1 server policy (MACs not hardened).
|
# Failing test for built-in OpenSSH 8.0p1 server policy (MACs not hardened).
|
||||||
run_builtin_policy_test "Hardened OpenSSH Server v8.0 (version 1)" "8.0p1" "test2" "-o HostKeyAlgorithms=rsa-sha2-512,rsa-sha2-256,ssh-ed25519 -o KexAlgorithms=curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha256 -o Ciphers=chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr" $PROGRAM_RETVAL_FAILURE
|
run_builtin_policy_test "Hardened OpenSSH Server v8.0 (version 2)" "8.0p1" "test2" "-o HostKeyAlgorithms=rsa-sha2-512,rsa-sha2-256,ssh-ed25519 -o KexAlgorithms=curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha256 -o Ciphers=chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr" $PROGRAM_RETVAL_FAILURE
|
||||||
|
|
||||||
|
|
||||||
if [[ $num_failures == 0 ]]; then
|
if [[ $num_failures == 0 ]]; then
|
||||||
echo -e "\n${GREENB}ALL TESTS PASS!${CLR}\n"
|
echo -e "\n${GREENB}ALL TESTS PASS!${CLR}\n"
|
||||||
rm -rf $TEST_RESULT_DIR
|
rm -rf -- "$TEST_RESULT_DIR"
|
||||||
else
|
else
|
||||||
echo -e "\n${REDB}${num_failures} TESTS FAILED!${CLR}\n"
|
echo -e "\n${REDB}${num_failures} TESTS FAILED!${CLR}\n"
|
||||||
fi
|
fi
|
||||||
|
@ -6,7 +6,8 @@ author_email = jtesta@positronsecurity.com
|
|||||||
description = An SSH server & client configuration security auditing tool
|
description = An SSH server & client configuration security auditing tool
|
||||||
long_description = file: README.md
|
long_description = file: README.md
|
||||||
long_description_content_type = text/markdown
|
long_description_content_type = text/markdown
|
||||||
license_file = LICENSE
|
license = MIT
|
||||||
|
license_files = LICENSE
|
||||||
url = https://github.com/jtesta/ssh-audit
|
url = https://github.com/jtesta/ssh-audit
|
||||||
project_urls =
|
project_urls =
|
||||||
Source Code = https://github.com/jtesta/ssh-audit
|
Source Code = https://github.com/jtesta/ssh-audit
|
||||||
@ -18,10 +19,11 @@ classifiers =
|
|||||||
License :: OSI Approved :: MIT License
|
License :: OSI Approved :: MIT License
|
||||||
Operating System :: OS Independent
|
Operating System :: OS Independent
|
||||||
Programming Language :: Python :: 3
|
Programming Language :: Python :: 3
|
||||||
Programming Language :: Python :: 3.6
|
|
||||||
Programming Language :: Python :: 3.7
|
Programming Language :: Python :: 3.7
|
||||||
Programming Language :: Python :: 3.8
|
Programming Language :: Python :: 3.8
|
||||||
Programming Language :: Python :: 3.9
|
Programming Language :: Python :: 3.9
|
||||||
|
Programming Language :: Python :: 3.10
|
||||||
|
Programming Language :: Python :: 3.11
|
||||||
Programming Language :: Python :: Implementation :: CPython
|
Programming Language :: Python :: Implementation :: CPython
|
||||||
Programming Language :: Python :: Implementation :: PyPy
|
Programming Language :: Python :: Implementation :: PyPy
|
||||||
Topic :: Security
|
Topic :: Security
|
||||||
@ -31,7 +33,7 @@ classifiers =
|
|||||||
packages = find:
|
packages = find:
|
||||||
package_dir =
|
package_dir =
|
||||||
= src
|
= src
|
||||||
python_requires = >=3.6,<4
|
python_requires = >=3.7,<4
|
||||||
|
|
||||||
[options.packages.find]
|
[options.packages.find]
|
||||||
where = src
|
where = src
|
||||||
|
@ -1,21 +1,20 @@
|
|||||||
name: ssh-audit
|
name: ssh-audit
|
||||||
version: '2.4.0-1'
|
# 'version' field will be automatically added by build_snap.sh.
|
||||||
license: 'MIT'
|
license: 'MIT'
|
||||||
summary: ssh-audit
|
summary: ssh-audit
|
||||||
description: |
|
description: |
|
||||||
SSH server and client security configuration auditor. Official repository: <https://github.com/jtesta/ssh-audit>
|
SSH server and client security configuration auditor. Official repository: <https://github.com/jtesta/ssh-audit>
|
||||||
|
|
||||||
base: core20
|
base: core22
|
||||||
grade: stable
|
grade: stable
|
||||||
confinement: strict
|
confinement: strict
|
||||||
|
|
||||||
apps:
|
apps:
|
||||||
ssh-audit:
|
ssh-audit:
|
||||||
command: bin/ssh-audit
|
command: bin/ssh-audit
|
||||||
plugs: [network,network-bind]
|
plugs: [network,network-bind,home]
|
||||||
|
|
||||||
parts:
|
parts:
|
||||||
ssh-audit:
|
ssh-audit:
|
||||||
plugin: python
|
plugin: python
|
||||||
# python-version: python3
|
|
||||||
source: .
|
source: .
|
||||||
|
@ -59,6 +59,7 @@ class AuditConf:
|
|||||||
self.lookup = ''
|
self.lookup = ''
|
||||||
self.manual = False
|
self.manual = False
|
||||||
self.debug = False
|
self.debug = False
|
||||||
|
self.gex_test = ''
|
||||||
|
|
||||||
def __setattr__(self, name: str, value: Union[str, int, float, bool, Sequence[int]]) -> None:
|
def __setattr__(self, name: str, value: Union[str, int, float, bool, Sequence[int]]) -> None:
|
||||||
valid = False
|
valid = False
|
||||||
@ -86,7 +87,7 @@ class AuditConf:
|
|||||||
if value == -1.0:
|
if value == -1.0:
|
||||||
raise ValueError('invalid timeout: {}'.format(value))
|
raise ValueError('invalid timeout: {}'.format(value))
|
||||||
valid = True
|
valid = True
|
||||||
elif name in ['ip_version_preference', 'lookup', 'policy_file', 'policy', 'target_file', 'target_list']:
|
elif name in ['ip_version_preference', 'lookup', 'policy_file', 'policy', 'target_file', 'target_list', 'gex_test']:
|
||||||
valid = True
|
valid = True
|
||||||
elif name == "threads":
|
elif name == "threads":
|
||||||
valid, num_threads = True, Utils.parse_int(value)
|
valid, num_threads = True, Utils.parse_int(value)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"""
|
"""
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (C) 2017-2021 Joe Testa (jtesta@positronsecurity.com)
|
Copyright (C) 2017-2023 Joe Testa (jtesta@positronsecurity.com)
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -21,18 +21,18 @@
|
|||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
"""
|
"""
|
||||||
|
import traceback
|
||||||
|
|
||||||
# pylint: disable=unused-import
|
# pylint: disable=unused-import
|
||||||
from typing import Dict, List, Set, Sequence, Tuple, Iterable # noqa: F401
|
from typing import Dict, List, Set, Sequence, Tuple, Iterable # noqa: F401
|
||||||
from typing import Callable, Optional, Union, Any # noqa: F401
|
from typing import Callable, Optional, Union, Any # noqa: F401
|
||||||
|
|
||||||
import traceback
|
from ssh_audit.kexdh import KexDHException, KexGroupExchange_SHA1, KexGroupExchange_SHA256
|
||||||
|
|
||||||
from ssh_audit.kexdh import KexGroupExchange_SHA1, KexGroupExchange_SHA256
|
|
||||||
from ssh_audit.ssh2_kexdb import SSH2_KexDB
|
from ssh_audit.ssh2_kexdb import SSH2_KexDB
|
||||||
from ssh_audit.ssh2_kex import SSH2_Kex
|
from ssh_audit.ssh2_kex import SSH2_Kex
|
||||||
from ssh_audit.ssh_socket import SSH_Socket
|
from ssh_audit.ssh_socket import SSH_Socket
|
||||||
from ssh_audit.outputbuffer import OutputBuffer
|
from ssh_audit.outputbuffer import OutputBuffer
|
||||||
|
from ssh_audit import exitcodes
|
||||||
|
|
||||||
|
|
||||||
# Performs DH group exchanges to find what moduli are supported, and checks
|
# Performs DH group exchanges to find what moduli are supported, and checks
|
||||||
@ -63,13 +63,75 @@ class GEXTest:
|
|||||||
try:
|
try:
|
||||||
# Parse the server's KEX.
|
# Parse the server's KEX.
|
||||||
_, payload = s.read_packet(2)
|
_, payload = s.read_packet(2)
|
||||||
SSH2_Kex.parse(payload)
|
SSH2_Kex.parse(out, payload)
|
||||||
except Exception:
|
except KexDHException:
|
||||||
out.v("Failed to parse server's kex. Stack trace:\n%s" % str(traceback.format_exc()), write_now=True)
|
out.v("Failed to parse server's kex. Stack trace:\n%s" % str(traceback.format_exc()), write_now=True)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def granular_modulus_size_test(out: 'OutputBuffer', s: 'SSH_Socket', kex: 'SSH2_Kex', bits_min: int, bits_pref: int, bits_max: int, modulus_dict: Dict[str, List[int]]) -> int:
|
||||||
|
'''
|
||||||
|
Tests for granular modulus sizes.
|
||||||
|
Builds a dictionary, where a key represents a DH algorithm name and the
|
||||||
|
values are the modulus sizes (in bits) that have been returned by the
|
||||||
|
target server.
|
||||||
|
Returns an exitcodes.* flag.
|
||||||
|
'''
|
||||||
|
|
||||||
|
retval = exitcodes.GOOD
|
||||||
|
|
||||||
|
out.d("Starting modulus_size_test...")
|
||||||
|
out.d("Bits Min: " + str(bits_min))
|
||||||
|
out.d("Bits Pref: " + str(bits_pref))
|
||||||
|
out.d("Bits Max: " + str(bits_max))
|
||||||
|
|
||||||
|
GEX_ALGS = {
|
||||||
|
'diffie-hellman-group-exchange-sha1': KexGroupExchange_SHA1,
|
||||||
|
'diffie-hellman-group-exchange-sha256': KexGroupExchange_SHA256,
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if the server supports any of the group-exchange
|
||||||
|
# algorithms. If so, test each one.
|
||||||
|
for gex_alg, kex_group_class in GEX_ALGS.items():
|
||||||
|
if gex_alg not in kex.kex_algorithms:
|
||||||
|
out.d('Server does not support the algorithm "' + gex_alg + '".', write_now=True)
|
||||||
|
else:
|
||||||
|
kex_group = kex_group_class(out)
|
||||||
|
out.d('Preparing to perform DH group exchange using ' + gex_alg + ' with min, pref and max modulus sizes of ' + str(bits_min) + ' bits, ' + str(bits_pref) + ' bits and ' + str(bits_max) + ' bits...', write_now=True)
|
||||||
|
|
||||||
|
# It has been observed that reconnecting to some SSH servers
|
||||||
|
# multiple times in quick succession can eventually result
|
||||||
|
# in a "connection reset by peer" error. It may be possible
|
||||||
|
# to recover from such an error by sleeping for some time
|
||||||
|
# before continuing to issue reconnects.
|
||||||
|
if GEXTest.reconnect(out, s, kex, gex_alg) is False:
|
||||||
|
out.fail('Reconnect failed.')
|
||||||
|
return exitcodes.FAILURE
|
||||||
|
try:
|
||||||
|
modulus_size_returned = None
|
||||||
|
kex_group.send_init_gex(s, bits_min, bits_pref, bits_max)
|
||||||
|
kex_group.recv_reply(s, False)
|
||||||
|
modulus_size_returned = kex_group.get_dh_modulus_size()
|
||||||
|
out.d('Modulus size returned by server: ' + str(modulus_size_returned) + ' bits', write_now=True)
|
||||||
|
except KexDHException:
|
||||||
|
out.d('[exception] ' + str(traceback.format_exc()), write_now=True)
|
||||||
|
finally:
|
||||||
|
# The server is in a state that is not re-testable,
|
||||||
|
# so there's nothing else to do with this open
|
||||||
|
# connection.
|
||||||
|
s.close()
|
||||||
|
|
||||||
|
if modulus_size_returned is not None:
|
||||||
|
if gex_alg in modulus_dict:
|
||||||
|
if modulus_size_returned not in modulus_dict[gex_alg]:
|
||||||
|
modulus_dict[gex_alg].append(modulus_size_returned)
|
||||||
|
else:
|
||||||
|
modulus_dict[gex_alg] = [modulus_size_returned]
|
||||||
|
|
||||||
|
return retval
|
||||||
|
|
||||||
# Runs the DH moduli test against the specified target.
|
# Runs the DH moduli test against the specified target.
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def run(out: 'OutputBuffer', s: 'SSH_Socket', kex: 'SSH2_Kex') -> None:
|
def run(out: 'OutputBuffer', s: 'SSH_Socket', kex: 'SSH2_Kex') -> None:
|
||||||
@ -88,12 +150,12 @@ class GEXTest:
|
|||||||
# algorithms. If so, test each one.
|
# algorithms. If so, test each one.
|
||||||
for gex_alg, kex_group_class in GEX_ALGS.items():
|
for gex_alg, kex_group_class in GEX_ALGS.items():
|
||||||
if gex_alg in kex.kex_algorithms:
|
if gex_alg in kex.kex_algorithms:
|
||||||
out.d('Preparing to perform DH group exchange using ' + gex_alg + '...', write_now=True)
|
out.d('Preparing to perform DH group exchange using ' + gex_alg + ' with min, pref and max modulus sizes of 512 bits, 1024 bits and 1536 bits...', write_now=True)
|
||||||
|
|
||||||
if GEXTest.reconnect(out, s, kex, gex_alg) is False:
|
if GEXTest.reconnect(out, s, kex, gex_alg) is False:
|
||||||
break
|
break
|
||||||
|
|
||||||
kex_group = kex_group_class()
|
kex_group = kex_group_class(out)
|
||||||
smallest_modulus = -1
|
smallest_modulus = -1
|
||||||
|
|
||||||
# First try a range of weak sizes.
|
# First try a range of weak sizes.
|
||||||
@ -105,9 +167,10 @@ class GEXTest:
|
|||||||
# larger than the requested max. So just because we
|
# larger than the requested max. So just because we
|
||||||
# got here, doesn't mean the server is vulnerable...
|
# got here, doesn't mean the server is vulnerable...
|
||||||
smallest_modulus = kex_group.get_dh_modulus_size()
|
smallest_modulus = kex_group.get_dh_modulus_size()
|
||||||
|
out.d('Modulus size returned by server: ' + str(smallest_modulus) + ' bits', write_now=True)
|
||||||
|
|
||||||
except Exception:
|
except KexDHException:
|
||||||
pass
|
out.d('[exception] ' + str(traceback.format_exc()), write_now=True)
|
||||||
finally:
|
finally:
|
||||||
s.close()
|
s.close()
|
||||||
|
|
||||||
@ -120,7 +183,7 @@ class GEXTest:
|
|||||||
if bits >= smallest_modulus > 0:
|
if bits >= smallest_modulus > 0:
|
||||||
break
|
break
|
||||||
|
|
||||||
out.d('Preparing to perform DH group exchange using ' + gex_alg + ' with modulus size ' + str(bits) + '...', write_now=True)
|
out.d('Preparing to perform DH group exchange using ' + gex_alg + ' with min, pref and max modulus sizes of ' + str(bits) + ' bits...', write_now=True)
|
||||||
|
|
||||||
if GEXTest.reconnect(out, s, kex, gex_alg) is False:
|
if GEXTest.reconnect(out, s, kex, gex_alg) is False:
|
||||||
reconnect_failed = True
|
reconnect_failed = True
|
||||||
@ -130,10 +193,9 @@ class GEXTest:
|
|||||||
kex_group.send_init_gex(s, bits, bits, bits)
|
kex_group.send_init_gex(s, bits, bits, bits)
|
||||||
kex_group.recv_reply(s, False)
|
kex_group.recv_reply(s, False)
|
||||||
smallest_modulus = kex_group.get_dh_modulus_size()
|
smallest_modulus = kex_group.get_dh_modulus_size()
|
||||||
except Exception:
|
out.d('Modulus size returned by server: ' + str(smallest_modulus) + ' bits', write_now=True)
|
||||||
# import traceback
|
except KexDHException as e:
|
||||||
# print(traceback.format_exc())
|
out.d('Exception when testing DH group exchange ' + gex_alg + ' with modulus size ' + str(bits) + '. (Hint: this is probably normal since the server does not support this modulus size.): ' + str(e), write_now=True)
|
||||||
pass
|
|
||||||
finally:
|
finally:
|
||||||
# The server is in a state that is not re-testable,
|
# The server is in a state that is not re-testable,
|
||||||
# so there's nothing else to do with this open
|
# so there's nothing else to do with this open
|
||||||
@ -158,5 +220,18 @@ class GEXTest:
|
|||||||
del lst[1]
|
del lst[1]
|
||||||
lst.insert(1, [text])
|
lst.insert(1, [text])
|
||||||
|
|
||||||
|
# Moduli smaller than 3072 get flagged as a warning.
|
||||||
|
elif smallest_modulus < 3072:
|
||||||
|
lst = SSH2_KexDB.ALGORITHMS['kex'][gex_alg]
|
||||||
|
|
||||||
|
# Ensure that a warning list exists for us to append to, below.
|
||||||
|
while len(lst) < 3:
|
||||||
|
lst.append([])
|
||||||
|
|
||||||
|
# Ensure this is only added once.
|
||||||
|
text = '2048-bit modulus only provides 112-bits of symmetric strength'
|
||||||
|
if text not in lst[2]:
|
||||||
|
lst[2].append(text)
|
||||||
|
|
||||||
if reconnect_failed:
|
if reconnect_failed:
|
||||||
break
|
break
|
||||||
|
@ -21,7 +21,20 @@
|
|||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
"""
|
"""
|
||||||
VERSION = 'v2.5.0'
|
# The version to display.
|
||||||
SSH_HEADER = 'SSH-{0}-OpenSSH_8.2' # SSH software to impersonate
|
VERSION = 'v2.9.0'
|
||||||
GITHUB_ISSUES_URL = 'https://github.com/jtesta/ssh-audit/issues' # The URL to the Github issues tracker.
|
|
||||||
|
# SSH software to impersonate
|
||||||
|
SSH_HEADER = 'SSH-{0}-OpenSSH_8.2'
|
||||||
|
|
||||||
|
# The URL to the Github issues tracker.
|
||||||
|
GITHUB_ISSUES_URL = 'https://github.com/jtesta/ssh-audit/issues'
|
||||||
|
|
||||||
|
# The man page. Only filled in on Windows systems.
|
||||||
WINDOWS_MAN_PAGE = ''
|
WINDOWS_MAN_PAGE = ''
|
||||||
|
|
||||||
|
# True when installed from a Snap package, otherwise False.
|
||||||
|
SNAP_PACKAGE = False
|
||||||
|
|
||||||
|
# Error message when installed as a Snap package and a file access fails.
|
||||||
|
SNAP_PERMISSIONS_ERROR = 'Error while accessing file. It appears that ssh-audit was installed as a Snap package. In that case, there are two options: 1.) only try to read & write files in the $HOME/snap/ssh-audit/common/ directory, or 2.) grant permissions to read & write files in $HOME using the following command: "sudo snap connect ssh-audit:home :home"'
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"""
|
"""
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (C) 2017-2021 Joe Testa (jtesta@positronsecurity.com)
|
Copyright (C) 2017-2023 Joe Testa (jtesta@positronsecurity.com)
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -28,7 +28,7 @@ from typing import Callable, Optional, Union, Any # noqa: F401
|
|||||||
|
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
from ssh_audit.kexdh import KexDH, KexGroup1, KexGroup14_SHA1, KexGroup14_SHA256, KexCurve25519_SHA256, KexGroup16_SHA512, KexGroup18_SHA512, KexGroupExchange_SHA1, KexGroupExchange_SHA256, KexNISTP256, KexNISTP384, KexNISTP521
|
from ssh_audit.kexdh import KexDH, KexDHException, KexGroup1, KexGroup14_SHA1, KexGroup14_SHA256, KexCurve25519_SHA256, KexGroup16_SHA512, KexGroup18_SHA512, KexGroupExchange_SHA1, KexGroupExchange_SHA256, KexNISTP256, KexNISTP384, KexNISTP521
|
||||||
from ssh_audit.ssh2_kex import SSH2_Kex
|
from ssh_audit.ssh2_kex import SSH2_Kex
|
||||||
from ssh_audit.ssh2_kexdb import SSH2_KexDB
|
from ssh_audit.ssh2_kexdb import SSH2_KexDB
|
||||||
from ssh_audit.ssh_socket import SSH_Socket
|
from ssh_audit.ssh_socket import SSH_Socket
|
||||||
@ -54,6 +54,10 @@ class HostKeyTest:
|
|||||||
'ssh-ed25519-cert-v01@openssh.com': {'cert': True, 'variable_key_len': False},
|
'ssh-ed25519-cert-v01@openssh.com': {'cert': True, 'variable_key_len': False},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TWO2K_MODULUS_WARNING = '2048-bit modulus only provides 112-bits of symmetric strength'
|
||||||
|
SMALL_ECC_MODULUS_WARNING = '224-bit ECC modulus only provides 112-bits of symmetric strength'
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def run(out: 'OutputBuffer', s: 'SSH_Socket', server_kex: 'SSH2_Kex') -> None:
|
def run(out: 'OutputBuffer', s: 'SSH_Socket', server_kex: 'SSH2_Kex') -> None:
|
||||||
KEX_TO_DHGROUP = {
|
KEX_TO_DHGROUP = {
|
||||||
@ -79,7 +83,7 @@ class HostKeyTest:
|
|||||||
for server_kex_alg in server_kex.kex_algorithms:
|
for server_kex_alg in server_kex.kex_algorithms:
|
||||||
if server_kex_alg in KEX_TO_DHGROUP:
|
if server_kex_alg in KEX_TO_DHGROUP:
|
||||||
kex_str = server_kex_alg
|
kex_str = server_kex_alg
|
||||||
kex_group = KEX_TO_DHGROUP[kex_str]()
|
kex_group = KEX_TO_DHGROUP[kex_str](out)
|
||||||
break
|
break
|
||||||
|
|
||||||
if kex_str is not None and kex_group is not None:
|
if kex_str is not None and kex_group is not None:
|
||||||
@ -98,6 +102,9 @@ class HostKeyTest:
|
|||||||
|
|
||||||
# For each host key type...
|
# For each host key type...
|
||||||
for host_key_type in host_key_types:
|
for host_key_type in host_key_types:
|
||||||
|
key_fail_comments = []
|
||||||
|
key_warn_comments = []
|
||||||
|
|
||||||
# Skip those already handled (i.e.: those in the RSA family, as testing one tests them all).
|
# 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 'parsed' in host_key_types[host_key_type] and host_key_types[host_key_type]['parsed']:
|
||||||
continue
|
continue
|
||||||
@ -107,7 +114,6 @@ class HostKeyTest:
|
|||||||
out.d('Preparing to obtain ' + host_key_type + ' host key...', write_now=True)
|
out.d('Preparing to obtain ' + host_key_type + ' host key...', write_now=True)
|
||||||
|
|
||||||
cert = host_key_types[host_key_type]['cert']
|
cert = host_key_types[host_key_type]['cert']
|
||||||
variable_key_len = host_key_types[host_key_type]['variable_key_len']
|
|
||||||
|
|
||||||
# If the connection is closed, re-open it and get the kex again.
|
# If the connection is closed, re-open it and get the kex again.
|
||||||
if not s.is_connected():
|
if not s.is_connected():
|
||||||
@ -128,7 +134,7 @@ class HostKeyTest:
|
|||||||
try:
|
try:
|
||||||
# Parse the server's KEX.
|
# Parse the server's KEX.
|
||||||
_, payload = s.read_packet()
|
_, payload = s.read_packet()
|
||||||
SSH2_Kex.parse(payload)
|
SSH2_Kex.parse(out, payload)
|
||||||
except Exception:
|
except Exception:
|
||||||
out.v("Failed to parse server's kex. Stack trace:\n%s" % str(traceback.format_exc()), write_now=True)
|
out.v("Failed to parse server's kex. Stack trace:\n%s" % str(traceback.format_exc()), write_now=True)
|
||||||
return
|
return
|
||||||
@ -136,15 +142,29 @@ class HostKeyTest:
|
|||||||
# Do the initial DH exchange. The server responds back
|
# Do the initial DH exchange. The server responds back
|
||||||
# with the host key and its length. Bingo. We also get back the host key fingerprint.
|
# with the host key and its length. Bingo. We also get back the host key fingerprint.
|
||||||
kex_group.send_init(s)
|
kex_group.send_init(s)
|
||||||
|
raw_hostkey_bytes = b''
|
||||||
try:
|
try:
|
||||||
host_key = kex_group.recv_reply(s, variable_key_len)
|
kex_reply = kex_group.recv_reply(s)
|
||||||
if host_key is not None:
|
raw_hostkey_bytes = kex_reply if kex_reply is not None else b''
|
||||||
server_kex.set_host_key(host_key_type, host_key)
|
except KexDHException:
|
||||||
except Exception:
|
out.v("Failed to parse server's host key. Stack trace:\n%s" % str(traceback.format_exc()), write_now=True)
|
||||||
pass
|
|
||||||
|
# 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()
|
||||||
|
continue
|
||||||
|
|
||||||
hostkey_modulus_size = kex_group.get_hostkey_size()
|
hostkey_modulus_size = kex_group.get_hostkey_size()
|
||||||
|
ca_key_type = kex_group.get_ca_type()
|
||||||
ca_modulus_size = kex_group.get_ca_size()
|
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)
|
||||||
|
|
||||||
|
# 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)
|
||||||
|
|
||||||
|
# Set the hostkey size for all RSA key types since 'ssh-rsa', 'rsa-sha2-256', etc. are all using the same host key. Note, however, that this may change in the future.
|
||||||
|
if cert is False and host_key_type in HostKeyTest.RSA_FAMILY:
|
||||||
|
for rsa_type in HostKeyTest.RSA_FAMILY:
|
||||||
|
server_kex.set_host_key(rsa_type, raw_hostkey_bytes, hostkey_modulus_size, ca_key_type, ca_modulus_size)
|
||||||
|
|
||||||
# Close the socket, as the connection has
|
# Close the socket, as the connection has
|
||||||
# been put in a state that later tests can't use.
|
# been put in a state that later tests can't use.
|
||||||
@ -152,37 +172,60 @@ class HostKeyTest:
|
|||||||
|
|
||||||
# If the host key modulus or CA modulus was successfully parsed, check to see that its a safe size.
|
# If the host key modulus or CA modulus was successfully parsed, check to see that its a safe size.
|
||||||
if hostkey_modulus_size > 0 or ca_modulus_size > 0:
|
if hostkey_modulus_size > 0 or ca_modulus_size > 0:
|
||||||
# Set the hostkey size for all RSA key types since 'ssh-rsa',
|
# The minimum good modulus size for RSA host keys is 3072. However, since ECC cryptosystems are fundamentally different, the minimum good is 256.
|
||||||
# 'rsa-sha2-256', etc. are all using the same host key.
|
hostkey_min_good = cakey_min_good = 3072
|
||||||
# Note, however, that this may change in the future.
|
hostkey_min_warn = cakey_min_warn = 2048
|
||||||
if cert is False and host_key_type in HostKeyTest.RSA_FAMILY:
|
hostkey_warn_str = cakey_warn_str = HostKeyTest.TWO2K_MODULUS_WARNING
|
||||||
for rsa_type in HostKeyTest.RSA_FAMILY:
|
if host_key_type.startswith('ssh-ed25519') or host_key_type.startswith('ecdsa-sha2-nistp'):
|
||||||
server_kex.set_rsa_key_size(rsa_type, hostkey_modulus_size)
|
hostkey_min_good = 256
|
||||||
elif cert is True:
|
hostkey_min_warn = 224
|
||||||
server_kex.set_rsa_key_size(host_key_type, hostkey_modulus_size, ca_modulus_size)
|
hostkey_warn_str = HostKeyTest.SMALL_ECC_MODULUS_WARNING
|
||||||
|
if ca_key_type.startswith('ssh-ed25519') or host_key_type.startswith('ecdsa-sha2-nistp'):
|
||||||
|
cakey_min_good = 256
|
||||||
|
cakey_min_warn = 224
|
||||||
|
cakey_warn_str = HostKeyTest.SMALL_ECC_MODULUS_WARNING
|
||||||
|
|
||||||
# Keys smaller than 2048 result in a failure. Update the database accordingly.
|
# 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 < 2048):
|
if (cert is False) and (hostkey_modulus_size < hostkey_min_good):
|
||||||
for rsa_type in HostKeyTest.RSA_FAMILY:
|
|
||||||
alg_list = SSH2_KexDB.ALGORITHMS['key'][rsa_type]
|
|
||||||
|
|
||||||
# If no failure list exists, add an empty failure list.
|
# If the key is under 2048, add to the failure list.
|
||||||
if len(alg_list) < 2:
|
if hostkey_modulus_size < hostkey_min_warn:
|
||||||
alg_list.append([])
|
key_fail_comments.append('using small %d-bit modulus' % hostkey_modulus_size)
|
||||||
alg_list[1].append('using small %d-bit modulus' % hostkey_modulus_size)
|
elif hostkey_warn_str not in key_warn_comments: # Issue a warning about 2048-bit moduli.
|
||||||
elif (cert is True) and ((hostkey_modulus_size < 2048) or (ca_modulus_size > 0 and ca_modulus_size < 2048)): # pylint: disable=chained-comparison
|
key_warn_comments.append(hostkey_warn_str)
|
||||||
alg_list = SSH2_KexDB.ALGORITHMS['key'][host_key_type]
|
|
||||||
min_modulus = min(hostkey_modulus_size, ca_modulus_size)
|
|
||||||
min_modulus = min_modulus if min_modulus > 0 else max(hostkey_modulus_size, ca_modulus_size)
|
|
||||||
|
|
||||||
# If no failure list exists, add an empty failure list.
|
elif (cert is True) and ((hostkey_modulus_size < hostkey_min_good) or (0 < ca_modulus_size < cakey_min_good)):
|
||||||
if len(alg_list) < 2:
|
# If the host key is smaller than 2048-bit/224-bit, flag this as a failure.
|
||||||
alg_list.append([])
|
if hostkey_modulus_size < hostkey_min_warn:
|
||||||
alg_list[1].append('using small %d-bit modulus' % min_modulus)
|
key_fail_comments.append('using small %d-bit hostkey modulus' % hostkey_modulus_size)
|
||||||
|
# Otherwise, this is just a warning.
|
||||||
|
elif (hostkey_modulus_size < hostkey_min_good) and (hostkey_warn_str not in key_warn_comments):
|
||||||
|
key_warn_comments.append(hostkey_warn_str)
|
||||||
|
|
||||||
|
# If the CA key is smaller than 2048-bit/224-bit, flag this as a failure.
|
||||||
|
if 0 < ca_modulus_size < cakey_min_warn:
|
||||||
|
key_fail_comments.append('using small %d-bit CA key modulus' % ca_modulus_size)
|
||||||
|
# Otherwise, this is just a warning.
|
||||||
|
elif (0 < ca_modulus_size < cakey_min_good) and (cakey_warn_str not in key_warn_comments):
|
||||||
|
key_warn_comments.append(cakey_warn_str)
|
||||||
|
|
||||||
# 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 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:
|
if host_key_type in HostKeyTest.RSA_FAMILY:
|
||||||
for rsa_type in HostKeyTest.RSA_FAMILY:
|
for rsa_type in HostKeyTest.RSA_FAMILY:
|
||||||
host_key_types[rsa_type]['parsed'] = True
|
host_key_types[rsa_type]['parsed'] = True
|
||||||
|
|
||||||
|
# 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.
|
||||||
|
while len(SSH2_KexDB.ALGORITHMS['key'][rsa_type]) < 3:
|
||||||
|
SSH2_KexDB.ALGORITHMS['key'][rsa_type].append([])
|
||||||
|
|
||||||
|
SSH2_KexDB.ALGORITHMS['key'][rsa_type][1].extend(key_fail_comments)
|
||||||
|
SSH2_KexDB.ALGORITHMS['key'][rsa_type][2].extend(key_warn_comments)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
host_key_types[host_key_type]['parsed'] = True
|
host_key_types[host_key_type]['parsed'] = True
|
||||||
|
while len(SSH2_KexDB.ALGORITHMS['key'][host_key_type]) < 3:
|
||||||
|
SSH2_KexDB.ALGORITHMS['key'][host_key_type].append([])
|
||||||
|
|
||||||
|
SSH2_KexDB.ALGORITHMS['key'][host_key_type][1].extend(key_fail_comments)
|
||||||
|
SSH2_KexDB.ALGORITHMS['key'][host_key_type][2].extend(key_warn_comments)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"""
|
"""
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (C) 2017-2021 Joe Testa (jtesta@positronsecurity.com)
|
Copyright (C) 2017-2023 Joe Testa (jtesta@positronsecurity.com)
|
||||||
Copyright (C) 2017 Andris Raugulis (moo@arthepsy.eu)
|
Copyright (C) 2017 Andris Raugulis (moo@arthepsy.eu)
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
@ -31,12 +31,18 @@ import struct
|
|||||||
from typing import Dict, List, Set, Sequence, Tuple, Iterable # noqa: F401
|
from typing import Dict, List, Set, Sequence, Tuple, Iterable # noqa: F401
|
||||||
from typing import Callable, Optional, Union, Any # noqa: F401
|
from typing import Callable, Optional, Union, Any # noqa: F401
|
||||||
|
|
||||||
|
from ssh_audit.outputbuffer import OutputBuffer
|
||||||
from ssh_audit.protocol import Protocol
|
from ssh_audit.protocol import Protocol
|
||||||
from ssh_audit.ssh_socket import SSH_Socket
|
from ssh_audit.ssh_socket import SSH_Socket
|
||||||
|
|
||||||
|
|
||||||
|
class KexDHException(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class KexDH: # pragma: nocover
|
class KexDH: # pragma: nocover
|
||||||
def __init__(self, kex_name: str, hash_alg: str, g: int, p: int) -> None:
|
def __init__(self, out: 'OutputBuffer', kex_name: str, hash_alg: str, g: int, p: int) -> None:
|
||||||
|
self.out = out
|
||||||
self.__kex_name = kex_name # pylint: disable=unused-private-member
|
self.__kex_name = kex_name # pylint: disable=unused-private-member
|
||||||
self.__hash_alg = hash_alg # pylint: disable=unused-private-member
|
self.__hash_alg = hash_alg # pylint: disable=unused-private-member
|
||||||
self.__g = 0
|
self.__g = 0
|
||||||
@ -47,10 +53,11 @@ class KexDH: # pragma: nocover
|
|||||||
self.set_params(g, p)
|
self.set_params(g, p)
|
||||||
|
|
||||||
self.__ed25519_pubkey: Optional[bytes] = None # pylint: disable=unused-private-member
|
self.__ed25519_pubkey: Optional[bytes] = None # pylint: disable=unused-private-member
|
||||||
self.__hostkey_type: Optional[bytes] = None
|
self.__hostkey_type = ''
|
||||||
self.__hostkey_e = 0 # pylint: disable=unused-private-member
|
self.__hostkey_e = 0 # pylint: disable=unused-private-member
|
||||||
self.__hostkey_n = 0 # pylint: disable=unused-private-member
|
self.__hostkey_n = 0 # pylint: disable=unused-private-member
|
||||||
self.__hostkey_n_len = 0 # Length of the host key modulus.
|
self.__hostkey_n_len = 0 # Length of the host key modulus.
|
||||||
|
self.__ca_key_type = '' # Type of CA key ('ssh-rsa', etc).
|
||||||
self.__ca_n_len = 0 # Length of the CA key modulus (if hostkey is a cert).
|
self.__ca_n_len = 0 # Length of the CA key modulus (if hostkey is a cert).
|
||||||
|
|
||||||
def set_params(self, g: int, p: int) -> None:
|
def set_params(self, g: int, p: int) -> None:
|
||||||
@ -72,6 +79,14 @@ class KexDH: # pragma: nocover
|
|||||||
# contains the host key, among other things. Function returns the host
|
# contains the host key, among other things. Function returns the host
|
||||||
# key blob (from which the fingerprint can be calculated).
|
# key blob (from which the fingerprint can be calculated).
|
||||||
def recv_reply(self, s: 'SSH_Socket', parse_host_key_size: bool = True) -> Optional[bytes]:
|
def recv_reply(self, s: 'SSH_Socket', parse_host_key_size: bool = True) -> Optional[bytes]:
|
||||||
|
# Reset the CA info, in case it was set from a prior invokation.
|
||||||
|
self.__hostkey_type = ''
|
||||||
|
self.__hostkey_e = 0 # pylint: disable=unused-private-member
|
||||||
|
self.__hostkey_n = 0 # pylint: disable=unused-private-member
|
||||||
|
self.__hostkey_n_len = 0
|
||||||
|
self.__ca_key_type = ''
|
||||||
|
self.__ca_n_len = 0
|
||||||
|
|
||||||
packet_type, payload = s.read_packet(2)
|
packet_type, payload = s.read_packet(2)
|
||||||
|
|
||||||
# Skip any & all MSG_DEBUG messages.
|
# Skip any & all MSG_DEBUG messages.
|
||||||
@ -79,29 +94,17 @@ class KexDH: # pragma: nocover
|
|||||||
packet_type, payload = s.read_packet(2)
|
packet_type, payload = s.read_packet(2)
|
||||||
|
|
||||||
if packet_type != -1 and packet_type not in [Protocol.MSG_KEXDH_REPLY, Protocol.MSG_KEXDH_GEX_REPLY]: # pylint: disable=no-else-raise
|
if packet_type != -1 and packet_type not in [Protocol.MSG_KEXDH_REPLY, Protocol.MSG_KEXDH_GEX_REPLY]: # pylint: disable=no-else-raise
|
||||||
# TODO: change Exception to something more specific.
|
raise KexDHException('Expected MSG_KEXDH_REPLY (%d) or MSG_KEXDH_GEX_REPLY (%d), but got %d instead.' % (Protocol.MSG_KEXDH_REPLY, Protocol.MSG_KEXDH_GEX_REPLY, packet_type))
|
||||||
raise Exception('Expected MSG_KEXDH_REPLY (%d) or MSG_KEXDH_GEX_REPLY (%d), but got %d instead.' % (Protocol.MSG_KEXDH_REPLY, Protocol.MSG_KEXDH_GEX_REPLY, packet_type))
|
|
||||||
elif packet_type == -1:
|
elif packet_type == -1:
|
||||||
# A connection error occurred. We can't parse anything, so just
|
# A connection error occurred. We can't parse anything, so just
|
||||||
# return. The host key modulus (and perhaps certificate modulus)
|
# return. The host key modulus (and perhaps certificate modulus)
|
||||||
# will remain at length 0.
|
# will remain at length 0.
|
||||||
|
self.out.d("KexDH.recv_reply(): received packge_type == -1.")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
hostkey_len = 0 # pylint: disable=unused-variable
|
|
||||||
hostkey_type_len = hostkey_e_len = 0 # pylint: disable=unused-variable
|
|
||||||
key_id_len = principles_len = 0 # pylint: disable=unused-variable
|
|
||||||
critical_options_len = extensions_len = 0 # pylint: disable=unused-variable
|
|
||||||
nonce_len = ca_key_len = ca_key_type_len = 0 # pylint: disable=unused-variable
|
|
||||||
ca_key_len = ca_key_type_len = ca_key_e_len = 0 # pylint: disable=unused-variable
|
|
||||||
|
|
||||||
key_id = principles = None # pylint: disable=unused-variable
|
|
||||||
critical_options = extensions = None # pylint: disable=unused-variable
|
|
||||||
nonce = ca_key = ca_key_type = None # pylint: disable=unused-variable
|
|
||||||
ca_key_e = ca_key_n = None # pylint: disable=unused-variable
|
|
||||||
|
|
||||||
# Get the host key blob, F, and signature.
|
# Get the host key blob, F, and signature.
|
||||||
ptr = 0
|
ptr = 0
|
||||||
hostkey, hostkey_len, ptr = KexDH.__get_bytes(payload, ptr)
|
hostkey, _, ptr = KexDH.__get_bytes(payload, ptr)
|
||||||
|
|
||||||
# If we are not supposed to parse the host key size (i.e.: it is a type that is of fixed size such as ed25519), then stop here.
|
# If we are not supposed to parse the host key size (i.e.: it is a type that is of fixed size such as ed25519), then stop here.
|
||||||
if not parse_host_key_size:
|
if not parse_host_key_size:
|
||||||
@ -113,23 +116,44 @@ class KexDH: # pragma: nocover
|
|||||||
# Now pick apart the host key blob.
|
# Now pick apart the host key blob.
|
||||||
# Get the host key type (i.e.: 'ssh-rsa', 'ssh-ed25519', etc).
|
# Get the host key type (i.e.: 'ssh-rsa', 'ssh-ed25519', etc).
|
||||||
ptr = 0
|
ptr = 0
|
||||||
self.__hostkey_type, hostkey_type_len, ptr = KexDH.__get_bytes(hostkey, ptr)
|
hostkey_type, _, ptr = KexDH.__get_bytes(hostkey, ptr)
|
||||||
|
self.__hostkey_type = hostkey_type.decode('ascii')
|
||||||
|
self.out.d("Parsing host key type: %s" % self.__hostkey_type)
|
||||||
|
|
||||||
# If this is an RSA certificate, skip over the nonce.
|
# If this is an RSA certificate, skip over the nonce.
|
||||||
if self.__hostkey_type.startswith(b'ssh-rsa-cert-v0'):
|
if self.__hostkey_type.startswith('ssh-rsa-cert-v0'):
|
||||||
nonce, nonce_len, ptr = KexDH.__get_bytes(hostkey, ptr)
|
self.out.d("RSA certificate found, so skipping nonce.")
|
||||||
|
_, _, ptr = KexDH.__get_bytes(hostkey, ptr) # Read & skip over the nonce.
|
||||||
|
|
||||||
# The public key exponent.
|
# The public key exponent.
|
||||||
hostkey_e, hostkey_e_len, ptr = KexDH.__get_bytes(hostkey, ptr)
|
hostkey_e, _, ptr = KexDH.__get_bytes(hostkey, ptr)
|
||||||
self.__hostkey_e = int(binascii.hexlify(hostkey_e), 16) # pylint: disable=unused-private-member
|
self.__hostkey_e = int(binascii.hexlify(hostkey_e), 16) # pylint: disable=unused-private-member
|
||||||
|
|
||||||
|
# ED25519 moduli are fixed at 32 bytes.
|
||||||
|
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
|
||||||
|
else:
|
||||||
# Here is the modulus size & actual modulus of the host key public key.
|
# 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)
|
hostkey_n, self.__hostkey_n_len, ptr = KexDH.__get_bytes(hostkey, ptr)
|
||||||
self.__hostkey_n = int(binascii.hexlify(hostkey_n), 16) # pylint: disable=unused-private-member
|
self.__hostkey_n = int(binascii.hexlify(hostkey_n), 16) # pylint: disable=unused-private-member
|
||||||
|
|
||||||
# If this is an RSA certificate, continue parsing to extract the CA
|
# If this is a certificate, continue parsing to extract the CA type and key length. Even though a hostkey type might be 'ssh-ed25519-cert-v01@openssh.com', its CA may still be RSA.
|
||||||
# key.
|
if self.__hostkey_type.startswith('ssh-rsa-cert-v0') or self.__hostkey_type.startswith('ssh-ed25519-cert-v0'):
|
||||||
if self.__hostkey_type.startswith(b'ssh-rsa-cert-v0'):
|
# Get the CA key type and key length.
|
||||||
|
self.__ca_key_type, self.__ca_n_len = self.__parse_ca_key(hostkey, self.__hostkey_type, ptr)
|
||||||
|
self.out.d("KexDH.__parse_ca_key(): CA key type: [%s]; CA key length: %u" % (self.__ca_key_type, self.__ca_n_len))
|
||||||
|
|
||||||
|
return hostkey
|
||||||
|
|
||||||
|
def __parse_ca_key(self, hostkey: bytes, hostkey_type: str, ptr: int) -> Tuple[str, int]:
|
||||||
|
ca_key_type = ''
|
||||||
|
ca_key_n_len = 0
|
||||||
|
|
||||||
|
# If this is a certificate, continue parsing to extract the CA type and key length. Even though a hostkey type might be 'ssh-ed25519-cert-v01@openssh.com', its CA may still be RSA.
|
||||||
|
# if hostkey_type.startswith('ssh-rsa-cert-v0') or hostkey_type.startswith('ssh-ed25519-cert-v0'):
|
||||||
|
self.out.d("Parsing CA for hostkey type [%s]..." % hostkey_type)
|
||||||
|
|
||||||
# Skip over the serial number.
|
# Skip over the serial number.
|
||||||
ptr += 8
|
ptr += 8
|
||||||
|
|
||||||
@ -142,10 +166,10 @@ class KexDH: # pragma: nocover
|
|||||||
|
|
||||||
# Skip the key ID (this is the serial number of the
|
# Skip the key ID (this is the serial number of the
|
||||||
# certificate).
|
# certificate).
|
||||||
key_id, key_id_len, ptr = KexDH.__get_bytes(hostkey, ptr)
|
key_id, key_id_len, ptr = KexDH.__get_bytes(hostkey, ptr) # pylint: disable=unused-variable
|
||||||
|
|
||||||
# The principles, which are... I don't know what.
|
# The principles, which are... I don't know what.
|
||||||
principles, principles_len, ptr = KexDH.__get_bytes(hostkey, ptr)
|
principles, principles_len, ptr = KexDH.__get_bytes(hostkey, ptr) # pylint: disable=unused-variable
|
||||||
|
|
||||||
# Skip over the timestamp that this certificate is valid after.
|
# Skip over the timestamp that this certificate is valid after.
|
||||||
ptr += 8
|
ptr += 8
|
||||||
@ -156,16 +180,16 @@ class KexDH: # pragma: nocover
|
|||||||
# TODO: validate the principles, and time range.
|
# TODO: validate the principles, and time range.
|
||||||
|
|
||||||
# The critical options.
|
# The critical options.
|
||||||
critical_options, critical_options_len, ptr = KexDH.__get_bytes(hostkey, ptr)
|
critical_options, critical_options_len, ptr = KexDH.__get_bytes(hostkey, ptr) # pylint: disable=unused-variable
|
||||||
|
|
||||||
# Certificate extensions.
|
# Certificate extensions.
|
||||||
extensions, extensions_len, ptr = KexDH.__get_bytes(hostkey, ptr)
|
extensions, extensions_len, ptr = KexDH.__get_bytes(hostkey, ptr) # pylint: disable=unused-variable
|
||||||
|
|
||||||
# Another nonce.
|
# Another nonce.
|
||||||
nonce, nonce_len, ptr = KexDH.__get_bytes(hostkey, ptr)
|
nonce, nonce_len, ptr = KexDH.__get_bytes(hostkey, ptr) # pylint: disable=unused-variable
|
||||||
|
|
||||||
# Finally, we get to the CA key.
|
# Finally, we get to the CA key.
|
||||||
ca_key, ca_key_len, ptr = KexDH.__get_bytes(hostkey, ptr)
|
ca_key, ca_key_len, ptr = KexDH.__get_bytes(hostkey, ptr) # pylint: disable=unused-variable
|
||||||
|
|
||||||
# Last in the host key blob is the CA signature. It isn't
|
# Last in the host key blob is the CA signature. It isn't
|
||||||
# interesting to us, so we won't bother parsing any further.
|
# interesting to us, so we won't bother parsing any further.
|
||||||
@ -173,15 +197,24 @@ class KexDH: # pragma: nocover
|
|||||||
ptr = 0
|
ptr = 0
|
||||||
|
|
||||||
# 'ssh-rsa', 'rsa-sha2-256', etc.
|
# 'ssh-rsa', 'rsa-sha2-256', etc.
|
||||||
ca_key_type, ca_key_type_len, ptr = KexDH.__get_bytes(ca_key, ptr)
|
ca_key_type_bytes, ca_key_type_len, ptr = KexDH.__get_bytes(ca_key, ptr) # pylint: disable=unused-variable
|
||||||
|
ca_key_type = ca_key_type_bytes.decode('ascii')
|
||||||
|
self.out.d("Found CA type: [%s]" % ca_key_type)
|
||||||
|
|
||||||
|
# ED25519 CA's don't explicitly include the modulus size in the public key, since its fixed at 32 in all cases.
|
||||||
|
if ca_key_type == 'ssh-ed25519':
|
||||||
|
ca_key_n_len = 32
|
||||||
|
else:
|
||||||
# CA's public key exponent.
|
# CA's public key exponent.
|
||||||
ca_key_e, ca_key_e_len, ptr = KexDH.__get_bytes(ca_key, ptr)
|
ca_key_e, ca_key_e_len, ptr = KexDH.__get_bytes(ca_key, ptr) # pylint: disable=unused-variable
|
||||||
|
|
||||||
# CA's modulus. Bingo.
|
# CA's modulus. Bingo.
|
||||||
ca_key_n, self.__ca_n_len, ptr = KexDH.__get_bytes(ca_key, ptr)
|
ca_key_n, ca_key_n_len, ptr = KexDH.__get_bytes(ca_key, ptr) # pylint: disable=unused-variable
|
||||||
|
|
||||||
return hostkey
|
else:
|
||||||
|
self.out.d("Certificate type %u found; this is not usually valid in the context of a host key! Skipping it..." % cert_type)
|
||||||
|
|
||||||
|
return ca_key_type, ca_key_n_len
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def __get_bytes(buf: bytes, ptr: int) -> Tuple[bytes, int, int]:
|
def __get_bytes(buf: bytes, ptr: int) -> Tuple[bytes, int, int]:
|
||||||
@ -202,10 +235,18 @@ class KexDH: # pragma: nocover
|
|||||||
size = size - 8
|
size = size - 8
|
||||||
return size
|
return size
|
||||||
|
|
||||||
|
# Returns the hostkey type.
|
||||||
|
def get_hostkey_type(self) -> str:
|
||||||
|
return self.__hostkey_type
|
||||||
|
|
||||||
# Returns the size of the hostkey, in bits.
|
# Returns the size of the hostkey, in bits.
|
||||||
def get_hostkey_size(self) -> int:
|
def get_hostkey_size(self) -> int:
|
||||||
return KexDH.__adjust_key_size(self.__hostkey_n_len)
|
return KexDH.__adjust_key_size(self.__hostkey_n_len)
|
||||||
|
|
||||||
|
# Returns the CA type ('ssh-rsa', 'ssh-ed25519', etc).
|
||||||
|
def get_ca_type(self) -> str:
|
||||||
|
return self.__ca_key_type
|
||||||
|
|
||||||
# Returns the size of the CA key, in bits.
|
# Returns the size of the CA key, in bits.
|
||||||
def get_ca_size(self) -> int:
|
def get_ca_size(self) -> int:
|
||||||
return KexDH.__adjust_key_size(self.__ca_n_len)
|
return KexDH.__adjust_key_size(self.__ca_n_len)
|
||||||
@ -217,46 +258,46 @@ class KexDH: # pragma: nocover
|
|||||||
|
|
||||||
|
|
||||||
class KexGroup1(KexDH): # pragma: nocover
|
class KexGroup1(KexDH): # pragma: nocover
|
||||||
def __init__(self) -> None:
|
def __init__(self, out: 'OutputBuffer') -> None:
|
||||||
# rfc2409: second oakley group
|
# rfc2409: second oakley group
|
||||||
p = int('ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece65381ffffffffffffffff', 16)
|
p = int('ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece65381ffffffffffffffff', 16)
|
||||||
super(KexGroup1, self).__init__('KexGroup1', 'sha1', 2, p)
|
super(KexGroup1, self).__init__(out, 'KexGroup1', 'sha1', 2, p)
|
||||||
|
|
||||||
|
|
||||||
class KexGroup14(KexDH): # pragma: nocover
|
class KexGroup14(KexDH): # pragma: nocover
|
||||||
def __init__(self, hash_alg: str) -> None:
|
def __init__(self, out: 'OutputBuffer', hash_alg: str) -> None:
|
||||||
# rfc3526: 2048-bit modp group
|
# rfc3526: 2048-bit modp group
|
||||||
p = int('ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aacaa68ffffffffffffffff', 16)
|
p = int('ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aacaa68ffffffffffffffff', 16)
|
||||||
super(KexGroup14, self).__init__('KexGroup14', hash_alg, 2, p)
|
super(KexGroup14, self).__init__(out, 'KexGroup14', hash_alg, 2, p)
|
||||||
|
|
||||||
|
|
||||||
class KexGroup14_SHA1(KexGroup14):
|
class KexGroup14_SHA1(KexGroup14):
|
||||||
def __init__(self) -> None:
|
def __init__(self, out: 'OutputBuffer') -> None:
|
||||||
super(KexGroup14_SHA1, self).__init__('sha1')
|
super(KexGroup14_SHA1, self).__init__(out, 'sha1')
|
||||||
|
|
||||||
|
|
||||||
class KexGroup14_SHA256(KexGroup14):
|
class KexGroup14_SHA256(KexGroup14):
|
||||||
def __init__(self) -> None:
|
def __init__(self, out: 'OutputBuffer') -> None:
|
||||||
super(KexGroup14_SHA256, self).__init__('sha256')
|
super(KexGroup14_SHA256, self).__init__(out, 'sha256')
|
||||||
|
|
||||||
|
|
||||||
class KexGroup16_SHA512(KexDH):
|
class KexGroup16_SHA512(KexDH):
|
||||||
def __init__(self) -> None:
|
def __init__(self, out: 'OutputBuffer') -> None:
|
||||||
# rfc3526: 4096-bit modp group
|
# rfc3526: 4096-bit modp group
|
||||||
p = int('ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c934063199ffffffffffffffff', 16)
|
p = int('ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c934063199ffffffffffffffff', 16)
|
||||||
super(KexGroup16_SHA512, self).__init__('KexGroup16_SHA512', 'sha512', 2, p)
|
super(KexGroup16_SHA512, self).__init__(out, 'KexGroup16_SHA512', 'sha512', 2, p)
|
||||||
|
|
||||||
|
|
||||||
class KexGroup18_SHA512(KexDH):
|
class KexGroup18_SHA512(KexDH):
|
||||||
def __init__(self) -> None:
|
def __init__(self, out: 'OutputBuffer') -> None:
|
||||||
# rfc3526: 8192-bit modp group
|
# rfc3526: 8192-bit modp group
|
||||||
p = int('ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c93402849236c3fab4d27c7026c1d4dcb2602646dec9751e763dba37bdf8ff9406ad9e530ee5db382f413001aeb06a53ed9027d831179727b0865a8918da3edbebcf9b14ed44ce6cbaced4bb1bdb7f1447e6cc254b332051512bd7af426fb8f401378cd2bf5983ca01c64b92ecf032ea15d1721d03f482d7ce6e74fef6d55e702f46980c82b5a84031900b1c9e59e7c97fbec7e8f323a97a7e36cc88be0f1d45b7ff585ac54bd407b22b4154aacc8f6d7ebf48e1d814cc5ed20f8037e0a79715eef29be32806a1d58bb7c5da76f550aa3d8a1fbff0eb19ccb1a313d55cda56c9ec2ef29632387fe8d76e3c0468043e8f663f4860ee12bf2d5b0b7474d6e694f91e6dbe115974a3926f12fee5e438777cb6a932df8cd8bec4d073b931ba3bc832b68d9dd300741fa7bf8afc47ed2576f6936ba424663aab639c5ae4f5683423b4742bf1c978238f16cbe39d652de3fdb8befc848ad922222e04a4037c0713eb57a81a23f0c73473fc646cea306b4bcbc8862f8385ddfa9d4b7fa2c087e879683303ed5bdd3a062b3cf5b3a278a66d2a13f83f44f82ddf310ee074ab6a364597e899a0255dc164f31cc50846851df9ab48195ded7ea1b1d510bd7ee74d73faf36bc31ecfa268359046f4eb879f924009438b481c6cd7889a002ed5ee382bc9190da6fc026e479558e4475677e9aa9e3050e2765694dfc81f56e880b96e7160c980dd98edd3dfffffffffffffffff', 16)
|
p = int('ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c93402849236c3fab4d27c7026c1d4dcb2602646dec9751e763dba37bdf8ff9406ad9e530ee5db382f413001aeb06a53ed9027d831179727b0865a8918da3edbebcf9b14ed44ce6cbaced4bb1bdb7f1447e6cc254b332051512bd7af426fb8f401378cd2bf5983ca01c64b92ecf032ea15d1721d03f482d7ce6e74fef6d55e702f46980c82b5a84031900b1c9e59e7c97fbec7e8f323a97a7e36cc88be0f1d45b7ff585ac54bd407b22b4154aacc8f6d7ebf48e1d814cc5ed20f8037e0a79715eef29be32806a1d58bb7c5da76f550aa3d8a1fbff0eb19ccb1a313d55cda56c9ec2ef29632387fe8d76e3c0468043e8f663f4860ee12bf2d5b0b7474d6e694f91e6dbe115974a3926f12fee5e438777cb6a932df8cd8bec4d073b931ba3bc832b68d9dd300741fa7bf8afc47ed2576f6936ba424663aab639c5ae4f5683423b4742bf1c978238f16cbe39d652de3fdb8befc848ad922222e04a4037c0713eb57a81a23f0c73473fc646cea306b4bcbc8862f8385ddfa9d4b7fa2c087e879683303ed5bdd3a062b3cf5b3a278a66d2a13f83f44f82ddf310ee074ab6a364597e899a0255dc164f31cc50846851df9ab48195ded7ea1b1d510bd7ee74d73faf36bc31ecfa268359046f4eb879f924009438b481c6cd7889a002ed5ee382bc9190da6fc026e479558e4475677e9aa9e3050e2765694dfc81f56e880b96e7160c980dd98edd3dfffffffffffffffff', 16)
|
||||||
super(KexGroup18_SHA512, self).__init__('KexGroup18_SHA512', 'sha512', 2, p)
|
super(KexGroup18_SHA512, self).__init__(out, 'KexGroup18_SHA512', 'sha512', 2, p)
|
||||||
|
|
||||||
|
|
||||||
class KexCurve25519_SHA256(KexDH):
|
class KexCurve25519_SHA256(KexDH):
|
||||||
def __init__(self) -> None:
|
def __init__(self, out: 'OutputBuffer') -> None:
|
||||||
super(KexCurve25519_SHA256, self).__init__('KexCurve25519_SHA256', 'sha256', 0, 0)
|
super(KexCurve25519_SHA256, self).__init__(out, 'KexCurve25519_SHA256', 'sha256', 0, 0)
|
||||||
|
|
||||||
# To start an ED25519 kex, we simply send a random 256-bit number as the
|
# To start an ED25519 kex, we simply send a random 256-bit number as the
|
||||||
# public key.
|
# public key.
|
||||||
@ -268,8 +309,8 @@ class KexCurve25519_SHA256(KexDH):
|
|||||||
|
|
||||||
|
|
||||||
class KexNISTP256(KexDH):
|
class KexNISTP256(KexDH):
|
||||||
def __init__(self) -> None:
|
def __init__(self, out: 'OutputBuffer') -> None:
|
||||||
super(KexNISTP256, self).__init__('KexNISTP256', 'sha256', 0, 0)
|
super(KexNISTP256, self).__init__(out, 'KexNISTP256', 'sha256', 0, 0)
|
||||||
|
|
||||||
# Because the server checks that the value sent here is valid (i.e.: it lies
|
# Because the server checks that the value sent here is valid (i.e.: it lies
|
||||||
# on the curve, among other things), we would have to write a lot of code
|
# on the curve, among other things), we would have to write a lot of code
|
||||||
@ -283,8 +324,8 @@ class KexNISTP256(KexDH):
|
|||||||
|
|
||||||
|
|
||||||
class KexNISTP384(KexDH):
|
class KexNISTP384(KexDH):
|
||||||
def __init__(self) -> None:
|
def __init__(self, out: 'OutputBuffer') -> None:
|
||||||
super(KexNISTP384, self).__init__('KexNISTP384', 'sha256', 0, 0)
|
super(KexNISTP384, self).__init__(out, 'KexNISTP384', 'sha256', 0, 0)
|
||||||
|
|
||||||
# See comment for KexNISTP256.send_init().
|
# See comment for KexNISTP256.send_init().
|
||||||
def send_init(self, s: 'SSH_Socket', init_msg: int = Protocol.MSG_KEXDH_INIT) -> None:
|
def send_init(self, s: 'SSH_Socket', init_msg: int = Protocol.MSG_KEXDH_INIT) -> None:
|
||||||
@ -294,8 +335,8 @@ class KexNISTP384(KexDH):
|
|||||||
|
|
||||||
|
|
||||||
class KexNISTP521(KexDH):
|
class KexNISTP521(KexDH):
|
||||||
def __init__(self) -> None:
|
def __init__(self, out: 'OutputBuffer') -> None:
|
||||||
super(KexNISTP521, self).__init__('KexNISTP521', 'sha256', 0, 0)
|
super(KexNISTP521, self).__init__(out, 'KexNISTP521', 'sha256', 0, 0)
|
||||||
|
|
||||||
# See comment for KexNISTP256.send_init().
|
# See comment for KexNISTP256.send_init().
|
||||||
def send_init(self, s: 'SSH_Socket', init_msg: int = Protocol.MSG_KEXDH_INIT) -> None:
|
def send_init(self, s: 'SSH_Socket', init_msg: int = Protocol.MSG_KEXDH_INIT) -> None:
|
||||||
@ -305,8 +346,8 @@ class KexNISTP521(KexDH):
|
|||||||
|
|
||||||
|
|
||||||
class KexGroupExchange(KexDH):
|
class KexGroupExchange(KexDH):
|
||||||
def __init__(self, classname: str, hash_alg: str) -> None:
|
def __init__(self, out: 'OutputBuffer', classname: str, hash_alg: str) -> None:
|
||||||
super(KexGroupExchange, self).__init__(classname, hash_alg, 0, 0)
|
super(KexGroupExchange, self).__init__(out, classname, hash_alg, 0, 0)
|
||||||
|
|
||||||
def send_init(self, s: 'SSH_Socket', init_msg: int = Protocol.MSG_KEXDH_GEX_REQUEST) -> None:
|
def send_init(self, s: 'SSH_Socket', init_msg: int = Protocol.MSG_KEXDH_GEX_REQUEST) -> None:
|
||||||
self.send_init_gex(s)
|
self.send_init_gex(s)
|
||||||
@ -328,8 +369,7 @@ class KexGroupExchange(KexDH):
|
|||||||
|
|
||||||
packet_type, payload = s.read_packet(2)
|
packet_type, payload = s.read_packet(2)
|
||||||
if packet_type not in [Protocol.MSG_KEXDH_GEX_GROUP, Protocol.MSG_DEBUG]:
|
if packet_type not in [Protocol.MSG_KEXDH_GEX_GROUP, Protocol.MSG_DEBUG]:
|
||||||
# TODO: replace with a better exception type.
|
raise KexDHException('Expected MSG_KEXDH_GEX_REPLY (%d), but got %d instead.' % (Protocol.MSG_KEXDH_GEX_REPLY, packet_type))
|
||||||
raise Exception('Expected MSG_KEXDH_GEX_REPLY (%d), but got %d instead.' % (Protocol.MSG_KEXDH_GEX_REPLY, packet_type))
|
|
||||||
|
|
||||||
# Skip any & all MSG_DEBUG messages.
|
# Skip any & all MSG_DEBUG messages.
|
||||||
while packet_type == Protocol.MSG_DEBUG:
|
while packet_type == Protocol.MSG_DEBUG:
|
||||||
@ -356,10 +396,10 @@ class KexGroupExchange(KexDH):
|
|||||||
|
|
||||||
|
|
||||||
class KexGroupExchange_SHA1(KexGroupExchange):
|
class KexGroupExchange_SHA1(KexGroupExchange):
|
||||||
def __init__(self) -> None:
|
def __init__(self, out: 'OutputBuffer') -> None:
|
||||||
super(KexGroupExchange_SHA1, self).__init__('KexGroupExchange_SHA1', 'sha1')
|
super(KexGroupExchange_SHA1, self).__init__(out, 'KexGroupExchange_SHA1', 'sha1')
|
||||||
|
|
||||||
|
|
||||||
class KexGroupExchange_SHA256(KexGroupExchange):
|
class KexGroupExchange_SHA256(KexGroupExchange):
|
||||||
def __init__(self) -> None:
|
def __init__(self, out: 'OutputBuffer') -> None:
|
||||||
super(KexGroupExchange_SHA256, self).__init__('KexGroupExchange_SHA256', 'sha256')
|
super(KexGroupExchange_SHA256, self).__init__(out, 'KexGroupExchange_SHA256', 'sha256')
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"""
|
"""
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (C) 2020-2021 Joe Testa (jtesta@positronsecurity.com)
|
Copyright (C) 2020-2023 Joe Testa (jtesta@positronsecurity.com)
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -21,6 +21,8 @@
|
|||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
"""
|
"""
|
||||||
|
import copy
|
||||||
|
import json
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from typing import Dict, List, Tuple
|
from typing import Dict, List, Tuple
|
||||||
@ -28,62 +30,80 @@ from typing import Optional, Any, Union, cast
|
|||||||
from datetime import date
|
from datetime import date
|
||||||
|
|
||||||
from ssh_audit import exitcodes
|
from ssh_audit import exitcodes
|
||||||
from ssh_audit.ssh2_kex import SSH2_Kex # pylint: disable=unused-import
|
from ssh_audit.banner import Banner
|
||||||
from ssh_audit.banner import Banner # pylint: disable=unused-import
|
from ssh_audit.globals import SNAP_PACKAGE, SNAP_PERMISSIONS_ERROR
|
||||||
|
from ssh_audit.ssh2_kex import SSH2_Kex
|
||||||
|
|
||||||
|
|
||||||
# Validates policy files and performs policy testing
|
# Validates policy files and performs policy testing
|
||||||
class Policy:
|
class Policy:
|
||||||
|
|
||||||
# Each field maps directly to a private member variable of the Policy class.
|
# Each field maps directly to a private member variable of the Policy class.
|
||||||
BUILTIN_POLICIES: Dict[str, Dict[str, Union[Optional[str], Optional[List[str]], bool, Dict[str, int]]]] = {
|
BUILTIN_POLICIES: Dict[str, Dict[str, Union[Optional[str], Optional[List[str]], bool, Dict[str, Any]]]] = {
|
||||||
|
|
||||||
# Ubuntu Server policies
|
# Ubuntu Server policies
|
||||||
|
|
||||||
'Hardened Ubuntu Server 16.04 LTS (version 1)': {'version': '1', 'banner': None, 'compressions': None, 'host_keys': ['ssh-ed25519'], 'optional_host_keys': ['ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['curve25519-sha256@libssh.org', 'diffie-hellman-group-exchange-sha256'], '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, 'cakey_sizes': None, 'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 2048}, 'server_policy': True},
|
'Hardened Ubuntu Server 16.04 LTS (version 2)': {'version': '2', 'banner': None, 'compressions': None, 'host_keys': ['ssh-ed25519'], 'optional_host_keys': ['ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['curve25519-sha256@libssh.org', 'diffie-hellman-group-exchange-sha256'], '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-cert-v01@openssh.com": {"ca_key_size": 4096, "ca_key_type": "ssh-rsa", "hostkey_size": 4096}, "rsa-sha2-512-cert-v01@openssh.com": {"ca_key_size": 4096, "ca_key_type": "ssh-rsa", "hostkey_size": 4096}, "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': 2048}, 'server_policy': True},
|
||||||
|
|
||||||
'Hardened Ubuntu Server 18.04 LTS (version 1)': {'version': '1', 'banner': None, 'compressions': None, 'host_keys': ['ssh-ed25519'], 'optional_host_keys': ['ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], '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, 'cakey_sizes': None, 'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 2048}, 'server_policy': True},
|
'Hardened Ubuntu Server 18.04 LTS (version 2)': {'version': '2', 'banner': None, 'compressions': None, 'host_keys': ['ssh-ed25519'], 'optional_host_keys': ['ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], '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-cert-v01@openssh.com": {"ca_key_size": 4096, "ca_key_type": "ssh-rsa", "hostkey_size": 4096}, "rsa-sha2-512-cert-v01@openssh.com": {"ca_key_size": 4096, "ca_key_type": "ssh-rsa", "hostkey_size": 4096}, "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': 2048}, 'server_policy': True},
|
||||||
|
|
||||||
'Hardened Ubuntu Server 20.04 LTS (version 1)': {'version': '1', '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': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], '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': 4096, 'rsa-sha2-512': 4096}, 'cakey_sizes': {'rsa-sha2-256-cert-v01@openssh.com': 4096, 'rsa-sha2-512-cert-v01@openssh.com': 4096}, 'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 2048}, 'server_policy': True},
|
'Hardened Ubuntu Server 20.04 LTS (version 2)': {'version': '2', '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': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], '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': 2048}, 'server_policy': True},
|
||||||
|
|
||||||
|
'Hardened Ubuntu Server 22.04 LTS (version 2)': {'version': '2', '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'], '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': 2048}, 'server_policy': True},
|
||||||
|
|
||||||
|
|
||||||
# Generic OpenSSH Server policies
|
# Generic OpenSSH Server policies
|
||||||
|
|
||||||
'Hardened OpenSSH Server v7.7 (version 1)': {'version': '1', 'banner': None, 'compressions': None, 'host_keys': ['rsa-sha2-512', 'rsa-sha2-256', 'ssh-ed25519'], 'optional_host_keys': ['ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], '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, 'cakey_sizes': None, 'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 2048}, 'server_policy': True},
|
'Hardened OpenSSH Server v7.7 (version 2)': {'version': '2', 'banner': None, 'compressions': None, 'host_keys': ['rsa-sha2-512', 'rsa-sha2-256', 'ssh-ed25519'], 'optional_host_keys': ['ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], '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}, "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': 2048}, 'server_policy': True},
|
||||||
|
|
||||||
'Hardened OpenSSH Server v7.8 (version 1)': {'version': '1', 'banner': None, 'compressions': None, 'host_keys': ['rsa-sha2-512', 'rsa-sha2-256', 'ssh-ed25519'], 'optional_host_keys': ['ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], '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, 'cakey_sizes': None, 'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 2048}, 'server_policy': True},
|
'Hardened OpenSSH Server v7.8 (version 2)': {'version': '2', 'banner': None, 'compressions': None, 'host_keys': ['rsa-sha2-512', 'rsa-sha2-256', 'ssh-ed25519'], 'optional_host_keys': ['ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], '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}, "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': 2048}, 'server_policy': True},
|
||||||
|
|
||||||
'Hardened OpenSSH Server v7.9 (version 1)': {'version': '1', 'banner': None, 'compressions': None, 'host_keys': ['rsa-sha2-512', 'rsa-sha2-256', 'ssh-ed25519'], 'optional_host_keys': ['ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], '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, 'cakey_sizes': None, 'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 2048}, 'server_policy': True},
|
'Hardened OpenSSH Server v7.9 (version 2)': {'version': '2', 'banner': None, 'compressions': None, 'host_keys': ['rsa-sha2-512', 'rsa-sha2-256', 'ssh-ed25519'], 'optional_host_keys': ['ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], '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}, "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': 2048}, 'server_policy': True},
|
||||||
|
|
||||||
'Hardened OpenSSH Server v8.0 (version 1)': {'version': '1', 'banner': None, 'compressions': None, 'host_keys': ['rsa-sha2-512', 'rsa-sha2-256', 'ssh-ed25519'], 'optional_host_keys': ['ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], '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, 'cakey_sizes': None, 'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 2048}, 'server_policy': True},
|
'Hardened OpenSSH Server v8.0 (version 2)': {'version': '2', 'banner': None, 'compressions': None, 'host_keys': ['rsa-sha2-512', 'rsa-sha2-256', 'ssh-ed25519'], 'optional_host_keys': ['ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], '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}, "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': 2048}, 'server_policy': True},
|
||||||
|
|
||||||
'Hardened OpenSSH Server v8.1 (version 1)': {'version': '1', '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': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], '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, 'cakey_sizes': None, 'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 2048}, 'server_policy': True},
|
'Hardened OpenSSH Server v8.1 (version 2)': {'version': '2', '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': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], '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': 2048}, 'server_policy': True},
|
||||||
|
|
||||||
'Hardened OpenSSH Server v8.2 (version 1)': {'version': '1', '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': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], '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': 4096, 'rsa-sha2-512': 4096}, 'cakey_sizes': {'rsa-sha2-256-cert-v01@openssh.com': 4096, 'rsa-sha2-512-cert-v01@openssh.com': 4096}, 'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 2048}, 'server_policy': True},
|
'Hardened OpenSSH Server v8.2 (version 2)': {'version': '2', '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': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], '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': 2048}, 'server_policy': True},
|
||||||
|
|
||||||
'Hardened OpenSSH Server v8.3 (version 1)': {'version': '1', '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': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], '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': 4096, 'rsa-sha2-512': 4096}, 'cakey_sizes': {'rsa-sha2-256-cert-v01@openssh.com': 4096, 'rsa-sha2-512-cert-v01@openssh.com': 4096}, 'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 2048}, 'server_policy': True},
|
'Hardened OpenSSH Server v8.3 (version 2)': {'version': '2', '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': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], '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': 2048}, 'server_policy': True},
|
||||||
|
|
||||||
'Hardened OpenSSH Server v8.4 (version 1)': {'version': '1', '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': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], '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': 4096, 'rsa-sha2-512': 4096}, 'cakey_sizes': {'rsa-sha2-256-cert-v01@openssh.com': 4096, 'rsa-sha2-512-cert-v01@openssh.com': 4096}, 'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 2048}, 'server_policy': True},
|
'Hardened OpenSSH Server v8.4 (version 2)': {'version': '2', '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': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], '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': 2048}, 'server_policy': True},
|
||||||
|
|
||||||
'Hardened OpenSSH Server v8.5 (version 1)': {'version': '1', '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': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], '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': 4096, 'rsa-sha2-512': 4096}, 'cakey_sizes': {'rsa-sha2-256-cert-v01@openssh.com': 4096, 'rsa-sha2-512-cert-v01@openssh.com': 4096}, 'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 2048}, 'server_policy': True},
|
'Hardened OpenSSH Server v8.5 (version 2)': {'version': '2', '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': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], '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': 2048}, 'server_policy': True},
|
||||||
|
|
||||||
'Hardened OpenSSH Server v8.6 (version 1)': {'version': '1', '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': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], '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': 4096, 'rsa-sha2-512': 4096}, 'cakey_sizes': {'rsa-sha2-256-cert-v01@openssh.com': 4096, 'rsa-sha2-512-cert-v01@openssh.com': 4096}, 'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 2048}, 'server_policy': True},
|
'Hardened OpenSSH Server v8.6 (version 2)': {'version': '2', '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': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], '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': 2048}, 'server_policy': True},
|
||||||
|
|
||||||
'Hardened OpenSSH Server v8.7 (version 1)': {'version': '1', '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': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], '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': 4096, 'rsa-sha2-512': 4096}, 'cakey_sizes': {'rsa-sha2-256-cert-v01@openssh.com': 4096, 'rsa-sha2-512-cert-v01@openssh.com': 4096}, 'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 2048}, 'server_policy': True},
|
'Hardened OpenSSH Server v8.7 (version 2)': {'version': '2', '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': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], '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': 2048}, 'server_policy': True},
|
||||||
|
|
||||||
|
'Hardened OpenSSH Server v8.8 (version 1)': {'version': '1', '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'], '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': 2048}, 'server_policy': True},
|
||||||
|
|
||||||
|
'Hardened OpenSSH Server v8.9 (version 1)': {'version': '1', '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'], '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': 2048}, 'server_policy': True},
|
||||||
|
|
||||||
|
'Hardened OpenSSH Server v9.0 (version 1)': {'version': '1', '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'], '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': 2048}, 'server_policy': True},
|
||||||
|
|
||||||
|
'Hardened OpenSSH Server v9.1 (version 1)': {'version': '1', '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'], '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': 2048}, 'server_policy': True},
|
||||||
|
|
||||||
|
'Hardened OpenSSH Server v9.2 (version 1)': {'version': '1', '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'], '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': 2048}, 'server_policy': True},
|
||||||
|
|
||||||
|
'Hardened OpenSSH Server v9.3 (version 1)': {'version': '1', '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'], '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': 2048}, 'server_policy': True},
|
||||||
|
|
||||||
|
|
||||||
# Ubuntu Client policies
|
# Ubuntu Client policies
|
||||||
|
|
||||||
'Hardened Ubuntu Client 16.04 LTS (version 2)': {'version': '2', 'banner': None, 'compressions': None, 'host_keys': ['ssh-ed25519', 'ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256', 'rsa-sha2-512'], 'optional_host_keys': None, 'kex': ['curve25519-sha256@libssh.org', 'diffie-hellman-group-exchange-sha256', 'ext-info-c'], '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, 'cakey_sizes': None, 'dh_modulus_sizes': None, 'server_policy': False},
|
'Hardened Ubuntu Client 16.04 LTS (version 2)': {'version': '2', 'banner': None, 'compressions': None, 'host_keys': ['ssh-ed25519', 'ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256', 'rsa-sha2-512'], 'optional_host_keys': None, 'kex': ['curve25519-sha256@libssh.org', 'diffie-hellman-group-exchange-sha256', 'ext-info-c'], '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 18.04 LTS (version 2)': {'version': '2', 'banner': None, 'compressions': None, 'host_keys': ['ssh-ed25519', 'ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256', 'rsa-sha2-512'], 'optional_host_keys': None, 'kex': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256', 'ext-info-c'], '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, 'cakey_sizes': None, 'dh_modulus_sizes': None, 'server_policy': False},
|
'Hardened Ubuntu Client 18.04 LTS (version 2)': {'version': '2', 'banner': None, 'compressions': None, 'host_keys': ['ssh-ed25519', 'ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256', 'rsa-sha2-512'], 'optional_host_keys': None, 'kex': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256', 'ext-info-c'], '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 20.04 LTS (version 2)': {'version': '2', 'banner': None, 'compressions': None, 'host_keys': ['ssh-ed25519', 'ssh-ed25519-cert-v01@openssh.com', 'sk-ssh-ed25519@openssh.com', 'sk-ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512', 'rsa-sha2-512-cert-v01@openssh.com'], 'optional_host_keys': None, 'kex': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256', 'ext-info-c'], '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, 'cakey_sizes': None, 'dh_modulus_sizes': None, 'server_policy': False},
|
'Hardened Ubuntu Client 20.04 LTS (version 2)': {'version': '2', 'banner': None, 'compressions': None, 'host_keys': ['ssh-ed25519', 'ssh-ed25519-cert-v01@openssh.com', 'sk-ssh-ed25519@openssh.com', 'sk-ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512', 'rsa-sha2-512-cert-v01@openssh.com'], 'optional_host_keys': None, 'kex': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256', 'ext-info-c'], '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 1)': {'version': '1', 'banner': None, 'compressions': None, 'host_keys': ['ssh-ed25519', 'ssh-ed25519-cert-v01@openssh.com', 'sk-ssh-ed25519@openssh.com', 'sk-ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512', 'rsa-sha2-512-cert-v01@openssh.com'], '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'], '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},
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WARNING_DEPRECATED_DIRECTIVES = "\nWARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.\n"
|
||||||
|
|
||||||
def __init__(self, policy_file: Optional[str] = None, policy_data: Optional[str] = None, manual_load: bool = False) -> None:
|
def __init__(self, policy_file: Optional[str] = None, policy_data: Optional[str] = None, manual_load: bool = False, json_output: bool = False) -> None:
|
||||||
self._name: Optional[str] = None
|
self._name: Optional[str] = None
|
||||||
self._version: Optional[str] = None
|
self._version: Optional[str] = None
|
||||||
self._banner: Optional[str] = None
|
self._banner: Optional[str] = None
|
||||||
@ -93,13 +113,18 @@ class Policy:
|
|||||||
self._kex: Optional[List[str]] = None
|
self._kex: Optional[List[str]] = None
|
||||||
self._ciphers: Optional[List[str]] = None
|
self._ciphers: Optional[List[str]] = None
|
||||||
self._macs: Optional[List[str]] = None
|
self._macs: Optional[List[str]] = None
|
||||||
self._hostkey_sizes: Optional[Dict[str, int]] = None
|
self._hostkey_sizes: Optional[Dict[str, Dict[str, Union[int, str, bytes]]]] = None
|
||||||
self._cakey_sizes: Optional[Dict[str, int]] = None
|
|
||||||
self._dh_modulus_sizes: Optional[Dict[str, int]] = None
|
self._dh_modulus_sizes: Optional[Dict[str, int]] = None
|
||||||
self._server_policy = True
|
self._server_policy = True
|
||||||
|
|
||||||
self._name_and_version: str = ''
|
self._name_and_version: str = ''
|
||||||
|
|
||||||
|
# If invoked while JSON output is expected, send warnings to stderr instead of stdout (which would corrupt the JSON output).
|
||||||
|
if json_output:
|
||||||
|
self._warning_target = sys.stderr
|
||||||
|
else:
|
||||||
|
self._warning_target = sys.stdout
|
||||||
|
|
||||||
# Ensure that only one mode was specified.
|
# Ensure that only one mode was specified.
|
||||||
num_modes = 0
|
num_modes = 0
|
||||||
if policy_file is not None:
|
if policy_file is not None:
|
||||||
@ -122,6 +147,13 @@ class Policy:
|
|||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
print("Error: policy file not found: %s" % policy_file)
|
print("Error: policy file not found: %s" % policy_file)
|
||||||
sys.exit(exitcodes.UNKNOWN_ERROR)
|
sys.exit(exitcodes.UNKNOWN_ERROR)
|
||||||
|
except PermissionError as e:
|
||||||
|
# If installed as a Snap package, print a more useful message with potential work-arounds.
|
||||||
|
if SNAP_PACKAGE:
|
||||||
|
print(SNAP_PERMISSIONS_ERROR)
|
||||||
|
else:
|
||||||
|
print("Error: insufficient permissions: %s" % str(e))
|
||||||
|
sys.exit(exitcodes.UNKNOWN_ERROR)
|
||||||
|
|
||||||
lines = []
|
lines = []
|
||||||
if policy_data is not None:
|
if policy_data is not None:
|
||||||
@ -142,7 +174,7 @@ class Policy:
|
|||||||
key = key.strip()
|
key = key.strip()
|
||||||
val = val.strip()
|
val = val.strip()
|
||||||
|
|
||||||
if key not in ['name', 'version', 'banner', 'compressions', 'host keys', 'optional host keys', 'key exchanges', 'ciphers', 'macs', 'client policy'] and not key.startswith('hostkey_size_') and not key.startswith('cakey_size_') and not key.startswith('dh_modulus_size_'):
|
if key not in ['name', 'version', 'banner', 'compressions', 'host keys', 'optional host keys', 'key exchanges', 'ciphers', 'macs', 'client policy', 'host_key_sizes', 'dh_modulus_sizes'] and not key.startswith('hostkey_size_') and not key.startswith('cakey_size_') and not key.startswith('dh_modulus_size_'):
|
||||||
raise ValueError("invalid field found in policy: %s" % line)
|
raise ValueError("invalid field found in policy: %s" % line)
|
||||||
|
|
||||||
if key in ['name', 'banner']:
|
if key in ['name', 'banner']:
|
||||||
@ -161,8 +193,10 @@ class Policy:
|
|||||||
self._name = val
|
self._name = val
|
||||||
elif key == 'banner':
|
elif key == 'banner':
|
||||||
self._banner = val
|
self._banner = val
|
||||||
|
|
||||||
elif key == 'version':
|
elif key == 'version':
|
||||||
self._version = val
|
self._version = val
|
||||||
|
|
||||||
elif key in ['compressions', 'host keys', 'optional host keys', 'key exchanges', 'ciphers', 'macs']:
|
elif key in ['compressions', 'host keys', 'optional host keys', 'key exchanges', 'ciphers', 'macs']:
|
||||||
try:
|
try:
|
||||||
algs = val.split(',')
|
algs = val.split(',')
|
||||||
@ -185,21 +219,52 @@ class Policy:
|
|||||||
self._ciphers = algs
|
self._ciphers = algs
|
||||||
elif key == 'macs':
|
elif key == 'macs':
|
||||||
self._macs = algs
|
self._macs = algs
|
||||||
elif key.startswith('hostkey_size_'):
|
|
||||||
|
elif key.startswith('hostkey_size_'): # Old host key size format.
|
||||||
|
print(Policy.WARNING_DEPRECATED_DIRECTIVES, file=self._warning_target) # Warn the user that the policy file is using deprecated directives.
|
||||||
|
|
||||||
hostkey_type = key[13:]
|
hostkey_type = key[13:]
|
||||||
|
hostkey_size = int(val)
|
||||||
|
|
||||||
if self._hostkey_sizes is None:
|
if self._hostkey_sizes is None:
|
||||||
self._hostkey_sizes = {}
|
self._hostkey_sizes = {}
|
||||||
self._hostkey_sizes[hostkey_type] = int(val)
|
|
||||||
elif key.startswith('cakey_size_'):
|
self._hostkey_sizes[hostkey_type] = {'hostkey_size': hostkey_size, 'ca_key_type': '', 'ca_key_size': 0}
|
||||||
cakey_type = key[11:]
|
|
||||||
if self._cakey_sizes is None:
|
elif key.startswith('cakey_size_'): # Old host key size format.
|
||||||
self._cakey_sizes = {}
|
print(Policy.WARNING_DEPRECATED_DIRECTIVES, file=self._warning_target) # Warn the user that the policy file is using deprecated directives.
|
||||||
self._cakey_sizes[cakey_type] = int(val)
|
|
||||||
elif key.startswith('dh_modulus_size_'):
|
hostkey_type = key[11:]
|
||||||
dh_modulus_type = key[16:]
|
ca_key_size = int(val)
|
||||||
|
|
||||||
|
ca_key_type = 'ssh-ed25519'
|
||||||
|
if hostkey_type in ['ssh-rsa-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com']:
|
||||||
|
ca_key_type = 'ssh-rsa'
|
||||||
|
|
||||||
|
if self._hostkey_sizes is None:
|
||||||
|
self._hostkey_sizes = {}
|
||||||
|
self._hostkey_sizes[hostkey_type] = {'hostkey_size': hostkey_size, 'ca_key_type': ca_key_type, 'ca_key_size': ca_key_size}
|
||||||
|
|
||||||
|
elif key == 'host_key_sizes': # New host key size format.
|
||||||
|
self._hostkey_sizes = json.loads(val)
|
||||||
|
|
||||||
|
# Fill in the trimmed fields that were omitted from the policy.
|
||||||
|
self._normalize_hostkey_sizes()
|
||||||
|
|
||||||
|
elif key.startswith('dh_modulus_size_'): # Old DH modulus format.
|
||||||
|
print(Policy.WARNING_DEPRECATED_DIRECTIVES, file=self._warning_target) # Warn the user that the policy file is using deprecated directives.
|
||||||
|
|
||||||
|
dh_type = key[16:]
|
||||||
|
dh_size = int(val)
|
||||||
|
|
||||||
if self._dh_modulus_sizes is None:
|
if self._dh_modulus_sizes is None:
|
||||||
self._dh_modulus_sizes = {}
|
self._dh_modulus_sizes = {}
|
||||||
self._dh_modulus_sizes[dh_modulus_type] = int(val)
|
|
||||||
|
self._dh_modulus_sizes[dh_type] = dh_size
|
||||||
|
|
||||||
|
elif key == 'dh_modulus_sizes': # New DH modulus format.
|
||||||
|
self._dh_modulus_sizes = json.loads(val)
|
||||||
|
|
||||||
elif key.startswith('client policy') and val.lower() == 'true':
|
elif key.startswith('client policy') and val.lower() == 'true':
|
||||||
self._server_policy = False
|
self._server_policy = False
|
||||||
|
|
||||||
@ -221,6 +286,19 @@ class Policy:
|
|||||||
errors.append({'mismatched_field': mismatched_field, 'expected_required': expected_required, 'expected_optional': expected_optional, 'actual': actual})
|
errors.append({'mismatched_field': mismatched_field, 'expected_required': expected_required, 'expected_optional': expected_optional, 'actual': actual})
|
||||||
|
|
||||||
|
|
||||||
|
def _normalize_hostkey_sizes(self) -> None:
|
||||||
|
'''Normalizes the self._hostkey_sizes structure to ensure all required fields are present.'''
|
||||||
|
|
||||||
|
if self._hostkey_sizes is not None:
|
||||||
|
for host_key_type in self._hostkey_sizes:
|
||||||
|
if 'ca_key_type' not in self._hostkey_sizes[host_key_type]:
|
||||||
|
self._hostkey_sizes[host_key_type]['ca_key_type'] = ''
|
||||||
|
if 'ca_key_size' not in self._hostkey_sizes[host_key_type]:
|
||||||
|
self._hostkey_sizes[host_key_type]['ca_key_size'] = 0
|
||||||
|
if 'raw_hostkey_bytes' not in self._hostkey_sizes[host_key_type]:
|
||||||
|
self._hostkey_sizes[host_key_type]['raw_hostkey_bytes'] = b''
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create(source: Optional[str], banner: Optional['Banner'], kex: Optional['SSH2_Kex'], client_audit: bool) -> str:
|
def create(source: Optional[str], banner: Optional['Banner'], kex: Optional['SSH2_Kex'], client_audit: bool) -> str:
|
||||||
'''Creates a policy based on a server configuration. Returns a string.'''
|
'''Creates a policy based on a server configuration. Returns a string.'''
|
||||||
@ -231,10 +309,9 @@ class Policy:
|
|||||||
kex_algs = None
|
kex_algs = None
|
||||||
ciphers = None
|
ciphers = None
|
||||||
macs = None
|
macs = None
|
||||||
rsa_hostkey_sizes_str = ''
|
|
||||||
rsa_cakey_sizes_str = ''
|
|
||||||
dh_modulus_sizes_str = ''
|
dh_modulus_sizes_str = ''
|
||||||
client_policy_str = ''
|
client_policy_str = ''
|
||||||
|
host_keys_json = ''
|
||||||
|
|
||||||
if client_audit:
|
if client_audit:
|
||||||
client_policy_str = "\n# Set to true to signify this is a policy for clients, not servers.\nclient policy = true\n"
|
client_policy_str = "\n# Set to true to signify this is a policy for clients, not servers.\nclient policy = true\n"
|
||||||
@ -250,26 +327,23 @@ class Policy:
|
|||||||
ciphers = ', '.join(kex.server.encryption)
|
ciphers = ', '.join(kex.server.encryption)
|
||||||
if kex.server.mac is not None:
|
if kex.server.mac is not None:
|
||||||
macs = ', '.join(kex.server.mac)
|
macs = ', '.join(kex.server.mac)
|
||||||
if kex.rsa_key_sizes():
|
|
||||||
rsa_key_sizes_dict = kex.rsa_key_sizes()
|
|
||||||
for host_key_type in sorted(rsa_key_sizes_dict):
|
|
||||||
hostkey_size, cakey_size = rsa_key_sizes_dict[host_key_type]
|
|
||||||
|
|
||||||
rsa_hostkey_sizes_str = "%shostkey_size_%s = %d\n" % (rsa_hostkey_sizes_str, host_key_type, hostkey_size)
|
if kex.host_keys():
|
||||||
if cakey_size != -1:
|
|
||||||
rsa_cakey_sizes_str = "%scakey_size_%s = %d\n" % (rsa_cakey_sizes_str, host_key_type, cakey_size)
|
# Make a deep copy of the host keys dict, then delete all the raw hostkey bytes from the copy.
|
||||||
|
host_keys_trimmed = copy.deepcopy(kex.host_keys())
|
||||||
|
for hostkey_alg in host_keys_trimmed:
|
||||||
|
del host_keys_trimmed[hostkey_alg]['raw_hostkey_bytes']
|
||||||
|
|
||||||
|
# Delete the CA signature if any of its fields are empty.
|
||||||
|
if host_keys_trimmed[hostkey_alg]['ca_key_type'] == '' or host_keys_trimmed[hostkey_alg]['ca_key_size'] == 0:
|
||||||
|
del host_keys_trimmed[hostkey_alg]['ca_key_type']
|
||||||
|
del host_keys_trimmed[hostkey_alg]['ca_key_size']
|
||||||
|
|
||||||
|
host_keys_json = "\n# Dictionary containing all host key and size information. Optionally contains the certificate authority's signature algorithm ('ca_key_type') and signature length ('ca_key_size'), if any.\nhost_key_sizes = %s\n" % json.dumps(host_keys_trimmed)
|
||||||
|
|
||||||
if len(rsa_hostkey_sizes_str) > 0:
|
|
||||||
rsa_hostkey_sizes_str = "\n# RSA host key sizes.\n%s" % rsa_hostkey_sizes_str
|
|
||||||
if len(rsa_cakey_sizes_str) > 0:
|
|
||||||
rsa_cakey_sizes_str = "\n# RSA CA key sizes.\n%s" % rsa_cakey_sizes_str
|
|
||||||
if kex.dh_modulus_sizes():
|
if kex.dh_modulus_sizes():
|
||||||
dh_modulus_sizes_dict = kex.dh_modulus_sizes()
|
dh_modulus_sizes_str = "\n# Group exchange DH modulus sizes.\ndh_modulus_sizes = %s\n" % json.dumps(kex.dh_modulus_sizes())
|
||||||
for gex_type in sorted(dh_modulus_sizes_dict):
|
|
||||||
modulus_size, _ = dh_modulus_sizes_dict[gex_type]
|
|
||||||
dh_modulus_sizes_str = "%sdh_modulus_size_%s = %d\n" % (dh_modulus_sizes_str, gex_type, modulus_size)
|
|
||||||
if len(dh_modulus_sizes_str) > 0:
|
|
||||||
dh_modulus_sizes_str = "\n# Group exchange DH modulus sizes.\n%s" % dh_modulus_sizes_str
|
|
||||||
|
|
||||||
|
|
||||||
policy_data = '''#
|
policy_data = '''#
|
||||||
@ -287,7 +361,7 @@ version = 1
|
|||||||
|
|
||||||
# The compression options that must match exactly (order matters). Commented out to ignore by default.
|
# The compression options that must match exactly (order matters). Commented out to ignore by default.
|
||||||
# compressions = %s
|
# compressions = %s
|
||||||
%s%s%s
|
%s%s
|
||||||
# The host key types that must match exactly (order matters).
|
# The host key types that must match exactly (order matters).
|
||||||
host keys = %s
|
host keys = %s
|
||||||
|
|
||||||
@ -302,7 +376,7 @@ ciphers = %s
|
|||||||
|
|
||||||
# The MACs that must match exactly (order matters).
|
# The MACs that must match exactly (order matters).
|
||||||
macs = %s
|
macs = %s
|
||||||
''' % (source, today, client_policy_str, source, today, banner, compressions, rsa_hostkey_sizes_str, rsa_cakey_sizes_str, dh_modulus_sizes_str, host_keys, kex_algs, ciphers, macs)
|
''' % (source, today, client_policy_str, source, today, banner, compressions, host_keys_json, dh_modulus_sizes_str, host_keys, kex_algs, ciphers, macs)
|
||||||
|
|
||||||
return policy_data
|
return policy_data
|
||||||
|
|
||||||
@ -339,23 +413,29 @@ macs = %s
|
|||||||
hostkey_types = list(self._hostkey_sizes.keys())
|
hostkey_types = list(self._hostkey_sizes.keys())
|
||||||
hostkey_types.sort() # Sorted to make testing output repeatable.
|
hostkey_types.sort() # Sorted to make testing output repeatable.
|
||||||
for hostkey_type in hostkey_types:
|
for hostkey_type in hostkey_types:
|
||||||
expected_hostkey_size = self._hostkey_sizes[hostkey_type]
|
expected_hostkey_size = self._hostkey_sizes[hostkey_type]['hostkey_size']
|
||||||
if hostkey_type in kex.rsa_key_sizes():
|
server_host_keys = kex.host_keys()
|
||||||
actual_hostkey_size, actual_cakey_size = kex.rsa_key_sizes()[hostkey_type]
|
if hostkey_type in server_host_keys:
|
||||||
|
actual_hostkey_size = server_host_keys[hostkey_type]['hostkey_size']
|
||||||
if actual_hostkey_size != expected_hostkey_size:
|
if actual_hostkey_size != expected_hostkey_size:
|
||||||
ret = False
|
ret = False
|
||||||
self._append_error(errors, 'RSA host key (%s) sizes' % hostkey_type, [str(expected_hostkey_size)], None, [str(actual_hostkey_size)])
|
self._append_error(errors, 'Host key (%s) sizes' % hostkey_type, [str(expected_hostkey_size)], None, [str(actual_hostkey_size)])
|
||||||
|
|
||||||
if self._cakey_sizes is not None:
|
# If we have expected CA signatures set, check them against what the server returned.
|
||||||
hostkey_types = list(self._cakey_sizes.keys())
|
if self._hostkey_sizes is not None and len(cast(str, self._hostkey_sizes[hostkey_type]['ca_key_type'])) > 0 and cast(int, self._hostkey_sizes[hostkey_type]['ca_key_size']) > 0:
|
||||||
hostkey_types.sort() # Sorted to make testing output repeatable.
|
expected_ca_key_type = cast(str, self._hostkey_sizes[hostkey_type]['ca_key_type'])
|
||||||
for hostkey_type in hostkey_types:
|
expected_ca_key_size = cast(int, self._hostkey_sizes[hostkey_type]['ca_key_size'])
|
||||||
expected_cakey_size = self._cakey_sizes[hostkey_type]
|
actual_ca_key_type = cast(str, server_host_keys[hostkey_type]['ca_key_type'])
|
||||||
if hostkey_type in kex.rsa_key_sizes():
|
actual_ca_key_size = cast(int, server_host_keys[hostkey_type]['ca_key_size'])
|
||||||
actual_hostkey_size, actual_cakey_size = kex.rsa_key_sizes()[hostkey_type]
|
|
||||||
if actual_cakey_size != expected_cakey_size:
|
# Ensure that the CA signature type is what's expected (i.e.: the server doesn't have an RSA sig when we're expecting an ED25519 sig).
|
||||||
|
if actual_ca_key_type != expected_ca_key_type:
|
||||||
ret = False
|
ret = False
|
||||||
self._append_error(errors, 'RSA CA key (%s) sizes' % hostkey_type, [str(expected_cakey_size)], None, [str(actual_cakey_size)])
|
self._append_error(errors, 'CA signature type', [expected_ca_key_type], None, [actual_ca_key_type])
|
||||||
|
# Ensure that the actual and expected signature sizes match.
|
||||||
|
elif actual_ca_key_size != expected_ca_key_size:
|
||||||
|
ret = False
|
||||||
|
self._append_error(errors, 'CA signature size (%s)' % actual_ca_key_type, [str(expected_ca_key_size)], None, [str(actual_ca_key_size)])
|
||||||
|
|
||||||
if kex.kex_algorithms != self._kex:
|
if kex.kex_algorithms != self._kex:
|
||||||
ret = False
|
ret = False
|
||||||
@ -375,7 +455,7 @@ macs = %s
|
|||||||
for dh_modulus_type in dh_modulus_types:
|
for dh_modulus_type in dh_modulus_types:
|
||||||
expected_dh_modulus_size = self._dh_modulus_sizes[dh_modulus_type]
|
expected_dh_modulus_size = self._dh_modulus_sizes[dh_modulus_type]
|
||||||
if dh_modulus_type in kex.dh_modulus_sizes():
|
if dh_modulus_type in kex.dh_modulus_sizes():
|
||||||
actual_dh_modulus_size, _ = kex.dh_modulus_sizes()[dh_modulus_type]
|
actual_dh_modulus_size = kex.dh_modulus_sizes()[dh_modulus_type]
|
||||||
if expected_dh_modulus_size != actual_dh_modulus_size:
|
if expected_dh_modulus_size != actual_dh_modulus_size:
|
||||||
ret = False
|
ret = False
|
||||||
self._append_error(errors, 'Group exchange (%s) modulus sizes' % dh_modulus_type, [str(expected_dh_modulus_size)], None, [str(actual_dh_modulus_size)])
|
self._append_error(errors, 'Group exchange (%s) modulus sizes' % dh_modulus_type, [str(expected_dh_modulus_size)], None, [str(actual_dh_modulus_size)])
|
||||||
@ -437,12 +517,12 @@ macs = %s
|
|||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def load_builtin_policy(policy_name: str) -> Optional['Policy']:
|
def load_builtin_policy(policy_name: str, json_output: bool = False) -> Optional['Policy']:
|
||||||
'''Returns a Policy with the specified built-in policy name loaded, or None if no policy of that name exists.'''
|
'''Returns a Policy with the specified built-in policy name loaded, or None if no policy of that name exists.'''
|
||||||
p = None
|
p = None
|
||||||
if policy_name in Policy.BUILTIN_POLICIES:
|
if policy_name in Policy.BUILTIN_POLICIES:
|
||||||
policy_struct = Policy.BUILTIN_POLICIES[policy_name]
|
policy_struct = Policy.BUILTIN_POLICIES[policy_name]
|
||||||
p = Policy(manual_load=True)
|
p = Policy(manual_load=True, json_output=json_output)
|
||||||
policy_name_without_version = policy_name[0:policy_name.rfind(' (')]
|
policy_name_without_version = policy_name[0:policy_name.rfind(' (')]
|
||||||
p._name = policy_name_without_version # pylint: disable=protected-access
|
p._name = policy_name_without_version # pylint: disable=protected-access
|
||||||
p._version = cast(str, policy_struct['version']) # pylint: disable=protected-access
|
p._version = cast(str, policy_struct['version']) # pylint: disable=protected-access
|
||||||
@ -453,13 +533,14 @@ macs = %s
|
|||||||
p._kex = cast(Optional[List[str]], policy_struct['kex']) # pylint: disable=protected-access
|
p._kex = cast(Optional[List[str]], policy_struct['kex']) # pylint: disable=protected-access
|
||||||
p._ciphers = cast(Optional[List[str]], policy_struct['ciphers']) # pylint: disable=protected-access
|
p._ciphers = cast(Optional[List[str]], policy_struct['ciphers']) # pylint: disable=protected-access
|
||||||
p._macs = cast(Optional[List[str]], policy_struct['macs']) # pylint: disable=protected-access
|
p._macs = cast(Optional[List[str]], policy_struct['macs']) # pylint: disable=protected-access
|
||||||
p._hostkey_sizes = cast(Optional[Dict[str, int]], policy_struct['hostkey_sizes']) # pylint: disable=protected-access
|
p._hostkey_sizes = cast(Optional[Dict[str, Dict[str, Union[int, str, bytes]]]], policy_struct['hostkey_sizes']) # pylint: disable=protected-access
|
||||||
p._cakey_sizes = cast(Optional[Dict[str, int]], policy_struct['cakey_sizes']) # pylint: disable=protected-access
|
|
||||||
p._dh_modulus_sizes = cast(Optional[Dict[str, int]], policy_struct['dh_modulus_sizes']) # pylint: disable=protected-access
|
p._dh_modulus_sizes = cast(Optional[Dict[str, int]], policy_struct['dh_modulus_sizes']) # pylint: disable=protected-access
|
||||||
p._server_policy = cast(bool, policy_struct['server_policy']) # pylint: disable=protected-access
|
p._server_policy = cast(bool, policy_struct['server_policy']) # pylint: disable=protected-access
|
||||||
|
|
||||||
p._name_and_version = "%s (version %s)" % (p._name, p._version) # pylint: disable=protected-access
|
p._name_and_version = "%s (version %s)" % (p._name, p._version) # pylint: disable=protected-access
|
||||||
|
|
||||||
|
# Ensure this struct has all the necessary fields.
|
||||||
|
p._normalize_hostkey_sizes() # pylint: disable=protected-access
|
||||||
|
|
||||||
return p
|
return p
|
||||||
|
|
||||||
|
|
||||||
@ -488,7 +569,6 @@ macs = %s
|
|||||||
ciphers_str = undefined
|
ciphers_str = undefined
|
||||||
macs_str = undefined
|
macs_str = undefined
|
||||||
hostkey_sizes_str = undefined
|
hostkey_sizes_str = undefined
|
||||||
cakey_sizes_str = undefined
|
|
||||||
dh_modulus_sizes_str = undefined
|
dh_modulus_sizes_str = undefined
|
||||||
|
|
||||||
|
|
||||||
@ -513,9 +593,7 @@ macs = %s
|
|||||||
macs_str = ', '.join(self._macs)
|
macs_str = ', '.join(self._macs)
|
||||||
if self._hostkey_sizes is not None:
|
if self._hostkey_sizes is not None:
|
||||||
hostkey_sizes_str = str(self._hostkey_sizes)
|
hostkey_sizes_str = str(self._hostkey_sizes)
|
||||||
if self._cakey_sizes is not None:
|
|
||||||
cakey_sizes_str = str(self._cakey_sizes)
|
|
||||||
if self._dh_modulus_sizes is not None:
|
if self._dh_modulus_sizes is not None:
|
||||||
dh_modulus_sizes_str = str(self._dh_modulus_sizes)
|
dh_modulus_sizes_str = str(self._dh_modulus_sizes)
|
||||||
|
|
||||||
return "Name: %s\nVersion: %s\nBanner: %s\nCompressions: %s\nHost Keys: %s\nOptional Host Keys: %s\nKey Exchanges: %s\nCiphers: %s\nMACs: %s\nHost Key Sizes: %s\nCA Key Sizes: %s\nDH Modulus Sizes: %s\nServer Policy: %r" % (name, version, banner, compressions_str, host_keys_str, optional_host_keys_str, kex_str, ciphers_str, macs_str, hostkey_sizes_str, cakey_sizes_str, dh_modulus_sizes_str, self._server_policy)
|
return "Name: %s\nVersion: %s\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, 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)
|
||||||
|
@ -22,17 +22,18 @@
|
|||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
"""
|
"""
|
||||||
# pylint: disable=unused-import
|
from typing import Dict, List
|
||||||
from typing import Dict, List, Set, Sequence, Tuple, Iterable # noqa: F401
|
from typing import Union
|
||||||
from typing import Callable, Optional, Union, Any # noqa: F401
|
|
||||||
|
|
||||||
from ssh_audit.ssh2_kexparty import SSH2_KexParty
|
from ssh_audit.outputbuffer import OutputBuffer
|
||||||
from ssh_audit.readbuf import ReadBuf
|
from ssh_audit.readbuf import ReadBuf
|
||||||
|
from ssh_audit.ssh2_kexparty import SSH2_KexParty
|
||||||
from ssh_audit.writebuf import WriteBuf
|
from ssh_audit.writebuf import WriteBuf
|
||||||
|
|
||||||
|
|
||||||
class SSH2_Kex:
|
class SSH2_Kex:
|
||||||
def __init__(self, cookie: bytes, kex_algs: List[str], key_algs: List[str], cli: 'SSH2_KexParty', srv: 'SSH2_KexParty', follows: bool, unused: int = 0) -> None:
|
def __init__(self, outputbuffer: 'OutputBuffer', cookie: bytes, kex_algs: List[str], key_algs: List[str], cli: 'SSH2_KexParty', srv: 'SSH2_KexParty', follows: bool, unused: int = 0) -> None: # pylint: disable=too-many-arguments
|
||||||
|
self.__outputbuffer = outputbuffer
|
||||||
self.__cookie = cookie
|
self.__cookie = cookie
|
||||||
self.__kex_algs = kex_algs
|
self.__kex_algs = kex_algs
|
||||||
self.__key_algs = key_algs
|
self.__key_algs = key_algs
|
||||||
@ -41,9 +42,8 @@ class SSH2_Kex:
|
|||||||
self.__follows = follows
|
self.__follows = follows
|
||||||
self.__unused = unused
|
self.__unused = unused
|
||||||
|
|
||||||
self.__rsa_key_sizes: Dict[str, Tuple[int, int]] = {}
|
self.__dh_modulus_sizes: Dict[str, int] = {}
|
||||||
self.__dh_modulus_sizes: Dict[str, Tuple[int, int]] = {}
|
self.__host_keys: Dict[str, Dict[str, Union[bytes, str, int]]] = {}
|
||||||
self.__host_keys: Dict[str, bytes] = {}
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def cookie(self) -> bytes:
|
def cookie(self) -> bytes:
|
||||||
@ -75,22 +75,20 @@ class SSH2_Kex:
|
|||||||
def unused(self) -> int:
|
def unused(self) -> int:
|
||||||
return self.__unused
|
return self.__unused
|
||||||
|
|
||||||
def set_rsa_key_size(self, rsa_type: str, hostkey_size: int, ca_size: int = -1) -> None:
|
|
||||||
self.__rsa_key_sizes[rsa_type] = (hostkey_size, ca_size)
|
|
||||||
|
|
||||||
def rsa_key_sizes(self) -> Dict[str, Tuple[int, int]]:
|
|
||||||
return self.__rsa_key_sizes
|
|
||||||
|
|
||||||
def set_dh_modulus_size(self, gex_alg: str, modulus_size: int) -> None:
|
def set_dh_modulus_size(self, gex_alg: str, modulus_size: int) -> None:
|
||||||
self.__dh_modulus_sizes[gex_alg] = (modulus_size, -1)
|
self.__dh_modulus_sizes[gex_alg] = modulus_size
|
||||||
|
|
||||||
def dh_modulus_sizes(self) -> Dict[str, Tuple[int, int]]:
|
def dh_modulus_sizes(self) -> Dict[str, int]:
|
||||||
return self.__dh_modulus_sizes
|
return self.__dh_modulus_sizes
|
||||||
|
|
||||||
def set_host_key(self, key_type: str, hostkey: bytes) -> None:
|
def set_host_key(self, key_type: str, raw_hostkey_bytes: bytes, hostkey_size: int, ca_key_type: str, ca_key_size: int) -> None:
|
||||||
self.__host_keys[key_type] = hostkey
|
|
||||||
|
|
||||||
def host_keys(self) -> Dict[str, bytes]:
|
if key_type not in self.__host_keys:
|
||||||
|
self.__host_keys[key_type] = {'raw_hostkey_bytes': raw_hostkey_bytes, 'hostkey_size': hostkey_size, 'ca_key_type': ca_key_type, 'ca_key_size': ca_key_size}
|
||||||
|
else: # A host key may only have one CA signature...
|
||||||
|
self.__outputbuffer.d("WARNING: called SSH2_Kex.set_host_key() multiple times with the same host key type (%s)! Existing info: %r, %r, %r; Duplicate (ignored) info: %r, %r, %r" % (key_type, self.__host_keys[key_type]['hostkey_size'], self.__host_keys[key_type]['ca_key_type'], self.__host_keys[key_type]['ca_key_size'], hostkey_size, ca_key_type, ca_key_size))
|
||||||
|
|
||||||
|
def host_keys(self) -> Dict[str, Dict[str, Union[bytes, str, int]]]:
|
||||||
return self.__host_keys
|
return self.__host_keys
|
||||||
|
|
||||||
def write(self, wbuf: 'WriteBuf') -> None:
|
def write(self, wbuf: 'WriteBuf') -> None:
|
||||||
@ -115,7 +113,7 @@ class SSH2_Kex:
|
|||||||
return wbuf.write_flush()
|
return wbuf.write_flush()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def parse(cls, payload: bytes) -> 'SSH2_Kex':
|
def parse(cls, outputbuffer: 'OutputBuffer', payload: bytes) -> 'SSH2_Kex':
|
||||||
buf = ReadBuf(payload)
|
buf = ReadBuf(payload)
|
||||||
cookie = buf.read(16)
|
cookie = buf.read(16)
|
||||||
kex_algs = buf.read_list()
|
kex_algs = buf.read_list()
|
||||||
@ -132,5 +130,5 @@ class SSH2_Kex:
|
|||||||
unused = buf.read_int()
|
unused = buf.read_int()
|
||||||
cli = SSH2_KexParty(cli_enc, cli_mac, cli_compression, cli_languages)
|
cli = SSH2_KexParty(cli_enc, cli_mac, cli_compression, cli_languages)
|
||||||
srv = SSH2_KexParty(srv_enc, srv_mac, srv_compression, srv_languages)
|
srv = SSH2_KexParty(srv_enc, srv_mac, srv_compression, srv_languages)
|
||||||
kex = cls(cookie, kex_algs, key_algs, cli, srv, follows, unused)
|
kex = cls(outputbuffer, cookie, kex_algs, key_algs, cli, srv, follows, unused)
|
||||||
return kex
|
return kex
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"""
|
"""
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (C) 2017-2021 Joe Testa (jtesta@positronsecurity.com)
|
Copyright (C) 2017-2023 Joe Testa (jtesta@positronsecurity.com)
|
||||||
Copyright (C) 2017 Andris Raugulis (moo@arthepsy.eu)
|
Copyright (C) 2017 Andris Raugulis (moo@arthepsy.eu)
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
@ -28,63 +28,59 @@ from typing import Callable, Optional, Union, Any # noqa: F401
|
|||||||
|
|
||||||
|
|
||||||
class SSH2_KexDB: # pylint: disable=too-few-public-methods
|
class SSH2_KexDB: # pylint: disable=too-few-public-methods
|
||||||
WARN_OPENSSH74_UNSAFE = 'disabled (in client) since OpenSSH 7.4, unsafe algorithm'
|
|
||||||
WARN_OPENSSH72_LEGACY = 'disabled (in client) since OpenSSH 7.2, legacy algorithm'
|
|
||||||
FAIL_OPENSSH70_LEGACY = 'removed since OpenSSH 7.0, legacy algorithm'
|
|
||||||
FAIL_OPENSSH70_WEAK = 'removed (in server) and disabled (in client) since OpenSSH 7.0, weak algorithm'
|
|
||||||
FAIL_OPENSSH70_LOGJAM = 'disabled (in client) since OpenSSH 7.0, logjam attack'
|
|
||||||
INFO_OPENSSH69_CHACHA = 'default cipher since OpenSSH 6.9.'
|
|
||||||
FAIL_OPENSSH67_UNSAFE = 'removed (in server) since OpenSSH 6.7, unsafe algorithm'
|
|
||||||
FAIL_OPENSSH61_REMOVE = 'removed since OpenSSH 6.1, removed from specification'
|
|
||||||
FAIL_OPENSSH31_REMOVE = 'removed since OpenSSH 3.1'
|
|
||||||
INFO_OPENSSH82_FUTURE_DEPRECATION = 'a future deprecation notice has been issued in OpenSSH 8.2: https://www.openssh.com/txt/release-8.2'
|
|
||||||
FAIL_DBEAR67_DISABLED = 'disabled since Dropbear SSH 2015.67'
|
|
||||||
FAIL_DBEAR53_DISABLED = 'disabled since Dropbear SSH 0.53'
|
|
||||||
FAIL_DEPRECATED_CIPHER = 'deprecated cipher'
|
|
||||||
FAIL_WEAK_CIPHER = 'using weak cipher'
|
|
||||||
FAIL_WEAK_ALGORITHM = 'using weak/obsolete algorithm'
|
|
||||||
FAIL_PLAINTEXT = 'no encryption/integrity'
|
|
||||||
FAIL_DEPRECATED_MAC = 'deprecated MAC'
|
|
||||||
FAIL_1024BIT_MODULUS = 'using small 1024-bit modulus'
|
FAIL_1024BIT_MODULUS = 'using small 1024-bit modulus'
|
||||||
|
FAIL_3DES = 'using broken & deprecated 3DES cipher'
|
||||||
|
FAIL_BLOWFISH = 'using weak & deprecated Blowfish cipher'
|
||||||
|
FAIL_CAST = 'using weak & deprecated CAST cipher'
|
||||||
|
FAIL_DES = 'using broken DES cipher'
|
||||||
|
FAIL_IDEA = 'using deprecated IDEA cipher'
|
||||||
|
FAIL_LOGJAM_ATTACK = 'vulnerable to the Logjam attack: https://en.wikipedia.org/wiki/Logjam_(computer_security)'
|
||||||
|
FAIL_MD5 = 'using broken MD5 hash algorithm'
|
||||||
|
FAIL_NSA_BACKDOORED_CURVE = 'using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency'
|
||||||
|
FAIL_PLAINTEXT = 'no encryption/integrity'
|
||||||
|
FAIL_RC4 = 'using broken RC4 cipher'
|
||||||
|
FAIL_RIJNDAEL = 'using deprecated & non-standardized Rijndael cipher'
|
||||||
|
FAIL_RIPEMD = 'using deprecated RIPEMD hash algorithm'
|
||||||
|
FAIL_SEED = 'using deprecated SEED cipher'
|
||||||
|
FAIL_SERPENT = 'using deprecated Serpent cipher'
|
||||||
|
FAIL_SHA1 = 'using broken SHA-1 hash algorithm'
|
||||||
|
FAIL_SMALL_ECC_MODULUS = 'using small ECC modulus'
|
||||||
|
FAIL_UNKNOWN = 'using unknown algorithm'
|
||||||
FAIL_UNPROVEN = 'using unproven algorithm'
|
FAIL_UNPROVEN = 'using unproven algorithm'
|
||||||
FAIL_HASH_WEAK = 'using weak hashing algorithm'
|
FAIL_UNTRUSTED = 'using untrusted algorithm developed in secret by a government entity'
|
||||||
WARN_CURVES_WEAK = 'using weak elliptic curves'
|
|
||||||
WARN_RNDSIG_KEY = 'using weak random number generator could reveal the key'
|
WARN_2048BIT_MODULUS = '2048-bit modulus only provides 112-bits of symmetric strength'
|
||||||
WARN_HASH_WEAK = 'using weak hashing algorithm'
|
|
||||||
WARN_CIPHER_MODE = 'using weak cipher mode'
|
|
||||||
WARN_BLOCK_SIZE = 'using small 64-bit block size'
|
WARN_BLOCK_SIZE = 'using small 64-bit block size'
|
||||||
WARN_CIPHER_WEAK = 'using weak cipher'
|
WARN_CIPHER_MODE = 'using weak cipher mode'
|
||||||
WARN_ENCRYPT_AND_MAC = 'using encrypt-and-MAC mode'
|
WARN_ENCRYPT_AND_MAC = 'using encrypt-and-MAC mode'
|
||||||
|
WARN_EXPERIMENTAL = 'using experimental algorithm'
|
||||||
|
WARN_RNDSIG_KEY = 'using weak random number generator could reveal the key'
|
||||||
WARN_TAG_SIZE = 'using small 64-bit tag size'
|
WARN_TAG_SIZE = 'using small 64-bit tag size'
|
||||||
WARN_TAG_SIZE_96 = 'using small 96-bit tag size'
|
WARN_TAG_SIZE_96 = 'using small 96-bit tag size'
|
||||||
WARN_EXPERIMENTAL = 'using experimental algorithm'
|
|
||||||
WARN_OBSOLETE = 'using obsolete algorithm'
|
INFO_DEFAULT_OPENSSH_CIPHER = 'default cipher since OpenSSH 6.9'
|
||||||
WARN_UNTRUSTED = 'using untrusted algorithm'
|
INFO_DEFAULT_OPENSSH_KEX = 'default key exchange since OpenSSH 6.4'
|
||||||
|
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_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'
|
||||||
|
INFO_WITHDRAWN_PQ_ALG = 'the sntrup4591761 algorithm was withdrawn, as it may not provide strong post-quantum security'
|
||||||
|
|
||||||
|
|
||||||
ALGORITHMS: Dict[str, Dict[str, List[List[Optional[str]]]]] = {
|
ALGORITHMS: Dict[str, Dict[str, List[List[Optional[str]]]]] = {
|
||||||
# Format: 'algorithm_name': [['version_first_appeared_in'], [reason_for_failure1, reason_for_failure2, ...], [warning1, warning2, ...]]
|
# Format: 'algorithm_name': [['version_first_appeared_in'], [reason_for_failure1, reason_for_failure2, ...], [warning1, warning2, ...], [info1, info2, ...]]
|
||||||
'kex': {
|
'kex': {
|
||||||
'diffie-hellman-group1-sha1': [['2.3.0,d0.28,l10.2', '6.6', '6.9'], [FAIL_1024BIT_MODULUS, FAIL_OPENSSH67_UNSAFE, FAIL_OPENSSH70_LOGJAM], [WARN_HASH_WEAK]],
|
'Curve25519SHA256': [[]],
|
||||||
'gss-group1-sha1-toWM5Slw5Ew8Mqkay+al2g==': [[], [FAIL_1024BIT_MODULUS, FAIL_OPENSSH67_UNSAFE, FAIL_OPENSSH70_LOGJAM], [WARN_HASH_WEAK]],
|
'curve25519-sha256': [['7.4,d2018.76'], [], [], [INFO_DEFAULT_OPENSSH_KEX]],
|
||||||
'gss-gex-sha1-eipGX3TCiQSrx573bT1o1Q==': [[], [], [WARN_HASH_WEAK]],
|
'curve25519-sha256@libssh.org': [['6.4,d2013.62,l10.6.0'], [], [], [INFO_DEFAULT_OPENSSH_KEX]],
|
||||||
'gss-gex-sha1-toWM5Slw5Ew8Mqkay+al2g==': [[], [], [WARN_HASH_WEAK]],
|
'curve448-sha512': [[]],
|
||||||
'gss-gex-sha1-': [[], [], [WARN_HASH_WEAK]],
|
'diffie-hellman-group14-sha1': [['3.9,d0.53,l10.6.0'], [FAIL_SHA1], [WARN_2048BIT_MODULUS]],
|
||||||
'gss-group1-sha1-eipGX3TCiQSrx573bT1o1Q==': [[], [FAIL_1024BIT_MODULUS], [WARN_HASH_WEAK]],
|
'diffie-hellman-group14-sha224@ssh.com': [[]],
|
||||||
'gss-group1-sha1-': [[], [FAIL_1024BIT_MODULUS], [WARN_HASH_WEAK]],
|
'diffie-hellman-group14-sha256': [['7.3,d2016.73'], [], [WARN_2048BIT_MODULUS]],
|
||||||
'gss-group14-sha1-': [[], [], [WARN_HASH_WEAK]],
|
'diffie-hellman-group14-sha256@ssh.com': [[], [], [WARN_2048BIT_MODULUS]],
|
||||||
'gss-group14-sha1-eipGX3TCiQSrx573bT1o1Q==': [[], [], [WARN_HASH_WEAK]],
|
|
||||||
'gss-group14-sha1-toWM5Slw5Ew8Mqkay+al2g==': [[], [], [WARN_HASH_WEAK]],
|
|
||||||
'gss-group14-sha256-': [[]],
|
|
||||||
'gss-group14-sha256-toWM5Slw5Ew8Mqkay+al2g==': [[]],
|
|
||||||
'gss-group15-sha512-': [[]],
|
|
||||||
'gss-group15-sha512-toWM5Slw5Ew8Mqkay+al2g==': [[]],
|
|
||||||
'gss-group16-sha512-': [[]],
|
|
||||||
'gss-nistp256-sha256-': [[], [WARN_CURVES_WEAK]],
|
|
||||||
'gss-curve25519-sha256-': [[]],
|
|
||||||
'diffie-hellman-group1-sha256': [[], [FAIL_1024BIT_MODULUS]],
|
|
||||||
'diffie-hellman-group14-sha1': [['3.9,d0.53,l10.6.0'], [], [WARN_HASH_WEAK]],
|
|
||||||
'diffie-hellman-group14-sha256': [['7.3,d2016.73']],
|
|
||||||
'diffie-hellman-group14-sha256@ssh.com': [[]],
|
|
||||||
'diffie-hellman-group15-sha256': [[]],
|
'diffie-hellman-group15-sha256': [[]],
|
||||||
'diffie-hellman-group15-sha256@ssh.com': [[]],
|
'diffie-hellman-group15-sha256@ssh.com': [[]],
|
||||||
'diffie-hellman-group15-sha384@ssh.com': [[]],
|
'diffie-hellman-group15-sha384@ssh.com': [[]],
|
||||||
@ -94,187 +90,302 @@ class SSH2_KexDB: # pylint: disable=too-few-public-methods
|
|||||||
'diffie-hellman-group16-sha512': [['7.3,d2016.73']],
|
'diffie-hellman-group16-sha512': [['7.3,d2016.73']],
|
||||||
'diffie-hellman-group16-sha512@ssh.com': [[]],
|
'diffie-hellman-group16-sha512@ssh.com': [[]],
|
||||||
'diffie-hellman-group17-sha512': [[]],
|
'diffie-hellman-group17-sha512': [[]],
|
||||||
|
'diffie-hellman_group17-sha512': [[]],
|
||||||
'diffie-hellman-group18-sha512': [['7.3']],
|
'diffie-hellman-group18-sha512': [['7.3']],
|
||||||
'diffie-hellman-group18-sha512@ssh.com': [[]],
|
'diffie-hellman-group18-sha512@ssh.com': [[]],
|
||||||
'diffie-hellman-group-exchange-sha1': [['2.3.0', '6.6', None], [FAIL_OPENSSH67_UNSAFE], [WARN_HASH_WEAK]],
|
'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': [['4.4']],
|
||||||
'diffie-hellman-group-exchange-sha256@ssh.com': [[]],
|
'diffie-hellman-group-exchange-sha256@ssh.com': [[]],
|
||||||
|
'diffie-hellman-group-exchange-sha384@ssh.com': [[]],
|
||||||
'diffie-hellman-group-exchange-sha512@ssh.com': [[]],
|
'diffie-hellman-group-exchange-sha512@ssh.com': [[]],
|
||||||
'ecdh-sha2-curve25519': [[], []],
|
'ecdh-sha2-1.2.840.10045.3.1.1': [[], [FAIL_SMALL_ECC_MODULUS, FAIL_NSA_BACKDOORED_CURVE]], # NIST P-192 / secp192r1
|
||||||
'ecdh-sha2-nistb233': [[], [WARN_CURVES_WEAK]],
|
'ecdh-sha2-1.2.840.10045.3.1.7': [[], [FAIL_NSA_BACKDOORED_CURVE]], # NIST P-256 / secp256r1
|
||||||
'ecdh-sha2-nistb409': [[], [WARN_CURVES_WEAK]],
|
|
||||||
'ecdh-sha2-nistk163': [[], [WARN_CURVES_WEAK]],
|
|
||||||
'ecdh-sha2-nistk233': [[], [WARN_CURVES_WEAK]],
|
|
||||||
'ecdh-sha2-nistk283': [[], [WARN_CURVES_WEAK]],
|
|
||||||
'ecdh-sha2-nistk409': [[], [WARN_CURVES_WEAK]],
|
|
||||||
'ecdh-sha2-nistp192': [[], [WARN_CURVES_WEAK]],
|
|
||||||
'ecdh-sha2-nistp224': [[], [WARN_CURVES_WEAK]],
|
|
||||||
'ecdh-sha2-nistp256': [['5.7,d2013.62,l10.6.0'], [WARN_CURVES_WEAK]],
|
|
||||||
'ecdh-sha2-nistp384': [['5.7,d2013.62'], [WARN_CURVES_WEAK]],
|
|
||||||
'ecdh-sha2-nistp521': [['5.7,d2013.62'], [WARN_CURVES_WEAK]],
|
|
||||||
'ecdh-sha2-nistt571': [[], [WARN_CURVES_WEAK]],
|
|
||||||
'ecdh-sha2-1.3.132.0.10': [[]], # ECDH over secp256k1 (i.e.: the Bitcoin curve)
|
'ecdh-sha2-1.3.132.0.10': [[]], # ECDH over secp256k1 (i.e.: the Bitcoin curve)
|
||||||
'curve25519-sha256@libssh.org': [['6.5,d2013.62,l10.6.0']],
|
'ecdh-sha2-1.3.132.0.16': [[]], # sect283k1
|
||||||
'curve25519-sha256': [['7.4,d2018.76']],
|
'ecdh-sha2-1.3.132.0.1': [[], [FAIL_SMALL_ECC_MODULUS]], # sect163k1
|
||||||
'curve448-sha512': [[]],
|
'ecdh-sha2-1.3.132.0.26': [[], [FAIL_SMALL_ECC_MODULUS]], # sect233k1
|
||||||
'kexguess2@matt.ucc.asn.au': [['d2013.57']],
|
'ecdh-sha2-1.3.132.0.27': [[], [FAIL_SMALL_ECC_MODULUS, FAIL_NSA_BACKDOORED_CURVE]], # sect233r1
|
||||||
'rsa1024-sha1': [[], [FAIL_1024BIT_MODULUS], [WARN_HASH_WEAK]],
|
'ecdh-sha2-1.3.132.0.33': [[], [FAIL_SMALL_ECC_MODULUS, FAIL_NSA_BACKDOORED_CURVE]], # NIST P-224 / secp224r1
|
||||||
'rsa2048-sha256': [[]],
|
'ecdh-sha2-1.3.132.0.34': [[], [FAIL_NSA_BACKDOORED_CURVE]], # NIST P-384 / secp384r1
|
||||||
'sntrup4591761x25519-sha512@tinyssh.org': [['8.0', '8.4'], [], [WARN_EXPERIMENTAL]],
|
'ecdh-sha2-1.3.132.0.35': [[], [FAIL_NSA_BACKDOORED_CURVE]], # NIST P-521 / secp521r1
|
||||||
'sntrup761x25519-sha512@openssh.com': [['8.5'], [], [WARN_EXPERIMENTAL]],
|
'ecdh-sha2-1.3.132.0.36': [[]], # sect409k1
|
||||||
'kexAlgoCurve25519SHA256': [[]],
|
'ecdh-sha2-1.3.132.0.37': [[], [FAIL_NSA_BACKDOORED_CURVE]], # sect409r1
|
||||||
'Curve25519SHA256': [[]],
|
'ecdh-sha2-1.3.132.0.38': [[]], # 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_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-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==': [[]], # sect409k1
|
||||||
|
'ecdh-sha2-mNVwCXAoS1HGmHpLvBC94w==': [[]], # sect571k1
|
||||||
|
|
||||||
|
'ecdh-sha2-nistb233': [[]], # The NIST P-curves are suspected as being backdoored; this isn't a P-curve.
|
||||||
|
'ecdh-sha2-nistb409': [[]], # Not a NIST P-curve.
|
||||||
|
'ecdh-sha2-nistk163': [[], [FAIL_SMALL_ECC_MODULUS]], # Not a NIST P-curve.
|
||||||
|
'ecdh-sha2-nistk233': [[]], # Not a NIST P-curve.
|
||||||
|
'ecdh-sha2-nistk283': [[]], # Not a NIST P-curve.
|
||||||
|
'ecdh-sha2-nistk409': [[]], # Not a NIST P-curve.
|
||||||
|
'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': [[]], # Not a NIST P-curve.
|
||||||
|
'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_SMALL_ECC_MODULUS, FAIL_NSA_BACKDOORED_CURVE]], # NIST P-224 / secp224r1
|
||||||
|
'ecdh-sha2-wiRIU8TKjMZ418sMqlqtvQ==': [[]], # sect283k1
|
||||||
|
'ecdh-sha2-zD/b3hu/71952ArpUG4OjQ==': [[], [FAIL_SMALL_ECC_MODULUS]], # sect233k1
|
||||||
|
'ecmqv-sha2': [[], [FAIL_UNPROVEN]],
|
||||||
'ext-info-c': [[]], # Extension negotiation (RFC 8308)
|
'ext-info-c': [[]], # Extension negotiation (RFC 8308)
|
||||||
'ext-info-s': [[]], # Extension negotiation (RFC 8308)
|
'ext-info-s': [[]], # Extension negotiation (RFC 8308)
|
||||||
|
|
||||||
|
# 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-nistp521-sha512-*': [[], [FAIL_NSA_BACKDOORED_CURVE]],
|
||||||
|
|
||||||
|
'kexAlgoCurve25519SHA256': [[]],
|
||||||
|
'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]],
|
||||||
|
'sntrup4591761x25519-sha512@tinyssh.org': [['8.0', '8.4'], [], [WARN_EXPERIMENTAL], [INFO_WITHDRAWN_PQ_ALG]],
|
||||||
|
'sntrup761x25519-sha512@openssh.com': [['8.5'], [], []],
|
||||||
},
|
},
|
||||||
'key': {
|
'key': {
|
||||||
'ssh-rsa1': [[], [FAIL_WEAK_ALGORITHM]],
|
'dsa2048-sha224@libassh.org': [[], [FAIL_UNPROVEN], [WARN_2048BIT_MODULUS]],
|
||||||
'rsa-sha2-256': [['7.2']],
|
'dsa2048-sha256@libassh.org': [[], [FAIL_UNPROVEN], [WARN_2048BIT_MODULUS]],
|
||||||
'rsa-sha2-512': [['7.2']],
|
'dsa3072-sha256@libassh.org': [[], [FAIL_UNPROVEN]],
|
||||||
'ssh-ed25519': [['6.5,l10.7.0']],
|
'ecdsa-sha2-1.3.132.0.10-cert-v01@openssh.com': [[], [FAIL_UNKNOWN]],
|
||||||
'ssh-ed25519-cert-v01@openssh.com': [['6.5']],
|
|
||||||
'ssh-rsa': [['2.5.0,d0.28,l10.2'], [FAIL_HASH_WEAK], [], [INFO_OPENSSH82_FUTURE_DEPRECATION]],
|
|
||||||
'ssh-dss': [['2.1.0,d0.28,l10.2', '6.9'], [FAIL_1024BIT_MODULUS, FAIL_OPENSSH70_WEAK], [WARN_RNDSIG_KEY]],
|
|
||||||
'ecdsa-sha2-nistp256': [['5.7,d2013.62,l10.6.4'], [WARN_CURVES_WEAK], [WARN_RNDSIG_KEY]],
|
|
||||||
'ecdsa-sha2-nistp384': [['5.7,d2013.62,l10.6.4'], [WARN_CURVES_WEAK], [WARN_RNDSIG_KEY]],
|
|
||||||
'ecdsa-sha2-nistp521': [['5.7,d2013.62,l10.6.4'], [WARN_CURVES_WEAK], [WARN_RNDSIG_KEY]],
|
|
||||||
'ecdsa-sha2-1.3.132.0.10': [[], [], [WARN_RNDSIG_KEY]], # ECDSA over secp256k1 (i.e.: the Bitcoin curve)
|
'ecdsa-sha2-1.3.132.0.10': [[], [], [WARN_RNDSIG_KEY]], # ECDSA over secp256k1 (i.e.: the Bitcoin curve)
|
||||||
'x509v3-sign-dss': [[], [FAIL_1024BIT_MODULUS, FAIL_OPENSSH70_WEAK], [WARN_RNDSIG_KEY]],
|
'ecdsa-sha2-nistp256': [['5.7,d2013.62,l10.6.4'], [FAIL_NSA_BACKDOORED_CURVE], [WARN_RNDSIG_KEY]],
|
||||||
'x509v3-sign-rsa': [[], [FAIL_HASH_WEAK], [], [INFO_OPENSSH82_FUTURE_DEPRECATION]],
|
'ecdsa-sha2-nistp256-cert-v01@openssh.com': [['5.7'], [FAIL_NSA_BACKDOORED_CURVE], [WARN_RNDSIG_KEY]],
|
||||||
'x509v3-sign-rsa-sha256@ssh.com': [[]],
|
'ecdsa-sha2-nistp384': [['5.7,d2013.62,l10.6.4'], [FAIL_NSA_BACKDOORED_CURVE], [WARN_RNDSIG_KEY]],
|
||||||
'x509v3-ssh-dss': [[], [FAIL_1024BIT_MODULUS, FAIL_OPENSSH70_WEAK], [WARN_RNDSIG_KEY]],
|
'ecdsa-sha2-nistp384-cert-v01@openssh.com': [['5.7'], [FAIL_NSA_BACKDOORED_CURVE], [WARN_RNDSIG_KEY]],
|
||||||
'x509v3-ssh-rsa': [[], [FAIL_HASH_WEAK], [], [INFO_OPENSSH82_FUTURE_DEPRECATION]],
|
'ecdsa-sha2-nistp521': [['5.7,d2013.62,l10.6.4'], [FAIL_NSA_BACKDOORED_CURVE], [WARN_RNDSIG_KEY]],
|
||||||
'ssh-rsa-cert-v00@openssh.com': [['5.4', '6.9'], [FAIL_OPENSSH70_LEGACY, FAIL_HASH_WEAK], [], [INFO_OPENSSH82_FUTURE_DEPRECATION]],
|
'ecdsa-sha2-nistp521-cert-v01@openssh.com': [['5.7'], [FAIL_NSA_BACKDOORED_CURVE], [WARN_RNDSIG_KEY]],
|
||||||
'ssh-dss-cert-v00@openssh.com': [['5.4', '6.9'], [FAIL_1024BIT_MODULUS, FAIL_OPENSSH70_LEGACY], [WARN_RNDSIG_KEY]],
|
'eddsa-e382-shake256@libassh.org': [[], [FAIL_UNPROVEN]],
|
||||||
'ssh-rsa-cert-v01@openssh.com': [['5.6'], [FAIL_HASH_WEAK], [], [INFO_OPENSSH82_FUTURE_DEPRECATION]],
|
'eddsa-e521-shake256@libassh.org': [[], [FAIL_UNPROVEN]],
|
||||||
'ssh-dss-cert-v01@openssh.com': [['5.6', '6.9'], [FAIL_1024BIT_MODULUS, FAIL_OPENSSH70_WEAK], [WARN_RNDSIG_KEY]],
|
'null': [[], [FAIL_PLAINTEXT]],
|
||||||
'ecdsa-sha2-nistp256-cert-v01@openssh.com': [['5.7'], [WARN_CURVES_WEAK], [WARN_RNDSIG_KEY]],
|
'pgp-sign-dss': [[], [FAIL_1024BIT_MODULUS]],
|
||||||
'ecdsa-sha2-nistp384-cert-v01@openssh.com': [['5.7'], [WARN_CURVES_WEAK], [WARN_RNDSIG_KEY]],
|
'pgp-sign-rsa': [[], [FAIL_1024BIT_MODULUS]],
|
||||||
'ecdsa-sha2-nistp521-cert-v01@openssh.com': [['5.7'], [WARN_CURVES_WEAK], [WARN_RNDSIG_KEY]],
|
'rsa-sha2-256': [['7.2']],
|
||||||
'rsa-sha2-256-cert-v01@openssh.com': [['7.8']],
|
'rsa-sha2-256-cert-v01@openssh.com': [['7.8']],
|
||||||
|
'rsa-sha2-512': [['7.2']],
|
||||||
'rsa-sha2-512-cert-v01@openssh.com': [['7.8']],
|
'rsa-sha2-512-cert-v01@openssh.com': [['7.8']],
|
||||||
'ssh-rsa-sha256@ssh.com': [[]],
|
'sk-ecdsa-sha2-nistp256-cert-v01@openssh.com': [['8.2'], [FAIL_NSA_BACKDOORED_CURVE], [WARN_RNDSIG_KEY]],
|
||||||
'ssh-dss-sha256@ssh.com': [[], [FAIL_1024BIT_MODULUS]],
|
'sk-ecdsa-sha2-nistp256@openssh.com': [['8.2'], [FAIL_NSA_BACKDOORED_CURVE], [WARN_RNDSIG_KEY]],
|
||||||
'sk-ecdsa-sha2-nistp256-cert-v01@openssh.com': [['8.2'], [WARN_CURVES_WEAK], [WARN_RNDSIG_KEY]],
|
|
||||||
'sk-ecdsa-sha2-nistp256@openssh.com': [['8.2'], [WARN_CURVES_WEAK], [WARN_RNDSIG_KEY]],
|
|
||||||
'sk-ssh-ed25519-cert-v01@openssh.com': [['8.2']],
|
'sk-ssh-ed25519-cert-v01@openssh.com': [['8.2']],
|
||||||
'sk-ssh-ed25519@openssh.com': [['8.2']],
|
'sk-ssh-ed25519@openssh.com': [['8.2']],
|
||||||
'ssh-gost2001': [[], [], [WARN_UNTRUSTED]],
|
|
||||||
'ssh-gost2012-256': [[], [], [WARN_UNTRUSTED]],
|
|
||||||
'ssh-gost2012-512': [[], [], [WARN_UNTRUSTED]],
|
|
||||||
'spi-sign-rsa': [[]],
|
'spi-sign-rsa': [[]],
|
||||||
|
'spki-sign-dss': [[], [FAIL_1024BIT_MODULUS]],
|
||||||
|
'spki-sign-rsa': [[], [FAIL_1024BIT_MODULUS]],
|
||||||
|
'ssh-dss': [['2.1.0,d0.28,l10.2', '6.9'], [FAIL_1024BIT_MODULUS], [WARN_RNDSIG_KEY], [INFO_DISABLED_IN_OPENSSH70]],
|
||||||
|
'ssh-dss-cert-v00@openssh.com': [['5.4', '6.9'], [FAIL_1024BIT_MODULUS], [WARN_RNDSIG_KEY], [INFO_DISABLED_IN_OPENSSH70]],
|
||||||
|
'ssh-dss-cert-v01@openssh.com': [['5.6', '6.9'], [FAIL_1024BIT_MODULUS], [WARN_RNDSIG_KEY]],
|
||||||
|
'ssh-dss-sha224@ssh.com': [[], [FAIL_1024BIT_MODULUS]],
|
||||||
|
'ssh-dss-sha256@ssh.com': [[], [FAIL_1024BIT_MODULUS]],
|
||||||
|
'ssh-dss-sha384@ssh.com': [[], [FAIL_1024BIT_MODULUS]],
|
||||||
|
'ssh-dss-sha512@ssh.com': [[], [FAIL_1024BIT_MODULUS]],
|
||||||
|
'ssh-ed25519': [['6.5,l10.7.0']],
|
||||||
|
'ssh-ed25519-cert-v01@openssh.com': [['6.5']],
|
||||||
'ssh-ed448': [[]],
|
'ssh-ed448': [[]],
|
||||||
'x509v3-ecdsa-sha2-nistp256': [[], [WARN_CURVES_WEAK]],
|
'ssh-ed448-cert-v01@openssh.com': [[], [], [], [INFO_NEVER_IMPLEMENTED_IN_OPENSSH]],
|
||||||
'x509v3-ecdsa-sha2-nistp384': [[], [WARN_CURVES_WEAK]],
|
'ssh-gost2001': [[], [FAIL_UNTRUSTED]],
|
||||||
'x509v3-ecdsa-sha2-nistp521': [[], [WARN_CURVES_WEAK]],
|
'ssh-gost2012-256': [[], [FAIL_UNTRUSTED]],
|
||||||
|
'ssh-gost2012-512': [[], [FAIL_UNTRUSTED]],
|
||||||
|
'ssh-rsa1': [[], [FAIL_SHA1]],
|
||||||
|
'ssh-rsa': [['2.5.0,d0.28,l10.2'], [FAIL_SHA1], [], [INFO_DEPRECATED_IN_OPENSSH88]],
|
||||||
|
'ssh-rsa-cert-v00@openssh.com': [['5.4', '6.9'], [FAIL_SHA1], [], [INFO_REMOVED_IN_OPENSSH70]],
|
||||||
|
'ssh-rsa-cert-v01@openssh.com': [['5.6'], [FAIL_SHA1], [], [INFO_DEPRECATED_IN_OPENSSH88]],
|
||||||
|
'ssh-rsa-sha224@ssh.com': [[]],
|
||||||
|
'ssh-rsa-sha2-256': [[]],
|
||||||
|
'ssh-rsa-sha2-512': [[]],
|
||||||
|
'ssh-rsa-sha256@ssh.com': [[]],
|
||||||
|
'ssh-rsa-sha384@ssh.com': [[]],
|
||||||
|
'ssh-rsa-sha512@ssh.com': [[]],
|
||||||
|
'ssh-xmss-cert-v01@openssh.com': [['7.7'], [WARN_EXPERIMENTAL]],
|
||||||
|
'ssh-xmss@openssh.com': [['7.7'], [WARN_EXPERIMENTAL]],
|
||||||
|
'webauthn-sk-ecdsa-sha2-nistp256@openssh.com': [['8.3'], [FAIL_NSA_BACKDOORED_CURVE]],
|
||||||
|
'x509v3-ecdsa-sha2-1.3.132.0.10': [[], [FAIL_UNKNOWN]],
|
||||||
|
'x509v3-ecdsa-sha2-nistp256': [[], [FAIL_NSA_BACKDOORED_CURVE]],
|
||||||
|
'x509v3-ecdsa-sha2-nistp384': [[], [FAIL_NSA_BACKDOORED_CURVE]],
|
||||||
|
'x509v3-ecdsa-sha2-nistp521': [[], [FAIL_NSA_BACKDOORED_CURVE]],
|
||||||
'x509v3-rsa2048-sha256': [[]],
|
'x509v3-rsa2048-sha256': [[]],
|
||||||
|
'x509v3-sign-dss': [[], [FAIL_1024BIT_MODULUS], [WARN_RNDSIG_KEY]],
|
||||||
|
'x509v3-sign-dss-sha1': [[], [FAIL_1024BIT_MODULUS, FAIL_SHA1]],
|
||||||
|
'x509v3-sign-dss-sha224@ssh.com': [[], [FAIL_1024BIT_MODULUS]],
|
||||||
|
'x509v3-sign-dss-sha256@ssh.com': [[], [FAIL_1024BIT_MODULUS]],
|
||||||
|
'x509v3-sign-dss-sha384@ssh.com': [[], [FAIL_1024BIT_MODULUS]],
|
||||||
|
'x509v3-sign-dss-sha512@ssh.com': [[], [FAIL_1024BIT_MODULUS]],
|
||||||
|
'x509v3-sign-rsa': [[], [FAIL_SHA1]],
|
||||||
|
'x509v3-sign-rsa-sha1': [[], [FAIL_SHA1]],
|
||||||
|
'x509v3-sign-rsa-sha224@ssh.com': [[]],
|
||||||
|
'x509v3-sign-rsa-sha256@ssh.com': [[]],
|
||||||
|
'x509v3-sign-rsa-sha384@ssh.com': [[]],
|
||||||
|
'x509v3-sign-rsa-sha512@ssh.com': [[]],
|
||||||
|
'x509v3-ssh-dss': [[], [FAIL_1024BIT_MODULUS], [WARN_RNDSIG_KEY]],
|
||||||
|
'x509v3-ssh-rsa': [[], [FAIL_SHA1], [], [INFO_DEPRECATED_IN_OPENSSH88]],
|
||||||
},
|
},
|
||||||
'enc': {
|
'enc': {
|
||||||
'none': [['1.2.2,d2013.56,l10.2'], [FAIL_PLAINTEXT]],
|
'3des-cbc': [['1.2.2,d0.28,l10.2', '6.6', None], [FAIL_3DES], [WARN_CIPHER_MODE, WARN_BLOCK_SIZE]],
|
||||||
'des': [[], [FAIL_WEAK_CIPHER], [WARN_CIPHER_MODE, WARN_BLOCK_SIZE]],
|
'3des-cfb': [[], [FAIL_3DES], [WARN_CIPHER_MODE]],
|
||||||
'des-cbc': [[], [FAIL_WEAK_CIPHER], [WARN_CIPHER_MODE, WARN_BLOCK_SIZE]],
|
'3des-ctr': [['d0.52'], [FAIL_3DES]],
|
||||||
'des-cbc@ssh.com': [[], [FAIL_WEAK_CIPHER], [WARN_CIPHER_MODE, WARN_BLOCK_SIZE]],
|
'3des-ecb': [[], [FAIL_3DES], [WARN_CIPHER_MODE]],
|
||||||
'des-cbc-ssh1': [[], [FAIL_WEAK_CIPHER], [WARN_CIPHER_MODE, WARN_BLOCK_SIZE]],
|
'3des': [[], [FAIL_3DES], [WARN_CIPHER_MODE, WARN_BLOCK_SIZE]],
|
||||||
'3des': [[], [FAIL_OPENSSH67_UNSAFE], [WARN_OPENSSH74_UNSAFE, WARN_CIPHER_WEAK, WARN_CIPHER_MODE, WARN_BLOCK_SIZE]],
|
'3des-ofb': [[], [FAIL_3DES], [WARN_CIPHER_MODE]],
|
||||||
'3des-cbc': [['1.2.2,d0.28,l10.2', '6.6', None], [FAIL_OPENSSH67_UNSAFE], [WARN_OPENSSH74_UNSAFE, WARN_CIPHER_WEAK, WARN_CIPHER_MODE, WARN_BLOCK_SIZE]],
|
|
||||||
'3des-ctr': [['d0.52'], [FAIL_WEAK_CIPHER]],
|
|
||||||
'blowfish': [[], [FAIL_WEAK_ALGORITHM], [WARN_BLOCK_SIZE]],
|
|
||||||
'blowfish-cbc': [['1.2.2,d0.28,l10.2', '6.6,d0.52', '7.1,d0.52'], [FAIL_OPENSSH67_UNSAFE, FAIL_DBEAR53_DISABLED], [WARN_OPENSSH72_LEGACY, WARN_CIPHER_MODE, WARN_BLOCK_SIZE]],
|
|
||||||
'blowfish-ctr': [[], [FAIL_OPENSSH67_UNSAFE, FAIL_DBEAR53_DISABLED], [WARN_OPENSSH72_LEGACY, WARN_CIPHER_MODE, WARN_BLOCK_SIZE]],
|
|
||||||
'twofish-cbc': [['d0.28', 'd2014.66'], [FAIL_DBEAR67_DISABLED], [WARN_CIPHER_MODE]],
|
|
||||||
'twofish128-cbc': [['d0.47', 'd2014.66'], [FAIL_DBEAR67_DISABLED], [WARN_CIPHER_MODE]],
|
|
||||||
'twofish192-cbc': [[], [], [WARN_CIPHER_MODE]],
|
|
||||||
'twofish256-cbc': [['d0.47', 'd2014.66'], [FAIL_DBEAR67_DISABLED], [WARN_CIPHER_MODE]],
|
|
||||||
'twofish-ctr': [[]],
|
|
||||||
'twofish128-ctr': [['d2015.68']],
|
|
||||||
'twofish192-ctr': [[]],
|
|
||||||
'twofish256-ctr': [['d2015.68']],
|
|
||||||
'serpent128-cbc': [[], [FAIL_DEPRECATED_CIPHER], [WARN_CIPHER_MODE]],
|
|
||||||
'serpent192-cbc': [[], [FAIL_DEPRECATED_CIPHER], [WARN_CIPHER_MODE]],
|
|
||||||
'serpent256-cbc': [[], [FAIL_DEPRECATED_CIPHER], [WARN_CIPHER_MODE]],
|
|
||||||
'serpent128-ctr': [[], [FAIL_DEPRECATED_CIPHER]],
|
|
||||||
'serpent192-ctr': [[], [FAIL_DEPRECATED_CIPHER]],
|
|
||||||
'serpent256-ctr': [[], [FAIL_DEPRECATED_CIPHER]],
|
|
||||||
'idea-cbc': [[], [FAIL_DEPRECATED_CIPHER], [WARN_CIPHER_MODE]],
|
|
||||||
'idea-ctr': [[], [FAIL_DEPRECATED_CIPHER]],
|
|
||||||
'cast128-ctr': [[], [FAIL_DEPRECATED_CIPHER]],
|
|
||||||
'cast128-cbc': [['2.1.0', '6.6', '7.1'], [FAIL_OPENSSH67_UNSAFE], [WARN_OPENSSH72_LEGACY, WARN_CIPHER_MODE, WARN_BLOCK_SIZE]],
|
|
||||||
'arcfour': [['2.1.0', '6.6', '7.1'], [FAIL_OPENSSH67_UNSAFE], [WARN_OPENSSH72_LEGACY, WARN_CIPHER_WEAK]],
|
|
||||||
'arcfour128': [['4.2', '6.6', '7.1'], [FAIL_OPENSSH67_UNSAFE], [WARN_OPENSSH72_LEGACY, WARN_CIPHER_WEAK]],
|
|
||||||
'arcfour256': [['4.2', '6.6', '7.1'], [FAIL_OPENSSH67_UNSAFE], [WARN_OPENSSH72_LEGACY, WARN_CIPHER_WEAK]],
|
|
||||||
'aes128-cbc': [['2.3.0,d0.28,l10.2', '6.6', None], [FAIL_OPENSSH67_UNSAFE], [WARN_CIPHER_MODE]],
|
|
||||||
'aes192-cbc': [['2.3.0,l10.2', '6.6', None], [FAIL_OPENSSH67_UNSAFE], [WARN_CIPHER_MODE]],
|
|
||||||
'aes256-cbc': [['2.3.0,d0.47,l10.2', '6.6', None], [FAIL_OPENSSH67_UNSAFE], [WARN_CIPHER_MODE]],
|
|
||||||
'rijndael128-cbc': [['2.3.0', '3.0.2'], [FAIL_OPENSSH31_REMOVE], [WARN_CIPHER_MODE]],
|
|
||||||
'rijndael192-cbc': [['2.3.0', '3.0.2'], [FAIL_OPENSSH31_REMOVE], [WARN_CIPHER_MODE]],
|
|
||||||
'rijndael256-cbc': [['2.3.0', '3.0.2'], [FAIL_OPENSSH31_REMOVE], [WARN_CIPHER_MODE]],
|
|
||||||
'rijndael-cbc@lysator.liu.se': [['2.3.0', '6.6', '7.1'], [FAIL_OPENSSH67_UNSAFE], [WARN_OPENSSH72_LEGACY, WARN_CIPHER_MODE]],
|
|
||||||
'aes128-ctr': [['3.7,d0.52,l10.4.1']],
|
|
||||||
'aes192-ctr': [['3.7,l10.4.1']],
|
|
||||||
'aes256-ctr': [['3.7,d0.52,l10.4.1']],
|
|
||||||
'aes128-gcm': [[]],
|
|
||||||
'aes256-gcm': [[]],
|
|
||||||
'AEAD_AES_128_GCM': [[]],
|
'AEAD_AES_128_GCM': [[]],
|
||||||
'AEAD_AES_256_GCM': [[]],
|
'AEAD_AES_256_GCM': [[]],
|
||||||
|
'aes128-cbc': [['2.3.0,d0.28,l10.2', '6.6', None], [], [WARN_CIPHER_MODE]],
|
||||||
|
'aes128-ctr': [['3.7,d0.52,l10.4.1']],
|
||||||
|
'aes128-gcm': [[]],
|
||||||
'aes128-gcm@openssh.com': [['6.2']],
|
'aes128-gcm@openssh.com': [['6.2']],
|
||||||
|
'aes192-cbc': [['2.3.0,l10.2', '6.6', None], [], [WARN_CIPHER_MODE]],
|
||||||
|
'aes192-ctr': [['3.7,l10.4.1']],
|
||||||
|
'aes256-cbc': [['2.3.0,d0.47,l10.2', '6.6', None], [], [WARN_CIPHER_MODE]],
|
||||||
|
'aes256-ctr': [['3.7,d0.52,l10.4.1']],
|
||||||
|
'aes256-gcm': [[]],
|
||||||
'aes256-gcm@openssh.com': [['6.2']],
|
'aes256-gcm@openssh.com': [['6.2']],
|
||||||
'chacha20-poly1305': [[], [], [], [INFO_OPENSSH69_CHACHA]],
|
'arcfour128': [['4.2', '6.6', '7.1'], [FAIL_RC4]],
|
||||||
'chacha20-poly1305@openssh.com': [['6.5'], [], [], [INFO_OPENSSH69_CHACHA]],
|
'arcfour': [['2.1.0', '6.6', '7.1'], [FAIL_RC4]],
|
||||||
|
'arcfour256': [['4.2', '6.6', '7.1'], [FAIL_RC4]],
|
||||||
|
'blowfish-cbc': [['1.2.2,d0.28,l10.2', '6.6,d0.52', '7.1,d0.52'], [FAIL_BLOWFISH], [WARN_CIPHER_MODE, WARN_BLOCK_SIZE]],
|
||||||
|
'blowfish-cfb': [[], [FAIL_BLOWFISH], [WARN_CIPHER_MODE]],
|
||||||
|
'blowfish-ctr': [[], [FAIL_BLOWFISH], [WARN_CIPHER_MODE, WARN_BLOCK_SIZE]],
|
||||||
|
'blowfish-ecb': [[], [FAIL_BLOWFISH], [WARN_CIPHER_MODE]],
|
||||||
|
'blowfish': [[], [FAIL_BLOWFISH], [WARN_BLOCK_SIZE]],
|
||||||
|
'blowfish-ofb': [[], [FAIL_BLOWFISH], [WARN_CIPHER_MODE]],
|
||||||
|
'camellia128-cbc@openssh.org': [[], [], [WARN_CIPHER_MODE]],
|
||||||
'camellia128-cbc': [[], [], [WARN_CIPHER_MODE]],
|
'camellia128-cbc': [[], [], [WARN_CIPHER_MODE]],
|
||||||
'camellia128-ctr': [[]],
|
'camellia128-ctr': [[]],
|
||||||
|
'camellia128-ctr@openssh.org': [[]],
|
||||||
|
'camellia192-cbc@openssh.org': [[], [], [WARN_CIPHER_MODE]],
|
||||||
'camellia192-cbc': [[], [], [WARN_CIPHER_MODE]],
|
'camellia192-cbc': [[], [], [WARN_CIPHER_MODE]],
|
||||||
'camellia192-ctr': [[]],
|
'camellia192-ctr': [[]],
|
||||||
|
'camellia192-ctr@openssh.org': [[]],
|
||||||
|
'camellia256-cbc@openssh.org': [[], [], [WARN_CIPHER_MODE]],
|
||||||
'camellia256-cbc': [[], [], [WARN_CIPHER_MODE]],
|
'camellia256-cbc': [[], [], [WARN_CIPHER_MODE]],
|
||||||
'camellia256-ctr': [[]],
|
'camellia256-ctr': [[]],
|
||||||
|
'camellia256-ctr@openssh.org': [[]],
|
||||||
|
'cast128-12-cbc@ssh.com': [[], [FAIL_CAST], [WARN_CIPHER_MODE]],
|
||||||
|
'cast128-cbc': [['2.1.0', '6.6', '7.1'], [FAIL_CAST], [WARN_CIPHER_MODE, WARN_BLOCK_SIZE]],
|
||||||
|
'cast128-cfb': [[], [FAIL_CAST], [WARN_CIPHER_MODE]],
|
||||||
|
'cast128-ctr': [[], [FAIL_CAST]],
|
||||||
|
'cast128-ecb': [[], [FAIL_CAST], [WARN_CIPHER_MODE]],
|
||||||
|
'cast128-ofb': [[], [FAIL_CAST], [WARN_CIPHER_MODE]],
|
||||||
|
'chacha20-poly1305': [[], [], [], [INFO_DEFAULT_OPENSSH_CIPHER]],
|
||||||
|
'chacha20-poly1305@openssh.com': [['6.5'], [], [], [INFO_DEFAULT_OPENSSH_CIPHER]],
|
||||||
'crypticore128@ssh.com': [[], [FAIL_UNPROVEN]],
|
'crypticore128@ssh.com': [[], [FAIL_UNPROVEN]],
|
||||||
'seed-cbc@ssh.com': [[], [], [WARN_OBSOLETE, WARN_CIPHER_MODE]],
|
'des-cbc': [[], [FAIL_DES], [WARN_CIPHER_MODE, WARN_BLOCK_SIZE]],
|
||||||
|
'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]],
|
||||||
|
'idea-cbc': [[], [FAIL_IDEA], [WARN_CIPHER_MODE]],
|
||||||
|
'idea-cfb': [[], [FAIL_IDEA], [WARN_CIPHER_MODE]],
|
||||||
|
'idea-ctr': [[], [FAIL_IDEA]],
|
||||||
|
'idea-ecb': [[], [FAIL_IDEA], [WARN_CIPHER_MODE]],
|
||||||
|
'idea-ofb': [[], [FAIL_IDEA], [WARN_CIPHER_MODE]],
|
||||||
|
'none': [['1.2.2,d2013.56,l10.2'], [FAIL_PLAINTEXT]],
|
||||||
|
'rijndael128-cbc': [['2.3.0', '7.0'], [FAIL_RIJNDAEL], [WARN_CIPHER_MODE], [INFO_DISABLED_IN_OPENSSH70]],
|
||||||
|
'rijndael192-cbc': [['2.3.0', '7.0'], [FAIL_RIJNDAEL], [WARN_CIPHER_MODE], [INFO_DISABLED_IN_OPENSSH70]],
|
||||||
|
'rijndael256-cbc': [['2.3.0', '7.0'], [FAIL_RIJNDAEL], [WARN_CIPHER_MODE], [INFO_DISABLED_IN_OPENSSH70]],
|
||||||
|
'rijndael-cbc@lysator.liu.se': [['2.3.0', '6.6', '7.0'], [FAIL_RIJNDAEL], [WARN_CIPHER_MODE], [INFO_DISABLED_IN_OPENSSH70]],
|
||||||
|
'rijndael-cbc@ssh.com': [[], [FAIL_RIJNDAEL], [WARN_CIPHER_MODE]],
|
||||||
|
'seed-cbc@ssh.com': [[], [FAIL_SEED], [WARN_CIPHER_MODE]],
|
||||||
|
'seed-ctr@ssh.com': [[], [FAIL_SEED]],
|
||||||
|
'serpent128-cbc': [[], [FAIL_SERPENT], [WARN_CIPHER_MODE]],
|
||||||
|
'serpent128-ctr': [[], [FAIL_SERPENT]],
|
||||||
|
'serpent128-gcm@libassh.org': [[], [FAIL_SERPENT]],
|
||||||
|
'serpent192-cbc': [[], [FAIL_SERPENT], [WARN_CIPHER_MODE]],
|
||||||
|
'serpent192-ctr': [[], [FAIL_SERPENT]],
|
||||||
|
'serpent256-cbc': [[], [FAIL_SERPENT], [WARN_CIPHER_MODE]],
|
||||||
|
'serpent256-ctr': [[], [FAIL_SERPENT]],
|
||||||
|
'serpent256-gcm@libassh.org': [[], [FAIL_SERPENT]],
|
||||||
|
'twofish128-cbc': [['d0.47', 'd2014.66'], [], [WARN_CIPHER_MODE], [INFO_DISABLED_IN_DBEAR67]],
|
||||||
|
'twofish128-ctr': [['d2015.68']],
|
||||||
|
'twofish128-gcm@libassh.org': [[]],
|
||||||
|
'twofish192-cbc': [[], [], [WARN_CIPHER_MODE]],
|
||||||
|
'twofish192-ctr': [[]],
|
||||||
|
'twofish256-cbc': [['d0.47', 'd2014.66'], [], [WARN_CIPHER_MODE], [INFO_DISABLED_IN_DBEAR67]],
|
||||||
|
'twofish256-ctr': [['d2015.68']],
|
||||||
|
'twofish256-gcm@libassh.org': [[]],
|
||||||
|
'twofish-cbc': [['d0.28', 'd2014.66'], [], [WARN_CIPHER_MODE], [INFO_DISABLED_IN_DBEAR67]],
|
||||||
|
'twofish-cfb': [[], [], [WARN_CIPHER_MODE]],
|
||||||
|
'twofish-ctr': [[]],
|
||||||
|
'twofish-ecb': [[], [], [WARN_CIPHER_MODE]],
|
||||||
|
'twofish-ofb': [[], [], [WARN_CIPHER_MODE]],
|
||||||
},
|
},
|
||||||
'mac': {
|
'mac': {
|
||||||
'none': [['d2013.56'], [FAIL_PLAINTEXT]],
|
'AEAD_AES_128_GCM': [[]],
|
||||||
'hmac-sha1': [['2.1.0,d0.28,l10.2'], [], [WARN_ENCRYPT_AND_MAC, WARN_HASH_WEAK]],
|
'AEAD_AES_256_GCM': [[]],
|
||||||
'hmac-sha1-96': [['2.5.0,d0.47', '6.6', '7.1'], [FAIL_OPENSSH67_UNSAFE], [WARN_OPENSSH72_LEGACY, WARN_ENCRYPT_AND_MAC, WARN_HASH_WEAK]],
|
'aes128-gcm': [[]],
|
||||||
'hmac-sha2-56': [[], [], [WARN_TAG_SIZE, WARN_ENCRYPT_AND_MAC]],
|
'aes256-gcm': [[]],
|
||||||
|
'chacha20-poly1305@openssh.com': [[], [], [], [INFO_NEVER_IMPLEMENTED_IN_OPENSSH]], # Despite the @openssh.com tag, this was never shipped as a MAC in OpenSSH (only as a cipher); it is only implemented as a MAC in Syncplify.
|
||||||
|
'crypticore-mac@ssh.com': [[], [FAIL_UNPROVEN]],
|
||||||
|
'hmac-md5': [['2.1.0,d0.28', '6.6', '7.1'], [FAIL_MD5], [WARN_ENCRYPT_AND_MAC]],
|
||||||
|
'hmac-md5-96': [['2.5.0', '6.6', '7.1'], [FAIL_MD5], [WARN_ENCRYPT_AND_MAC]],
|
||||||
|
'hmac-md5-96-etm@openssh.com': [['6.2', '6.6', '7.1'], [FAIL_MD5]],
|
||||||
|
'hmac-md5-etm@openssh.com': [['6.2', '6.6', '7.1'], [FAIL_MD5]],
|
||||||
|
'hmac-ripemd160': [['2.5.0', '6.6', '7.1'], [FAIL_RIPEMD], [WARN_ENCRYPT_AND_MAC]],
|
||||||
|
'hmac-ripemd160-96': [[], [FAIL_RIPEMD], [WARN_ENCRYPT_AND_MAC, WARN_TAG_SIZE]],
|
||||||
|
'hmac-ripemd160-etm@openssh.com': [['6.2', '6.6', '7.1'], [FAIL_RIPEMD]],
|
||||||
|
'hmac-ripemd160@openssh.com': [['2.1.0', '6.6', '7.1'], [FAIL_RIPEMD], [WARN_ENCRYPT_AND_MAC]],
|
||||||
|
'hmac-ripemd': [[], [FAIL_RIPEMD], [WARN_ENCRYPT_AND_MAC]],
|
||||||
|
'hmac-sha1': [['2.1.0,d0.28,l10.2'], [FAIL_SHA1], [WARN_ENCRYPT_AND_MAC]],
|
||||||
|
'hmac-sha1-96': [['2.5.0,d0.47', '6.6', '7.1'], [FAIL_SHA1], [WARN_ENCRYPT_AND_MAC]],
|
||||||
|
'hmac-sha1-96-etm@openssh.com': [['6.2', '6.6', None], [FAIL_SHA1]],
|
||||||
|
'hmac-sha1-96@openssh.com': [[], [FAIL_SHA1], [WARN_TAG_SIZE, WARN_ENCRYPT_AND_MAC], [INFO_NEVER_IMPLEMENTED_IN_OPENSSH]],
|
||||||
|
'hmac-sha1-etm@openssh.com': [['6.2'], [FAIL_SHA1]],
|
||||||
'hmac-sha2-224': [[], [], [WARN_TAG_SIZE, WARN_ENCRYPT_AND_MAC]],
|
'hmac-sha2-224': [[], [], [WARN_TAG_SIZE, WARN_ENCRYPT_AND_MAC]],
|
||||||
|
'hmac-sha224@ssh.com': [[], [], [WARN_ENCRYPT_AND_MAC]],
|
||||||
'hmac-sha2-256': [['5.9,d2013.56,l10.7.0'], [], [WARN_ENCRYPT_AND_MAC]],
|
'hmac-sha2-256': [['5.9,d2013.56,l10.7.0'], [], [WARN_ENCRYPT_AND_MAC]],
|
||||||
'hmac-sha2-256-96': [['5.9', '6.0'], [FAIL_OPENSSH61_REMOVE], [WARN_ENCRYPT_AND_MAC]],
|
'hmac-sha2-256-96': [['5.9', '6.0'], [], [WARN_ENCRYPT_AND_MAC], [INFO_REMOVED_IN_OPENSSH61]],
|
||||||
|
'hmac-sha2-256-96-etm@openssh.com': [[], [], [WARN_TAG_SIZE_96], [INFO_NEVER_IMPLEMENTED_IN_OPENSSH]], # Only ever implemented in AsyncSSH (?).
|
||||||
|
'hmac-sha2-256-etm@openssh.com': [['6.2']],
|
||||||
'hmac-sha2-384': [[], [], [WARN_ENCRYPT_AND_MAC]],
|
'hmac-sha2-384': [[], [], [WARN_ENCRYPT_AND_MAC]],
|
||||||
'hmac-sha2-512': [['5.9,d2013.56,l10.7.0'], [], [WARN_ENCRYPT_AND_MAC]],
|
'hmac-sha2-512': [['5.9,d2013.56,l10.7.0'], [], [WARN_ENCRYPT_AND_MAC]],
|
||||||
'hmac-sha2-512-96': [['5.9', '6.0'], [FAIL_OPENSSH61_REMOVE], [WARN_ENCRYPT_AND_MAC]],
|
'hmac-sha2-512-96': [['5.9', '6.0'], [], [WARN_ENCRYPT_AND_MAC], [INFO_REMOVED_IN_OPENSSH61]],
|
||||||
|
'hmac-sha2-512-96-etm@openssh.com': [[], [], [WARN_TAG_SIZE_96], [INFO_NEVER_IMPLEMENTED_IN_OPENSSH]], # Only ever implemented in AsyncSSH (?).
|
||||||
|
'hmac-sha2-512-etm@openssh.com': [['6.2']],
|
||||||
|
'hmac-sha256-2@ssh.com': [[], [], [WARN_ENCRYPT_AND_MAC]],
|
||||||
|
'hmac-sha256-96@ssh.com': [[], [], [WARN_ENCRYPT_AND_MAC, WARN_TAG_SIZE]],
|
||||||
|
'hmac-sha256@ssh.com': [[], [], [WARN_ENCRYPT_AND_MAC]],
|
||||||
|
'hmac-sha256': [[], [], [WARN_ENCRYPT_AND_MAC]],
|
||||||
|
'hmac-sha2-56': [[], [], [WARN_TAG_SIZE, WARN_ENCRYPT_AND_MAC]],
|
||||||
'hmac-sha3-224': [[], [], [WARN_ENCRYPT_AND_MAC]],
|
'hmac-sha3-224': [[], [], [WARN_ENCRYPT_AND_MAC]],
|
||||||
'hmac-sha3-256': [[], [], [WARN_ENCRYPT_AND_MAC]],
|
'hmac-sha3-256': [[], [], [WARN_ENCRYPT_AND_MAC]],
|
||||||
'hmac-sha3-384': [[], [], [WARN_ENCRYPT_AND_MAC]],
|
'hmac-sha3-384': [[], [], [WARN_ENCRYPT_AND_MAC]],
|
||||||
'hmac-sha3-512': [[], [], [WARN_ENCRYPT_AND_MAC]],
|
'hmac-sha3-512': [[], [], [WARN_ENCRYPT_AND_MAC]],
|
||||||
'hmac-sha256': [[], [], [WARN_ENCRYPT_AND_MAC]],
|
'hmac-sha384@ssh.com': [[], [], [WARN_ENCRYPT_AND_MAC]],
|
||||||
'hmac-sha256-96@ssh.com': [[], [], [WARN_ENCRYPT_AND_MAC, WARN_TAG_SIZE]],
|
|
||||||
'hmac-sha256@ssh.com': [[], [], [WARN_ENCRYPT_AND_MAC]],
|
|
||||||
'hmac-sha512': [[], [], [WARN_ENCRYPT_AND_MAC]],
|
|
||||||
'hmac-sha512@ssh.com': [[], [], [WARN_ENCRYPT_AND_MAC]],
|
'hmac-sha512@ssh.com': [[], [], [WARN_ENCRYPT_AND_MAC]],
|
||||||
'hmac-md5': [['2.1.0,d0.28', '6.6', '7.1'], [FAIL_OPENSSH67_UNSAFE], [WARN_OPENSSH72_LEGACY, WARN_ENCRYPT_AND_MAC, WARN_HASH_WEAK]],
|
'hmac-sha512': [[], [], [WARN_ENCRYPT_AND_MAC]],
|
||||||
'hmac-md5-96': [['2.5.0', '6.6', '7.1'], [FAIL_OPENSSH67_UNSAFE], [WARN_OPENSSH72_LEGACY, WARN_ENCRYPT_AND_MAC, WARN_HASH_WEAK]],
|
'hmac-whirlpool': [[], [], [WARN_ENCRYPT_AND_MAC]],
|
||||||
'hmac-ripemd': [[], [FAIL_DEPRECATED_MAC], [WARN_OPENSSH72_LEGACY, WARN_ENCRYPT_AND_MAC]],
|
'none': [['d2013.56'], [FAIL_PLAINTEXT]],
|
||||||
'hmac-ripemd160': [['2.5.0', '6.6', '7.1'], [FAIL_OPENSSH67_UNSAFE], [WARN_OPENSSH72_LEGACY, WARN_ENCRYPT_AND_MAC]],
|
|
||||||
'hmac-ripemd160-96': [[], [FAIL_DEPRECATED_MAC], [WARN_ENCRYPT_AND_MAC, WARN_TAG_SIZE]],
|
|
||||||
'hmac-ripemd160@openssh.com': [['2.1.0', '6.6', '7.1'], [FAIL_OPENSSH67_UNSAFE], [WARN_OPENSSH72_LEGACY, WARN_ENCRYPT_AND_MAC]],
|
|
||||||
'umac-64@openssh.com': [['4.7'], [], [WARN_ENCRYPT_AND_MAC, WARN_TAG_SIZE]],
|
|
||||||
'umac-128@openssh.com': [['6.2'], [], [WARN_ENCRYPT_AND_MAC]],
|
|
||||||
'hmac-sha1-etm@openssh.com': [['6.2'], [], [WARN_HASH_WEAK]],
|
|
||||||
'hmac-sha1-96-etm@openssh.com': [['6.2', '6.6', None], [FAIL_OPENSSH67_UNSAFE], [WARN_HASH_WEAK]],
|
|
||||||
'hmac-sha2-256-96-etm@openssh.com': [[], [], [WARN_TAG_SIZE_96]], # Despite the @openssh.com tag, it doesn't appear that this was ever shipped with OpenSSH; it is only implemented in AsyncSSH (?).
|
|
||||||
'hmac-sha2-512-96-etm@openssh.com': [[], [], [WARN_TAG_SIZE_96]], # Despite the @openssh.com tag, it doesn't appear that this was ever shipped with OpenSSH; it is only implemented in AsyncSSH (?).
|
|
||||||
'hmac-sha2-256-etm@openssh.com': [['6.2']],
|
|
||||||
'hmac-sha2-512-etm@openssh.com': [['6.2']],
|
|
||||||
'hmac-md5-etm@openssh.com': [['6.2', '6.6', '7.1'], [FAIL_OPENSSH67_UNSAFE], [WARN_OPENSSH72_LEGACY, WARN_HASH_WEAK]],
|
|
||||||
'hmac-md5-96-etm@openssh.com': [['6.2', '6.6', '7.1'], [FAIL_OPENSSH67_UNSAFE], [WARN_OPENSSH72_LEGACY, WARN_HASH_WEAK]],
|
|
||||||
'hmac-ripemd160-etm@openssh.com': [['6.2', '6.6', '7.1'], [FAIL_OPENSSH67_UNSAFE], [WARN_OPENSSH72_LEGACY]],
|
|
||||||
'umac-32@openssh.com': [[], [], [WARN_ENCRYPT_AND_MAC, WARN_TAG_SIZE]], # Despite having the @openssh.com suffix, this may never have shipped with OpenSSH (!).
|
|
||||||
'umac-64-etm@openssh.com': [['6.2'], [], [WARN_TAG_SIZE]],
|
|
||||||
'umac-96@openssh.com': [[], [], [WARN_ENCRYPT_AND_MAC]], # Despite having the @openssh.com suffix, this may never have shipped with OpenSSH (!).
|
|
||||||
'umac-128-etm@openssh.com': [['6.2']],
|
'umac-128-etm@openssh.com': [['6.2']],
|
||||||
'aes128-gcm': [[]],
|
'umac-128@openssh.com': [['6.2'], [], [WARN_ENCRYPT_AND_MAC]],
|
||||||
'aes256-gcm': [[]],
|
'umac-32@openssh.com': [[], [], [WARN_ENCRYPT_AND_MAC, WARN_TAG_SIZE], [INFO_NEVER_IMPLEMENTED_IN_OPENSSH]],
|
||||||
'chacha20-poly1305@openssh.com': [[]], # Despite the @openssh.com tag, this was never shipped as a MAC in OpenSSH (only as a cipher); it is only implemented as a MAC in Syncplify.
|
'umac-64-etm@openssh.com': [['6.2'], [], [WARN_TAG_SIZE]],
|
||||||
'crypticore-mac@ssh.com': [[], [FAIL_UNPROVEN]],
|
'umac-64@openssh.com': [['4.7'], [], [WARN_ENCRYPT_AND_MAC, WARN_TAG_SIZE]],
|
||||||
'AEAD_AES_128_GCM': [[]],
|
'umac-96@openssh.com': [[], [], [WARN_ENCRYPT_AND_MAC], [INFO_NEVER_IMPLEMENTED_IN_OPENSSH]],
|
||||||
'AEAD_AES_256_GCM': [[]],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"""
|
"""
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (C) 2017-2021 Joe Testa (jtesta@positronsecurity.com)
|
Copyright (C) 2017-2023 Joe Testa (jtesta@positronsecurity.com)
|
||||||
Copyright (C) 2017 Andris Raugulis (moo@arthepsy.eu)
|
Copyright (C) 2017 Andris Raugulis (moo@arthepsy.eu)
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
@ -34,8 +34,10 @@ import traceback
|
|||||||
|
|
||||||
# pylint: disable=unused-import
|
# pylint: disable=unused-import
|
||||||
from typing import Dict, List, Set, Sequence, Tuple, Iterable # noqa: F401
|
from typing import Dict, List, Set, Sequence, Tuple, Iterable # noqa: F401
|
||||||
from typing import Callable, Optional, Union, Any # noqa: F401
|
from typing import cast, Callable, Optional, Union, Any # noqa: F401
|
||||||
|
|
||||||
|
from ssh_audit.globals import SNAP_PACKAGE
|
||||||
|
from ssh_audit.globals import SNAP_PERMISSIONS_ERROR
|
||||||
from ssh_audit.globals import VERSION
|
from ssh_audit.globals import VERSION
|
||||||
from ssh_audit.globals import WINDOWS_MAN_PAGE
|
from ssh_audit.globals import WINDOWS_MAN_PAGE
|
||||||
from ssh_audit.algorithm import Algorithm
|
from ssh_audit.algorithm import Algorithm
|
||||||
@ -59,22 +61,32 @@ from ssh_audit.ssh_socket import SSH_Socket
|
|||||||
from ssh_audit.utils import Utils
|
from ssh_audit.utils import Utils
|
||||||
from ssh_audit.versionvulnerabilitydb import VersionVulnerabilityDB
|
from ssh_audit.versionvulnerabilitydb import VersionVulnerabilityDB
|
||||||
|
|
||||||
|
|
||||||
|
# no_idna_workaround = False
|
||||||
|
|
||||||
# Only import colorama under Windows. Other OSes can natively handle terminal colors.
|
# Only import colorama under Windows. Other OSes can natively handle terminal colors.
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
try:
|
try:
|
||||||
from colorama import init as colorama_init
|
from colorama import just_fix_windows_console
|
||||||
colorama_init()
|
just_fix_windows_console()
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# This is a workaround for a Python bug that causes a crash on Windows when multiple threads are used (see https://github.com/python/cpython/issues/73474). Importing the idna module and using it in a no-op seems to fix the issue. Otherwise, if idna isn't available at run-time, force single threaded scans.
|
||||||
|
# try:
|
||||||
|
# import idna # noqa: F401
|
||||||
|
#
|
||||||
|
# ''.encode('idna')
|
||||||
|
# except ImportError:
|
||||||
|
# no_idna_workaround = True
|
||||||
|
|
||||||
def usage(err: Optional[str] = None) -> None:
|
|
||||||
|
def usage(uout: OutputBuffer, err: Optional[str] = None) -> None:
|
||||||
retval = exitcodes.GOOD
|
retval = exitcodes.GOOD
|
||||||
uout = OutputBuffer()
|
|
||||||
p = os.path.basename(sys.argv[0])
|
p = os.path.basename(sys.argv[0])
|
||||||
uout.head('# {} {}, https://github.com/jtesta/ssh-audit\n'.format(p, VERSION))
|
uout.head('# {} {}, https://github.com/jtesta/ssh-audit\n'.format(p, VERSION))
|
||||||
if err is not None and len(err) > 0:
|
if err is not None and len(err) > 0:
|
||||||
uout.fail('\n' + err)
|
uout.fail(err + '\n')
|
||||||
retval = exitcodes.UNKNOWN_ERROR
|
retval = exitcodes.UNKNOWN_ERROR
|
||||||
uout.info('usage: {0} [options] <host>\n'.format(p))
|
uout.info('usage: {0} [options] <host>\n'.format(p))
|
||||||
uout.info(' -h, --help print this help')
|
uout.info(' -h, --help print this help')
|
||||||
@ -85,6 +97,9 @@ def usage(err: Optional[str] = None) -> None:
|
|||||||
uout.info(' -b, --batch batch output')
|
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(' -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(' -d, --debug debug output')
|
uout.info(' -d, --debug debug output')
|
||||||
|
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(' -j, --json JSON output (use -jj to enable indents)')
|
||||||
uout.info(' -l, --level=<level> minimum output level (info|warn|fail)')
|
uout.info(' -l, --level=<level> minimum output level (info|warn|fail)')
|
||||||
uout.info(' -L, --list-policies list all the official, built-in policies')
|
uout.info(' -L, --list-policies list all the official, built-in policies')
|
||||||
@ -103,10 +118,10 @@ def usage(err: Optional[str] = None) -> None:
|
|||||||
sys.exit(retval)
|
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, alg_sizes: Optional[Dict[str, Tuple[int, int]]] = None) -> int: # pylint: disable=too-many-arguments
|
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:
|
with out:
|
||||||
for algorithm in algorithms:
|
for algorithm in algorithms:
|
||||||
program_retval = output_algorithm(out, alg_db, alg_type, algorithm, unknown_algs, program_retval, maxlen, alg_sizes)
|
program_retval = output_algorithm(out, alg_db, alg_type, algorithm, unknown_algs, program_retval, maxlen, host_keys=host_keys, dh_modulus_sizes=dh_modulus_sizes)
|
||||||
if not out.is_section_empty() and not is_json_output:
|
if not out.is_section_empty() and not is_json_output:
|
||||||
out.head('# ' + title)
|
out.head('# ' + title)
|
||||||
out.flush_section()
|
out.flush_section()
|
||||||
@ -115,7 +130,7 @@ def output_algorithms(out: OutputBuffer, title: str, alg_db: Dict[str, Dict[str,
|
|||||||
return program_retval
|
return program_retval
|
||||||
|
|
||||||
|
|
||||||
def output_algorithm(out: OutputBuffer, alg_db: Dict[str, Dict[str, List[List[Optional[str]]]]], alg_type: str, alg_name: str, unknown_algs: List[str], program_retval: int, alg_max_len: int = 0, alg_sizes: Optional[Dict[str, Tuple[int, int]]] = None) -> int:
|
def output_algorithm(out: OutputBuffer, alg_db: Dict[str, Dict[str, List[List[Optional[str]]]]], alg_type: str, alg_name: str, unknown_algs: List[str], program_retval: int, alg_max_len: 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
|
||||||
prefix = '(' + alg_type + ') '
|
prefix = '(' + alg_type + ') '
|
||||||
if alg_max_len == 0:
|
if alg_max_len == 0:
|
||||||
alg_max_len = len(alg_name)
|
alg_max_len = len(alg_name)
|
||||||
@ -124,14 +139,30 @@ def output_algorithm(out: OutputBuffer, alg_db: Dict[str, Dict[str, List[List[Op
|
|||||||
# If this is an RSA host key or DH GEX, append the size to its name and fix
|
# If this is an RSA host key or DH GEX, append the size to its name and fix
|
||||||
# the padding.
|
# the padding.
|
||||||
alg_name_with_size = None
|
alg_name_with_size = None
|
||||||
if (alg_sizes is not None) and (alg_name in alg_sizes):
|
if (dh_modulus_sizes is not None) and (alg_name in dh_modulus_sizes):
|
||||||
hostkey_size, ca_size = alg_sizes[alg_name]
|
alg_name_with_size = '%s (%u-bit)' % (alg_name, dh_modulus_sizes[alg_name])
|
||||||
if ca_size > 0:
|
|
||||||
alg_name_with_size = '%s (%d-bit cert/%d-bit CA)' % (alg_name, hostkey_size, ca_size)
|
|
||||||
padding = padding[0:-15]
|
|
||||||
else:
|
|
||||||
alg_name_with_size = '%s (%d-bit)' % (alg_name, hostkey_size)
|
|
||||||
padding = padding[0:-11]
|
padding = padding[0:-11]
|
||||||
|
elif (host_keys is not None) and (alg_name in host_keys):
|
||||||
|
hostkey_size = cast(int, host_keys[alg_name]['hostkey_size'])
|
||||||
|
ca_key_type = cast(str, host_keys[alg_name]['ca_key_type'])
|
||||||
|
ca_key_size = cast(int, host_keys[alg_name]['ca_key_size'])
|
||||||
|
|
||||||
|
# If this is an RSA variant, just print "RSA".
|
||||||
|
if ca_key_type in HostKeyTest.RSA_FAMILY:
|
||||||
|
ca_key_type = "RSA"
|
||||||
|
|
||||||
|
if len(ca_key_type) > 0 and ca_key_size > 0:
|
||||||
|
alg_name_with_size = '%s (%u-bit cert/%u-bit %s CA)' % (alg_name, hostkey_size, ca_key_size, ca_key_type)
|
||||||
|
padding = padding[0:-15]
|
||||||
|
elif alg_name in HostKeyTest.RSA_FAMILY:
|
||||||
|
alg_name_with_size = '%s (%u-bit)' % (alg_name, hostkey_size)
|
||||||
|
padding = padding[0:-11]
|
||||||
|
|
||||||
|
# If this is a kex algorithm and starts with 'gss-', then normalize its name (i.e.: 'gss-gex-sha1-vz8J1E9PzLr8b1K+0remTg==' => 'gss-gex-sha1-*'). The base64 field can vary, so we'll convert it to the wildcard that our database uses and we'll just resume doing a straight match like all other algorithm names.
|
||||||
|
alg_name_original = alg_name
|
||||||
|
if alg_type == 'kex' and alg_name.startswith('gss-'):
|
||||||
|
last_dash = alg_name.rindex('-')
|
||||||
|
alg_name = "%s-*" % alg_name[0:last_dash]
|
||||||
|
|
||||||
texts = []
|
texts = []
|
||||||
if len(alg_name.strip()) == 0:
|
if len(alg_name.strip()) == 0:
|
||||||
@ -158,6 +189,10 @@ def output_algorithm(out: OutputBuffer, alg_db: Dict[str, Dict[str, List[List[Op
|
|||||||
texts.append(('warn', 'unknown algorithm'))
|
texts.append(('warn', 'unknown algorithm'))
|
||||||
unknown_algs.append(alg_name)
|
unknown_algs.append(alg_name)
|
||||||
|
|
||||||
|
# For kex GSS algorithms, now that we already did the database lookup (above), restore the original algorithm name so its reported properly in the output.
|
||||||
|
if alg_name != alg_name_original:
|
||||||
|
alg_name = alg_name_original
|
||||||
|
|
||||||
alg_name = alg_name_with_size if alg_name_with_size is not None else alg_name
|
alg_name = alg_name_with_size if alg_name_with_size is not None else alg_name
|
||||||
first = True
|
first = True
|
||||||
for level, text in texts:
|
for level, text in texts:
|
||||||
@ -177,7 +212,7 @@ def output_algorithm(out: OutputBuffer, alg_db: Dict[str, Dict[str, List[List[Op
|
|||||||
if out.verbose:
|
if out.verbose:
|
||||||
f(prefix + alg_name + comment)
|
f(prefix + alg_name + comment)
|
||||||
elif text != '':
|
elif text != '':
|
||||||
comment = (padding + ' `- [' + level + '] ' + text)
|
comment = padding + ' `- [' + level + '] ' + text
|
||||||
f(' ' * len(prefix + alg_name) + comment)
|
f(' ' * len(prefix + alg_name) + comment)
|
||||||
|
|
||||||
return program_retval
|
return program_retval
|
||||||
@ -213,10 +248,12 @@ def output_compatibility(out: OutputBuffer, algs: Algorithms, client_audit: bool
|
|||||||
out.good('(gen) compatibility: ' + ', '.join(comp_text))
|
out.good('(gen) compatibility: ' + ', '.join(comp_text))
|
||||||
|
|
||||||
|
|
||||||
def output_security_sub(out: OutputBuffer, sub: str, software: Optional[Software], client_audit: bool, padlen: int) -> None:
|
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
|
secdb = VersionVulnerabilityDB.CVE if sub == 'cve' else VersionVulnerabilityDB.TXT
|
||||||
if software is None or software.product not in secdb:
|
if software is None or software.product not in secdb:
|
||||||
return
|
return ret
|
||||||
for line in secdb[software.product]:
|
for line in secdb[software.product]:
|
||||||
vfrom: str = ''
|
vfrom: str = ''
|
||||||
vtill: str = ''
|
vtill: str = ''
|
||||||
@ -244,17 +281,22 @@ def output_security_sub(out: OutputBuffer, sub: str, software: Optional[Software
|
|||||||
if cvss >= 8.0:
|
if cvss >= 8.0:
|
||||||
out_func = out.fail
|
out_func = out.fail
|
||||||
out_func('(cve) {}{} -- (CVSSv2: {}) {}'.format(name, p, cvss, descr))
|
out_func('(cve) {}{} -- (CVSSv2: {}) {}'.format(name, p, cvss, descr))
|
||||||
|
ret.append({'name': name, 'cvssv2': cvss, 'description': descr})
|
||||||
else:
|
else:
|
||||||
descr = line[4]
|
descr = line[4]
|
||||||
out.fail('(sec) {}{} -- {}'.format(name, p, descr))
|
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], client_audit: bool, padlen: int, is_json_output: bool) -> None:
|
|
||||||
with out:
|
with out:
|
||||||
if banner is not None:
|
if banner is not None:
|
||||||
software = Software.parse(banner)
|
software = Software.parse(banner)
|
||||||
output_security_sub(out, 'cve', software, client_audit, padlen)
|
cves = output_security_sub(out, 'cve', software, client_audit, padlen)
|
||||||
output_security_sub(out, 'txt', software, client_audit, padlen)
|
_ = output_security_sub(out, 'txt', software, client_audit, padlen)
|
||||||
if banner.protocol[0] == 1:
|
if banner.protocol[0] == 1:
|
||||||
p = '' if out.batch else ' ' * (padlen - 14)
|
p = '' if out.batch else ' ' * (padlen - 14)
|
||||||
out.fail('(sec) SSH v1 enabled{} -- SSH v1 can be exploited to recover plaintext passwords'.format(p))
|
out.fail('(sec) SSH v1 enabled{} -- SSH v1 can be exploited to recover plaintext passwords'.format(p))
|
||||||
@ -263,39 +305,41 @@ def output_security(out: OutputBuffer, banner: Optional[Banner], client_audit: b
|
|||||||
out.flush_section()
|
out.flush_section()
|
||||||
out.sep()
|
out.sep()
|
||||||
|
|
||||||
|
return cves
|
||||||
|
|
||||||
|
|
||||||
def output_fingerprints(out: OutputBuffer, algs: Algorithms, is_json_output: bool) -> None:
|
def output_fingerprints(out: OutputBuffer, algs: Algorithms, is_json_output: bool) -> None:
|
||||||
with out:
|
with out:
|
||||||
fps = []
|
fps = {}
|
||||||
if algs.ssh1kex is not None:
|
if algs.ssh1kex is not None:
|
||||||
name = 'ssh-rsa1'
|
name = 'ssh-rsa1'
|
||||||
fp = Fingerprint(algs.ssh1kex.host_key_fingerprint_data)
|
fp = Fingerprint(algs.ssh1kex.host_key_fingerprint_data)
|
||||||
# bits = algs.ssh1kex.host_key_bits
|
# bits = algs.ssh1kex.host_key_bits
|
||||||
fps.append((name, fp))
|
fps[name] = fp
|
||||||
if algs.ssh2kex is not None:
|
if algs.ssh2kex is not None:
|
||||||
host_keys = algs.ssh2kex.host_keys()
|
host_keys = algs.ssh2kex.host_keys()
|
||||||
for host_key_type in algs.ssh2kex.host_keys():
|
for host_key_type in algs.ssh2kex.host_keys():
|
||||||
if host_keys[host_key_type] is None:
|
if host_keys[host_key_type] is None:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
fp = Fingerprint(host_keys[host_key_type])
|
fp = Fingerprint(cast(bytes, host_keys[host_key_type]['raw_hostkey_bytes']))
|
||||||
|
|
||||||
# Workaround for Python's order-indifference in dicts. We might get a random RSA type (ssh-rsa, rsa-sha2-256, or rsa-sha2-512), so running the tool against the same server three times may give three different host key types here. So if we have any RSA type, we will simply hard-code it to 'ssh-rsa'.
|
# Workaround for Python's order-indifference in dicts. We might get a random RSA type (ssh-rsa, rsa-sha2-256, or rsa-sha2-512), so running the tool against the same server three times may give three different host key types here. So if we have any RSA type, we will simply hard-code it to 'ssh-rsa'.
|
||||||
if host_key_type in HostKeyTest.RSA_FAMILY:
|
if host_key_type in HostKeyTest.RSA_FAMILY:
|
||||||
host_key_type = 'ssh-rsa'
|
host_key_type = 'ssh-rsa'
|
||||||
|
|
||||||
# Skip over certificate host types (or we would return invalid fingerprints).
|
# Skip over certificate host types (or we would return invalid fingerprints), and only add one fingerprint in the RSA family.
|
||||||
if '-cert-' not in host_key_type:
|
if '-cert-' not in host_key_type:
|
||||||
fps.append((host_key_type, fp))
|
fps[host_key_type] = fp
|
||||||
# Similarly, the host keys can be processed in random order due to Python's order-indifference in dicts. So we sort this list before printing; this makes automated testing possible.
|
# Similarly, the host keys can be processed in random order due to Python's order-indifference in dicts. So we sort this list before printing; this makes automated testing possible.
|
||||||
fps = sorted(fps)
|
fp_types = sorted(fps.keys())
|
||||||
for fpp in fps:
|
for fp_type in fp_types:
|
||||||
name, fp = fpp
|
fp = fps[fp_type]
|
||||||
out.good('(fin) {}: {}'.format(name, fp.sha256))
|
out.good('(fin) {}: {}'.format(fp_type, fp.sha256))
|
||||||
|
|
||||||
# Output the MD5 hash too if verbose mode is enabled.
|
# Output the MD5 hash too if verbose mode is enabled.
|
||||||
if out.verbose:
|
if out.verbose:
|
||||||
out.info('(fin) {}: {} -- [info] do not rely on MD5 fingerprints for server identification; it is insecure for this use case'.format(name, fp.md5))
|
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))
|
||||||
|
|
||||||
if not out.is_section_empty() and not is_json_output:
|
if not out.is_section_empty() and not is_json_output:
|
||||||
out.head('# fingerprints')
|
out.head('# fingerprints')
|
||||||
@ -304,7 +348,7 @@ def output_fingerprints(out: OutputBuffer, algs: Algorithms, is_json_output: boo
|
|||||||
|
|
||||||
|
|
||||||
# Returns True if no warnings or failures encountered in configuration.
|
# Returns True if no warnings or failures encountered in configuration.
|
||||||
def output_recommendations(out: OutputBuffer, algs: Algorithms, software: Optional[Software], is_json_output: bool, padlen: int = 0) -> bool:
|
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
|
ret = True
|
||||||
# PuTTY's algorithms cannot be modified, so there's no point in issuing recommendations.
|
# PuTTY's algorithms cannot be modified, so there's no point in issuing recommendations.
|
||||||
@ -335,35 +379,35 @@ def output_recommendations(out: OutputBuffer, algs: Algorithms, software: Option
|
|||||||
ret = False
|
ret = False
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
for_server = True
|
|
||||||
with out:
|
with out:
|
||||||
software, alg_rec = algs.get_recommendations(software, for_server)
|
recommendations = get_algorithm_recommendations(algs, algorithm_recommendation_suppress_list, software, for_server=True)
|
||||||
for sshv in range(2, 0, -1):
|
|
||||||
if sshv not in alg_rec:
|
for level in recommendations: # pylint: disable=consider-using-dict-items
|
||||||
continue
|
for action in recommendations[level]:
|
||||||
for alg_type in ['kex', 'key', 'enc', 'mac']:
|
for alg_type in recommendations[level][action]:
|
||||||
if alg_type not in alg_rec[sshv]:
|
for alg_name_and_notes in recommendations[level][action][alg_type]:
|
||||||
continue
|
name = alg_name_and_notes['name']
|
||||||
for action in ['del', 'add', 'chg']:
|
notes = alg_name_and_notes['notes']
|
||||||
if action not in alg_rec[sshv][alg_type]:
|
|
||||||
continue
|
|
||||||
for name in alg_rec[sshv][alg_type][action]:
|
|
||||||
p = '' if out.batch else ' ' * (padlen - len(name))
|
p = '' if out.batch else ' ' * (padlen - len(name))
|
||||||
chg_additional_info = ''
|
|
||||||
if action == 'del':
|
if action == 'del':
|
||||||
an, sg, fn = 'remove', '-', out.warn
|
an, sg, fn = 'remove', '-', out.warn
|
||||||
ret = False
|
ret = False
|
||||||
if alg_rec[sshv][alg_type][action][name] >= 10:
|
if level == 'critical':
|
||||||
fn = out.fail
|
fn = out.fail
|
||||||
elif action == 'add':
|
elif action == 'add':
|
||||||
an, sg, fn = 'append', '+', out.good
|
an, sg, fn = 'append', '+', out.good
|
||||||
elif action == 'chg':
|
elif action == 'chg':
|
||||||
an, sg, fn = 'change', '!', out.fail
|
an, sg, fn = 'change', '!', out.fail
|
||||||
ret = False
|
ret = False
|
||||||
chg_additional_info = ' (increase modulus size to 2048 bits or larger)'
|
|
||||||
b = '(SSH{})'.format(sshv) if sshv == 1 else ''
|
if notes != '':
|
||||||
fm = '(rec) {0}{1}{2}-- {3} algorithm to {4}{5} {6}'
|
notes = " (%s)" % notes
|
||||||
fn(fm.format(sg, name, p, alg_type, an, chg_additional_info, b))
|
|
||||||
|
fm = '(rec) {0}{1}{2}-- {3} algorithm to {4}{5} '
|
||||||
|
fn(fm.format(sg, name, p, alg_type, an, notes))
|
||||||
|
|
||||||
if not out.is_section_empty() and not is_json_output:
|
if not out.is_section_empty() and not is_json_output:
|
||||||
if software is not None:
|
if software is not None:
|
||||||
title = '(for {})'.format(software.display(False))
|
title = '(for {})'.format(software.display(False))
|
||||||
@ -392,6 +436,27 @@ def output_info(out: OutputBuffer, software: Optional['Software'], client_audit:
|
|||||||
out.sep()
|
out.sep()
|
||||||
|
|
||||||
|
|
||||||
|
def post_process_findings(banner: Optional[Banner], algs: Algorithms) -> List[str]:
|
||||||
|
'''Perform post-processing on scan results before reporting them to the user. Returns a list of algorithms that should not be recommended'''
|
||||||
|
|
||||||
|
|
||||||
|
algorithm_recommendation_suppress_list = []
|
||||||
|
|
||||||
|
# If the server is OpenSSH, and the diffie-hellman-group-exchange-sha256 key exchange was found with modulus size 2048, add a note regarding the bug that causes the server to support 2048-bit moduli no matter the configuration.
|
||||||
|
if (algs.ssh2kex is not None and 'diffie-hellman-group-exchange-sha256' in algs.ssh2kex.kex_algorithms and 'diffie-hellman-group-exchange-sha256' in algs.ssh2kex.dh_modulus_sizes() and algs.ssh2kex.dh_modulus_sizes()['diffie-hellman-group-exchange-sha256'] == 2048) and (banner is not None and banner.software is not None and banner.software.find('OpenSSH') != -1):
|
||||||
|
|
||||||
|
# Ensure a list for notes exists.
|
||||||
|
while len(SSH2_KexDB.ALGORITHMS['kex']['diffie-hellman-group-exchange-sha256']) < 4:
|
||||||
|
SSH2_KexDB.ALGORITHMS['kex']['diffie-hellman-group-exchange-sha256'].append([])
|
||||||
|
|
||||||
|
SSH2_KexDB.ALGORITHMS['kex']['diffie-hellman-group-exchange-sha256'][3].append("A bug in OpenSSH causes it to fall back to a 2048-bit modulus regardless of server configuration (https://bugzilla.mindrot.org/show_bug.cgi?id=2793)")
|
||||||
|
|
||||||
|
# Ensure that this algorithm doesn't appear in the recommendations section since the user cannot control this OpenSSH bug.
|
||||||
|
algorithm_recommendation_suppress_list.append('diffie-hellman-group-exchange-sha256')
|
||||||
|
|
||||||
|
return algorithm_recommendation_suppress_list
|
||||||
|
|
||||||
|
|
||||||
# Returns a exitcodes.* flag to denote if any failures or warnings were encountered.
|
# Returns a exitcodes.* flag to denote if any failures or warnings were encountered.
|
||||||
def output(out: OutputBuffer, aconf: AuditConf, banner: Optional[Banner], header: List[str], client_host: Optional[str] = None, kex: Optional[SSH2_Kex] = None, pkm: Optional[SSH1_PublicKeyMessage] = None, print_target: bool = False) -> int:
|
def output(out: OutputBuffer, aconf: AuditConf, banner: Optional[Banner], header: List[str], client_host: Optional[str] = None, kex: Optional[SSH2_Kex] = None, pkm: Optional[SSH1_PublicKeyMessage] = None, print_target: bool = False) -> int:
|
||||||
|
|
||||||
@ -399,6 +464,10 @@ def output(out: OutputBuffer, aconf: AuditConf, banner: Optional[Banner], header
|
|||||||
client_audit = client_host is not None # If set, this is a client audit.
|
client_audit = client_host is not None # If set, this is a client audit.
|
||||||
sshv = 1 if pkm is not None else 2
|
sshv = 1 if pkm is not None else 2
|
||||||
algs = Algorithms(pkm, kex)
|
algs = Algorithms(pkm, kex)
|
||||||
|
|
||||||
|
# Perform post-processing on the findings to make final adjustments before outputting the results.
|
||||||
|
algorithm_recommendation_suppress_list = post_process_findings(banner, algs)
|
||||||
|
|
||||||
with out:
|
with out:
|
||||||
if print_target:
|
if print_target:
|
||||||
host = aconf.host
|
host = aconf.host
|
||||||
@ -447,9 +516,11 @@ def output(out: OutputBuffer, aconf: AuditConf, banner: Optional[Banner], header
|
|||||||
out.flush_section()
|
out.flush_section()
|
||||||
out.sep()
|
out.sep()
|
||||||
maxlen = algs.maxlen + 1
|
maxlen = algs.maxlen + 1
|
||||||
output_security(out, banner, client_audit, maxlen, aconf.json)
|
cves = output_security(out, banner, client_audit, maxlen, aconf.json)
|
||||||
# Filled in by output_algorithms() with unidentified algs.
|
# Filled in by output_algorithms() with unidentified algs.
|
||||||
unknown_algorithms: List[str] = []
|
unknown_algorithms: List[str] = []
|
||||||
|
|
||||||
|
# SSHv1
|
||||||
if pkm is not None:
|
if pkm is not None:
|
||||||
adb = SSH1_KexDB.ALGORITHMS
|
adb = SSH1_KexDB.ALGORITHMS
|
||||||
ciphers = pkm.supported_ciphers
|
ciphers = pkm.supported_ciphers
|
||||||
@ -460,24 +531,27 @@ def output(out: OutputBuffer, aconf: AuditConf, banner: Optional[Banner], header
|
|||||||
program_retval = output_algorithms(out, title, adb, atype, ciphers, unknown_algorithms, aconf.json, program_retval, maxlen)
|
program_retval = output_algorithms(out, title, adb, atype, ciphers, unknown_algorithms, aconf.json, program_retval, maxlen)
|
||||||
title, atype = 'SSH1 authentication types', 'aut'
|
title, atype = 'SSH1 authentication types', 'aut'
|
||||||
program_retval = output_algorithms(out, title, adb, atype, auths, unknown_algorithms, aconf.json, program_retval, maxlen)
|
program_retval = output_algorithms(out, title, adb, atype, auths, unknown_algorithms, aconf.json, program_retval, maxlen)
|
||||||
|
|
||||||
|
# SSHv2
|
||||||
if kex is not None:
|
if kex is not None:
|
||||||
adb = SSH2_KexDB.ALGORITHMS
|
adb = SSH2_KexDB.ALGORITHMS
|
||||||
title, atype = 'key exchange algorithms', 'kex'
|
title, atype = 'key exchange algorithms', 'kex'
|
||||||
program_retval = output_algorithms(out, title, adb, atype, kex.kex_algorithms, unknown_algorithms, aconf.json, program_retval, maxlen, kex.dh_modulus_sizes())
|
program_retval = output_algorithms(out, title, adb, atype, kex.kex_algorithms, unknown_algorithms, aconf.json, program_retval, maxlen, dh_modulus_sizes=kex.dh_modulus_sizes())
|
||||||
title, atype = 'host-key algorithms', 'key'
|
title, atype = 'host-key algorithms', 'key'
|
||||||
program_retval = output_algorithms(out, title, adb, atype, kex.key_algorithms, unknown_algorithms, aconf.json, program_retval, maxlen, kex.rsa_key_sizes())
|
program_retval = output_algorithms(out, title, adb, atype, kex.key_algorithms, unknown_algorithms, aconf.json, program_retval, maxlen, host_keys=kex.host_keys())
|
||||||
title, atype = 'encryption algorithms (ciphers)', 'enc'
|
title, atype = 'encryption algorithms (ciphers)', 'enc'
|
||||||
program_retval = output_algorithms(out, title, adb, atype, kex.server.encryption, unknown_algorithms, aconf.json, program_retval, maxlen)
|
program_retval = output_algorithms(out, title, adb, atype, kex.server.encryption, unknown_algorithms, aconf.json, program_retval, maxlen)
|
||||||
title, atype = 'message authentication code algorithms', 'mac'
|
title, atype = 'message authentication code algorithms', 'mac'
|
||||||
program_retval = output_algorithms(out, title, adb, atype, kex.server.mac, unknown_algorithms, aconf.json, program_retval, maxlen)
|
program_retval = output_algorithms(out, title, adb, atype, kex.server.mac, unknown_algorithms, aconf.json, program_retval, maxlen)
|
||||||
|
|
||||||
output_fingerprints(out, algs, aconf.json)
|
output_fingerprints(out, algs, aconf.json)
|
||||||
perfect_config = output_recommendations(out, algs, software, aconf.json, maxlen)
|
perfect_config = output_recommendations(out, algs, algorithm_recommendation_suppress_list, software, aconf.json, maxlen)
|
||||||
output_info(out, software, client_audit, not perfect_config, aconf.json)
|
output_info(out, software, client_audit, not perfect_config, aconf.json)
|
||||||
|
|
||||||
if aconf.json:
|
if aconf.json:
|
||||||
out.reset()
|
out.reset()
|
||||||
# Build & write the JSON struct.
|
# Build & write the JSON struct.
|
||||||
out.info(json.dumps(build_struct(aconf.host, banner, kex=kex, client_host=client_host), indent=4 if aconf.json_print_indent else None, sort_keys=True))
|
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), 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.
|
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. 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))
|
||||||
|
|
||||||
@ -527,6 +601,55 @@ def evaluate_policy(out: OutputBuffer, aconf: AuditConf, banner: Optional['Banne
|
|||||||
return passed
|
return passed
|
||||||
|
|
||||||
|
|
||||||
|
def get_algorithm_recommendations(algs: Optional[Algorithms], algorithm_recommendation_suppress_list: Optional[List[str]], software: Optional[Software], for_server: bool = True) -> Dict[str, Any]:
|
||||||
|
'''Returns the algorithm recommendations.'''
|
||||||
|
ret: Dict[str, Any] = {}
|
||||||
|
|
||||||
|
if algs is None or software is None:
|
||||||
|
return ret
|
||||||
|
|
||||||
|
software, alg_rec = algs.get_recommendations(software, for_server)
|
||||||
|
for sshv in range(2, 0, -1):
|
||||||
|
if sshv not in alg_rec:
|
||||||
|
continue
|
||||||
|
for alg_type in ['kex', 'key', 'enc', 'mac']:
|
||||||
|
if alg_type not in alg_rec[sshv]:
|
||||||
|
continue
|
||||||
|
for action in ['del', 'add', 'chg']:
|
||||||
|
if action not in alg_rec[sshv][alg_type]:
|
||||||
|
continue
|
||||||
|
|
||||||
|
for name in alg_rec[sshv][alg_type][action]:
|
||||||
|
|
||||||
|
# If this algorithm should be suppressed, skip it.
|
||||||
|
if algorithm_recommendation_suppress_list is not None and name in algorithm_recommendation_suppress_list:
|
||||||
|
continue
|
||||||
|
|
||||||
|
level = 'informational'
|
||||||
|
points = alg_rec[sshv][alg_type][action][name]
|
||||||
|
if points >= 10:
|
||||||
|
level = 'critical'
|
||||||
|
elif points >= 1:
|
||||||
|
level = 'warning'
|
||||||
|
|
||||||
|
if level not in ret:
|
||||||
|
ret[level] = {}
|
||||||
|
|
||||||
|
if action not in ret[level]:
|
||||||
|
ret[level][action] = {}
|
||||||
|
|
||||||
|
if alg_type not in ret[level][action]:
|
||||||
|
ret[level][action][alg_type] = []
|
||||||
|
|
||||||
|
notes = ''
|
||||||
|
if action == 'chg':
|
||||||
|
notes = 'increase modulus size to 3072 bits or larger'
|
||||||
|
|
||||||
|
ret[level][action][alg_type].append({'name': name, 'notes': notes})
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def list_policies(out: OutputBuffer) -> None:
|
def list_policies(out: OutputBuffer) -> None:
|
||||||
'''Prints a list of server & client policies.'''
|
'''Prints a list of server & client policies.'''
|
||||||
|
|
||||||
@ -560,36 +683,50 @@ def make_policy(aconf: AuditConf, banner: Optional['Banner'], kex: Optional['SSH
|
|||||||
if aconf.policy_file is None:
|
if aconf.policy_file is None:
|
||||||
raise RuntimeError('Internal error: cannot write policy file since filename is None!')
|
raise RuntimeError('Internal error: cannot write policy file since filename is None!')
|
||||||
|
|
||||||
# Open with mode 'x' (creates the file, or fails if it already exist).
|
succeeded = False
|
||||||
succeeded = True
|
err = ''
|
||||||
try:
|
try:
|
||||||
|
# Open with mode 'x' (creates the file, or fails if it already exist).
|
||||||
with open(aconf.policy_file, 'x', encoding='utf-8') as f:
|
with open(aconf.policy_file, 'x', encoding='utf-8') as f:
|
||||||
f.write(policy_data)
|
f.write(policy_data)
|
||||||
|
succeeded = True
|
||||||
except FileExistsError:
|
except FileExistsError:
|
||||||
succeeded = False
|
err = "Error: file already exists: %s" % aconf.policy_file
|
||||||
|
except PermissionError as e:
|
||||||
|
# If installed as a Snap package, print a more useful message with potential work-arounds.
|
||||||
|
if SNAP_PACKAGE:
|
||||||
|
print(SNAP_PERMISSIONS_ERROR)
|
||||||
|
sys.exit(exitcodes.UNKNOWN_ERROR)
|
||||||
|
else:
|
||||||
|
err = "Error: insufficient permissions: %s" % str(e)
|
||||||
|
|
||||||
if succeeded:
|
if succeeded:
|
||||||
print("Wrote policy to %s. Customize as necessary, then run a policy scan with -P option." % aconf.policy_file)
|
print("Wrote policy to %s. Customize as necessary, then run a policy scan with -P option." % aconf.policy_file)
|
||||||
else:
|
else:
|
||||||
print("Error: file already exists: %s" % aconf.policy_file)
|
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], usage_cb: Callable[..., None]) -> 'AuditConf': # pylint: disable=too-many-statements
|
||||||
# pylint: disable=too-many-branches
|
# pylint: disable=too-many-branches
|
||||||
aconf = AuditConf()
|
aconf = AuditConf()
|
||||||
|
|
||||||
|
enable_colors = not any(i in args for i in ['--no-colors', '-n'])
|
||||||
|
aconf.colors = enable_colors
|
||||||
|
out.use_colors = enable_colors
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sopts = 'h1246M:p:P:jbcnvl:t:T:Lmd'
|
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']
|
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=']
|
||||||
opts, args = getopt.gnu_getopt(args, sopts, lopts)
|
opts, args = getopt.gnu_getopt(args, sopts, lopts)
|
||||||
except getopt.GetoptError as err:
|
except getopt.GetoptError as err:
|
||||||
usage_cb(str(err))
|
usage_cb(out, str(err))
|
||||||
aconf.ssh1, aconf.ssh2 = False, False
|
aconf.ssh1, aconf.ssh2 = False, False
|
||||||
host: str = ''
|
host: str = ''
|
||||||
oport: Optional[str] = None
|
oport: Optional[str] = None
|
||||||
port: int = 0
|
port: int = 0
|
||||||
for o, a in opts:
|
for o, a in opts:
|
||||||
if o in ('-h', '--help'):
|
if o in ('-h', '--help'):
|
||||||
usage_cb()
|
usage_cb(out)
|
||||||
elif o in ('-1', '--ssh1'):
|
elif o in ('-1', '--ssh1'):
|
||||||
aconf.ssh1 = True
|
aconf.ssh1 = True
|
||||||
elif o in ('-2', '--ssh2'):
|
elif o in ('-2', '--ssh2'):
|
||||||
@ -605,9 +742,6 @@ def process_commandline(out: OutputBuffer, args: List[str], usage_cb: Callable[.
|
|||||||
aconf.verbose = True
|
aconf.verbose = True
|
||||||
elif o in ('-c', '--client-audit'):
|
elif o in ('-c', '--client-audit'):
|
||||||
aconf.client_audit = True
|
aconf.client_audit = True
|
||||||
elif o in ('-n', '--no-colors'):
|
|
||||||
aconf.colors = False
|
|
||||||
out.use_colors = False
|
|
||||||
elif o in ('-j', '--json'):
|
elif o in ('-j', '--json'):
|
||||||
if aconf.json: # If specified twice, enable indent printing.
|
if aconf.json: # If specified twice, enable indent printing.
|
||||||
aconf.json_print_indent = True
|
aconf.json_print_indent = True
|
||||||
@ -618,7 +752,7 @@ def process_commandline(out: OutputBuffer, args: List[str], usage_cb: Callable[.
|
|||||||
out.verbose = True
|
out.verbose = True
|
||||||
elif o in ('-l', '--level'):
|
elif o in ('-l', '--level'):
|
||||||
if a not in ('info', 'warn', 'fail'):
|
if a not in ('info', 'warn', 'fail'):
|
||||||
usage_cb('level {} is not valid'.format(a))
|
usage_cb(out, 'level {} is not valid'.format(a))
|
||||||
aconf.level = a
|
aconf.level = a
|
||||||
elif o in ('-t', '--timeout'):
|
elif o in ('-t', '--timeout'):
|
||||||
aconf.timeout = float(a)
|
aconf.timeout = float(a)
|
||||||
@ -630,8 +764,15 @@ def process_commandline(out: OutputBuffer, args: List[str], usage_cb: Callable[.
|
|||||||
aconf.policy_file = a
|
aconf.policy_file = a
|
||||||
elif o in ('-T', '--targets'):
|
elif o in ('-T', '--targets'):
|
||||||
aconf.target_file = a
|
aconf.target_file = a
|
||||||
|
|
||||||
|
# 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':
|
elif o == '--threads':
|
||||||
aconf.threads = int(a)
|
aconf.threads = int(a)
|
||||||
|
# if no_idna_workaround:
|
||||||
|
# aconf.threads = 1
|
||||||
elif o in ('-L', '--list-policies'):
|
elif o in ('-L', '--list-policies'):
|
||||||
aconf.list_policies = True
|
aconf.list_policies = True
|
||||||
elif o == '--lookup':
|
elif o == '--lookup':
|
||||||
@ -641,9 +782,32 @@ def process_commandline(out: OutputBuffer, args: List[str], usage_cb: Callable[.
|
|||||||
elif o in ('-d', '--debug'):
|
elif o in ('-d', '--debug'):
|
||||||
aconf.debug = True
|
aconf.debug = True
|
||||||
out.debug = True
|
out.debug = True
|
||||||
|
elif o in ('-g', '--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 re.search(permitted_syntax['RANGE'], a):
|
||||||
|
extracted_digits = re.findall(r'\d+', a)
|
||||||
|
bits_left_bound = int(extracted_digits[0])
|
||||||
|
bits_right_bound = int(extracted_digits[1])
|
||||||
|
|
||||||
|
bits_step = 1
|
||||||
|
if (len(extracted_digits)) == 3:
|
||||||
|
bits_step = int(extracted_digits[2])
|
||||||
|
|
||||||
|
if bits_step <= 0:
|
||||||
|
usage_cb(out, '{} {} is not valid'.format(o, bits_step))
|
||||||
|
|
||||||
|
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))
|
||||||
|
|
||||||
|
aconf.gex_test = a
|
||||||
|
|
||||||
|
|
||||||
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:
|
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()
|
usage_cb(out)
|
||||||
|
|
||||||
if aconf.manual:
|
if aconf.manual:
|
||||||
return aconf
|
return aconf
|
||||||
@ -661,7 +825,7 @@ def process_commandline(out: OutputBuffer, args: List[str], usage_cb: Callable[.
|
|||||||
else:
|
else:
|
||||||
host, port = Utils.parse_host_and_port(args[0])
|
host, port = Utils.parse_host_and_port(args[0])
|
||||||
if not host and aconf.target_file is None:
|
if not host and aconf.target_file is None:
|
||||||
usage_cb('host is empty')
|
usage_cb(out, 'host is empty')
|
||||||
|
|
||||||
if port == 0 and oport is None:
|
if port == 0 and oport is None:
|
||||||
if aconf.client_audit: # The default port to listen on during a client audit is 2222.
|
if aconf.client_audit: # The default port to listen on during a client audit is 2222.
|
||||||
@ -672,7 +836,7 @@ def process_commandline(out: OutputBuffer, args: List[str], usage_cb: Callable[.
|
|||||||
if oport is not None:
|
if oport is not None:
|
||||||
port = Utils.parse_int(oport)
|
port = Utils.parse_int(oport)
|
||||||
if port <= 0 or port > 65535:
|
if port <= 0 or port > 65535:
|
||||||
usage_cb('port {} is not valid'.format(oport))
|
usage_cb(out, 'port {} is not valid'.format(oport))
|
||||||
|
|
||||||
aconf.host = host
|
aconf.host = host
|
||||||
aconf.port = port
|
aconf.port = port
|
||||||
@ -681,8 +845,16 @@ def process_commandline(out: OutputBuffer, args: List[str], usage_cb: Callable[.
|
|||||||
|
|
||||||
# If a file containing a list of targets was given, read it.
|
# If a file containing a list of targets was given, read it.
|
||||||
if aconf.target_file is not None:
|
if aconf.target_file is not None:
|
||||||
|
try:
|
||||||
with open(aconf.target_file, 'r', encoding='utf-8') as f:
|
with open(aconf.target_file, 'r', encoding='utf-8') as f:
|
||||||
aconf.target_list = f.readlines()
|
aconf.target_list = f.readlines()
|
||||||
|
except PermissionError as e:
|
||||||
|
# If installed as a Snap package, print a more useful message with potential work-arounds.
|
||||||
|
if SNAP_PACKAGE:
|
||||||
|
print(SNAP_PERMISSIONS_ERROR)
|
||||||
|
else:
|
||||||
|
print("Error: insufficient permissions: %s" % str(e))
|
||||||
|
sys.exit(exitcodes.UNKNOWN_ERROR)
|
||||||
|
|
||||||
# Strip out whitespace from each line in target file, and skip empty lines.
|
# Strip out whitespace from each line in target file, and skip empty lines.
|
||||||
aconf.target_list = [target.strip() for target in aconf.target_list if target not in ("", "\n")]
|
aconf.target_list = [target.strip() for target in aconf.target_list if target not in ("", "\n")]
|
||||||
@ -691,10 +863,10 @@ def process_commandline(out: OutputBuffer, args: List[str], usage_cb: Callable[.
|
|||||||
if (aconf.policy_file is not None) and (aconf.make_policy is False):
|
if (aconf.policy_file is not None) and (aconf.make_policy is False):
|
||||||
|
|
||||||
# First, see if this is a built-in policy name. If not, assume a file path was provided, and try to load it from disk.
|
# First, see if this is a built-in policy name. If not, assume a file path was provided, and try to load it from disk.
|
||||||
aconf.policy = Policy.load_builtin_policy(aconf.policy_file)
|
aconf.policy = Policy.load_builtin_policy(aconf.policy_file, json_output=aconf.json)
|
||||||
if aconf.policy is None:
|
if aconf.policy is None:
|
||||||
try:
|
try:
|
||||||
aconf.policy = Policy(policy_file=aconf.policy_file)
|
aconf.policy = Policy(policy_file=aconf.policy_file, json_output=aconf.json)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
out.fail("Error while loading policy file: %s: %s" % (str(e), traceback.format_exc()))
|
out.fail("Error while loading policy file: %s: %s" % (str(e), traceback.format_exc()))
|
||||||
out.write()
|
out.write()
|
||||||
@ -715,7 +887,7 @@ def process_commandline(out: OutputBuffer, args: List[str], usage_cb: Callable[.
|
|||||||
return aconf
|
return aconf
|
||||||
|
|
||||||
|
|
||||||
def build_struct(target_host: str, banner: Optional['Banner'], kex: Optional['SSH2_Kex'] = None, pkm: Optional['SSH1_PublicKeyMessage'] = None, client_host: Optional[str] = None) -> Any:
|
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) -> Any: # pylint: disable=too-many-arguments
|
||||||
|
|
||||||
banner_str = ''
|
banner_str = ''
|
||||||
banner_protocol = None
|
banner_protocol = None
|
||||||
@ -746,28 +918,37 @@ def build_struct(target_host: str, banner: Optional['Banner'], kex: Optional['SS
|
|||||||
res['compression'] = kex.server.compression
|
res['compression'] = kex.server.compression
|
||||||
|
|
||||||
res['kex'] = []
|
res['kex'] = []
|
||||||
alg_sizes = kex.dh_modulus_sizes()
|
dh_alg_sizes = kex.dh_modulus_sizes()
|
||||||
for algorithm in kex.kex_algorithms:
|
for algorithm in kex.kex_algorithms:
|
||||||
entry: Any = {
|
entry: Any = {
|
||||||
'algorithm': algorithm,
|
'algorithm': algorithm,
|
||||||
}
|
}
|
||||||
if algorithm in alg_sizes:
|
if algorithm in dh_alg_sizes:
|
||||||
hostkey_size, ca_size = alg_sizes[algorithm]
|
hostkey_size = dh_alg_sizes[algorithm]
|
||||||
entry['keysize'] = hostkey_size
|
entry['keysize'] = hostkey_size
|
||||||
if ca_size > 0:
|
|
||||||
entry['casize'] = ca_size
|
|
||||||
res['kex'].append(entry)
|
res['kex'].append(entry)
|
||||||
|
|
||||||
res['key'] = []
|
res['key'] = []
|
||||||
alg_sizes = kex.rsa_key_sizes()
|
host_keys = kex.host_keys()
|
||||||
for algorithm in kex.key_algorithms:
|
for algorithm in kex.key_algorithms:
|
||||||
entry = {
|
entry = {
|
||||||
'algorithm': algorithm,
|
'algorithm': algorithm,
|
||||||
}
|
}
|
||||||
if algorithm in alg_sizes:
|
if algorithm in host_keys:
|
||||||
hostkey_size, ca_size = alg_sizes[algorithm]
|
hostkey_info = host_keys[algorithm]
|
||||||
|
hostkey_size = cast(int, hostkey_info['hostkey_size'])
|
||||||
|
|
||||||
|
ca_type = ''
|
||||||
|
ca_size = 0
|
||||||
|
if 'ca_key_type' in hostkey_info:
|
||||||
|
ca_type = cast(str, hostkey_info['ca_key_type'])
|
||||||
|
if 'ca_key_size' in hostkey_info:
|
||||||
|
ca_size = cast(int, hostkey_info['ca_key_size'])
|
||||||
|
|
||||||
|
if algorithm in HostKeyTest.RSA_FAMILY or algorithm.startswith('ssh-rsa-cert-v0'):
|
||||||
entry['keysize'] = hostkey_size
|
entry['keysize'] = hostkey_size
|
||||||
if ca_size > 0:
|
if ca_size > 0:
|
||||||
|
entry['ca_algorithm'] = ca_type
|
||||||
entry['casize'] = ca_size
|
entry['casize'] = ca_size
|
||||||
res['key'].append(entry)
|
res['key'].append(entry)
|
||||||
|
|
||||||
@ -787,7 +968,7 @@ def build_struct(target_host: str, banner: Optional['Banner'], kex: Optional['SS
|
|||||||
if host_keys[host_key_type] is None:
|
if host_keys[host_key_type] is None:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
fp = Fingerprint(host_keys[host_key_type])
|
fp = Fingerprint(cast(bytes, host_keys[host_key_type]['raw_hostkey_bytes']))
|
||||||
|
|
||||||
# Skip over certificate host types (or we would return invalid fingerprints).
|
# Skip over certificate host types (or we would return invalid fingerprints).
|
||||||
if '-cert-' in host_key_type:
|
if '-cert-' in host_key_type:
|
||||||
@ -821,6 +1002,12 @@ def build_struct(target_host: str, banner: Optional['Banner'], kex: Optional['SS
|
|||||||
'fp': pkm_fp,
|
'fp': pkm_fp,
|
||||||
}]
|
}]
|
||||||
|
|
||||||
|
# Add in the CVE information.
|
||||||
|
res['cves'] = cves
|
||||||
|
|
||||||
|
# Add in the recommendations.
|
||||||
|
res['recommendations'] = get_algorithm_recommendations(algorithms, algorithm_recommendation_suppress_list, software, for_server=True)
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
@ -896,13 +1083,16 @@ def audit(out: OutputBuffer, aconf: AuditConf, sshv: Optional[int] = None, print
|
|||||||
program_retval = output(out, aconf, banner, header, pkm=SSH1_PublicKeyMessage.parse(payload))
|
program_retval = output(out, aconf, banner, header, pkm=SSH1_PublicKeyMessage.parse(payload))
|
||||||
elif sshv == 2:
|
elif sshv == 2:
|
||||||
try:
|
try:
|
||||||
kex = SSH2_Kex.parse(payload)
|
kex = SSH2_Kex.parse(out, payload)
|
||||||
except Exception:
|
except Exception:
|
||||||
out.fail("Failed to parse server's kex. Stack trace:\n%s" % str(traceback.format_exc()))
|
out.fail("Failed to parse server's kex. Stack trace:\n%s" % str(traceback.format_exc()))
|
||||||
return exitcodes.CONNECTION_ERROR
|
return exitcodes.CONNECTION_ERROR
|
||||||
|
|
||||||
if aconf.client_audit is False:
|
if aconf.client_audit is False:
|
||||||
HostKeyTest.run(out, s, kex)
|
HostKeyTest.run(out, s, kex)
|
||||||
|
if aconf.gex_test != '':
|
||||||
|
return run_gex_granular_modulus_size_test(out, s, kex, aconf)
|
||||||
|
else:
|
||||||
GEXTest.run(out, s, kex)
|
GEXTest.run(out, s, kex)
|
||||||
|
|
||||||
# This is a standard audit scan.
|
# This is a standard audit scan.
|
||||||
@ -1042,6 +1232,79 @@ def windows_manual(out: OutputBuffer) -> int:
|
|||||||
return retval
|
return retval
|
||||||
|
|
||||||
|
|
||||||
|
def get_permitted_syntax_for_gex_test() -> Dict[str, str]:
|
||||||
|
syntax = {
|
||||||
|
'RANGE': r'^\d+-\d+(:\d+)?$',
|
||||||
|
'LIST_WITHOUT_MIN_PREF_MAX': r'^\d+(,\d+)*$',
|
||||||
|
'LIST_WITH_MIN_PREF_MAX': r'^\d+:\d+:\d+(,\d+:\d+:\d+)*$'
|
||||||
|
}
|
||||||
|
return syntax
|
||||||
|
|
||||||
|
|
||||||
|
def run_gex_granular_modulus_size_test(out: OutputBuffer, s: 'SSH_Socket', kex: 'SSH2_Kex', aconf: AuditConf) -> int:
|
||||||
|
'''Extracts the user specified modulus sizes and submits them for testing against the target server. Returns an exitcodes.* flag.'''
|
||||||
|
|
||||||
|
permitted_syntax = get_permitted_syntax_for_gex_test()
|
||||||
|
|
||||||
|
mod_dict: Dict[str, List[int]] = {}
|
||||||
|
|
||||||
|
# Range syntax.
|
||||||
|
if re.search(permitted_syntax['RANGE'], aconf.gex_test):
|
||||||
|
extracted_digits = re.findall(r'\d+', aconf.gex_test)
|
||||||
|
bits_left_bound = int(extracted_digits[0])
|
||||||
|
bits_right_bound = int(extracted_digits[1])
|
||||||
|
|
||||||
|
bits_step = 1
|
||||||
|
if (len(extracted_digits)) == 3:
|
||||||
|
bits_step = int(extracted_digits[2])
|
||||||
|
|
||||||
|
# If the left value is greater than the right value, then the sequence
|
||||||
|
# operates from right to left.
|
||||||
|
if bits_left_bound <= bits_right_bound:
|
||||||
|
bits_in_range_to_test = range(bits_left_bound, bits_right_bound + 1, bits_step)
|
||||||
|
else:
|
||||||
|
bits_in_range_to_test = range(bits_left_bound, bits_right_bound - 1, -abs(bits_step))
|
||||||
|
|
||||||
|
out.v("A separate test will be performed against each of the following modulus sizes: " + ", ".join([str(x) for x in bits_in_range_to_test]) + ".", write_now=True)
|
||||||
|
|
||||||
|
for i_bits in bits_in_range_to_test:
|
||||||
|
program_retval = GEXTest.granular_modulus_size_test(out, s, kex, i_bits, i_bits, i_bits, mod_dict)
|
||||||
|
if program_retval != exitcodes.GOOD:
|
||||||
|
return program_retval
|
||||||
|
|
||||||
|
# Two variations of list syntax.
|
||||||
|
if re.search(permitted_syntax['LIST_WITHOUT_MIN_PREF_MAX'], aconf.gex_test):
|
||||||
|
bits_in_list_to_test = aconf.gex_test.split(',')
|
||||||
|
out.v("A separate test will be performed against each of the following modulus sizes: " + ", ".join([str(x) for x in bits_in_list_to_test]) + ".", write_now=True)
|
||||||
|
for s_bits in bits_in_list_to_test:
|
||||||
|
program_retval = GEXTest.granular_modulus_size_test(out, s, kex, int(s_bits), int(s_bits), int(s_bits), mod_dict)
|
||||||
|
if program_retval != exitcodes.GOOD:
|
||||||
|
return program_retval
|
||||||
|
|
||||||
|
if re.search(permitted_syntax['LIST_WITH_MIN_PREF_MAX'], aconf.gex_test):
|
||||||
|
sets_of_min_pref_max = aconf.gex_test.split(',')
|
||||||
|
out.v("A separate test will be performed against each of the following sets of 'min:pref:max' modulus sizes: " + ', '.join(sets_of_min_pref_max), write_now=True)
|
||||||
|
for set_of_min_pref_max in sets_of_min_pref_max:
|
||||||
|
bits_in_list_to_test = set_of_min_pref_max.split(':')
|
||||||
|
program_retval = GEXTest.granular_modulus_size_test(out, s, kex, int(bits_in_list_to_test[0]), int(bits_in_list_to_test[1]), int(bits_in_list_to_test[2]), mod_dict)
|
||||||
|
if program_retval != exitcodes.GOOD:
|
||||||
|
return program_retval
|
||||||
|
|
||||||
|
if mod_dict:
|
||||||
|
if aconf.json:
|
||||||
|
json_struct = {'dh-gex-modulus-size': mod_dict}
|
||||||
|
out.info(json.dumps(json_struct, indent=4 if aconf.json_print_indent else None, sort_keys=True))
|
||||||
|
else:
|
||||||
|
out.head('# diffie-hellman group exchange modulus size')
|
||||||
|
max_key_len = len(max(mod_dict, key=len))
|
||||||
|
|
||||||
|
for key, value in mod_dict.items():
|
||||||
|
padding = (max_key_len - len(key)) + 1
|
||||||
|
out.info(key + " " * padding + '--> ' + ', '.join([str(i) for i in value]))
|
||||||
|
|
||||||
|
return program_retval
|
||||||
|
|
||||||
|
|
||||||
def main() -> int:
|
def main() -> int:
|
||||||
out = OutputBuffer()
|
out = OutputBuffer()
|
||||||
aconf = process_commandline(out, sys.argv[1:], usage)
|
aconf = process_commandline(out, sys.argv[1:], usage)
|
||||||
@ -1083,7 +1346,7 @@ def main() -> int:
|
|||||||
host, port = Utils.parse_host_and_port(target, default_port=22)
|
host, port = Utils.parse_host_and_port(target, default_port=22)
|
||||||
target_servers.append((host, port))
|
target_servers.append((host, port))
|
||||||
|
|
||||||
# A ranked list of return codes. Those with higher indices will take precendence over lower ones. For example, if three servers are scanned, yielding WARNING, GOOD, and UNKNOWN_ERROR, the overall result will be UNKNOWN_ERROR, since its index is the highest. Errors have highest priority, followed by failures, then warnings.
|
# A ranked list of return codes. Those with higher indices will take precedence over lower ones. For example, if three servers are scanned, yielding WARNING, GOOD, and UNKNOWN_ERROR, the overall result will be UNKNOWN_ERROR, since its index is the highest. Errors have highest priority, followed by failures, then warnings.
|
||||||
ranked_return_codes = [exitcodes.GOOD, exitcodes.WARNING, exitcodes.FAILURE, exitcodes.CONNECTION_ERROR, exitcodes.UNKNOWN_ERROR]
|
ranked_return_codes = [exitcodes.GOOD, exitcodes.WARNING, exitcodes.FAILURE, exitcodes.CONNECTION_ERROR, exitcodes.UNKNOWN_ERROR]
|
||||||
|
|
||||||
# Queue all worker threads.
|
# Queue all worker threads.
|
||||||
|
@ -86,7 +86,7 @@ class SSH_Socket(ReadBuf, WriteBuf):
|
|||||||
|
|
||||||
# If the user has a preference for using IPv4 over IPv6 (or vice-versa), then sort the list returned by getaddrinfo() so that the preferred address type comes first.
|
# If the user has a preference for using IPv4 over IPv6 (or vice-versa), then sort the list returned by getaddrinfo() so that the preferred address type comes first.
|
||||||
if len(self.__ip_version_preference) == 2:
|
if len(self.__ip_version_preference) == 2:
|
||||||
r = sorted(r, key=lambda x: x[0], reverse=(self.__ip_version_preference[0] == 6))
|
r = sorted(r, key=lambda x: x[0], reverse=(self.__ip_version_preference[0] == 6)) # pylint: disable=superfluous-parens
|
||||||
for af, socktype, _proto, _canonname, addr in r:
|
for af, socktype, _proto, _canonname, addr in r:
|
||||||
if socktype == socket.SOCK_STREAM:
|
if socktype == socket.SOCK_STREAM:
|
||||||
yield af, addr
|
yield af, addr
|
||||||
@ -236,7 +236,7 @@ class SSH_Socket(ReadBuf, WriteBuf):
|
|||||||
self.__outputbuffer.d('KEX initialisation...', write_now=True)
|
self.__outputbuffer.d('KEX initialisation...', write_now=True)
|
||||||
|
|
||||||
kexparty = SSH2_KexParty(ciphers, macs, compressions, languages)
|
kexparty = SSH2_KexParty(ciphers, macs, compressions, languages)
|
||||||
kex = SSH2_Kex(os.urandom(16), key_exchanges, hostkeys, kexparty, kexparty, False, 0)
|
kex = SSH2_Kex(self.__outputbuffer, os.urandom(16), key_exchanges, hostkeys, kexparty, kexparty, False, 0)
|
||||||
|
|
||||||
self.write_byte(Protocol.MSG_KEXINIT)
|
self.write_byte(Protocol.MSG_KEXINIT)
|
||||||
kex.write(self)
|
kex.write(self)
|
||||||
@ -325,7 +325,7 @@ class SSH_Socket(ReadBuf, WriteBuf):
|
|||||||
self.__header = []
|
self.__header = []
|
||||||
self.__banner = None
|
self.__banner = None
|
||||||
|
|
||||||
def _close_socket(self, s: Optional[socket.socket]) -> None: # pylint: disable=no-self-use
|
def _close_socket(self, s: Optional[socket.socket]) -> None:
|
||||||
try:
|
try:
|
||||||
if s is not None:
|
if s is not None:
|
||||||
s.shutdown(socket.SHUT_RDWR)
|
s.shutdown(socket.SHUT_RDWR)
|
||||||
|
@ -35,6 +35,7 @@ class VersionVulnerabilityDB: # pylint: disable=too-few-public-methods
|
|||||||
# then affected = 1 + 4 = 5.
|
# then affected = 1 + 4 = 5.
|
||||||
CVE: Dict[str, List[List[Any]]] = {
|
CVE: Dict[str, List[List[Any]]] = {
|
||||||
'Dropbear SSH': [
|
'Dropbear SSH': [
|
||||||
|
['0.0', '2020.81', 2, 'CVE-2021-36369', 7.5, 'trivial authentication attack to bypass FIDO tokens and SSH-ASKPASS'],
|
||||||
['0.0', '2018.76', 1, 'CVE-2018-15599', 5.0, 'remote users may enumerate users on the system'],
|
['0.0', '2018.76', 1, 'CVE-2018-15599', 5.0, 'remote users may enumerate users on the system'],
|
||||||
['0.0', '2017.74', 5, 'CVE-2017-9079', 4.7, 'local users can read certain files as root'],
|
['0.0', '2017.74', 5, 'CVE-2017-9079', 4.7, 'local users can read certain files as root'],
|
||||||
['0.0', '2017.74', 5, 'CVE-2017-9078', 9.3, 'local users may elevate privileges to root under certain conditions'],
|
['0.0', '2017.74', 5, 'CVE-2017-9078', 9.3, 'local users may elevate privileges to root under certain conditions'],
|
||||||
@ -66,7 +67,21 @@ class VersionVulnerabilityDB: # pylint: disable=too-few-public-methods
|
|||||||
['0.4.7', '0.5.2', 1, 'CVE-2012-4560', 7.5, 'cause DoS or execute arbitrary code (buffer overflow)'],
|
['0.4.7', '0.5.2', 1, 'CVE-2012-4560', 7.5, 'cause DoS or execute arbitrary code (buffer overflow)'],
|
||||||
['0.4.7', '0.5.2', 1, 'CVE-2012-4559', 6.8, 'cause DoS or execute arbitrary code (double free)']],
|
['0.4.7', '0.5.2', 1, 'CVE-2012-4559', 6.8, 'cause DoS or execute arbitrary code (double free)']],
|
||||||
'OpenSSH': [
|
'OpenSSH': [
|
||||||
['1.0', '7.7', 1, 'CVE-2018-15473', 5.3, 'enumerate usernames due to timing discrepencies'],
|
['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)'],
|
['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'],
|
['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.1', 1, 'CVE-2016-1907', 5.0, 'cause DoS via crafted network traffic (out of bounds read)'],
|
||||||
@ -125,6 +140,10 @@ class VersionVulnerabilityDB: # pylint: disable=too-few-public-methods
|
|||||||
['1.2.3', '2.1.1', 1, 'CVE-2001-0361', 4.0, 'recover plaintext from ciphertext'],
|
['1.2.3', '2.1.1', 1, 'CVE-2001-0361', 4.0, 'recover plaintext from ciphertext'],
|
||||||
['1.2', '2.1', 1, 'CVE-2000-0525', 10.0, 'execute arbitrary code (improper privileges)']],
|
['1.2', '2.1', 1, 'CVE-2000-0525', 10.0, 'execute arbitrary code (improper privileges)']],
|
||||||
'PuTTY': [
|
'PuTTY': [
|
||||||
|
# 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.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.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.71', '0.72', 2, 'CVE-2019-17068', 5.0, 'xterm bracketed paste mode command injection'],
|
||||||
|
58
ssh-audit.1
58
ssh-audit.1
@ -1,4 +1,4 @@
|
|||||||
.TH SSH-AUDIT 1 "March 2, 2021"
|
.TH SSH-AUDIT 1 "March 13, 2022"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
\fBssh-audit\fP \- SSH server & client configuration auditor
|
\fBssh-audit\fP \- SSH server & client configuration auditor
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@ -6,7 +6,7 @@
|
|||||||
.RI [ options ] " <target_host>"
|
.RI [ options ] " <target_host>"
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.PP
|
.PP
|
||||||
\fBssh-audit\fP analyzes the configuration of SSH servers & clients, then warns the user of weak, obsolete, and/or un-tested cryptographic primitives. It is very useful for hardening SSH tunnels, which by default tend to be optimized for compatibility, not security.
|
\fBssh-audit\fP analyzes the configuration of SSH servers & clients, then warns the user of weak, obsolete, and/or untested cryptographic primitives. It is very useful for hardening SSH tunnels, which by default tend to be optimized for compatibility, not security.
|
||||||
.PP
|
.PP
|
||||||
See <https://www.ssh\-audit.com/> for official hardening guides for common platforms.
|
See <https://www.ssh\-audit.com/> for official hardening guides for common platforms.
|
||||||
|
|
||||||
@ -51,6 +51,36 @@ Starts a server on port 2222 to audit client software configuration. Use -p/--p
|
|||||||
.br
|
.br
|
||||||
Enable debug output.
|
Enable debug output.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.B -g, \-\-gex-test=<x[,y,...] | min1:pref1:max1[,min2:pref2:max2,...] | x-y[:step]>
|
||||||
|
.br
|
||||||
|
Runs a Diffie-Hellman Group Exchange modulus size test against a server.
|
||||||
|
|
||||||
|
Diffie-Hellman requires the client and server to agree on a generator value and a modulus value. In the "Group Exchange" implementation of Diffie-Hellman, the client specifies the size of the modulus in bits by providing the server with minimum, preferred and maximum values. The server then finds a group that best matches the client's request, returning the corresponding generator and modulus. For a full explanation of this process see RFC 4419 and its successors.
|
||||||
|
|
||||||
|
This test acts as a client by providing an SSH server with the size of a modulus and then obtains the size of the modulus returned by the server.
|
||||||
|
|
||||||
|
Three types of syntax are supported:
|
||||||
|
|
||||||
|
1. <x[,y,...]>
|
||||||
|
|
||||||
|
A comma delimited list of modulus sizes.
|
||||||
|
A test is performed against each value in the list where it acts as the minimum, preferred and maximum modulus size.
|
||||||
|
|
||||||
|
2. <min:pref:max[,min:pref:max,...]>
|
||||||
|
|
||||||
|
A set of three colon delimited values denoting minimum, preferred and maximum modulus size.
|
||||||
|
A test is performed against each set.
|
||||||
|
Multiple sets can specified as a comma separated list.
|
||||||
|
|
||||||
|
3. <x-y[:step]>
|
||||||
|
|
||||||
|
A range of modulus sizes with an optional step value. Step defaults to 1 if omitted.
|
||||||
|
If the left value is greater than the right value, then the sequence operates from right to left.
|
||||||
|
A test is performed against each value in the range where it acts as the minimum, preferred and maximum modulus size.
|
||||||
|
|
||||||
|
Duplicates are excluded from the return value.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B -j, \-\-json
|
.B -j, \-\-json
|
||||||
.br
|
.br
|
||||||
@ -219,6 +249,30 @@ ssh-audit -M new_policy.txt targetserver
|
|||||||
.fi
|
.fi
|
||||||
.RE
|
.RE
|
||||||
|
|
||||||
|
.LP
|
||||||
|
To run a Diffie-Hellman Group Exchange modulus size test using the values 2000 bits, 3000 bits, 4000 bits and 5000 bits:
|
||||||
|
.RS
|
||||||
|
.nf
|
||||||
|
ssh-audit targetserver --gex-test=2000,3000,4000,5000
|
||||||
|
.fi
|
||||||
|
.RE
|
||||||
|
|
||||||
|
.LP
|
||||||
|
To run a Diffie-Hellman Group Exchange modulus size test where 2048 bits is the minimum, 3072 bits is the preferred and 5000 bits is the maximum:
|
||||||
|
.RS
|
||||||
|
.nf
|
||||||
|
ssh-audit targetserver --gex-test=2048:3072:5000
|
||||||
|
.fi
|
||||||
|
.RE
|
||||||
|
|
||||||
|
.LP
|
||||||
|
To run a Diffie-Hellman Group Exchange modulus size test from 0 bits to 5120 bits in increments of 1024 bits:
|
||||||
|
.RS
|
||||||
|
.nf
|
||||||
|
ssh-audit targetserver --gex-test=0-5120:1024
|
||||||
|
.fi
|
||||||
|
.RE
|
||||||
|
|
||||||
.SH RETURN VALUES
|
.SH RETURN VALUES
|
||||||
When a successful connection is made and all algorithms are rated as "good", \fBssh-audit\fP returns 0. Other possible return values are:
|
When a successful connection is made and all algorithms are rated as "good", \fBssh-audit\fP returns 0. Other possible return values are:
|
||||||
|
|
||||||
|
@ -1 +1,184 @@
|
|||||||
{"banner": {"comments": null, "protocol": [2, 0], "raw": "SSH-2.0-dropbear_2019.78", "software": "dropbear_2019.78"}, "compression": ["zlib@openssh.com", "none"], "enc": ["aes128-ctr", "aes256-ctr", "aes128-cbc", "aes256-cbc", "3des-ctr", "3des-cbc"], "fingerprints": [{"hash": "CDfAU12pjQS7/91kg7gYacza0U/6PDbE04Ic3IpYxkM", "hash_alg": "SHA256", "hostkey": "ssh-rsa"}, {"hash": "63:7f:54:f7:0a:28:7f:75:0b:f4:07:0b:fc:66:51:a2", "hash_alg": "MD5", "hostkey": "ssh-rsa"}], "kex": [{"algorithm": "curve25519-sha256"}, {"algorithm": "curve25519-sha256@libssh.org"}, {"algorithm": "ecdh-sha2-nistp521"}, {"algorithm": "ecdh-sha2-nistp384"}, {"algorithm": "ecdh-sha2-nistp256"}, {"algorithm": "diffie-hellman-group14-sha256"}, {"algorithm": "diffie-hellman-group14-sha1"}, {"algorithm": "kexguess2@matt.ucc.asn.au"}], "key": [{"algorithm": "ecdsa-sha2-nistp256"}, {"algorithm": "ssh-rsa", "keysize": 1024}, {"algorithm": "ssh-dss"}], "mac": ["hmac-sha1-96", "hmac-sha1", "hmac-sha2-256"], "target": "localhost"}
|
{
|
||||||
|
"banner": {
|
||||||
|
"comments": null,
|
||||||
|
"protocol": [
|
||||||
|
2,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"raw": "SSH-2.0-dropbear_2019.78",
|
||||||
|
"software": "dropbear_2019.78"
|
||||||
|
},
|
||||||
|
"compression": [
|
||||||
|
"zlib@openssh.com",
|
||||||
|
"none"
|
||||||
|
],
|
||||||
|
"cves": [],
|
||||||
|
"enc": [
|
||||||
|
"aes128-ctr",
|
||||||
|
"aes256-ctr",
|
||||||
|
"aes128-cbc",
|
||||||
|
"aes256-cbc",
|
||||||
|
"3des-ctr",
|
||||||
|
"3des-cbc"
|
||||||
|
],
|
||||||
|
"fingerprints": [
|
||||||
|
{
|
||||||
|
"hash": "CDfAU12pjQS7/91kg7gYacza0U/6PDbE04Ic3IpYxkM",
|
||||||
|
"hash_alg": "SHA256",
|
||||||
|
"hostkey": "ssh-rsa"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hash": "63:7f:54:f7:0a:28:7f:75:0b:f4:07:0b:fc:66:51:a2",
|
||||||
|
"hash_alg": "MD5",
|
||||||
|
"hostkey": "ssh-rsa"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"kex": [
|
||||||
|
{
|
||||||
|
"algorithm": "curve25519-sha256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "curve25519-sha256@libssh.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "ecdh-sha2-nistp521"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "ecdh-sha2-nistp384"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "ecdh-sha2-nistp256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group14-sha256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group14-sha1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "kexguess2@matt.ucc.asn.au"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"key": [
|
||||||
|
{
|
||||||
|
"algorithm": "ecdsa-sha2-nistp256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "ssh-rsa",
|
||||||
|
"keysize": 1024
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "ssh-dss"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mac": [
|
||||||
|
"hmac-sha1-96",
|
||||||
|
"hmac-sha1",
|
||||||
|
"hmac-sha2-256"
|
||||||
|
],
|
||||||
|
"recommendations": {
|
||||||
|
"critical": {
|
||||||
|
"del": {
|
||||||
|
"enc": [
|
||||||
|
{
|
||||||
|
"name": "3des-cbc",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "3des-ctr",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"kex": [
|
||||||
|
{
|
||||||
|
"name": "diffie-hellman-group14-sha1",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ecdh-sha2-nistp256",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ecdh-sha2-nistp384",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ecdh-sha2-nistp521",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"key": [
|
||||||
|
{
|
||||||
|
"name": "ecdsa-sha2-nistp256",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ssh-dss",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ssh-rsa",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mac": [
|
||||||
|
{
|
||||||
|
"name": "hmac-sha1",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-sha1-96",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"informational": {
|
||||||
|
"add": {
|
||||||
|
"enc": [
|
||||||
|
{
|
||||||
|
"name": "twofish128-ctr",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "twofish256-ctr",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"kex": [
|
||||||
|
{
|
||||||
|
"name": "diffie-hellman-group16-sha512",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"warning": {
|
||||||
|
"del": {
|
||||||
|
"enc": [
|
||||||
|
{
|
||||||
|
"name": "aes128-cbc",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "aes256-cbc",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"kex": [
|
||||||
|
{
|
||||||
|
"name": "diffie-hellman-group14-sha256",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mac": [
|
||||||
|
{
|
||||||
|
"name": "hmac-sha2-256",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"target": "localhost:2222"
|
||||||
|
}
|
||||||
|
@ -6,57 +6,55 @@
|
|||||||
|
|
||||||
[0;36m# key exchange algorithms[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(kex) curve25519-sha256 -- [info] available since OpenSSH 7.4, Dropbear SSH 2018.76[0m
|
||||||
[0;32m(kex) curve25519-sha256@libssh.org -- [info] available since OpenSSH 6.5, Dropbear SSH 2013.62[0m
|
`- [info] default key exchange since OpenSSH 6.4
|
||||||
[0;31m(kex) ecdh-sha2-nistp521 -- [fail] using weak elliptic curves[0m
|
[0;32m(kex) curve25519-sha256@libssh.org -- [info] available since OpenSSH 6.4, Dropbear SSH 2013.62[0m
|
||||||
|
`- [info] default key exchange since OpenSSH 6.4
|
||||||
|
[0;31m(kex) ecdh-sha2-nistp521 -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency[0m
|
||||||
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
|
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
|
||||||
[0;31m(kex) ecdh-sha2-nistp384 -- [fail] using weak elliptic curves[0m
|
[0;31m(kex) ecdh-sha2-nistp384 -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency[0m
|
||||||
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
|
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
|
||||||
[0;31m(kex) ecdh-sha2-nistp256 -- [fail] using weak elliptic curves[0m
|
[0;31m(kex) ecdh-sha2-nistp256 -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency[0m
|
||||||
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
|
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
|
||||||
[0;32m(kex) diffie-hellman-group14-sha256 -- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73[0m
|
[0;33m(kex) diffie-hellman-group14-sha256 -- [warn] 2048-bit modulus only provides 112-bits of symmetric strength[0m
|
||||||
[0;33m(kex) diffie-hellman-group14-sha1 -- [warn] using weak hashing algorithm[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
|
||||||
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
|
`- [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;32m(kex) kexguess2@matt.ucc.asn.au -- [info] available since Dropbear SSH 2013.57[0m
|
||||||
|
|
||||||
[0;36m# host-key algorithms[0m
|
[0;36m# host-key algorithms[0m
|
||||||
[0;31m(key) ecdsa-sha2-nistp256 -- [fail] using weak elliptic curves[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
|
||||||
[0;33m `- [warn] using weak random number generator could reveal the key[0m
|
[0;33m `- [warn] using weak random number generator could reveal the key[0m
|
||||||
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
|
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
|
||||||
[0;31m(key) ssh-rsa (1024-bit) -- [fail] using weak hashing algorithm[0m
|
[0;31m(key) ssh-rsa (1024-bit) -- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
[0;31m `- [fail] using small 1024-bit modulus[0m
|
[0;31m `- [fail] using small 1024-bit modulus[0m
|
||||||
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
|
||||||
`- [info] a future deprecation notice has been issued in OpenSSH 8.2: https://www.openssh.com/txt/release-8.2
|
`- [info] deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8
|
||||||
[0;31m(key) ssh-dss -- [fail] using small 1024-bit modulus[0m
|
[0;31m(key) ssh-dss -- [fail] using small 1024-bit modulus[0m
|
||||||
[0;31m `- [fail] removed (in server) and disabled (in client) since OpenSSH 7.0, weak algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak random number generator could reveal the key[0m
|
[0;33m `- [warn] using weak random number generator could reveal the key[0m
|
||||||
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
||||||
|
`- [info] disabled in OpenSSH 7.0: https://www.openssh.com/txt/release-7.0
|
||||||
|
|
||||||
[0;36m# encryption algorithms (ciphers)[0m
|
[0;36m# encryption algorithms (ciphers)[0m
|
||||||
[0;32m(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
[0;32m(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
||||||
[0;32m(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
[0;32m(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
||||||
[0;31m(enc) aes128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;33m(enc) aes128-cbc -- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
|
||||||
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
|
||||||
[0;31m(enc) aes256-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;33m(enc) aes256-cbc -- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
|
||||||
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47
|
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47
|
||||||
[0;31m(enc) 3des-ctr -- [fail] using weak cipher[0m
|
[0;31m(enc) 3des-ctr -- [fail] using broken & deprecated 3DES cipher[0m
|
||||||
`- [info] available since Dropbear SSH 0.52
|
`- [info] available since Dropbear SSH 0.52
|
||||||
[0;31m(enc) 3des-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) 3des-cbc -- [fail] using broken & deprecated 3DES cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.4, unsafe algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher[0m
|
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
[0;33m `- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using small 64-bit block size[0m
|
[0;33m `- [warn] using small 64-bit block size[0m
|
||||||
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
|
||||||
|
|
||||||
[0;36m# message authentication code algorithms[0m
|
[0;36m# message authentication code algorithms[0m
|
||||||
[0;31m(mac) hmac-sha1-96 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(mac) hmac-sha1-96 -- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
|
||||||
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.47
|
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.47
|
||||||
[0;33m(mac) hmac-sha1 -- [warn] using encrypt-and-MAC mode[0m
|
[0;31m(mac) hmac-sha1 -- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
||||||
[0;33m(mac) hmac-sha2-256 -- [warn] using encrypt-and-MAC mode[0m
|
[0;33m(mac) hmac-sha2-256 -- [warn] using encrypt-and-MAC mode[0m
|
||||||
`- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56
|
`- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56
|
||||||
@ -67,20 +65,21 @@
|
|||||||
[0;36m# algorithm recommendations (for Dropbear SSH 2019.78)[0m
|
[0;36m# algorithm recommendations (for Dropbear SSH 2019.78)[0m
|
||||||
[0;31m(rec) -3des-cbc -- enc algorithm to remove [0m
|
[0;31m(rec) -3des-cbc -- enc algorithm to remove [0m
|
||||||
[0;31m(rec) -3des-ctr -- enc algorithm to remove [0m
|
[0;31m(rec) -3des-ctr -- enc algorithm to remove [0m
|
||||||
[0;31m(rec) -aes128-cbc -- enc algorithm to remove [0m
|
[0;31m(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove [0m
|
||||||
[0;31m(rec) -aes256-cbc -- enc algorithm to remove [0m
|
|
||||||
[0;31m(rec) -ecdh-sha2-nistp256 -- kex algorithm to remove [0m
|
[0;31m(rec) -ecdh-sha2-nistp256 -- kex algorithm to remove [0m
|
||||||
[0;31m(rec) -ecdh-sha2-nistp384 -- kex algorithm to remove [0m
|
[0;31m(rec) -ecdh-sha2-nistp384 -- kex algorithm to remove [0m
|
||||||
[0;31m(rec) -ecdh-sha2-nistp521 -- kex algorithm to remove [0m
|
[0;31m(rec) -ecdh-sha2-nistp521 -- kex algorithm to remove [0m
|
||||||
[0;31m(rec) -ecdsa-sha2-nistp256 -- key algorithm to remove [0m
|
[0;31m(rec) -ecdsa-sha2-nistp256 -- key algorithm to remove [0m
|
||||||
|
[0;31m(rec) -hmac-sha1 -- mac algorithm to remove [0m
|
||||||
[0;31m(rec) -hmac-sha1-96 -- mac algorithm to remove [0m
|
[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-dss -- key algorithm to remove [0m
|
||||||
[0;31m(rec) -ssh-rsa -- 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) +diffie-hellman-group16-sha512 -- kex algorithm to append [0m
|
||||||
[0;32m(rec) +twofish128-ctr -- enc 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;32m(rec) +twofish256-ctr -- enc algorithm to append [0m
|
||||||
[0;33m(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove [0m
|
[0;33m(rec) -aes128-cbc -- enc algorithm to remove [0m
|
||||||
[0;33m(rec) -hmac-sha1 -- mac algorithm to remove [0m
|
[0;33m(rec) -aes256-cbc -- enc 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) -hmac-sha2-256 -- mac algorithm to remove [0m
|
||||||
|
|
||||||
[0;36m# additional info[0m
|
[0;36m# additional info[0m
|
||||||
|
@ -1 +1,278 @@
|
|||||||
{"banner": {"comments": null, "protocol": [1, 99], "raw": "SSH-1.99-OpenSSH_4.0", "software": "OpenSSH_4.0"}, "compression": ["none", "zlib"], "enc": ["aes128-cbc", "3des-cbc", "blowfish-cbc", "cast128-cbc", "arcfour", "aes192-cbc", "aes256-cbc", "rijndael-cbc@lysator.liu.se", "aes128-ctr", "aes192-ctr", "aes256-ctr"], "fingerprints": [{"hash": "YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4", "hash_alg": "SHA256", "hostkey": "ssh-rsa"}, {"hash": "3c:c3:38:f8:55:39:c0:4a:5a:17:89:60:2c:a1:fc:6a", "hash_alg": "MD5", "hostkey": "ssh-rsa"}], "kex": [{"algorithm": "diffie-hellman-group-exchange-sha1", "keysize": 1024}, {"algorithm": "diffie-hellman-group14-sha1"}, {"algorithm": "diffie-hellman-group1-sha1"}], "key": [{"algorithm": "ssh-rsa", "keysize": 1024}, {"algorithm": "ssh-dss"}], "mac": ["hmac-md5", "hmac-sha1", "hmac-ripemd160", "hmac-ripemd160@openssh.com", "hmac-sha1-96", "hmac-md5-96"], "target": "localhost"}
|
{
|
||||||
|
"banner": {
|
||||||
|
"comments": null,
|
||||||
|
"protocol": [
|
||||||
|
1,
|
||||||
|
99
|
||||||
|
],
|
||||||
|
"raw": "SSH-1.99-OpenSSH_4.0",
|
||||||
|
"software": "OpenSSH_4.0"
|
||||||
|
},
|
||||||
|
"compression": [
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"enc": [
|
||||||
|
"aes128-cbc",
|
||||||
|
"3des-cbc",
|
||||||
|
"blowfish-cbc",
|
||||||
|
"cast128-cbc",
|
||||||
|
"arcfour",
|
||||||
|
"aes192-cbc",
|
||||||
|
"aes256-cbc",
|
||||||
|
"rijndael-cbc@lysator.liu.se",
|
||||||
|
"aes128-ctr",
|
||||||
|
"aes192-ctr",
|
||||||
|
"aes256-ctr"
|
||||||
|
],
|
||||||
|
"fingerprints": [
|
||||||
|
{
|
||||||
|
"hash": "YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4",
|
||||||
|
"hash_alg": "SHA256",
|
||||||
|
"hostkey": "ssh-rsa"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hash": "3c:c3:38:f8:55:39:c0:4a:5a:17:89:60:2c:a1:fc:6a",
|
||||||
|
"hash_alg": "MD5",
|
||||||
|
"hostkey": "ssh-rsa"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"kex": [
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group-exchange-sha1",
|
||||||
|
"keysize": 1024
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group14-sha1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group1-sha1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"key": [
|
||||||
|
{
|
||||||
|
"algorithm": "ssh-rsa",
|
||||||
|
"keysize": 1024
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "ssh-dss"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mac": [
|
||||||
|
"hmac-md5",
|
||||||
|
"hmac-sha1",
|
||||||
|
"hmac-ripemd160",
|
||||||
|
"hmac-ripemd160@openssh.com",
|
||||||
|
"hmac-sha1-96",
|
||||||
|
"hmac-md5-96"
|
||||||
|
],
|
||||||
|
"recommendations": {
|
||||||
|
"critical": {
|
||||||
|
"del": {
|
||||||
|
"enc": [
|
||||||
|
{
|
||||||
|
"name": "3des-cbc",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "arcfour",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "blowfish-cbc",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cast128-cbc",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rijndael-cbc@lysator.liu.se",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"kex": [
|
||||||
|
{
|
||||||
|
"name": "diffie-hellman-group14-sha1",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "diffie-hellman-group1-sha1",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "diffie-hellman-group-exchange-sha1",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"key": [
|
||||||
|
{
|
||||||
|
"name": "ssh-dss",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ssh-rsa",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mac": [
|
||||||
|
{
|
||||||
|
"name": "hmac-md5",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-md5-96",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-ripemd160",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-ripemd160@openssh.com",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-sha1",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-sha1-96",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"warning": {
|
||||||
|
"del": {
|
||||||
|
"enc": [
|
||||||
|
{
|
||||||
|
"name": "aes128-cbc",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "aes192-cbc",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "aes256-cbc",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"target": "localhost:2222"
|
||||||
|
}
|
||||||
|
@ -6,7 +6,10 @@
|
|||||||
[0;32m(gen) compression: enabled (zlib)[0m
|
[0;32m(gen) compression: enabled (zlib)[0m
|
||||||
|
|
||||||
[0;36m# security[0m
|
[0;36m# security[0m
|
||||||
[0;33m(cve) CVE-2018-15473 -- (CVSSv2: 5.3) enumerate usernames due to timing discrepencies[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-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-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-2012-0814 -- (CVSSv2: 3.5) leak data via debug messages[0m
|
||||||
@ -29,91 +32,73 @@
|
|||||||
|
|
||||||
[0;36m# key exchange algorithms[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;31m(kex) diffie-hellman-group-exchange-sha1 (1024-bit) -- [fail] using small 1024-bit modulus[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
|
||||||
`- [info] available since OpenSSH 2.3.0
|
`- [info] available since OpenSSH 2.3.0
|
||||||
[0;33m(kex) diffie-hellman-group14-sha1 -- [warn] using weak hashing algorithm[0m
|
[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
|
||||||
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
|
`- [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(kex) diffie-hellman-group1-sha1 -- [fail] using small 1024-bit modulus[0m
|
||||||
[0;31m `- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m `- [fail] vulnerable to the Logjam attack: https://en.wikipedia.org/wiki/Logjam_(computer_security)[0m
|
||||||
[0;31m `- [fail] disabled (in client) since OpenSSH 7.0, logjam attack[0m
|
[0;31m `- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
|
||||||
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
|
`- [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
|
||||||
|
|
||||||
[0;36m# host-key algorithms[0m
|
[0;36m# host-key algorithms[0m
|
||||||
[0;31m(key) ssh-rsa (1024-bit) -- [fail] using weak hashing algorithm[0m
|
[0;31m(key) ssh-rsa (1024-bit) -- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
[0;31m `- [fail] using small 1024-bit modulus[0m
|
[0;31m `- [fail] using small 1024-bit modulus[0m
|
||||||
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
|
||||||
`- [info] a future deprecation notice has been issued in OpenSSH 8.2: https://www.openssh.com/txt/release-8.2
|
`- [info] deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8
|
||||||
[0;31m(key) ssh-dss -- [fail] using small 1024-bit modulus[0m
|
[0;31m(key) ssh-dss -- [fail] using small 1024-bit modulus[0m
|
||||||
[0;31m `- [fail] removed (in server) and disabled (in client) since OpenSSH 7.0, weak algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak random number generator could reveal the key[0m
|
[0;33m `- [warn] using weak random number generator could reveal the key[0m
|
||||||
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
||||||
|
`- [info] disabled in OpenSSH 7.0: https://www.openssh.com/txt/release-7.0
|
||||||
|
|
||||||
[0;36m# encryption algorithms (ciphers)[0m
|
[0;36m# encryption algorithms (ciphers)[0m
|
||||||
[0;31m(enc) aes128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;33m(enc) aes128-cbc -- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
|
||||||
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
|
||||||
[0;31m(enc) 3des-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) 3des-cbc -- [fail] using broken & deprecated 3DES cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.4, unsafe algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher[0m
|
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
[0;33m `- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using small 64-bit block size[0m
|
[0;33m `- [warn] using small 64-bit block size[0m
|
||||||
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
|
||||||
[0;31m(enc) blowfish-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) blowfish-cbc -- [fail] using weak & deprecated Blowfish cipher[0m
|
||||||
[0;31m `- [fail] disabled since Dropbear SSH 0.53[0m
|
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
[0;33m `- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using small 64-bit block size[0m
|
[0;33m `- [warn] using small 64-bit block size[0m
|
||||||
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
|
||||||
[0;31m(enc) cast128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) cast128-cbc -- [fail] using weak & deprecated CAST cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
[0;33m `- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using small 64-bit block size[0m
|
[0;33m `- [warn] using small 64-bit block size[0m
|
||||||
`- [info] available since OpenSSH 2.1.0
|
`- [info] available since OpenSSH 2.1.0
|
||||||
[0;31m(enc) arcfour -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) arcfour -- [fail] using broken RC4 cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher[0m
|
|
||||||
`- [info] available since OpenSSH 2.1.0
|
`- [info] available since OpenSSH 2.1.0
|
||||||
[0;31m(enc) aes192-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;33m(enc) aes192-cbc -- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
|
||||||
`- [info] available since OpenSSH 2.3.0
|
`- [info] available since OpenSSH 2.3.0
|
||||||
[0;31m(enc) aes256-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;33m(enc) aes256-cbc -- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
|
||||||
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47
|
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47
|
||||||
[0;31m(enc) rijndael-cbc@lysator.liu.se -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) rijndael-cbc@lysator.liu.se -- [fail] using deprecated & non-standardized Rijndael cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
[0;33m `- [warn] using weak cipher mode[0m
|
||||||
`- [info] available since OpenSSH 2.3.0
|
`- [info] available since OpenSSH 2.3.0
|
||||||
|
`- [info] disabled in OpenSSH 7.0: https://www.openssh.com/txt/release-7.0
|
||||||
[0;32m(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
[0;32m(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
||||||
[0;32m(enc) aes192-ctr -- [info] available since OpenSSH 3.7[0m
|
[0;32m(enc) aes192-ctr -- [info] available since OpenSSH 3.7[0m
|
||||||
[0;32m(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
[0;32m(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
||||||
|
|
||||||
[0;36m# message authentication code algorithms[0m
|
[0;36m# message authentication code algorithms[0m
|
||||||
[0;31m(mac) hmac-md5 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(mac) hmac-md5 -- [fail] using broken MD5 hash algorithm[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
|
||||||
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
||||||
[0;33m(mac) hmac-sha1 -- [warn] using encrypt-and-MAC mode[0m
|
[0;31m(mac) hmac-sha1 -- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
||||||
[0;31m(mac) hmac-ripemd160 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(mac) hmac-ripemd160 -- [fail] using deprecated RIPEMD hash algorithm[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
`- [info] available since OpenSSH 2.5.0
|
`- [info] available since OpenSSH 2.5.0
|
||||||
[0;31m(mac) hmac-ripemd160@openssh.com -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(mac) hmac-ripemd160@openssh.com -- [fail] using deprecated RIPEMD hash algorithm[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
`- [info] available since OpenSSH 2.1.0
|
`- [info] available since OpenSSH 2.1.0
|
||||||
[0;31m(mac) hmac-sha1-96 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(mac) hmac-sha1-96 -- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
|
||||||
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.47
|
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.47
|
||||||
[0;31m(mac) hmac-md5-96 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(mac) hmac-md5-96 -- [fail] using broken MD5 hash algorithm[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
|
||||||
`- [info] available since OpenSSH 2.5.0
|
`- [info] available since OpenSSH 2.5.0
|
||||||
|
|
||||||
[0;36m# fingerprints[0m
|
[0;36m# fingerprints[0m
|
||||||
@ -121,24 +106,24 @@
|
|||||||
|
|
||||||
[0;36m# algorithm recommendations (for OpenSSH 4.0)[0m
|
[0;36m# algorithm recommendations (for OpenSSH 4.0)[0m
|
||||||
[0;31m(rec) -3des-cbc -- enc algorithm to remove [0m
|
[0;31m(rec) -3des-cbc -- enc algorithm to remove [0m
|
||||||
[0;31m(rec) -aes128-cbc -- enc algorithm to remove [0m
|
|
||||||
[0;31m(rec) -aes192-cbc -- enc algorithm to remove [0m
|
|
||||||
[0;31m(rec) -aes256-cbc -- enc algorithm to remove [0m
|
|
||||||
[0;31m(rec) -arcfour -- enc algorithm to remove [0m
|
[0;31m(rec) -arcfour -- enc algorithm to remove [0m
|
||||||
[0;31m(rec) -blowfish-cbc -- enc algorithm to remove [0m
|
[0;31m(rec) -blowfish-cbc -- enc algorithm to remove [0m
|
||||||
[0;31m(rec) -cast128-cbc -- enc algorithm to remove [0m
|
[0;31m(rec) -cast128-cbc -- enc algorithm to remove [0m
|
||||||
[0;31m(rec) -diffie-hellman-group-exchange-sha1 -- kex algorithm to remove [0m
|
[0;31m(rec) -diffie-hellman-group-exchange-sha1 -- kex algorithm to remove [0m
|
||||||
[0;31m(rec) -diffie-hellman-group1-sha1 -- kex algorithm to remove [0m
|
[0;31m(rec) -diffie-hellman-group1-sha1 -- kex algorithm to remove [0m
|
||||||
|
[0;31m(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove [0m
|
||||||
[0;31m(rec) -hmac-md5 -- mac algorithm to remove [0m
|
[0;31m(rec) -hmac-md5 -- mac algorithm to remove [0m
|
||||||
[0;31m(rec) -hmac-md5-96 -- mac algorithm to remove [0m
|
[0;31m(rec) -hmac-md5-96 -- mac algorithm to remove [0m
|
||||||
[0;31m(rec) -hmac-ripemd160 -- mac algorithm to remove [0m
|
[0;31m(rec) -hmac-ripemd160 -- mac algorithm to remove [0m
|
||||||
[0;31m(rec) -hmac-ripemd160@openssh.com -- mac algorithm to remove [0m
|
[0;31m(rec) -hmac-ripemd160@openssh.com -- mac algorithm to remove [0m
|
||||||
|
[0;31m(rec) -hmac-sha1 -- mac algorithm to remove [0m
|
||||||
[0;31m(rec) -hmac-sha1-96 -- mac algorithm to remove [0m
|
[0;31m(rec) -hmac-sha1-96 -- mac algorithm to remove [0m
|
||||||
[0;31m(rec) -rijndael-cbc@lysator.liu.se -- enc algorithm to remove [0m
|
[0;31m(rec) -rijndael-cbc@lysator.liu.se -- enc algorithm to remove [0m
|
||||||
[0;31m(rec) -ssh-dss -- key 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;31m(rec) -ssh-rsa -- key algorithm to remove [0m
|
||||||
[0;33m(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove [0m
|
[0;33m(rec) -aes128-cbc -- enc algorithm to remove [0m
|
||||||
[0;33m(rec) -hmac-sha1 -- mac algorithm to remove [0m
|
[0;33m(rec) -aes192-cbc -- enc algorithm to remove [0m
|
||||||
|
[0;33m(rec) -aes256-cbc -- enc algorithm to remove [0m
|
||||||
|
|
||||||
[0;36m# additional info[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
|
[0;33m(nfo) For hardening guides on common OSes, please see: <https://www.ssh-audit.com/hardening_guides.html>[0m
|
||||||
|
@ -1 +1,6 @@
|
|||||||
{"errors": [], "host": "localhost", "passed": true, "policy": "Docker policy: test1 (version 1)"}
|
{
|
||||||
|
"errors": [],
|
||||||
|
"host": "localhost",
|
||||||
|
"passed": true,
|
||||||
|
"policy": "Docker policy: test1 (version 1)"
|
||||||
|
}
|
||||||
|
@ -1 +1,31 @@
|
|||||||
{"errors": [{"actual": ["3072"], "expected_optional": [""], "expected_required": ["4096"], "mismatched_field": "RSA host key (ssh-rsa-cert-v01@openssh.com) sizes"}, {"actual": ["1024"], "expected_optional": [""], "expected_required": ["4096"], "mismatched_field": "RSA CA key (ssh-rsa-cert-v01@openssh.com) sizes"}], "host": "localhost", "passed": false, "policy": "Docker poliicy: test10 (version 1)"}
|
{
|
||||||
|
"errors": [
|
||||||
|
{
|
||||||
|
"actual": [
|
||||||
|
"3072"
|
||||||
|
],
|
||||||
|
"expected_optional": [
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"expected_required": [
|
||||||
|
"4096"
|
||||||
|
],
|
||||||
|
"mismatched_field": "Host key (ssh-rsa-cert-v01@openssh.com) sizes"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actual": [
|
||||||
|
"1024"
|
||||||
|
],
|
||||||
|
"expected_optional": [
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"expected_required": [
|
||||||
|
"4096"
|
||||||
|
],
|
||||||
|
"mismatched_field": "CA signature size (ssh-rsa)"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"host": "localhost",
|
||||||
|
"passed": false,
|
||||||
|
"policy": "Docker poliicy: test10 (version 1)"
|
||||||
|
}
|
||||||
|
@ -1,13 +1,28 @@
|
|||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
Host: localhost:2222
|
Host: localhost:2222
|
||||||
Policy: Docker poliicy: test10 (version 1)
|
Policy: Docker poliicy: test10 (version 1)
|
||||||
Result: [0;31m❌ Failed![0m
|
Result: [0;31m❌ Failed![0m
|
||||||
[0;33m
|
[0;33m
|
||||||
Errors:
|
Errors:
|
||||||
* RSA CA key (ssh-rsa-cert-v01@openssh.com) sizes did not match.
|
* CA signature size (ssh-rsa) did not match.
|
||||||
- Expected: 4096
|
- Expected: 4096
|
||||||
- Actual: 1024
|
- Actual: 1024
|
||||||
|
|
||||||
* RSA host key (ssh-rsa-cert-v01@openssh.com) sizes did not match.
|
* Host key (ssh-rsa-cert-v01@openssh.com) sizes did not match.
|
||||||
- Expected: 4096
|
- Expected: 4096
|
||||||
- Actual: 3072
|
- Actual: 3072
|
||||||
[0m
|
[0m
|
||||||
|
@ -1 +1,23 @@
|
|||||||
{"errors": [{"actual": ["diffie-hellman-group-exchange-sha256", "diffie-hellman-group-exchange-sha1", "diffie-hellman-group14-sha1", "diffie-hellman-group1-sha1"], "expected_optional": [""], "expected_required": ["kex_alg1", "kex_alg2"], "mismatched_field": "Key exchanges"}], "host": "localhost", "passed": false, "policy": "Docker policy: test2 (version 1)"}
|
{
|
||||||
|
"errors": [
|
||||||
|
{
|
||||||
|
"actual": [
|
||||||
|
"diffie-hellman-group-exchange-sha256",
|
||||||
|
"diffie-hellman-group-exchange-sha1",
|
||||||
|
"diffie-hellman-group14-sha1",
|
||||||
|
"diffie-hellman-group1-sha1"
|
||||||
|
],
|
||||||
|
"expected_optional": [
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"expected_required": [
|
||||||
|
"kex_alg1",
|
||||||
|
"kex_alg2"
|
||||||
|
],
|
||||||
|
"mismatched_field": "Key exchanges"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"host": "localhost",
|
||||||
|
"passed": false,
|
||||||
|
"policy": "Docker policy: test2 (version 1)"
|
||||||
|
}
|
||||||
|
@ -1 +1,22 @@
|
|||||||
{"errors": [{"actual": ["ssh-rsa", "ssh-dss"], "expected_optional": [""], "expected_required": ["ssh-rsa", "ssh-dss", "key_alg1"], "mismatched_field": "Host keys"}], "host": "localhost", "passed": false, "policy": "Docker policy: test3 (version 1)"}
|
{
|
||||||
|
"errors": [
|
||||||
|
{
|
||||||
|
"actual": [
|
||||||
|
"ssh-rsa",
|
||||||
|
"ssh-dss"
|
||||||
|
],
|
||||||
|
"expected_optional": [
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"expected_required": [
|
||||||
|
"ssh-rsa",
|
||||||
|
"ssh-dss",
|
||||||
|
"key_alg1"
|
||||||
|
],
|
||||||
|
"mismatched_field": "Host keys"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"host": "localhost",
|
||||||
|
"passed": false,
|
||||||
|
"policy": "Docker policy: test3 (version 1)"
|
||||||
|
}
|
||||||
|
@ -1 +1,32 @@
|
|||||||
{"errors": [{"actual": ["aes128-ctr", "aes192-ctr", "aes256-ctr", "arcfour256", "arcfour128", "aes128-cbc", "3des-cbc", "blowfish-cbc", "cast128-cbc", "aes192-cbc", "aes256-cbc", "arcfour", "rijndael-cbc@lysator.liu.se"], "expected_optional": [""], "expected_required": ["cipher_alg1", "cipher_alg2"], "mismatched_field": "Ciphers"}], "host": "localhost", "passed": false, "policy": "Docker policy: test4 (version 1)"}
|
{
|
||||||
|
"errors": [
|
||||||
|
{
|
||||||
|
"actual": [
|
||||||
|
"aes128-ctr",
|
||||||
|
"aes192-ctr",
|
||||||
|
"aes256-ctr",
|
||||||
|
"arcfour256",
|
||||||
|
"arcfour128",
|
||||||
|
"aes128-cbc",
|
||||||
|
"3des-cbc",
|
||||||
|
"blowfish-cbc",
|
||||||
|
"cast128-cbc",
|
||||||
|
"aes192-cbc",
|
||||||
|
"aes256-cbc",
|
||||||
|
"arcfour",
|
||||||
|
"rijndael-cbc@lysator.liu.se"
|
||||||
|
],
|
||||||
|
"expected_optional": [
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"expected_required": [
|
||||||
|
"cipher_alg1",
|
||||||
|
"cipher_alg2"
|
||||||
|
],
|
||||||
|
"mismatched_field": "Ciphers"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"host": "localhost",
|
||||||
|
"passed": false,
|
||||||
|
"policy": "Docker policy: test4 (version 1)"
|
||||||
|
}
|
||||||
|
@ -1 +1,31 @@
|
|||||||
{"errors": [{"actual": ["hmac-md5", "hmac-sha1", "umac-64@openssh.com", "hmac-ripemd160", "hmac-ripemd160@openssh.com", "hmac-sha1-96", "hmac-md5-96"], "expected_optional": [""], "expected_required": ["hmac-md5", "hmac-sha1", "umac-64@openssh.com", "hmac-ripemd160", "hmac-ripemd160@openssh.com", "hmac_alg1", "hmac-md5-96"], "mismatched_field": "MACs"}], "host": "localhost", "passed": false, "policy": "Docker policy: test5 (version 1)"}
|
{
|
||||||
|
"errors": [
|
||||||
|
{
|
||||||
|
"actual": [
|
||||||
|
"hmac-md5",
|
||||||
|
"hmac-sha1",
|
||||||
|
"umac-64@openssh.com",
|
||||||
|
"hmac-ripemd160",
|
||||||
|
"hmac-ripemd160@openssh.com",
|
||||||
|
"hmac-sha1-96",
|
||||||
|
"hmac-md5-96"
|
||||||
|
],
|
||||||
|
"expected_optional": [
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"expected_required": [
|
||||||
|
"hmac-md5",
|
||||||
|
"hmac-sha1",
|
||||||
|
"umac-64@openssh.com",
|
||||||
|
"hmac-ripemd160",
|
||||||
|
"hmac-ripemd160@openssh.com",
|
||||||
|
"hmac_alg1",
|
||||||
|
"hmac-md5-96"
|
||||||
|
],
|
||||||
|
"mismatched_field": "MACs"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"host": "localhost",
|
||||||
|
"passed": false,
|
||||||
|
"policy": "Docker policy: test5 (version 1)"
|
||||||
|
}
|
||||||
|
@ -1 +1,6 @@
|
|||||||
{"errors": [], "host": "localhost", "passed": true, "policy": "Docker poliicy: test7 (version 1)"}
|
{
|
||||||
|
"errors": [],
|
||||||
|
"host": "localhost",
|
||||||
|
"passed": true,
|
||||||
|
"policy": "Docker poliicy: test7 (version 1)"
|
||||||
|
}
|
||||||
|
@ -1,3 +1,18 @@
|
|||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
Host: localhost:2222
|
Host: localhost:2222
|
||||||
Policy: Docker poliicy: test7 (version 1)
|
Policy: Docker poliicy: test7 (version 1)
|
||||||
Result: [0;32m✔ Passed[0m
|
Result: [0;32m✔ Passed[0m
|
||||||
|
@ -1 +1,19 @@
|
|||||||
{"errors": [{"actual": ["1024"], "expected_optional": [""], "expected_required": ["2048"], "mismatched_field": "RSA CA key (ssh-rsa-cert-v01@openssh.com) sizes"}], "host": "localhost", "passed": false, "policy": "Docker poliicy: test8 (version 1)"}
|
{
|
||||||
|
"errors": [
|
||||||
|
{
|
||||||
|
"actual": [
|
||||||
|
"1024"
|
||||||
|
],
|
||||||
|
"expected_optional": [
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"expected_required": [
|
||||||
|
"2048"
|
||||||
|
],
|
||||||
|
"mismatched_field": "CA signature size (ssh-rsa)"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"host": "localhost",
|
||||||
|
"passed": false,
|
||||||
|
"policy": "Docker poliicy: test8 (version 1)"
|
||||||
|
}
|
||||||
|
@ -1,9 +1,24 @@
|
|||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
Host: localhost:2222
|
Host: localhost:2222
|
||||||
Policy: Docker poliicy: test8 (version 1)
|
Policy: Docker poliicy: test8 (version 1)
|
||||||
Result: [0;31m❌ Failed![0m
|
Result: [0;31m❌ Failed![0m
|
||||||
[0;33m
|
[0;33m
|
||||||
Errors:
|
Errors:
|
||||||
* RSA CA key (ssh-rsa-cert-v01@openssh.com) sizes did not match.
|
* CA signature size (ssh-rsa) did not match.
|
||||||
- Expected: 2048
|
- Expected: 2048
|
||||||
- Actual: 1024
|
- Actual: 1024
|
||||||
[0m
|
[0m
|
||||||
|
@ -1 +1,19 @@
|
|||||||
{"errors": [{"actual": ["3072"], "expected_optional": [""], "expected_required": ["4096"], "mismatched_field": "RSA host key (ssh-rsa-cert-v01@openssh.com) sizes"}], "host": "localhost", "passed": false, "policy": "Docker poliicy: test9 (version 1)"}
|
{
|
||||||
|
"errors": [
|
||||||
|
{
|
||||||
|
"actual": [
|
||||||
|
"3072"
|
||||||
|
],
|
||||||
|
"expected_optional": [
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"expected_required": [
|
||||||
|
"4096"
|
||||||
|
],
|
||||||
|
"mismatched_field": "Host key (ssh-rsa-cert-v01@openssh.com) sizes"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"host": "localhost",
|
||||||
|
"passed": false,
|
||||||
|
"policy": "Docker poliicy: test9 (version 1)"
|
||||||
|
}
|
||||||
|
@ -1,9 +1,24 @@
|
|||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
Host: localhost:2222
|
Host: localhost:2222
|
||||||
Policy: Docker poliicy: test9 (version 1)
|
Policy: Docker poliicy: test9 (version 1)
|
||||||
Result: [0;31m❌ Failed![0m
|
Result: [0;31m❌ Failed![0m
|
||||||
[0;33m
|
[0;33m
|
||||||
Errors:
|
Errors:
|
||||||
* RSA host key (ssh-rsa-cert-v01@openssh.com) sizes did not match.
|
* Host key (ssh-rsa-cert-v01@openssh.com) sizes did not match.
|
||||||
- Expected: 4096
|
- Expected: 4096
|
||||||
- Actual: 3072
|
- Actual: 3072
|
||||||
[0m
|
[0m
|
||||||
|
@ -1 +1,272 @@
|
|||||||
{"banner": {"comments": null, "protocol": [2, 0], "raw": "SSH-2.0-OpenSSH_5.6", "software": "OpenSSH_5.6"}, "compression": ["none", "zlib@openssh.com"], "enc": ["aes128-ctr", "aes192-ctr", "aes256-ctr", "arcfour256", "arcfour128", "aes128-cbc", "3des-cbc", "blowfish-cbc", "cast128-cbc", "aes192-cbc", "aes256-cbc", "arcfour", "rijndael-cbc@lysator.liu.se"], "fingerprints": [{"hash": "YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4", "hash_alg": "SHA256", "hostkey": "ssh-rsa"}, {"hash": "3c:c3:38:f8:55:39:c0:4a:5a:17:89:60:2c:a1:fc:6a", "hash_alg": "MD5", "hostkey": "ssh-rsa"}], "kex": [{"algorithm": "diffie-hellman-group-exchange-sha256", "keysize": 1024}, {"algorithm": "diffie-hellman-group-exchange-sha1", "keysize": 1024}, {"algorithm": "diffie-hellman-group14-sha1"}, {"algorithm": "diffie-hellman-group1-sha1"}], "key": [{"algorithm": "ssh-rsa", "keysize": 1024}, {"algorithm": "ssh-dss"}], "mac": ["hmac-md5", "hmac-sha1", "umac-64@openssh.com", "hmac-ripemd160", "hmac-ripemd160@openssh.com", "hmac-sha1-96", "hmac-md5-96"], "target": "localhost"}
|
{
|
||||||
|
"banner": {
|
||||||
|
"comments": null,
|
||||||
|
"protocol": [
|
||||||
|
2,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"raw": "SSH-2.0-OpenSSH_5.6",
|
||||||
|
"software": "OpenSSH_5.6"
|
||||||
|
},
|
||||||
|
"compression": [
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"enc": [
|
||||||
|
"aes128-ctr",
|
||||||
|
"aes192-ctr",
|
||||||
|
"aes256-ctr",
|
||||||
|
"arcfour256",
|
||||||
|
"arcfour128",
|
||||||
|
"aes128-cbc",
|
||||||
|
"3des-cbc",
|
||||||
|
"blowfish-cbc",
|
||||||
|
"cast128-cbc",
|
||||||
|
"aes192-cbc",
|
||||||
|
"aes256-cbc",
|
||||||
|
"arcfour",
|
||||||
|
"rijndael-cbc@lysator.liu.se"
|
||||||
|
],
|
||||||
|
"fingerprints": [
|
||||||
|
{
|
||||||
|
"hash": "YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4",
|
||||||
|
"hash_alg": "SHA256",
|
||||||
|
"hostkey": "ssh-rsa"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hash": "3c:c3:38:f8:55:39:c0:4a:5a:17:89:60:2c:a1:fc:6a",
|
||||||
|
"hash_alg": "MD5",
|
||||||
|
"hostkey": "ssh-rsa"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"kex": [
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group-exchange-sha256",
|
||||||
|
"keysize": 1024
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group-exchange-sha1",
|
||||||
|
"keysize": 1024
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group14-sha1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group1-sha1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"key": [
|
||||||
|
{
|
||||||
|
"algorithm": "ssh-rsa",
|
||||||
|
"keysize": 1024
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "ssh-dss"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mac": [
|
||||||
|
"hmac-md5",
|
||||||
|
"hmac-sha1",
|
||||||
|
"umac-64@openssh.com",
|
||||||
|
"hmac-ripemd160",
|
||||||
|
"hmac-ripemd160@openssh.com",
|
||||||
|
"hmac-sha1-96",
|
||||||
|
"hmac-md5-96"
|
||||||
|
],
|
||||||
|
"recommendations": {
|
||||||
|
"critical": {
|
||||||
|
"chg": {
|
||||||
|
"kex": [
|
||||||
|
{
|
||||||
|
"name": "diffie-hellman-group-exchange-sha256",
|
||||||
|
"notes": "increase modulus size to 3072 bits or larger"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"del": {
|
||||||
|
"enc": [
|
||||||
|
{
|
||||||
|
"name": "3des-cbc",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "arcfour128",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "arcfour",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "arcfour256",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "blowfish-cbc",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cast128-cbc",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rijndael-cbc@lysator.liu.se",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"kex": [
|
||||||
|
{
|
||||||
|
"name": "diffie-hellman-group14-sha1",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "diffie-hellman-group1-sha1",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "diffie-hellman-group-exchange-sha1",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"key": [
|
||||||
|
{
|
||||||
|
"name": "ssh-dss",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ssh-rsa",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mac": [
|
||||||
|
{
|
||||||
|
"name": "hmac-md5",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-md5-96",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-ripemd160",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-ripemd160@openssh.com",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-sha1",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-sha1-96",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"warning": {
|
||||||
|
"del": {
|
||||||
|
"enc": [
|
||||||
|
{
|
||||||
|
"name": "aes128-cbc",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "aes192-cbc",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "aes256-cbc",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mac": [
|
||||||
|
{
|
||||||
|
"name": "umac-64@openssh.com",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"target": "localhost:2222"
|
||||||
|
}
|
||||||
|
@ -5,7 +5,10 @@
|
|||||||
[0;32m(gen) compression: enabled (zlib@openssh.com)[0m
|
[0;32m(gen) compression: enabled (zlib@openssh.com)[0m
|
||||||
|
|
||||||
[0;36m# security[0m
|
[0;36m# security[0m
|
||||||
[0;33m(cve) CVE-2018-15473 -- (CVSSv2: 5.3) enumerate usernames due to timing discrepencies[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-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-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-6564 -- (CVSSv2: 6.9) privilege escalation via leveraging sshd uid[0m
|
||||||
@ -22,113 +25,88 @@
|
|||||||
[0;31m(kex) diffie-hellman-group-exchange-sha256 (1024-bit) -- [fail] using small 1024-bit modulus[0m
|
[0;31m(kex) diffie-hellman-group-exchange-sha256 (1024-bit) -- [fail] using small 1024-bit modulus[0m
|
||||||
`- [info] available since OpenSSH 4.4
|
`- [info] available since OpenSSH 4.4
|
||||||
[0;31m(kex) diffie-hellman-group-exchange-sha1 (1024-bit) -- [fail] using small 1024-bit modulus[0m
|
[0;31m(kex) diffie-hellman-group-exchange-sha1 (1024-bit) -- [fail] using small 1024-bit modulus[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
|
||||||
`- [info] available since OpenSSH 2.3.0
|
`- [info] available since OpenSSH 2.3.0
|
||||||
[0;33m(kex) diffie-hellman-group14-sha1 -- [warn] using weak hashing algorithm[0m
|
[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
|
||||||
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
|
`- [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(kex) diffie-hellman-group1-sha1 -- [fail] using small 1024-bit modulus[0m
|
||||||
[0;31m `- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m `- [fail] vulnerable to the Logjam attack: https://en.wikipedia.org/wiki/Logjam_(computer_security)[0m
|
||||||
[0;31m `- [fail] disabled (in client) since OpenSSH 7.0, logjam attack[0m
|
[0;31m `- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
|
||||||
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
|
`- [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
|
||||||
|
|
||||||
[0;36m# host-key algorithms[0m
|
[0;36m# host-key algorithms[0m
|
||||||
[0;31m(key) ssh-rsa (1024-bit) -- [fail] using weak hashing algorithm[0m
|
[0;31m(key) ssh-rsa (1024-bit) -- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
[0;31m `- [fail] using small 1024-bit modulus[0m
|
[0;31m `- [fail] using small 1024-bit modulus[0m
|
||||||
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
|
||||||
`- [info] a future deprecation notice has been issued in OpenSSH 8.2: https://www.openssh.com/txt/release-8.2
|
`- [info] deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8
|
||||||
[0;31m(key) ssh-dss -- [fail] using small 1024-bit modulus[0m
|
[0;31m(key) ssh-dss -- [fail] using small 1024-bit modulus[0m
|
||||||
[0;31m `- [fail] removed (in server) and disabled (in client) since OpenSSH 7.0, weak algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak random number generator could reveal the key[0m
|
[0;33m `- [warn] using weak random number generator could reveal the key[0m
|
||||||
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
||||||
|
`- [info] disabled in OpenSSH 7.0: https://www.openssh.com/txt/release-7.0
|
||||||
|
|
||||||
[0;36m# encryption algorithms (ciphers)[0m
|
[0;36m# encryption algorithms (ciphers)[0m
|
||||||
[0;32m(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
[0;32m(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
||||||
[0;32m(enc) aes192-ctr -- [info] available since OpenSSH 3.7[0m
|
[0;32m(enc) aes192-ctr -- [info] available since OpenSSH 3.7[0m
|
||||||
[0;32m(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
[0;32m(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
||||||
[0;31m(enc) arcfour256 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) arcfour256 -- [fail] using broken RC4 cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher[0m
|
|
||||||
`- [info] available since OpenSSH 4.2
|
`- [info] available since OpenSSH 4.2
|
||||||
[0;31m(enc) arcfour128 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) arcfour128 -- [fail] using broken RC4 cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher[0m
|
|
||||||
`- [info] available since OpenSSH 4.2
|
`- [info] available since OpenSSH 4.2
|
||||||
[0;31m(enc) aes128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;33m(enc) aes128-cbc -- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
|
||||||
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
|
||||||
[0;31m(enc) 3des-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) 3des-cbc -- [fail] using broken & deprecated 3DES cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.4, unsafe algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher[0m
|
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
[0;33m `- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using small 64-bit block size[0m
|
[0;33m `- [warn] using small 64-bit block size[0m
|
||||||
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
|
||||||
[0;31m(enc) blowfish-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) blowfish-cbc -- [fail] using weak & deprecated Blowfish cipher[0m
|
||||||
[0;31m `- [fail] disabled since Dropbear SSH 0.53[0m
|
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
[0;33m `- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using small 64-bit block size[0m
|
[0;33m `- [warn] using small 64-bit block size[0m
|
||||||
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
|
||||||
[0;31m(enc) cast128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) cast128-cbc -- [fail] using weak & deprecated CAST cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
[0;33m `- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using small 64-bit block size[0m
|
[0;33m `- [warn] using small 64-bit block size[0m
|
||||||
`- [info] available since OpenSSH 2.1.0
|
`- [info] available since OpenSSH 2.1.0
|
||||||
[0;31m(enc) aes192-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;33m(enc) aes192-cbc -- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
|
||||||
`- [info] available since OpenSSH 2.3.0
|
`- [info] available since OpenSSH 2.3.0
|
||||||
[0;31m(enc) aes256-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;33m(enc) aes256-cbc -- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
|
||||||
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47
|
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47
|
||||||
[0;31m(enc) arcfour -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) arcfour -- [fail] using broken RC4 cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher[0m
|
|
||||||
`- [info] available since OpenSSH 2.1.0
|
`- [info] available since OpenSSH 2.1.0
|
||||||
[0;31m(enc) rijndael-cbc@lysator.liu.se -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) rijndael-cbc@lysator.liu.se -- [fail] using deprecated & non-standardized Rijndael cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
[0;33m `- [warn] using weak cipher mode[0m
|
||||||
`- [info] available since OpenSSH 2.3.0
|
`- [info] available since OpenSSH 2.3.0
|
||||||
|
`- [info] disabled in OpenSSH 7.0: https://www.openssh.com/txt/release-7.0
|
||||||
|
|
||||||
[0;36m# message authentication code algorithms[0m
|
[0;36m# message authentication code algorithms[0m
|
||||||
[0;31m(mac) hmac-md5 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(mac) hmac-md5 -- [fail] using broken MD5 hash algorithm[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
|
||||||
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
||||||
[0;33m(mac) hmac-sha1 -- [warn] using encrypt-and-MAC mode[0m
|
[0;31m(mac) hmac-sha1 -- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
||||||
[0;33m(mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode[0m
|
[0;33m(mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode[0m
|
||||||
[0;33m `- [warn] using small 64-bit tag size[0m
|
[0;33m `- [warn] using small 64-bit tag size[0m
|
||||||
`- [info] available since OpenSSH 4.7
|
`- [info] available since OpenSSH 4.7
|
||||||
[0;31m(mac) hmac-ripemd160 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(mac) hmac-ripemd160 -- [fail] using deprecated RIPEMD hash algorithm[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
`- [info] available since OpenSSH 2.5.0
|
`- [info] available since OpenSSH 2.5.0
|
||||||
[0;31m(mac) hmac-ripemd160@openssh.com -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(mac) hmac-ripemd160@openssh.com -- [fail] using deprecated RIPEMD hash algorithm[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
`- [info] available since OpenSSH 2.1.0
|
`- [info] available since OpenSSH 2.1.0
|
||||||
[0;31m(mac) hmac-sha1-96 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(mac) hmac-sha1-96 -- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
|
||||||
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.47
|
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.47
|
||||||
[0;31m(mac) hmac-md5-96 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(mac) hmac-md5-96 -- [fail] using broken MD5 hash algorithm[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
|
||||||
`- [info] available since OpenSSH 2.5.0
|
`- [info] available since OpenSSH 2.5.0
|
||||||
|
|
||||||
[0;36m# fingerprints[0m
|
[0;36m# fingerprints[0m
|
||||||
[0;32m(fin) ssh-rsa: SHA256:YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4[0m
|
[0;32m(fin) ssh-rsa: SHA256:YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4[0m
|
||||||
|
|
||||||
[0;36m# algorithm recommendations (for OpenSSH 5.6)[0m
|
[0;36m# algorithm recommendations (for OpenSSH 5.6)[0m
|
||||||
[0;31m(rec) !diffie-hellman-group-exchange-sha256 -- kex algorithm to change (increase modulus size to 2048 bits or larger) [0m
|
[0;31m(rec) !diffie-hellman-group-exchange-sha256 -- kex algorithm to change (increase modulus size to 3072 bits or larger) [0m
|
||||||
[0;31m(rec) -3des-cbc -- enc algorithm to remove [0m
|
[0;31m(rec) -3des-cbc -- enc algorithm to remove [0m
|
||||||
[0;31m(rec) -aes128-cbc -- enc algorithm to remove [0m
|
|
||||||
[0;31m(rec) -aes192-cbc -- enc algorithm to remove [0m
|
|
||||||
[0;31m(rec) -aes256-cbc -- enc algorithm to remove [0m
|
|
||||||
[0;31m(rec) -arcfour -- enc algorithm to remove [0m
|
[0;31m(rec) -arcfour -- enc algorithm to remove [0m
|
||||||
[0;31m(rec) -arcfour128 -- enc algorithm to remove [0m
|
[0;31m(rec) -arcfour128 -- enc algorithm to remove [0m
|
||||||
[0;31m(rec) -arcfour256 -- enc algorithm to remove [0m
|
[0;31m(rec) -arcfour256 -- enc algorithm to remove [0m
|
||||||
@ -136,16 +114,19 @@
|
|||||||
[0;31m(rec) -cast128-cbc -- enc algorithm to remove [0m
|
[0;31m(rec) -cast128-cbc -- enc algorithm to remove [0m
|
||||||
[0;31m(rec) -diffie-hellman-group-exchange-sha1 -- kex algorithm to remove [0m
|
[0;31m(rec) -diffie-hellman-group-exchange-sha1 -- kex algorithm to remove [0m
|
||||||
[0;31m(rec) -diffie-hellman-group1-sha1 -- kex algorithm to remove [0m
|
[0;31m(rec) -diffie-hellman-group1-sha1 -- kex algorithm to remove [0m
|
||||||
|
[0;31m(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove [0m
|
||||||
[0;31m(rec) -hmac-md5 -- mac algorithm to remove [0m
|
[0;31m(rec) -hmac-md5 -- mac algorithm to remove [0m
|
||||||
[0;31m(rec) -hmac-md5-96 -- mac algorithm to remove [0m
|
[0;31m(rec) -hmac-md5-96 -- mac algorithm to remove [0m
|
||||||
[0;31m(rec) -hmac-ripemd160 -- mac algorithm to remove [0m
|
[0;31m(rec) -hmac-ripemd160 -- mac algorithm to remove [0m
|
||||||
[0;31m(rec) -hmac-ripemd160@openssh.com -- mac algorithm to remove [0m
|
[0;31m(rec) -hmac-ripemd160@openssh.com -- mac algorithm to remove [0m
|
||||||
|
[0;31m(rec) -hmac-sha1 -- mac algorithm to remove [0m
|
||||||
[0;31m(rec) -hmac-sha1-96 -- mac algorithm to remove [0m
|
[0;31m(rec) -hmac-sha1-96 -- mac algorithm to remove [0m
|
||||||
[0;31m(rec) -rijndael-cbc@lysator.liu.se -- enc algorithm to remove [0m
|
[0;31m(rec) -rijndael-cbc@lysator.liu.se -- enc algorithm to remove [0m
|
||||||
[0;31m(rec) -ssh-dss -- key 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;31m(rec) -ssh-rsa -- key algorithm to remove [0m
|
||||||
[0;33m(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove [0m
|
[0;33m(rec) -aes128-cbc -- enc algorithm to remove [0m
|
||||||
[0;33m(rec) -hmac-sha1 -- mac algorithm to remove [0m
|
[0;33m(rec) -aes192-cbc -- enc algorithm to remove [0m
|
||||||
|
[0;33m(rec) -aes256-cbc -- enc algorithm to remove [0m
|
||||||
[0;33m(rec) -umac-64@openssh.com -- mac algorithm to remove [0m
|
[0;33m(rec) -umac-64@openssh.com -- mac algorithm to remove [0m
|
||||||
|
|
||||||
[0;36m# additional info[0m
|
[0;36m# additional info[0m
|
||||||
|
@ -1 +1,275 @@
|
|||||||
{"banner": {"comments": null, "protocol": [2, 0], "raw": "SSH-2.0-OpenSSH_5.6", "software": "OpenSSH_5.6"}, "compression": ["none", "zlib@openssh.com"], "enc": ["aes128-ctr", "aes192-ctr", "aes256-ctr", "arcfour256", "arcfour128", "aes128-cbc", "3des-cbc", "blowfish-cbc", "cast128-cbc", "aes192-cbc", "aes256-cbc", "arcfour", "rijndael-cbc@lysator.liu.se"], "fingerprints": [{"hash": "YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4", "hash_alg": "SHA256", "hostkey": "ssh-rsa"}, {"hash": "3c:c3:38:f8:55:39:c0:4a:5a:17:89:60:2c:a1:fc:6a", "hash_alg": "MD5", "hostkey": "ssh-rsa"}], "kex": [{"algorithm": "diffie-hellman-group-exchange-sha256", "keysize": 1024}, {"algorithm": "diffie-hellman-group-exchange-sha1", "keysize": 1024}, {"algorithm": "diffie-hellman-group14-sha1"}, {"algorithm": "diffie-hellman-group1-sha1"}], "key": [{"algorithm": "ssh-rsa", "keysize": 1024}, {"algorithm": "ssh-rsa-cert-v01@openssh.com", "casize": 1024, "keysize": 1024}], "mac": ["hmac-md5", "hmac-sha1", "umac-64@openssh.com", "hmac-ripemd160", "hmac-ripemd160@openssh.com", "hmac-sha1-96", "hmac-md5-96"], "target": "localhost"}
|
{
|
||||||
|
"banner": {
|
||||||
|
"comments": null,
|
||||||
|
"protocol": [
|
||||||
|
2,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"raw": "SSH-2.0-OpenSSH_5.6",
|
||||||
|
"software": "OpenSSH_5.6"
|
||||||
|
},
|
||||||
|
"compression": [
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"enc": [
|
||||||
|
"aes128-ctr",
|
||||||
|
"aes192-ctr",
|
||||||
|
"aes256-ctr",
|
||||||
|
"arcfour256",
|
||||||
|
"arcfour128",
|
||||||
|
"aes128-cbc",
|
||||||
|
"3des-cbc",
|
||||||
|
"blowfish-cbc",
|
||||||
|
"cast128-cbc",
|
||||||
|
"aes192-cbc",
|
||||||
|
"aes256-cbc",
|
||||||
|
"arcfour",
|
||||||
|
"rijndael-cbc@lysator.liu.se"
|
||||||
|
],
|
||||||
|
"fingerprints": [
|
||||||
|
{
|
||||||
|
"hash": "YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4",
|
||||||
|
"hash_alg": "SHA256",
|
||||||
|
"hostkey": "ssh-rsa"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hash": "3c:c3:38:f8:55:39:c0:4a:5a:17:89:60:2c:a1:fc:6a",
|
||||||
|
"hash_alg": "MD5",
|
||||||
|
"hostkey": "ssh-rsa"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"kex": [
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group-exchange-sha256",
|
||||||
|
"keysize": 1024
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group-exchange-sha1",
|
||||||
|
"keysize": 1024
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group14-sha1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group1-sha1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"key": [
|
||||||
|
{
|
||||||
|
"algorithm": "ssh-rsa",
|
||||||
|
"keysize": 1024
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "ssh-rsa-cert-v01@openssh.com",
|
||||||
|
"ca_algorithm": "ssh-rsa",
|
||||||
|
"casize": 1024,
|
||||||
|
"keysize": 1024
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mac": [
|
||||||
|
"hmac-md5",
|
||||||
|
"hmac-sha1",
|
||||||
|
"umac-64@openssh.com",
|
||||||
|
"hmac-ripemd160",
|
||||||
|
"hmac-ripemd160@openssh.com",
|
||||||
|
"hmac-sha1-96",
|
||||||
|
"hmac-md5-96"
|
||||||
|
],
|
||||||
|
"recommendations": {
|
||||||
|
"critical": {
|
||||||
|
"chg": {
|
||||||
|
"kex": [
|
||||||
|
{
|
||||||
|
"name": "diffie-hellman-group-exchange-sha256",
|
||||||
|
"notes": "increase modulus size to 3072 bits or larger"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"del": {
|
||||||
|
"enc": [
|
||||||
|
{
|
||||||
|
"name": "3des-cbc",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "arcfour128",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "arcfour",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "arcfour256",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "blowfish-cbc",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cast128-cbc",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rijndael-cbc@lysator.liu.se",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"kex": [
|
||||||
|
{
|
||||||
|
"name": "diffie-hellman-group14-sha1",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "diffie-hellman-group1-sha1",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "diffie-hellman-group-exchange-sha1",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"key": [
|
||||||
|
{
|
||||||
|
"name": "ssh-rsa",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ssh-rsa-cert-v01@openssh.com",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mac": [
|
||||||
|
{
|
||||||
|
"name": "hmac-md5",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-md5-96",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-ripemd160",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-ripemd160@openssh.com",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-sha1",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-sha1-96",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"warning": {
|
||||||
|
"del": {
|
||||||
|
"enc": [
|
||||||
|
{
|
||||||
|
"name": "aes128-cbc",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "aes192-cbc",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "aes256-cbc",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mac": [
|
||||||
|
{
|
||||||
|
"name": "umac-64@openssh.com",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"target": "localhost:2222"
|
||||||
|
}
|
||||||
|
@ -5,7 +5,10 @@
|
|||||||
[0;32m(gen) compression: enabled (zlib@openssh.com)[0m
|
[0;32m(gen) compression: enabled (zlib@openssh.com)[0m
|
||||||
|
|
||||||
[0;36m# security[0m
|
[0;36m# security[0m
|
||||||
[0;33m(cve) CVE-2018-15473 -- (CVSSv2: 5.3) enumerate usernames due to timing discrepencies[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-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-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-6564 -- (CVSSv2: 6.9) privilege escalation via leveraging sshd uid[0m
|
||||||
@ -22,113 +25,89 @@
|
|||||||
[0;31m(kex) diffie-hellman-group-exchange-sha256 (1024-bit) -- [fail] using small 1024-bit modulus[0m
|
[0;31m(kex) diffie-hellman-group-exchange-sha256 (1024-bit) -- [fail] using small 1024-bit modulus[0m
|
||||||
`- [info] available since OpenSSH 4.4
|
`- [info] available since OpenSSH 4.4
|
||||||
[0;31m(kex) diffie-hellman-group-exchange-sha1 (1024-bit) -- [fail] using small 1024-bit modulus[0m
|
[0;31m(kex) diffie-hellman-group-exchange-sha1 (1024-bit) -- [fail] using small 1024-bit modulus[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
|
||||||
`- [info] available since OpenSSH 2.3.0
|
`- [info] available since OpenSSH 2.3.0
|
||||||
[0;33m(kex) diffie-hellman-group14-sha1 -- [warn] using weak hashing algorithm[0m
|
[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
|
||||||
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
|
`- [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(kex) diffie-hellman-group1-sha1 -- [fail] using small 1024-bit modulus[0m
|
||||||
[0;31m `- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m `- [fail] vulnerable to the Logjam attack: https://en.wikipedia.org/wiki/Logjam_(computer_security)[0m
|
||||||
[0;31m `- [fail] disabled (in client) since OpenSSH 7.0, logjam attack[0m
|
[0;31m `- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
|
||||||
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
|
`- [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
|
||||||
|
|
||||||
[0;36m# host-key algorithms[0m
|
[0;36m# host-key algorithms[0m
|
||||||
[0;31m(key) ssh-rsa (1024-bit) -- [fail] using weak hashing algorithm[0m
|
[0;31m(key) ssh-rsa (1024-bit) -- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
[0;31m `- [fail] using small 1024-bit modulus[0m
|
[0;31m `- [fail] using small 1024-bit modulus[0m
|
||||||
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
|
||||||
`- [info] a future deprecation notice has been issued in OpenSSH 8.2: https://www.openssh.com/txt/release-8.2
|
`- [info] deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8
|
||||||
[0;31m(key) ssh-rsa-cert-v01@openssh.com (1024-bit cert/1024-bit CA) -- [fail] using weak hashing algorithm[0m
|
[0;31m(key) ssh-rsa-cert-v01@openssh.com (1024-bit cert/1024-bit RSA CA) -- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
[0;31m `- [fail] using small 1024-bit modulus[0m
|
[0;31m `- [fail] using small 1024-bit hostkey modulus[0m
|
||||||
|
[0;31m `- [fail] using small 1024-bit CA key modulus[0m
|
||||||
`- [info] available since OpenSSH 5.6
|
`- [info] available since OpenSSH 5.6
|
||||||
`- [info] a future deprecation notice has been issued in OpenSSH 8.2: https://www.openssh.com/txt/release-8.2
|
`- [info] deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8
|
||||||
|
|
||||||
[0;36m# encryption algorithms (ciphers)[0m
|
[0;36m# encryption algorithms (ciphers)[0m
|
||||||
[0;32m(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
[0;32m(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
||||||
[0;32m(enc) aes192-ctr -- [info] available since OpenSSH 3.7[0m
|
[0;32m(enc) aes192-ctr -- [info] available since OpenSSH 3.7[0m
|
||||||
[0;32m(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
[0;32m(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
||||||
[0;31m(enc) arcfour256 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) arcfour256 -- [fail] using broken RC4 cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher[0m
|
|
||||||
`- [info] available since OpenSSH 4.2
|
`- [info] available since OpenSSH 4.2
|
||||||
[0;31m(enc) arcfour128 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) arcfour128 -- [fail] using broken RC4 cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher[0m
|
|
||||||
`- [info] available since OpenSSH 4.2
|
`- [info] available since OpenSSH 4.2
|
||||||
[0;31m(enc) aes128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;33m(enc) aes128-cbc -- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
|
||||||
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
|
||||||
[0;31m(enc) 3des-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) 3des-cbc -- [fail] using broken & deprecated 3DES cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.4, unsafe algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher[0m
|
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
[0;33m `- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using small 64-bit block size[0m
|
[0;33m `- [warn] using small 64-bit block size[0m
|
||||||
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
|
||||||
[0;31m(enc) blowfish-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) blowfish-cbc -- [fail] using weak & deprecated Blowfish cipher[0m
|
||||||
[0;31m `- [fail] disabled since Dropbear SSH 0.53[0m
|
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
[0;33m `- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using small 64-bit block size[0m
|
[0;33m `- [warn] using small 64-bit block size[0m
|
||||||
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
|
||||||
[0;31m(enc) cast128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) cast128-cbc -- [fail] using weak & deprecated CAST cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
[0;33m `- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using small 64-bit block size[0m
|
[0;33m `- [warn] using small 64-bit block size[0m
|
||||||
`- [info] available since OpenSSH 2.1.0
|
`- [info] available since OpenSSH 2.1.0
|
||||||
[0;31m(enc) aes192-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;33m(enc) aes192-cbc -- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
|
||||||
`- [info] available since OpenSSH 2.3.0
|
`- [info] available since OpenSSH 2.3.0
|
||||||
[0;31m(enc) aes256-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;33m(enc) aes256-cbc -- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
|
||||||
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47
|
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47
|
||||||
[0;31m(enc) arcfour -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) arcfour -- [fail] using broken RC4 cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher[0m
|
|
||||||
`- [info] available since OpenSSH 2.1.0
|
`- [info] available since OpenSSH 2.1.0
|
||||||
[0;31m(enc) rijndael-cbc@lysator.liu.se -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) rijndael-cbc@lysator.liu.se -- [fail] using deprecated & non-standardized Rijndael cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
[0;33m `- [warn] using weak cipher mode[0m
|
||||||
`- [info] available since OpenSSH 2.3.0
|
`- [info] available since OpenSSH 2.3.0
|
||||||
|
`- [info] disabled in OpenSSH 7.0: https://www.openssh.com/txt/release-7.0
|
||||||
|
|
||||||
[0;36m# message authentication code algorithms[0m
|
[0;36m# message authentication code algorithms[0m
|
||||||
[0;31m(mac) hmac-md5 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(mac) hmac-md5 -- [fail] using broken MD5 hash algorithm[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
|
||||||
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
||||||
[0;33m(mac) hmac-sha1 -- [warn] using encrypt-and-MAC mode[0m
|
[0;31m(mac) hmac-sha1 -- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
||||||
[0;33m(mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode[0m
|
[0;33m(mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode[0m
|
||||||
[0;33m `- [warn] using small 64-bit tag size[0m
|
[0;33m `- [warn] using small 64-bit tag size[0m
|
||||||
`- [info] available since OpenSSH 4.7
|
`- [info] available since OpenSSH 4.7
|
||||||
[0;31m(mac) hmac-ripemd160 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(mac) hmac-ripemd160 -- [fail] using deprecated RIPEMD hash algorithm[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
`- [info] available since OpenSSH 2.5.0
|
`- [info] available since OpenSSH 2.5.0
|
||||||
[0;31m(mac) hmac-ripemd160@openssh.com -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(mac) hmac-ripemd160@openssh.com -- [fail] using deprecated RIPEMD hash algorithm[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
`- [info] available since OpenSSH 2.1.0
|
`- [info] available since OpenSSH 2.1.0
|
||||||
[0;31m(mac) hmac-sha1-96 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(mac) hmac-sha1-96 -- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
|
||||||
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.47
|
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.47
|
||||||
[0;31m(mac) hmac-md5-96 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(mac) hmac-md5-96 -- [fail] using broken MD5 hash algorithm[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
|
||||||
`- [info] available since OpenSSH 2.5.0
|
`- [info] available since OpenSSH 2.5.0
|
||||||
|
|
||||||
[0;36m# fingerprints[0m
|
[0;36m# fingerprints[0m
|
||||||
[0;32m(fin) ssh-rsa: SHA256:YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4[0m
|
[0;32m(fin) ssh-rsa: SHA256:YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4[0m
|
||||||
|
|
||||||
[0;36m# algorithm recommendations (for OpenSSH 5.6)[0m
|
[0;36m# algorithm recommendations (for OpenSSH 5.6)[0m
|
||||||
[0;31m(rec) !diffie-hellman-group-exchange-sha256 -- kex algorithm to change (increase modulus size to 2048 bits or larger) [0m
|
[0;31m(rec) !diffie-hellman-group-exchange-sha256 -- kex algorithm to change (increase modulus size to 3072 bits or larger) [0m
|
||||||
[0;31m(rec) -3des-cbc -- enc algorithm to remove [0m
|
[0;31m(rec) -3des-cbc -- enc algorithm to remove [0m
|
||||||
[0;31m(rec) -aes128-cbc -- enc algorithm to remove [0m
|
|
||||||
[0;31m(rec) -aes192-cbc -- enc algorithm to remove [0m
|
|
||||||
[0;31m(rec) -aes256-cbc -- enc algorithm to remove [0m
|
|
||||||
[0;31m(rec) -arcfour -- enc algorithm to remove [0m
|
[0;31m(rec) -arcfour -- enc algorithm to remove [0m
|
||||||
[0;31m(rec) -arcfour128 -- enc algorithm to remove [0m
|
[0;31m(rec) -arcfour128 -- enc algorithm to remove [0m
|
||||||
[0;31m(rec) -arcfour256 -- enc algorithm to remove [0m
|
[0;31m(rec) -arcfour256 -- enc algorithm to remove [0m
|
||||||
@ -136,16 +115,19 @@
|
|||||||
[0;31m(rec) -cast128-cbc -- enc algorithm to remove [0m
|
[0;31m(rec) -cast128-cbc -- enc algorithm to remove [0m
|
||||||
[0;31m(rec) -diffie-hellman-group-exchange-sha1 -- kex algorithm to remove [0m
|
[0;31m(rec) -diffie-hellman-group-exchange-sha1 -- kex algorithm to remove [0m
|
||||||
[0;31m(rec) -diffie-hellman-group1-sha1 -- kex algorithm to remove [0m
|
[0;31m(rec) -diffie-hellman-group1-sha1 -- kex algorithm to remove [0m
|
||||||
|
[0;31m(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove [0m
|
||||||
[0;31m(rec) -hmac-md5 -- mac algorithm to remove [0m
|
[0;31m(rec) -hmac-md5 -- mac algorithm to remove [0m
|
||||||
[0;31m(rec) -hmac-md5-96 -- mac algorithm to remove [0m
|
[0;31m(rec) -hmac-md5-96 -- mac algorithm to remove [0m
|
||||||
[0;31m(rec) -hmac-ripemd160 -- mac algorithm to remove [0m
|
[0;31m(rec) -hmac-ripemd160 -- mac algorithm to remove [0m
|
||||||
[0;31m(rec) -hmac-ripemd160@openssh.com -- mac algorithm to remove [0m
|
[0;31m(rec) -hmac-ripemd160@openssh.com -- mac algorithm to remove [0m
|
||||||
|
[0;31m(rec) -hmac-sha1 -- mac algorithm to remove [0m
|
||||||
[0;31m(rec) -hmac-sha1-96 -- mac algorithm to remove [0m
|
[0;31m(rec) -hmac-sha1-96 -- mac algorithm to remove [0m
|
||||||
[0;31m(rec) -rijndael-cbc@lysator.liu.se -- enc algorithm to remove [0m
|
[0;31m(rec) -rijndael-cbc@lysator.liu.se -- enc algorithm to remove [0m
|
||||||
[0;31m(rec) -ssh-rsa -- key algorithm to remove [0m
|
[0;31m(rec) -ssh-rsa -- key algorithm to remove [0m
|
||||||
[0;31m(rec) -ssh-rsa-cert-v01@openssh.com -- key algorithm to remove [0m
|
[0;31m(rec) -ssh-rsa-cert-v01@openssh.com -- key algorithm to remove [0m
|
||||||
[0;33m(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove [0m
|
[0;33m(rec) -aes128-cbc -- enc algorithm to remove [0m
|
||||||
[0;33m(rec) -hmac-sha1 -- mac algorithm to remove [0m
|
[0;33m(rec) -aes192-cbc -- enc algorithm to remove [0m
|
||||||
|
[0;33m(rec) -aes256-cbc -- enc algorithm to remove [0m
|
||||||
[0;33m(rec) -umac-64@openssh.com -- mac algorithm to remove [0m
|
[0;33m(rec) -umac-64@openssh.com -- mac algorithm to remove [0m
|
||||||
|
|
||||||
[0;36m# additional info[0m
|
[0;36m# additional info[0m
|
||||||
|
@ -1 +1,275 @@
|
|||||||
{"banner": {"comments": null, "protocol": [2, 0], "raw": "SSH-2.0-OpenSSH_5.6", "software": "OpenSSH_5.6"}, "compression": ["none", "zlib@openssh.com"], "enc": ["aes128-ctr", "aes192-ctr", "aes256-ctr", "arcfour256", "arcfour128", "aes128-cbc", "3des-cbc", "blowfish-cbc", "cast128-cbc", "aes192-cbc", "aes256-cbc", "arcfour", "rijndael-cbc@lysator.liu.se"], "fingerprints": [{"hash": "YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4", "hash_alg": "SHA256", "hostkey": "ssh-rsa"}, {"hash": "3c:c3:38:f8:55:39:c0:4a:5a:17:89:60:2c:a1:fc:6a", "hash_alg": "MD5", "hostkey": "ssh-rsa"}], "kex": [{"algorithm": "diffie-hellman-group-exchange-sha256", "keysize": 1024}, {"algorithm": "diffie-hellman-group-exchange-sha1", "keysize": 1024}, {"algorithm": "diffie-hellman-group14-sha1"}, {"algorithm": "diffie-hellman-group1-sha1"}], "key": [{"algorithm": "ssh-rsa", "keysize": 1024}, {"algorithm": "ssh-rsa-cert-v01@openssh.com", "casize": 3072, "keysize": 1024}], "mac": ["hmac-md5", "hmac-sha1", "umac-64@openssh.com", "hmac-ripemd160", "hmac-ripemd160@openssh.com", "hmac-sha1-96", "hmac-md5-96"], "target": "localhost"}
|
{
|
||||||
|
"banner": {
|
||||||
|
"comments": null,
|
||||||
|
"protocol": [
|
||||||
|
2,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"raw": "SSH-2.0-OpenSSH_5.6",
|
||||||
|
"software": "OpenSSH_5.6"
|
||||||
|
},
|
||||||
|
"compression": [
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"enc": [
|
||||||
|
"aes128-ctr",
|
||||||
|
"aes192-ctr",
|
||||||
|
"aes256-ctr",
|
||||||
|
"arcfour256",
|
||||||
|
"arcfour128",
|
||||||
|
"aes128-cbc",
|
||||||
|
"3des-cbc",
|
||||||
|
"blowfish-cbc",
|
||||||
|
"cast128-cbc",
|
||||||
|
"aes192-cbc",
|
||||||
|
"aes256-cbc",
|
||||||
|
"arcfour",
|
||||||
|
"rijndael-cbc@lysator.liu.se"
|
||||||
|
],
|
||||||
|
"fingerprints": [
|
||||||
|
{
|
||||||
|
"hash": "YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4",
|
||||||
|
"hash_alg": "SHA256",
|
||||||
|
"hostkey": "ssh-rsa"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hash": "3c:c3:38:f8:55:39:c0:4a:5a:17:89:60:2c:a1:fc:6a",
|
||||||
|
"hash_alg": "MD5",
|
||||||
|
"hostkey": "ssh-rsa"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"kex": [
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group-exchange-sha256",
|
||||||
|
"keysize": 1024
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group-exchange-sha1",
|
||||||
|
"keysize": 1024
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group14-sha1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group1-sha1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"key": [
|
||||||
|
{
|
||||||
|
"algorithm": "ssh-rsa",
|
||||||
|
"keysize": 1024
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "ssh-rsa-cert-v01@openssh.com",
|
||||||
|
"ca_algorithm": "ssh-rsa",
|
||||||
|
"casize": 3072,
|
||||||
|
"keysize": 1024
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mac": [
|
||||||
|
"hmac-md5",
|
||||||
|
"hmac-sha1",
|
||||||
|
"umac-64@openssh.com",
|
||||||
|
"hmac-ripemd160",
|
||||||
|
"hmac-ripemd160@openssh.com",
|
||||||
|
"hmac-sha1-96",
|
||||||
|
"hmac-md5-96"
|
||||||
|
],
|
||||||
|
"recommendations": {
|
||||||
|
"critical": {
|
||||||
|
"chg": {
|
||||||
|
"kex": [
|
||||||
|
{
|
||||||
|
"name": "diffie-hellman-group-exchange-sha256",
|
||||||
|
"notes": "increase modulus size to 3072 bits or larger"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"del": {
|
||||||
|
"enc": [
|
||||||
|
{
|
||||||
|
"name": "3des-cbc",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "arcfour128",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "arcfour",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "arcfour256",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "blowfish-cbc",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cast128-cbc",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rijndael-cbc@lysator.liu.se",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"kex": [
|
||||||
|
{
|
||||||
|
"name": "diffie-hellman-group14-sha1",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "diffie-hellman-group1-sha1",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "diffie-hellman-group-exchange-sha1",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"key": [
|
||||||
|
{
|
||||||
|
"name": "ssh-rsa",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ssh-rsa-cert-v01@openssh.com",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mac": [
|
||||||
|
{
|
||||||
|
"name": "hmac-md5",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-md5-96",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-ripemd160",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-ripemd160@openssh.com",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-sha1",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-sha1-96",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"warning": {
|
||||||
|
"del": {
|
||||||
|
"enc": [
|
||||||
|
{
|
||||||
|
"name": "aes128-cbc",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "aes192-cbc",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "aes256-cbc",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mac": [
|
||||||
|
{
|
||||||
|
"name": "umac-64@openssh.com",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"target": "localhost:2222"
|
||||||
|
}
|
||||||
|
@ -5,7 +5,10 @@
|
|||||||
[0;32m(gen) compression: enabled (zlib@openssh.com)[0m
|
[0;32m(gen) compression: enabled (zlib@openssh.com)[0m
|
||||||
|
|
||||||
[0;36m# security[0m
|
[0;36m# security[0m
|
||||||
[0;33m(cve) CVE-2018-15473 -- (CVSSv2: 5.3) enumerate usernames due to timing discrepencies[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-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-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-6564 -- (CVSSv2: 6.9) privilege escalation via leveraging sshd uid[0m
|
||||||
@ -22,113 +25,88 @@
|
|||||||
[0;31m(kex) diffie-hellman-group-exchange-sha256 (1024-bit) -- [fail] using small 1024-bit modulus[0m
|
[0;31m(kex) diffie-hellman-group-exchange-sha256 (1024-bit) -- [fail] using small 1024-bit modulus[0m
|
||||||
`- [info] available since OpenSSH 4.4
|
`- [info] available since OpenSSH 4.4
|
||||||
[0;31m(kex) diffie-hellman-group-exchange-sha1 (1024-bit) -- [fail] using small 1024-bit modulus[0m
|
[0;31m(kex) diffie-hellman-group-exchange-sha1 (1024-bit) -- [fail] using small 1024-bit modulus[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
|
||||||
`- [info] available since OpenSSH 2.3.0
|
`- [info] available since OpenSSH 2.3.0
|
||||||
[0;33m(kex) diffie-hellman-group14-sha1 -- [warn] using weak hashing algorithm[0m
|
[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
|
||||||
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
|
`- [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(kex) diffie-hellman-group1-sha1 -- [fail] using small 1024-bit modulus[0m
|
||||||
[0;31m `- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m `- [fail] vulnerable to the Logjam attack: https://en.wikipedia.org/wiki/Logjam_(computer_security)[0m
|
||||||
[0;31m `- [fail] disabled (in client) since OpenSSH 7.0, logjam attack[0m
|
[0;31m `- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
|
||||||
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
|
`- [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
|
||||||
|
|
||||||
[0;36m# host-key algorithms[0m
|
[0;36m# host-key algorithms[0m
|
||||||
[0;31m(key) ssh-rsa (1024-bit) -- [fail] using weak hashing algorithm[0m
|
[0;31m(key) ssh-rsa (1024-bit) -- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
[0;31m `- [fail] using small 1024-bit modulus[0m
|
[0;31m `- [fail] using small 1024-bit modulus[0m
|
||||||
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
|
||||||
`- [info] a future deprecation notice has been issued in OpenSSH 8.2: https://www.openssh.com/txt/release-8.2
|
`- [info] deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8
|
||||||
[0;31m(key) ssh-rsa-cert-v01@openssh.com (1024-bit cert/3072-bit CA) -- [fail] using weak hashing algorithm[0m
|
[0;31m(key) ssh-rsa-cert-v01@openssh.com (1024-bit cert/3072-bit RSA CA) -- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
[0;31m `- [fail] using small 1024-bit modulus[0m
|
[0;31m `- [fail] using small 1024-bit hostkey modulus[0m
|
||||||
`- [info] available since OpenSSH 5.6
|
`- [info] available since OpenSSH 5.6
|
||||||
`- [info] a future deprecation notice has been issued in OpenSSH 8.2: https://www.openssh.com/txt/release-8.2
|
`- [info] deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8
|
||||||
|
|
||||||
[0;36m# encryption algorithms (ciphers)[0m
|
[0;36m# encryption algorithms (ciphers)[0m
|
||||||
[0;32m(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
[0;32m(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
||||||
[0;32m(enc) aes192-ctr -- [info] available since OpenSSH 3.7[0m
|
[0;32m(enc) aes192-ctr -- [info] available since OpenSSH 3.7[0m
|
||||||
[0;32m(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
[0;32m(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
||||||
[0;31m(enc) arcfour256 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) arcfour256 -- [fail] using broken RC4 cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher[0m
|
|
||||||
`- [info] available since OpenSSH 4.2
|
`- [info] available since OpenSSH 4.2
|
||||||
[0;31m(enc) arcfour128 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) arcfour128 -- [fail] using broken RC4 cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher[0m
|
|
||||||
`- [info] available since OpenSSH 4.2
|
`- [info] available since OpenSSH 4.2
|
||||||
[0;31m(enc) aes128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;33m(enc) aes128-cbc -- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
|
||||||
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
|
||||||
[0;31m(enc) 3des-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) 3des-cbc -- [fail] using broken & deprecated 3DES cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.4, unsafe algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher[0m
|
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
[0;33m `- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using small 64-bit block size[0m
|
[0;33m `- [warn] using small 64-bit block size[0m
|
||||||
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
|
||||||
[0;31m(enc) blowfish-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) blowfish-cbc -- [fail] using weak & deprecated Blowfish cipher[0m
|
||||||
[0;31m `- [fail] disabled since Dropbear SSH 0.53[0m
|
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
[0;33m `- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using small 64-bit block size[0m
|
[0;33m `- [warn] using small 64-bit block size[0m
|
||||||
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
|
||||||
[0;31m(enc) cast128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) cast128-cbc -- [fail] using weak & deprecated CAST cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
[0;33m `- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using small 64-bit block size[0m
|
[0;33m `- [warn] using small 64-bit block size[0m
|
||||||
`- [info] available since OpenSSH 2.1.0
|
`- [info] available since OpenSSH 2.1.0
|
||||||
[0;31m(enc) aes192-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;33m(enc) aes192-cbc -- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
|
||||||
`- [info] available since OpenSSH 2.3.0
|
`- [info] available since OpenSSH 2.3.0
|
||||||
[0;31m(enc) aes256-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;33m(enc) aes256-cbc -- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
|
||||||
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47
|
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47
|
||||||
[0;31m(enc) arcfour -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) arcfour -- [fail] using broken RC4 cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher[0m
|
|
||||||
`- [info] available since OpenSSH 2.1.0
|
`- [info] available since OpenSSH 2.1.0
|
||||||
[0;31m(enc) rijndael-cbc@lysator.liu.se -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) rijndael-cbc@lysator.liu.se -- [fail] using deprecated & non-standardized Rijndael cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
[0;33m `- [warn] using weak cipher mode[0m
|
||||||
`- [info] available since OpenSSH 2.3.0
|
`- [info] available since OpenSSH 2.3.0
|
||||||
|
`- [info] disabled in OpenSSH 7.0: https://www.openssh.com/txt/release-7.0
|
||||||
|
|
||||||
[0;36m# message authentication code algorithms[0m
|
[0;36m# message authentication code algorithms[0m
|
||||||
[0;31m(mac) hmac-md5 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(mac) hmac-md5 -- [fail] using broken MD5 hash algorithm[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
|
||||||
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
||||||
[0;33m(mac) hmac-sha1 -- [warn] using encrypt-and-MAC mode[0m
|
[0;31m(mac) hmac-sha1 -- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
||||||
[0;33m(mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode[0m
|
[0;33m(mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode[0m
|
||||||
[0;33m `- [warn] using small 64-bit tag size[0m
|
[0;33m `- [warn] using small 64-bit tag size[0m
|
||||||
`- [info] available since OpenSSH 4.7
|
`- [info] available since OpenSSH 4.7
|
||||||
[0;31m(mac) hmac-ripemd160 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(mac) hmac-ripemd160 -- [fail] using deprecated RIPEMD hash algorithm[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
`- [info] available since OpenSSH 2.5.0
|
`- [info] available since OpenSSH 2.5.0
|
||||||
[0;31m(mac) hmac-ripemd160@openssh.com -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(mac) hmac-ripemd160@openssh.com -- [fail] using deprecated RIPEMD hash algorithm[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
`- [info] available since OpenSSH 2.1.0
|
`- [info] available since OpenSSH 2.1.0
|
||||||
[0;31m(mac) hmac-sha1-96 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(mac) hmac-sha1-96 -- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
|
||||||
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.47
|
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.47
|
||||||
[0;31m(mac) hmac-md5-96 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(mac) hmac-md5-96 -- [fail] using broken MD5 hash algorithm[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
|
||||||
`- [info] available since OpenSSH 2.5.0
|
`- [info] available since OpenSSH 2.5.0
|
||||||
|
|
||||||
[0;36m# fingerprints[0m
|
[0;36m# fingerprints[0m
|
||||||
[0;32m(fin) ssh-rsa: SHA256:YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4[0m
|
[0;32m(fin) ssh-rsa: SHA256:YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4[0m
|
||||||
|
|
||||||
[0;36m# algorithm recommendations (for OpenSSH 5.6)[0m
|
[0;36m# algorithm recommendations (for OpenSSH 5.6)[0m
|
||||||
[0;31m(rec) !diffie-hellman-group-exchange-sha256 -- kex algorithm to change (increase modulus size to 2048 bits or larger) [0m
|
[0;31m(rec) !diffie-hellman-group-exchange-sha256 -- kex algorithm to change (increase modulus size to 3072 bits or larger) [0m
|
||||||
[0;31m(rec) -3des-cbc -- enc algorithm to remove [0m
|
[0;31m(rec) -3des-cbc -- enc algorithm to remove [0m
|
||||||
[0;31m(rec) -aes128-cbc -- enc algorithm to remove [0m
|
|
||||||
[0;31m(rec) -aes192-cbc -- enc algorithm to remove [0m
|
|
||||||
[0;31m(rec) -aes256-cbc -- enc algorithm to remove [0m
|
|
||||||
[0;31m(rec) -arcfour -- enc algorithm to remove [0m
|
[0;31m(rec) -arcfour -- enc algorithm to remove [0m
|
||||||
[0;31m(rec) -arcfour128 -- enc algorithm to remove [0m
|
[0;31m(rec) -arcfour128 -- enc algorithm to remove [0m
|
||||||
[0;31m(rec) -arcfour256 -- enc algorithm to remove [0m
|
[0;31m(rec) -arcfour256 -- enc algorithm to remove [0m
|
||||||
@ -136,16 +114,19 @@
|
|||||||
[0;31m(rec) -cast128-cbc -- enc algorithm to remove [0m
|
[0;31m(rec) -cast128-cbc -- enc algorithm to remove [0m
|
||||||
[0;31m(rec) -diffie-hellman-group-exchange-sha1 -- kex algorithm to remove [0m
|
[0;31m(rec) -diffie-hellman-group-exchange-sha1 -- kex algorithm to remove [0m
|
||||||
[0;31m(rec) -diffie-hellman-group1-sha1 -- kex algorithm to remove [0m
|
[0;31m(rec) -diffie-hellman-group1-sha1 -- kex algorithm to remove [0m
|
||||||
|
[0;31m(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove [0m
|
||||||
[0;31m(rec) -hmac-md5 -- mac algorithm to remove [0m
|
[0;31m(rec) -hmac-md5 -- mac algorithm to remove [0m
|
||||||
[0;31m(rec) -hmac-md5-96 -- mac algorithm to remove [0m
|
[0;31m(rec) -hmac-md5-96 -- mac algorithm to remove [0m
|
||||||
[0;31m(rec) -hmac-ripemd160 -- mac algorithm to remove [0m
|
[0;31m(rec) -hmac-ripemd160 -- mac algorithm to remove [0m
|
||||||
[0;31m(rec) -hmac-ripemd160@openssh.com -- mac algorithm to remove [0m
|
[0;31m(rec) -hmac-ripemd160@openssh.com -- mac algorithm to remove [0m
|
||||||
|
[0;31m(rec) -hmac-sha1 -- mac algorithm to remove [0m
|
||||||
[0;31m(rec) -hmac-sha1-96 -- mac algorithm to remove [0m
|
[0;31m(rec) -hmac-sha1-96 -- mac algorithm to remove [0m
|
||||||
[0;31m(rec) -rijndael-cbc@lysator.liu.se -- enc algorithm to remove [0m
|
[0;31m(rec) -rijndael-cbc@lysator.liu.se -- enc algorithm to remove [0m
|
||||||
[0;31m(rec) -ssh-rsa -- key algorithm to remove [0m
|
[0;31m(rec) -ssh-rsa -- key algorithm to remove [0m
|
||||||
[0;31m(rec) -ssh-rsa-cert-v01@openssh.com -- key algorithm to remove [0m
|
[0;31m(rec) -ssh-rsa-cert-v01@openssh.com -- key algorithm to remove [0m
|
||||||
[0;33m(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove [0m
|
[0;33m(rec) -aes128-cbc -- enc algorithm to remove [0m
|
||||||
[0;33m(rec) -hmac-sha1 -- mac algorithm to remove [0m
|
[0;33m(rec) -aes192-cbc -- enc algorithm to remove [0m
|
||||||
|
[0;33m(rec) -aes256-cbc -- enc algorithm to remove [0m
|
||||||
[0;33m(rec) -umac-64@openssh.com -- mac algorithm to remove [0m
|
[0;33m(rec) -umac-64@openssh.com -- mac algorithm to remove [0m
|
||||||
|
|
||||||
[0;36m# additional info[0m
|
[0;36m# additional info[0m
|
||||||
|
@ -1 +1,275 @@
|
|||||||
{"banner": {"comments": null, "protocol": [2, 0], "raw": "SSH-2.0-OpenSSH_5.6", "software": "OpenSSH_5.6"}, "compression": ["none", "zlib@openssh.com"], "enc": ["aes128-ctr", "aes192-ctr", "aes256-ctr", "arcfour256", "arcfour128", "aes128-cbc", "3des-cbc", "blowfish-cbc", "cast128-cbc", "aes192-cbc", "aes256-cbc", "arcfour", "rijndael-cbc@lysator.liu.se"], "fingerprints": [{"hash": "nsWtdJ9Z67Vrf7OsUzQov7esXhsWAfVppArGh25u244", "hash_alg": "SHA256", "hostkey": "ssh-rsa"}, {"hash": "18:e2:51:fe:21:6c:78:d0:b8:cf:32:d4:bd:56:42:e1", "hash_alg": "MD5", "hostkey": "ssh-rsa"}], "kex": [{"algorithm": "diffie-hellman-group-exchange-sha256", "keysize": 1024}, {"algorithm": "diffie-hellman-group-exchange-sha1", "keysize": 1024}, {"algorithm": "diffie-hellman-group14-sha1"}, {"algorithm": "diffie-hellman-group1-sha1"}], "key": [{"algorithm": "ssh-rsa", "keysize": 3072}, {"algorithm": "ssh-rsa-cert-v01@openssh.com", "casize": 1024, "keysize": 3072}], "mac": ["hmac-md5", "hmac-sha1", "umac-64@openssh.com", "hmac-ripemd160", "hmac-ripemd160@openssh.com", "hmac-sha1-96", "hmac-md5-96"], "target": "localhost"}
|
{
|
||||||
|
"banner": {
|
||||||
|
"comments": null,
|
||||||
|
"protocol": [
|
||||||
|
2,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"raw": "SSH-2.0-OpenSSH_5.6",
|
||||||
|
"software": "OpenSSH_5.6"
|
||||||
|
},
|
||||||
|
"compression": [
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"enc": [
|
||||||
|
"aes128-ctr",
|
||||||
|
"aes192-ctr",
|
||||||
|
"aes256-ctr",
|
||||||
|
"arcfour256",
|
||||||
|
"arcfour128",
|
||||||
|
"aes128-cbc",
|
||||||
|
"3des-cbc",
|
||||||
|
"blowfish-cbc",
|
||||||
|
"cast128-cbc",
|
||||||
|
"aes192-cbc",
|
||||||
|
"aes256-cbc",
|
||||||
|
"arcfour",
|
||||||
|
"rijndael-cbc@lysator.liu.se"
|
||||||
|
],
|
||||||
|
"fingerprints": [
|
||||||
|
{
|
||||||
|
"hash": "nsWtdJ9Z67Vrf7OsUzQov7esXhsWAfVppArGh25u244",
|
||||||
|
"hash_alg": "SHA256",
|
||||||
|
"hostkey": "ssh-rsa"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hash": "18:e2:51:fe:21:6c:78:d0:b8:cf:32:d4:bd:56:42:e1",
|
||||||
|
"hash_alg": "MD5",
|
||||||
|
"hostkey": "ssh-rsa"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"kex": [
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group-exchange-sha256",
|
||||||
|
"keysize": 1024
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group-exchange-sha1",
|
||||||
|
"keysize": 1024
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group14-sha1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group1-sha1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"key": [
|
||||||
|
{
|
||||||
|
"algorithm": "ssh-rsa",
|
||||||
|
"keysize": 3072
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "ssh-rsa-cert-v01@openssh.com",
|
||||||
|
"ca_algorithm": "ssh-rsa",
|
||||||
|
"casize": 1024,
|
||||||
|
"keysize": 3072
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mac": [
|
||||||
|
"hmac-md5",
|
||||||
|
"hmac-sha1",
|
||||||
|
"umac-64@openssh.com",
|
||||||
|
"hmac-ripemd160",
|
||||||
|
"hmac-ripemd160@openssh.com",
|
||||||
|
"hmac-sha1-96",
|
||||||
|
"hmac-md5-96"
|
||||||
|
],
|
||||||
|
"recommendations": {
|
||||||
|
"critical": {
|
||||||
|
"chg": {
|
||||||
|
"kex": [
|
||||||
|
{
|
||||||
|
"name": "diffie-hellman-group-exchange-sha256",
|
||||||
|
"notes": "increase modulus size to 3072 bits or larger"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"del": {
|
||||||
|
"enc": [
|
||||||
|
{
|
||||||
|
"name": "3des-cbc",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "arcfour128",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "arcfour",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "arcfour256",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "blowfish-cbc",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cast128-cbc",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rijndael-cbc@lysator.liu.se",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"kex": [
|
||||||
|
{
|
||||||
|
"name": "diffie-hellman-group14-sha1",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "diffie-hellman-group1-sha1",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "diffie-hellman-group-exchange-sha1",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"key": [
|
||||||
|
{
|
||||||
|
"name": "ssh-rsa",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ssh-rsa-cert-v01@openssh.com",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mac": [
|
||||||
|
{
|
||||||
|
"name": "hmac-md5",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-md5-96",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-ripemd160",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-ripemd160@openssh.com",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-sha1",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-sha1-96",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"warning": {
|
||||||
|
"del": {
|
||||||
|
"enc": [
|
||||||
|
{
|
||||||
|
"name": "aes128-cbc",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "aes192-cbc",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "aes256-cbc",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mac": [
|
||||||
|
{
|
||||||
|
"name": "umac-64@openssh.com",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"target": "localhost:2222"
|
||||||
|
}
|
||||||
|
@ -5,7 +5,10 @@
|
|||||||
[0;32m(gen) compression: enabled (zlib@openssh.com)[0m
|
[0;32m(gen) compression: enabled (zlib@openssh.com)[0m
|
||||||
|
|
||||||
[0;36m# security[0m
|
[0;36m# security[0m
|
||||||
[0;33m(cve) CVE-2018-15473 -- (CVSSv2: 5.3) enumerate usernames due to timing discrepencies[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-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-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-6564 -- (CVSSv2: 6.9) privilege escalation via leveraging sshd uid[0m
|
||||||
@ -22,112 +25,87 @@
|
|||||||
[0;31m(kex) diffie-hellman-group-exchange-sha256 (1024-bit) -- [fail] using small 1024-bit modulus[0m
|
[0;31m(kex) diffie-hellman-group-exchange-sha256 (1024-bit) -- [fail] using small 1024-bit modulus[0m
|
||||||
`- [info] available since OpenSSH 4.4
|
`- [info] available since OpenSSH 4.4
|
||||||
[0;31m(kex) diffie-hellman-group-exchange-sha1 (1024-bit) -- [fail] using small 1024-bit modulus[0m
|
[0;31m(kex) diffie-hellman-group-exchange-sha1 (1024-bit) -- [fail] using small 1024-bit modulus[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
|
||||||
`- [info] available since OpenSSH 2.3.0
|
`- [info] available since OpenSSH 2.3.0
|
||||||
[0;33m(kex) diffie-hellman-group14-sha1 -- [warn] using weak hashing algorithm[0m
|
[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
|
||||||
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
|
`- [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(kex) diffie-hellman-group1-sha1 -- [fail] using small 1024-bit modulus[0m
|
||||||
[0;31m `- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m `- [fail] vulnerable to the Logjam attack: https://en.wikipedia.org/wiki/Logjam_(computer_security)[0m
|
||||||
[0;31m `- [fail] disabled (in client) since OpenSSH 7.0, logjam attack[0m
|
[0;31m `- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
|
||||||
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
|
`- [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
|
||||||
|
|
||||||
[0;36m# host-key algorithms[0m
|
[0;36m# host-key algorithms[0m
|
||||||
[0;31m(key) ssh-rsa (3072-bit) -- [fail] using weak hashing algorithm[0m
|
[0;31m(key) ssh-rsa (3072-bit) -- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
|
||||||
`- [info] a future deprecation notice has been issued in OpenSSH 8.2: https://www.openssh.com/txt/release-8.2
|
`- [info] deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8
|
||||||
[0;31m(key) ssh-rsa-cert-v01@openssh.com (3072-bit cert/1024-bit CA) -- [fail] using weak hashing algorithm[0m
|
[0;31m(key) ssh-rsa-cert-v01@openssh.com (3072-bit cert/1024-bit RSA CA) -- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
[0;31m `- [fail] using small 1024-bit modulus[0m
|
[0;31m `- [fail] using small 1024-bit CA key modulus[0m
|
||||||
`- [info] available since OpenSSH 5.6
|
`- [info] available since OpenSSH 5.6
|
||||||
`- [info] a future deprecation notice has been issued in OpenSSH 8.2: https://www.openssh.com/txt/release-8.2
|
`- [info] deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8
|
||||||
|
|
||||||
[0;36m# encryption algorithms (ciphers)[0m
|
[0;36m# encryption algorithms (ciphers)[0m
|
||||||
[0;32m(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
[0;32m(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
||||||
[0;32m(enc) aes192-ctr -- [info] available since OpenSSH 3.7[0m
|
[0;32m(enc) aes192-ctr -- [info] available since OpenSSH 3.7[0m
|
||||||
[0;32m(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
[0;32m(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
||||||
[0;31m(enc) arcfour256 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) arcfour256 -- [fail] using broken RC4 cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher[0m
|
|
||||||
`- [info] available since OpenSSH 4.2
|
`- [info] available since OpenSSH 4.2
|
||||||
[0;31m(enc) arcfour128 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) arcfour128 -- [fail] using broken RC4 cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher[0m
|
|
||||||
`- [info] available since OpenSSH 4.2
|
`- [info] available since OpenSSH 4.2
|
||||||
[0;31m(enc) aes128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;33m(enc) aes128-cbc -- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
|
||||||
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
|
||||||
[0;31m(enc) 3des-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) 3des-cbc -- [fail] using broken & deprecated 3DES cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.4, unsafe algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher[0m
|
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
[0;33m `- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using small 64-bit block size[0m
|
[0;33m `- [warn] using small 64-bit block size[0m
|
||||||
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
|
||||||
[0;31m(enc) blowfish-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) blowfish-cbc -- [fail] using weak & deprecated Blowfish cipher[0m
|
||||||
[0;31m `- [fail] disabled since Dropbear SSH 0.53[0m
|
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
[0;33m `- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using small 64-bit block size[0m
|
[0;33m `- [warn] using small 64-bit block size[0m
|
||||||
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
|
||||||
[0;31m(enc) cast128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) cast128-cbc -- [fail] using weak & deprecated CAST cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
[0;33m `- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using small 64-bit block size[0m
|
[0;33m `- [warn] using small 64-bit block size[0m
|
||||||
`- [info] available since OpenSSH 2.1.0
|
`- [info] available since OpenSSH 2.1.0
|
||||||
[0;31m(enc) aes192-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;33m(enc) aes192-cbc -- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
|
||||||
`- [info] available since OpenSSH 2.3.0
|
`- [info] available since OpenSSH 2.3.0
|
||||||
[0;31m(enc) aes256-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;33m(enc) aes256-cbc -- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
|
||||||
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47
|
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47
|
||||||
[0;31m(enc) arcfour -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) arcfour -- [fail] using broken RC4 cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher[0m
|
|
||||||
`- [info] available since OpenSSH 2.1.0
|
`- [info] available since OpenSSH 2.1.0
|
||||||
[0;31m(enc) rijndael-cbc@lysator.liu.se -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) rijndael-cbc@lysator.liu.se -- [fail] using deprecated & non-standardized Rijndael cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
[0;33m `- [warn] using weak cipher mode[0m
|
||||||
`- [info] available since OpenSSH 2.3.0
|
`- [info] available since OpenSSH 2.3.0
|
||||||
|
`- [info] disabled in OpenSSH 7.0: https://www.openssh.com/txt/release-7.0
|
||||||
|
|
||||||
[0;36m# message authentication code algorithms[0m
|
[0;36m# message authentication code algorithms[0m
|
||||||
[0;31m(mac) hmac-md5 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(mac) hmac-md5 -- [fail] using broken MD5 hash algorithm[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
|
||||||
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
||||||
[0;33m(mac) hmac-sha1 -- [warn] using encrypt-and-MAC mode[0m
|
[0;31m(mac) hmac-sha1 -- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
||||||
[0;33m(mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode[0m
|
[0;33m(mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode[0m
|
||||||
[0;33m `- [warn] using small 64-bit tag size[0m
|
[0;33m `- [warn] using small 64-bit tag size[0m
|
||||||
`- [info] available since OpenSSH 4.7
|
`- [info] available since OpenSSH 4.7
|
||||||
[0;31m(mac) hmac-ripemd160 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(mac) hmac-ripemd160 -- [fail] using deprecated RIPEMD hash algorithm[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
`- [info] available since OpenSSH 2.5.0
|
`- [info] available since OpenSSH 2.5.0
|
||||||
[0;31m(mac) hmac-ripemd160@openssh.com -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(mac) hmac-ripemd160@openssh.com -- [fail] using deprecated RIPEMD hash algorithm[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
`- [info] available since OpenSSH 2.1.0
|
`- [info] available since OpenSSH 2.1.0
|
||||||
[0;31m(mac) hmac-sha1-96 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(mac) hmac-sha1-96 -- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
|
||||||
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.47
|
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.47
|
||||||
[0;31m(mac) hmac-md5-96 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(mac) hmac-md5-96 -- [fail] using broken MD5 hash algorithm[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
|
||||||
`- [info] available since OpenSSH 2.5.0
|
`- [info] available since OpenSSH 2.5.0
|
||||||
|
|
||||||
[0;36m# fingerprints[0m
|
[0;36m# fingerprints[0m
|
||||||
[0;32m(fin) ssh-rsa: SHA256:nsWtdJ9Z67Vrf7OsUzQov7esXhsWAfVppArGh25u244[0m
|
[0;32m(fin) ssh-rsa: SHA256:nsWtdJ9Z67Vrf7OsUzQov7esXhsWAfVppArGh25u244[0m
|
||||||
|
|
||||||
[0;36m# algorithm recommendations (for OpenSSH 5.6)[0m
|
[0;36m# algorithm recommendations (for OpenSSH 5.6)[0m
|
||||||
[0;31m(rec) !diffie-hellman-group-exchange-sha256 -- kex algorithm to change (increase modulus size to 2048 bits or larger) [0m
|
[0;31m(rec) !diffie-hellman-group-exchange-sha256 -- kex algorithm to change (increase modulus size to 3072 bits or larger) [0m
|
||||||
[0;31m(rec) -3des-cbc -- enc algorithm to remove [0m
|
[0;31m(rec) -3des-cbc -- enc algorithm to remove [0m
|
||||||
[0;31m(rec) -aes128-cbc -- enc algorithm to remove [0m
|
|
||||||
[0;31m(rec) -aes192-cbc -- enc algorithm to remove [0m
|
|
||||||
[0;31m(rec) -aes256-cbc -- enc algorithm to remove [0m
|
|
||||||
[0;31m(rec) -arcfour -- enc algorithm to remove [0m
|
[0;31m(rec) -arcfour -- enc algorithm to remove [0m
|
||||||
[0;31m(rec) -arcfour128 -- enc algorithm to remove [0m
|
[0;31m(rec) -arcfour128 -- enc algorithm to remove [0m
|
||||||
[0;31m(rec) -arcfour256 -- enc algorithm to remove [0m
|
[0;31m(rec) -arcfour256 -- enc algorithm to remove [0m
|
||||||
@ -135,16 +113,19 @@
|
|||||||
[0;31m(rec) -cast128-cbc -- enc algorithm to remove [0m
|
[0;31m(rec) -cast128-cbc -- enc algorithm to remove [0m
|
||||||
[0;31m(rec) -diffie-hellman-group-exchange-sha1 -- kex algorithm to remove [0m
|
[0;31m(rec) -diffie-hellman-group-exchange-sha1 -- kex algorithm to remove [0m
|
||||||
[0;31m(rec) -diffie-hellman-group1-sha1 -- kex algorithm to remove [0m
|
[0;31m(rec) -diffie-hellman-group1-sha1 -- kex algorithm to remove [0m
|
||||||
|
[0;31m(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove [0m
|
||||||
[0;31m(rec) -hmac-md5 -- mac algorithm to remove [0m
|
[0;31m(rec) -hmac-md5 -- mac algorithm to remove [0m
|
||||||
[0;31m(rec) -hmac-md5-96 -- mac algorithm to remove [0m
|
[0;31m(rec) -hmac-md5-96 -- mac algorithm to remove [0m
|
||||||
[0;31m(rec) -hmac-ripemd160 -- mac algorithm to remove [0m
|
[0;31m(rec) -hmac-ripemd160 -- mac algorithm to remove [0m
|
||||||
[0;31m(rec) -hmac-ripemd160@openssh.com -- mac algorithm to remove [0m
|
[0;31m(rec) -hmac-ripemd160@openssh.com -- mac algorithm to remove [0m
|
||||||
|
[0;31m(rec) -hmac-sha1 -- mac algorithm to remove [0m
|
||||||
[0;31m(rec) -hmac-sha1-96 -- mac algorithm to remove [0m
|
[0;31m(rec) -hmac-sha1-96 -- mac algorithm to remove [0m
|
||||||
[0;31m(rec) -rijndael-cbc@lysator.liu.se -- enc algorithm to remove [0m
|
[0;31m(rec) -rijndael-cbc@lysator.liu.se -- enc algorithm to remove [0m
|
||||||
[0;31m(rec) -ssh-rsa -- key algorithm to remove [0m
|
[0;31m(rec) -ssh-rsa -- key algorithm to remove [0m
|
||||||
[0;31m(rec) -ssh-rsa-cert-v01@openssh.com -- key algorithm to remove [0m
|
[0;31m(rec) -ssh-rsa-cert-v01@openssh.com -- key algorithm to remove [0m
|
||||||
[0;33m(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove [0m
|
[0;33m(rec) -aes128-cbc -- enc algorithm to remove [0m
|
||||||
[0;33m(rec) -hmac-sha1 -- mac algorithm to remove [0m
|
[0;33m(rec) -aes192-cbc -- enc algorithm to remove [0m
|
||||||
|
[0;33m(rec) -aes256-cbc -- enc algorithm to remove [0m
|
||||||
[0;33m(rec) -umac-64@openssh.com -- mac algorithm to remove [0m
|
[0;33m(rec) -umac-64@openssh.com -- mac algorithm to remove [0m
|
||||||
|
|
||||||
[0;36m# additional info[0m
|
[0;36m# additional info[0m
|
||||||
|
@ -1 +1,275 @@
|
|||||||
{"banner": {"comments": null, "protocol": [2, 0], "raw": "SSH-2.0-OpenSSH_5.6", "software": "OpenSSH_5.6"}, "compression": ["none", "zlib@openssh.com"], "enc": ["aes128-ctr", "aes192-ctr", "aes256-ctr", "arcfour256", "arcfour128", "aes128-cbc", "3des-cbc", "blowfish-cbc", "cast128-cbc", "aes192-cbc", "aes256-cbc", "arcfour", "rijndael-cbc@lysator.liu.se"], "fingerprints": [{"hash": "nsWtdJ9Z67Vrf7OsUzQov7esXhsWAfVppArGh25u244", "hash_alg": "SHA256", "hostkey": "ssh-rsa"}, {"hash": "18:e2:51:fe:21:6c:78:d0:b8:cf:32:d4:bd:56:42:e1", "hash_alg": "MD5", "hostkey": "ssh-rsa"}], "kex": [{"algorithm": "diffie-hellman-group-exchange-sha256", "keysize": 1024}, {"algorithm": "diffie-hellman-group-exchange-sha1", "keysize": 1024}, {"algorithm": "diffie-hellman-group14-sha1"}, {"algorithm": "diffie-hellman-group1-sha1"}], "key": [{"algorithm": "ssh-rsa", "keysize": 3072}, {"algorithm": "ssh-rsa-cert-v01@openssh.com", "casize": 3072, "keysize": 3072}], "mac": ["hmac-md5", "hmac-sha1", "umac-64@openssh.com", "hmac-ripemd160", "hmac-ripemd160@openssh.com", "hmac-sha1-96", "hmac-md5-96"], "target": "localhost"}
|
{
|
||||||
|
"banner": {
|
||||||
|
"comments": null,
|
||||||
|
"protocol": [
|
||||||
|
2,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"raw": "SSH-2.0-OpenSSH_5.6",
|
||||||
|
"software": "OpenSSH_5.6"
|
||||||
|
},
|
||||||
|
"compression": [
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"enc": [
|
||||||
|
"aes128-ctr",
|
||||||
|
"aes192-ctr",
|
||||||
|
"aes256-ctr",
|
||||||
|
"arcfour256",
|
||||||
|
"arcfour128",
|
||||||
|
"aes128-cbc",
|
||||||
|
"3des-cbc",
|
||||||
|
"blowfish-cbc",
|
||||||
|
"cast128-cbc",
|
||||||
|
"aes192-cbc",
|
||||||
|
"aes256-cbc",
|
||||||
|
"arcfour",
|
||||||
|
"rijndael-cbc@lysator.liu.se"
|
||||||
|
],
|
||||||
|
"fingerprints": [
|
||||||
|
{
|
||||||
|
"hash": "nsWtdJ9Z67Vrf7OsUzQov7esXhsWAfVppArGh25u244",
|
||||||
|
"hash_alg": "SHA256",
|
||||||
|
"hostkey": "ssh-rsa"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hash": "18:e2:51:fe:21:6c:78:d0:b8:cf:32:d4:bd:56:42:e1",
|
||||||
|
"hash_alg": "MD5",
|
||||||
|
"hostkey": "ssh-rsa"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"kex": [
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group-exchange-sha256",
|
||||||
|
"keysize": 1024
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group-exchange-sha1",
|
||||||
|
"keysize": 1024
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group14-sha1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group1-sha1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"key": [
|
||||||
|
{
|
||||||
|
"algorithm": "ssh-rsa",
|
||||||
|
"keysize": 3072
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "ssh-rsa-cert-v01@openssh.com",
|
||||||
|
"ca_algorithm": "ssh-rsa",
|
||||||
|
"casize": 3072,
|
||||||
|
"keysize": 3072
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mac": [
|
||||||
|
"hmac-md5",
|
||||||
|
"hmac-sha1",
|
||||||
|
"umac-64@openssh.com",
|
||||||
|
"hmac-ripemd160",
|
||||||
|
"hmac-ripemd160@openssh.com",
|
||||||
|
"hmac-sha1-96",
|
||||||
|
"hmac-md5-96"
|
||||||
|
],
|
||||||
|
"recommendations": {
|
||||||
|
"critical": {
|
||||||
|
"chg": {
|
||||||
|
"kex": [
|
||||||
|
{
|
||||||
|
"name": "diffie-hellman-group-exchange-sha256",
|
||||||
|
"notes": "increase modulus size to 3072 bits or larger"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"del": {
|
||||||
|
"enc": [
|
||||||
|
{
|
||||||
|
"name": "3des-cbc",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "arcfour128",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "arcfour",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "arcfour256",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "blowfish-cbc",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cast128-cbc",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rijndael-cbc@lysator.liu.se",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"kex": [
|
||||||
|
{
|
||||||
|
"name": "diffie-hellman-group14-sha1",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "diffie-hellman-group1-sha1",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "diffie-hellman-group-exchange-sha1",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"key": [
|
||||||
|
{
|
||||||
|
"name": "ssh-rsa",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ssh-rsa-cert-v01@openssh.com",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mac": [
|
||||||
|
{
|
||||||
|
"name": "hmac-md5",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-md5-96",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-ripemd160",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-ripemd160@openssh.com",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-sha1",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-sha1-96",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"warning": {
|
||||||
|
"del": {
|
||||||
|
"enc": [
|
||||||
|
{
|
||||||
|
"name": "aes128-cbc",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "aes192-cbc",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "aes256-cbc",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mac": [
|
||||||
|
{
|
||||||
|
"name": "umac-64@openssh.com",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"target": "localhost:2222"
|
||||||
|
}
|
||||||
|
@ -5,7 +5,10 @@
|
|||||||
[0;32m(gen) compression: enabled (zlib@openssh.com)[0m
|
[0;32m(gen) compression: enabled (zlib@openssh.com)[0m
|
||||||
|
|
||||||
[0;36m# security[0m
|
[0;36m# security[0m
|
||||||
[0;33m(cve) CVE-2018-15473 -- (CVSSv2: 5.3) enumerate usernames due to timing discrepencies[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-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-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-6564 -- (CVSSv2: 6.9) privilege escalation via leveraging sshd uid[0m
|
||||||
@ -22,111 +25,86 @@
|
|||||||
[0;31m(kex) diffie-hellman-group-exchange-sha256 (1024-bit) -- [fail] using small 1024-bit modulus[0m
|
[0;31m(kex) diffie-hellman-group-exchange-sha256 (1024-bit) -- [fail] using small 1024-bit modulus[0m
|
||||||
`- [info] available since OpenSSH 4.4
|
`- [info] available since OpenSSH 4.4
|
||||||
[0;31m(kex) diffie-hellman-group-exchange-sha1 (1024-bit) -- [fail] using small 1024-bit modulus[0m
|
[0;31m(kex) diffie-hellman-group-exchange-sha1 (1024-bit) -- [fail] using small 1024-bit modulus[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
|
||||||
`- [info] available since OpenSSH 2.3.0
|
`- [info] available since OpenSSH 2.3.0
|
||||||
[0;33m(kex) diffie-hellman-group14-sha1 -- [warn] using weak hashing algorithm[0m
|
[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
|
||||||
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
|
`- [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(kex) diffie-hellman-group1-sha1 -- [fail] using small 1024-bit modulus[0m
|
||||||
[0;31m `- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m `- [fail] vulnerable to the Logjam attack: https://en.wikipedia.org/wiki/Logjam_(computer_security)[0m
|
||||||
[0;31m `- [fail] disabled (in client) since OpenSSH 7.0, logjam attack[0m
|
[0;31m `- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
|
||||||
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
|
`- [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
|
||||||
|
|
||||||
[0;36m# host-key algorithms[0m
|
[0;36m# host-key algorithms[0m
|
||||||
[0;31m(key) ssh-rsa (3072-bit) -- [fail] using weak hashing algorithm[0m
|
[0;31m(key) ssh-rsa (3072-bit) -- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
|
||||||
`- [info] a future deprecation notice has been issued in OpenSSH 8.2: https://www.openssh.com/txt/release-8.2
|
`- [info] deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8
|
||||||
[0;31m(key) ssh-rsa-cert-v01@openssh.com (3072-bit cert/3072-bit CA) -- [fail] using weak hashing algorithm[0m
|
[0;31m(key) ssh-rsa-cert-v01@openssh.com (3072-bit cert/3072-bit RSA CA) -- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
`- [info] available since OpenSSH 5.6
|
`- [info] available since OpenSSH 5.6
|
||||||
`- [info] a future deprecation notice has been issued in OpenSSH 8.2: https://www.openssh.com/txt/release-8.2
|
`- [info] deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8
|
||||||
|
|
||||||
[0;36m# encryption algorithms (ciphers)[0m
|
[0;36m# encryption algorithms (ciphers)[0m
|
||||||
[0;32m(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
[0;32m(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
||||||
[0;32m(enc) aes192-ctr -- [info] available since OpenSSH 3.7[0m
|
[0;32m(enc) aes192-ctr -- [info] available since OpenSSH 3.7[0m
|
||||||
[0;32m(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
[0;32m(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
||||||
[0;31m(enc) arcfour256 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) arcfour256 -- [fail] using broken RC4 cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher[0m
|
|
||||||
`- [info] available since OpenSSH 4.2
|
`- [info] available since OpenSSH 4.2
|
||||||
[0;31m(enc) arcfour128 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) arcfour128 -- [fail] using broken RC4 cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher[0m
|
|
||||||
`- [info] available since OpenSSH 4.2
|
`- [info] available since OpenSSH 4.2
|
||||||
[0;31m(enc) aes128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;33m(enc) aes128-cbc -- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
|
||||||
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
|
||||||
[0;31m(enc) 3des-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) 3des-cbc -- [fail] using broken & deprecated 3DES cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.4, unsafe algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher[0m
|
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
[0;33m `- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using small 64-bit block size[0m
|
[0;33m `- [warn] using small 64-bit block size[0m
|
||||||
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
|
||||||
[0;31m(enc) blowfish-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) blowfish-cbc -- [fail] using weak & deprecated Blowfish cipher[0m
|
||||||
[0;31m `- [fail] disabled since Dropbear SSH 0.53[0m
|
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
[0;33m `- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using small 64-bit block size[0m
|
[0;33m `- [warn] using small 64-bit block size[0m
|
||||||
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
|
||||||
[0;31m(enc) cast128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) cast128-cbc -- [fail] using weak & deprecated CAST cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
[0;33m `- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using small 64-bit block size[0m
|
[0;33m `- [warn] using small 64-bit block size[0m
|
||||||
`- [info] available since OpenSSH 2.1.0
|
`- [info] available since OpenSSH 2.1.0
|
||||||
[0;31m(enc) aes192-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;33m(enc) aes192-cbc -- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
|
||||||
`- [info] available since OpenSSH 2.3.0
|
`- [info] available since OpenSSH 2.3.0
|
||||||
[0;31m(enc) aes256-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;33m(enc) aes256-cbc -- [warn] using weak cipher mode[0m
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
|
||||||
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47
|
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47
|
||||||
[0;31m(enc) arcfour -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) arcfour -- [fail] using broken RC4 cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher[0m
|
|
||||||
`- [info] available since OpenSSH 2.1.0
|
`- [info] available since OpenSSH 2.1.0
|
||||||
[0;31m(enc) rijndael-cbc@lysator.liu.se -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(enc) rijndael-cbc@lysator.liu.se -- [fail] using deprecated & non-standardized Rijndael cipher[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using weak cipher mode[0m
|
[0;33m `- [warn] using weak cipher mode[0m
|
||||||
`- [info] available since OpenSSH 2.3.0
|
`- [info] available since OpenSSH 2.3.0
|
||||||
|
`- [info] disabled in OpenSSH 7.0: https://www.openssh.com/txt/release-7.0
|
||||||
|
|
||||||
[0;36m# message authentication code algorithms[0m
|
[0;36m# message authentication code algorithms[0m
|
||||||
[0;31m(mac) hmac-md5 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(mac) hmac-md5 -- [fail] using broken MD5 hash algorithm[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
|
||||||
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
||||||
[0;33m(mac) hmac-sha1 -- [warn] using encrypt-and-MAC mode[0m
|
[0;31m(mac) hmac-sha1 -- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
||||||
[0;33m(mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode[0m
|
[0;33m(mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode[0m
|
||||||
[0;33m `- [warn] using small 64-bit tag size[0m
|
[0;33m `- [warn] using small 64-bit tag size[0m
|
||||||
`- [info] available since OpenSSH 4.7
|
`- [info] available since OpenSSH 4.7
|
||||||
[0;31m(mac) hmac-ripemd160 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(mac) hmac-ripemd160 -- [fail] using deprecated RIPEMD hash algorithm[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
`- [info] available since OpenSSH 2.5.0
|
`- [info] available since OpenSSH 2.5.0
|
||||||
[0;31m(mac) hmac-ripemd160@openssh.com -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(mac) hmac-ripemd160@openssh.com -- [fail] using deprecated RIPEMD hash algorithm[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
`- [info] available since OpenSSH 2.1.0
|
`- [info] available since OpenSSH 2.1.0
|
||||||
[0;31m(mac) hmac-sha1-96 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(mac) hmac-sha1-96 -- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
|
||||||
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.47
|
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.47
|
||||||
[0;31m(mac) hmac-md5-96 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm[0m
|
[0;31m(mac) hmac-md5-96 -- [fail] using broken MD5 hash algorithm[0m
|
||||||
[0;33m `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm[0m
|
|
||||||
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
|
||||||
`- [info] available since OpenSSH 2.5.0
|
`- [info] available since OpenSSH 2.5.0
|
||||||
|
|
||||||
[0;36m# fingerprints[0m
|
[0;36m# fingerprints[0m
|
||||||
[0;32m(fin) ssh-rsa: SHA256:nsWtdJ9Z67Vrf7OsUzQov7esXhsWAfVppArGh25u244[0m
|
[0;32m(fin) ssh-rsa: SHA256:nsWtdJ9Z67Vrf7OsUzQov7esXhsWAfVppArGh25u244[0m
|
||||||
|
|
||||||
[0;36m# algorithm recommendations (for OpenSSH 5.6)[0m
|
[0;36m# algorithm recommendations (for OpenSSH 5.6)[0m
|
||||||
[0;31m(rec) !diffie-hellman-group-exchange-sha256 -- kex algorithm to change (increase modulus size to 2048 bits or larger) [0m
|
[0;31m(rec) !diffie-hellman-group-exchange-sha256 -- kex algorithm to change (increase modulus size to 3072 bits or larger) [0m
|
||||||
[0;31m(rec) -3des-cbc -- enc algorithm to remove [0m
|
[0;31m(rec) -3des-cbc -- enc algorithm to remove [0m
|
||||||
[0;31m(rec) -aes128-cbc -- enc algorithm to remove [0m
|
|
||||||
[0;31m(rec) -aes192-cbc -- enc algorithm to remove [0m
|
|
||||||
[0;31m(rec) -aes256-cbc -- enc algorithm to remove [0m
|
|
||||||
[0;31m(rec) -arcfour -- enc algorithm to remove [0m
|
[0;31m(rec) -arcfour -- enc algorithm to remove [0m
|
||||||
[0;31m(rec) -arcfour128 -- enc algorithm to remove [0m
|
[0;31m(rec) -arcfour128 -- enc algorithm to remove [0m
|
||||||
[0;31m(rec) -arcfour256 -- enc algorithm to remove [0m
|
[0;31m(rec) -arcfour256 -- enc algorithm to remove [0m
|
||||||
@ -134,16 +112,19 @@
|
|||||||
[0;31m(rec) -cast128-cbc -- enc algorithm to remove [0m
|
[0;31m(rec) -cast128-cbc -- enc algorithm to remove [0m
|
||||||
[0;31m(rec) -diffie-hellman-group-exchange-sha1 -- kex algorithm to remove [0m
|
[0;31m(rec) -diffie-hellman-group-exchange-sha1 -- kex algorithm to remove [0m
|
||||||
[0;31m(rec) -diffie-hellman-group1-sha1 -- kex algorithm to remove [0m
|
[0;31m(rec) -diffie-hellman-group1-sha1 -- kex algorithm to remove [0m
|
||||||
|
[0;31m(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove [0m
|
||||||
[0;31m(rec) -hmac-md5 -- mac algorithm to remove [0m
|
[0;31m(rec) -hmac-md5 -- mac algorithm to remove [0m
|
||||||
[0;31m(rec) -hmac-md5-96 -- mac algorithm to remove [0m
|
[0;31m(rec) -hmac-md5-96 -- mac algorithm to remove [0m
|
||||||
[0;31m(rec) -hmac-ripemd160 -- mac algorithm to remove [0m
|
[0;31m(rec) -hmac-ripemd160 -- mac algorithm to remove [0m
|
||||||
[0;31m(rec) -hmac-ripemd160@openssh.com -- mac algorithm to remove [0m
|
[0;31m(rec) -hmac-ripemd160@openssh.com -- mac algorithm to remove [0m
|
||||||
|
[0;31m(rec) -hmac-sha1 -- mac algorithm to remove [0m
|
||||||
[0;31m(rec) -hmac-sha1-96 -- mac algorithm to remove [0m
|
[0;31m(rec) -hmac-sha1-96 -- mac algorithm to remove [0m
|
||||||
[0;31m(rec) -rijndael-cbc@lysator.liu.se -- enc algorithm to remove [0m
|
[0;31m(rec) -rijndael-cbc@lysator.liu.se -- enc algorithm to remove [0m
|
||||||
[0;31m(rec) -ssh-rsa -- key algorithm to remove [0m
|
[0;31m(rec) -ssh-rsa -- key algorithm to remove [0m
|
||||||
[0;31m(rec) -ssh-rsa-cert-v01@openssh.com -- key algorithm to remove [0m
|
[0;31m(rec) -ssh-rsa-cert-v01@openssh.com -- key algorithm to remove [0m
|
||||||
[0;33m(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove [0m
|
[0;33m(rec) -aes128-cbc -- enc algorithm to remove [0m
|
||||||
[0;33m(rec) -hmac-sha1 -- mac algorithm to remove [0m
|
[0;33m(rec) -aes192-cbc -- enc algorithm to remove [0m
|
||||||
|
[0;33m(rec) -aes256-cbc -- enc algorithm to remove [0m
|
||||||
[0;33m(rec) -umac-64@openssh.com -- mac algorithm to remove [0m
|
[0;33m(rec) -umac-64@openssh.com -- mac algorithm to remove [0m
|
||||||
|
|
||||||
[0;36m# additional info[0m
|
[0;36m# additional info[0m
|
||||||
|
@ -1 +1,31 @@
|
|||||||
{"errors": [], "host": "localhost", "passed": true, "policy": "Hardened OpenSSH Server v8.0 (version 1)"}
|
{
|
||||||
|
"errors": [
|
||||||
|
{
|
||||||
|
"actual": [
|
||||||
|
"3072"
|
||||||
|
],
|
||||||
|
"expected_optional": [
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"expected_required": [
|
||||||
|
"4096"
|
||||||
|
],
|
||||||
|
"mismatched_field": "Host key (rsa-sha2-256) sizes"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actual": [
|
||||||
|
"3072"
|
||||||
|
],
|
||||||
|
"expected_optional": [
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"expected_required": [
|
||||||
|
"4096"
|
||||||
|
],
|
||||||
|
"mismatched_field": "Host key (rsa-sha2-512) sizes"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"host": "localhost",
|
||||||
|
"passed": false,
|
||||||
|
"policy": "Hardened OpenSSH Server v8.0 (version 2)"
|
||||||
|
}
|
||||||
|
@ -1,3 +1,13 @@
|
|||||||
Host: localhost:2222
|
Host: localhost:2222
|
||||||
Policy: Hardened OpenSSH Server v8.0 (version 1)
|
Policy: Hardened OpenSSH Server v8.0 (version 2)
|
||||||
Result: [0;32m✔ Passed[0m
|
Result: [0;31m❌ Failed![0m
|
||||||
|
[0;33m
|
||||||
|
Errors:
|
||||||
|
* Host key (rsa-sha2-256) sizes did not match.
|
||||||
|
- Expected: 4096
|
||||||
|
- Actual: 3072
|
||||||
|
|
||||||
|
* Host key (rsa-sha2-512) sizes did not match.
|
||||||
|
- Expected: 4096
|
||||||
|
- Actual: 3072
|
||||||
|
[0m
|
||||||
|
@ -1 +1,54 @@
|
|||||||
{"errors": [{"actual": ["umac-64-etm@openssh.com", "umac-128-etm@openssh.com", "hmac-sha2-256-etm@openssh.com", "hmac-sha2-512-etm@openssh.com", "hmac-sha1-etm@openssh.com", "umac-64@openssh.com", "umac-128@openssh.com", "hmac-sha2-256", "hmac-sha2-512", "hmac-sha1"], "expected_optional": [""], "expected_required": ["hmac-sha2-256-etm@openssh.com", "hmac-sha2-512-etm@openssh.com", "umac-128-etm@openssh.com"], "mismatched_field": "MACs"}], "host": "localhost", "passed": false, "policy": "Hardened OpenSSH Server v8.0 (version 1)"}
|
{
|
||||||
|
"errors": [
|
||||||
|
{
|
||||||
|
"actual": [
|
||||||
|
"3072"
|
||||||
|
],
|
||||||
|
"expected_optional": [
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"expected_required": [
|
||||||
|
"4096"
|
||||||
|
],
|
||||||
|
"mismatched_field": "Host key (rsa-sha2-256) sizes"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actual": [
|
||||||
|
"3072"
|
||||||
|
],
|
||||||
|
"expected_optional": [
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"expected_required": [
|
||||||
|
"4096"
|
||||||
|
],
|
||||||
|
"mismatched_field": "Host key (rsa-sha2-512) sizes"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actual": [
|
||||||
|
"umac-64-etm@openssh.com",
|
||||||
|
"umac-128-etm@openssh.com",
|
||||||
|
"hmac-sha2-256-etm@openssh.com",
|
||||||
|
"hmac-sha2-512-etm@openssh.com",
|
||||||
|
"hmac-sha1-etm@openssh.com",
|
||||||
|
"umac-64@openssh.com",
|
||||||
|
"umac-128@openssh.com",
|
||||||
|
"hmac-sha2-256",
|
||||||
|
"hmac-sha2-512",
|
||||||
|
"hmac-sha1"
|
||||||
|
],
|
||||||
|
"expected_optional": [
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"expected_required": [
|
||||||
|
"hmac-sha2-256-etm@openssh.com",
|
||||||
|
"hmac-sha2-512-etm@openssh.com",
|
||||||
|
"umac-128-etm@openssh.com"
|
||||||
|
],
|
||||||
|
"mismatched_field": "MACs"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"host": "localhost",
|
||||||
|
"passed": false,
|
||||||
|
"policy": "Hardened OpenSSH Server v8.0 (version 2)"
|
||||||
|
}
|
||||||
|
@ -1,8 +1,16 @@
|
|||||||
Host: localhost:2222
|
Host: localhost:2222
|
||||||
Policy: Hardened OpenSSH Server v8.0 (version 1)
|
Policy: Hardened OpenSSH Server v8.0 (version 2)
|
||||||
Result: [0;31m❌ Failed![0m
|
Result: [0;31m❌ Failed![0m
|
||||||
[0;33m
|
[0;33m
|
||||||
Errors:
|
Errors:
|
||||||
|
* Host key (rsa-sha2-256) sizes did not match.
|
||||||
|
- Expected: 4096
|
||||||
|
- Actual: 3072
|
||||||
|
|
||||||
|
* Host key (rsa-sha2-512) sizes did not match.
|
||||||
|
- Expected: 4096
|
||||||
|
- Actual: 3072
|
||||||
|
|
||||||
* MACs did not match.
|
* MACs did not match.
|
||||||
- Expected: hmac-sha2-256-etm@openssh.com, hmac-sha2-512-etm@openssh.com, umac-128-etm@openssh.com
|
- Expected: hmac-sha2-256-etm@openssh.com, hmac-sha2-512-etm@openssh.com, umac-128-etm@openssh.com
|
||||||
- Actual: umac-64-etm@openssh.com, umac-128-etm@openssh.com, hmac-sha2-256-etm@openssh.com, hmac-sha2-512-etm@openssh.com, hmac-sha1-etm@openssh.com, umac-64@openssh.com, umac-128@openssh.com, hmac-sha2-256, hmac-sha2-512, hmac-sha1
|
- Actual: umac-64-etm@openssh.com, umac-128-etm@openssh.com, hmac-sha2-256-etm@openssh.com, hmac-sha2-512-etm@openssh.com, hmac-sha1-etm@openssh.com, umac-64@openssh.com, umac-128@openssh.com, hmac-sha2-256, hmac-sha2-512, hmac-sha1
|
||||||
|
@ -1 +1,6 @@
|
|||||||
{"errors": [], "host": "localhost", "passed": true, "policy": "Docker policy: test11 (version 1)"}
|
{
|
||||||
|
"errors": [],
|
||||||
|
"host": "localhost",
|
||||||
|
"passed": true,
|
||||||
|
"policy": "Docker policy: test11 (version 1)"
|
||||||
|
}
|
||||||
|
@ -1,3 +1,12 @@
|
|||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
Host: localhost:2222
|
Host: localhost:2222
|
||||||
Policy: Docker policy: test11 (version 1)
|
Policy: Docker policy: test11 (version 1)
|
||||||
Result: [0;32m✔ Passed[0m
|
Result: [0;32m✔ Passed[0m
|
||||||
|
@ -1 +1,43 @@
|
|||||||
{"errors": [{"actual": ["3072"], "expected_optional": [""], "expected_required": ["4096"], "mismatched_field": "RSA host key (rsa-sha2-256) sizes"}, {"actual": ["3072"], "expected_optional": [""], "expected_required": ["4096"], "mismatched_field": "RSA host key (rsa-sha2-512) sizes"}, {"actual": ["3072"], "expected_optional": [""], "expected_required": ["4096"], "mismatched_field": "RSA host key (ssh-rsa) sizes"}], "host": "localhost", "passed": false, "policy": "Docker policy: test12 (version 1)"}
|
{
|
||||||
|
"errors": [
|
||||||
|
{
|
||||||
|
"actual": [
|
||||||
|
"3072"
|
||||||
|
],
|
||||||
|
"expected_optional": [
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"expected_required": [
|
||||||
|
"4096"
|
||||||
|
],
|
||||||
|
"mismatched_field": "Host key (rsa-sha2-256) sizes"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actual": [
|
||||||
|
"3072"
|
||||||
|
],
|
||||||
|
"expected_optional": [
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"expected_required": [
|
||||||
|
"4096"
|
||||||
|
],
|
||||||
|
"mismatched_field": "Host key (rsa-sha2-512) sizes"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actual": [
|
||||||
|
"3072"
|
||||||
|
],
|
||||||
|
"expected_optional": [
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"expected_required": [
|
||||||
|
"4096"
|
||||||
|
],
|
||||||
|
"mismatched_field": "Host key (ssh-rsa) sizes"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"host": "localhost",
|
||||||
|
"passed": false,
|
||||||
|
"policy": "Docker policy: test12 (version 1)"
|
||||||
|
}
|
||||||
|
@ -1,17 +1,26 @@
|
|||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
Host: localhost:2222
|
Host: localhost:2222
|
||||||
Policy: Docker policy: test12 (version 1)
|
Policy: Docker policy: test12 (version 1)
|
||||||
Result: [0;31m❌ Failed![0m
|
Result: [0;31m❌ Failed![0m
|
||||||
[0;33m
|
[0;33m
|
||||||
Errors:
|
Errors:
|
||||||
* RSA host key (rsa-sha2-256) sizes did not match.
|
* Host key (rsa-sha2-256) sizes did not match.
|
||||||
- Expected: 4096
|
- Expected: 4096
|
||||||
- Actual: 3072
|
- Actual: 3072
|
||||||
|
|
||||||
* RSA host key (rsa-sha2-512) sizes did not match.
|
* Host key (rsa-sha2-512) sizes did not match.
|
||||||
- Expected: 4096
|
- Expected: 4096
|
||||||
- Actual: 3072
|
- Actual: 3072
|
||||||
|
|
||||||
* RSA host key (ssh-rsa) sizes did not match.
|
* Host key (ssh-rsa) sizes did not match.
|
||||||
- Expected: 4096
|
- Expected: 4096
|
||||||
- Actual: 3072
|
- Actual: 3072
|
||||||
[0m
|
[0m
|
||||||
|
@ -1 +1,6 @@
|
|||||||
{"errors": [], "host": "localhost", "passed": true, "policy": "Docker policy: test13 (version 1)"}
|
{
|
||||||
|
"errors": [],
|
||||||
|
"host": "localhost",
|
||||||
|
"passed": true,
|
||||||
|
"policy": "Docker policy: test13 (version 1)"
|
||||||
|
}
|
||||||
|
@ -1,3 +1,15 @@
|
|||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
Host: localhost:2222
|
Host: localhost:2222
|
||||||
Policy: Docker policy: test13 (version 1)
|
Policy: Docker policy: test13 (version 1)
|
||||||
Result: [0;32m✔ Passed[0m
|
Result: [0;32m✔ Passed[0m
|
||||||
|
@ -1 +1,19 @@
|
|||||||
{"errors": [{"actual": ["2048"], "expected_optional": [""], "expected_required": ["4096"], "mismatched_field": "Group exchange (diffie-hellman-group-exchange-sha256) modulus sizes"}], "host": "localhost", "passed": false, "policy": "Docker policy: test14 (version 1)"}
|
{
|
||||||
|
"errors": [
|
||||||
|
{
|
||||||
|
"actual": [
|
||||||
|
"2048"
|
||||||
|
],
|
||||||
|
"expected_optional": [
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"expected_required": [
|
||||||
|
"4096"
|
||||||
|
],
|
||||||
|
"mismatched_field": "Group exchange (diffie-hellman-group-exchange-sha256) modulus sizes"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"host": "localhost",
|
||||||
|
"passed": false,
|
||||||
|
"policy": "Docker policy: test14 (version 1)"
|
||||||
|
}
|
||||||
|
@ -1,3 +1,15 @@
|
|||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
|
|
||||||
|
WARNING: this policy is using deprecated features. Future versions of ssh-audit may remove support for them. Re-generating the policy file is perhaps the most straight-forward way of resolving this issue. Manually converting the 'hostkey_size_*', 'cakey_size_*', and 'dh_modulus_size_*' directives into the new format is another option.
|
||||||
|
|
||||||
Host: localhost:2222
|
Host: localhost:2222
|
||||||
Policy: Docker policy: test14 (version 1)
|
Policy: Docker policy: test14 (version 1)
|
||||||
Result: [0;31m❌ Failed![0m
|
Result: [0;31m❌ Failed![0m
|
||||||
|
@ -1 +1,6 @@
|
|||||||
{"errors": [], "host": "localhost", "passed": true, "policy": "Docker policy: test6 (version 1)"}
|
{
|
||||||
|
"errors": [],
|
||||||
|
"host": "localhost",
|
||||||
|
"passed": true,
|
||||||
|
"policy": "Docker policy: test6 (version 1)"
|
||||||
|
}
|
||||||
|
@ -1 +1,209 @@
|
|||||||
{"banner": {"comments": null, "protocol": [2, 0], "raw": "SSH-2.0-OpenSSH_8.0", "software": "OpenSSH_8.0"}, "compression": ["none", "zlib@openssh.com"], "enc": ["chacha20-poly1305@openssh.com", "aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-gcm@openssh.com", "aes256-gcm@openssh.com"], "fingerprints": [{"hash": "UrnXIVH+7dlw8UqYocl48yUEcKrthGDQG2CPCgp7MxU", "hash_alg": "SHA256", "hostkey": "ssh-ed25519"}, {"hash": "1e:0c:7b:34:73:bf:52:41:b0:f9:d1:a9:ab:98:c7:c9", "hash_alg": "MD5", "hostkey": "ssh-ed25519"}, {"hash": "nsWtdJ9Z67Vrf7OsUzQov7esXhsWAfVppArGh25u244", "hash_alg": "SHA256", "hostkey": "ssh-rsa"}, {"hash": "18:e2:51:fe:21:6c:78:d0:b8:cf:32:d4:bd:56:42:e1", "hash_alg": "MD5", "hostkey": "ssh-rsa"}], "kex": [{"algorithm": "curve25519-sha256"}, {"algorithm": "curve25519-sha256@libssh.org"}, {"algorithm": "ecdh-sha2-nistp256"}, {"algorithm": "ecdh-sha2-nistp384"}, {"algorithm": "ecdh-sha2-nistp521"}, {"algorithm": "diffie-hellman-group-exchange-sha256", "keysize": 2048}, {"algorithm": "diffie-hellman-group16-sha512"}, {"algorithm": "diffie-hellman-group18-sha512"}, {"algorithm": "diffie-hellman-group14-sha256"}, {"algorithm": "diffie-hellman-group14-sha1"}], "key": [{"algorithm": "rsa-sha2-512", "keysize": 3072}, {"algorithm": "rsa-sha2-256", "keysize": 3072}, {"algorithm": "ssh-rsa", "keysize": 3072}, {"algorithm": "ecdsa-sha2-nistp256"}, {"algorithm": "ssh-ed25519"}], "mac": ["umac-64-etm@openssh.com", "umac-128-etm@openssh.com", "hmac-sha2-256-etm@openssh.com", "hmac-sha2-512-etm@openssh.com", "hmac-sha1-etm@openssh.com", "umac-64@openssh.com", "umac-128@openssh.com", "hmac-sha2-256", "hmac-sha2-512", "hmac-sha1"], "target": "localhost"}
|
{
|
||||||
|
"banner": {
|
||||||
|
"comments": null,
|
||||||
|
"protocol": [
|
||||||
|
2,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"raw": "SSH-2.0-OpenSSH_8.0",
|
||||||
|
"software": "OpenSSH_8.0"
|
||||||
|
},
|
||||||
|
"compression": [
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"enc": [
|
||||||
|
"chacha20-poly1305@openssh.com",
|
||||||
|
"aes128-ctr",
|
||||||
|
"aes192-ctr",
|
||||||
|
"aes256-ctr",
|
||||||
|
"aes128-gcm@openssh.com",
|
||||||
|
"aes256-gcm@openssh.com"
|
||||||
|
],
|
||||||
|
"fingerprints": [
|
||||||
|
{
|
||||||
|
"hash": "UrnXIVH+7dlw8UqYocl48yUEcKrthGDQG2CPCgp7MxU",
|
||||||
|
"hash_alg": "SHA256",
|
||||||
|
"hostkey": "ssh-ed25519"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hash": "1e:0c:7b:34:73:bf:52:41:b0:f9:d1:a9:ab:98:c7:c9",
|
||||||
|
"hash_alg": "MD5",
|
||||||
|
"hostkey": "ssh-ed25519"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hash": "nsWtdJ9Z67Vrf7OsUzQov7esXhsWAfVppArGh25u244",
|
||||||
|
"hash_alg": "SHA256",
|
||||||
|
"hostkey": "ssh-rsa"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hash": "18:e2:51:fe:21:6c:78:d0:b8:cf:32:d4:bd:56:42:e1",
|
||||||
|
"hash_alg": "MD5",
|
||||||
|
"hostkey": "ssh-rsa"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"kex": [
|
||||||
|
{
|
||||||
|
"algorithm": "curve25519-sha256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "curve25519-sha256@libssh.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "ecdh-sha2-nistp256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "ecdh-sha2-nistp384"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "ecdh-sha2-nistp521"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group-exchange-sha256",
|
||||||
|
"keysize": 2048
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group16-sha512"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group18-sha512"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group14-sha256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group14-sha1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"key": [
|
||||||
|
{
|
||||||
|
"algorithm": "rsa-sha2-512",
|
||||||
|
"keysize": 3072
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "rsa-sha2-256",
|
||||||
|
"keysize": 3072
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "ssh-rsa",
|
||||||
|
"keysize": 3072
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "ecdsa-sha2-nistp256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "ssh-ed25519"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mac": [
|
||||||
|
"umac-64-etm@openssh.com",
|
||||||
|
"umac-128-etm@openssh.com",
|
||||||
|
"hmac-sha2-256-etm@openssh.com",
|
||||||
|
"hmac-sha2-512-etm@openssh.com",
|
||||||
|
"hmac-sha1-etm@openssh.com",
|
||||||
|
"umac-64@openssh.com",
|
||||||
|
"umac-128@openssh.com",
|
||||||
|
"hmac-sha2-256",
|
||||||
|
"hmac-sha2-512",
|
||||||
|
"hmac-sha1"
|
||||||
|
],
|
||||||
|
"recommendations": {
|
||||||
|
"critical": {
|
||||||
|
"del": {
|
||||||
|
"kex": [
|
||||||
|
{
|
||||||
|
"name": "diffie-hellman-group14-sha1",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ecdh-sha2-nistp256",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ecdh-sha2-nistp384",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ecdh-sha2-nistp521",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"key": [
|
||||||
|
{
|
||||||
|
"name": "ecdsa-sha2-nistp256",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ssh-rsa",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mac": [
|
||||||
|
{
|
||||||
|
"name": "hmac-sha1",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-sha1-etm@openssh.com",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"warning": {
|
||||||
|
"del": {
|
||||||
|
"kex": [
|
||||||
|
{
|
||||||
|
"name": "diffie-hellman-group14-sha256",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mac": [
|
||||||
|
{
|
||||||
|
"name": "hmac-sha2-256",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-sha2-512",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "umac-128@openssh.com",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "umac-64-etm@openssh.com",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "umac-64@openssh.com",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"target": "localhost:2222"
|
||||||
|
}
|
||||||
|
@ -4,36 +4,48 @@
|
|||||||
[0;32m(gen) compatibility: OpenSSH 7.4+, Dropbear SSH 2018.76+[0m
|
[0;32m(gen) compatibility: OpenSSH 7.4+, Dropbear SSH 2018.76+[0m
|
||||||
[0;32m(gen) compression: enabled (zlib@openssh.com)[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;36m# key exchange algorithms[0m
|
||||||
[0;32m(kex) curve25519-sha256 -- [info] available since OpenSSH 7.4, Dropbear SSH 2018.76[0m
|
[0;32m(kex) curve25519-sha256 -- [info] available since OpenSSH 7.4, Dropbear SSH 2018.76[0m
|
||||||
[0;32m(kex) curve25519-sha256@libssh.org -- [info] available since OpenSSH 6.5, Dropbear SSH 2013.62[0m
|
`- [info] default key exchange since OpenSSH 6.4
|
||||||
[0;31m(kex) ecdh-sha2-nistp256 -- [fail] using weak elliptic curves[0m
|
[0;32m(kex) curve25519-sha256@libssh.org -- [info] available since OpenSSH 6.4, Dropbear SSH 2013.62[0m
|
||||||
|
`- [info] default key exchange since OpenSSH 6.4
|
||||||
|
[0;31m(kex) ecdh-sha2-nistp256 -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency[0m
|
||||||
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
|
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
|
||||||
[0;31m(kex) ecdh-sha2-nistp384 -- [fail] using weak elliptic curves[0m
|
[0;31m(kex) ecdh-sha2-nistp384 -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency[0m
|
||||||
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
|
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
|
||||||
[0;31m(kex) ecdh-sha2-nistp521 -- [fail] using weak elliptic curves[0m
|
[0;31m(kex) ecdh-sha2-nistp521 -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency[0m
|
||||||
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
|
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
|
||||||
[0;32m(kex) diffie-hellman-group-exchange-sha256 (2048-bit) -- [info] available since OpenSSH 4.4[0m
|
[0;33m(kex) diffie-hellman-group-exchange-sha256 (2048-bit) -- [warn] 2048-bit modulus only provides 112-bits of symmetric strength[0m
|
||||||
|
`- [info] available since OpenSSH 4.4
|
||||||
|
`- [info] A bug in OpenSSH causes it to fall back to a 2048-bit modulus regardless of server configuration (https://bugzilla.mindrot.org/show_bug.cgi?id=2793)
|
||||||
[0;32m(kex) diffie-hellman-group16-sha512 -- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73[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;32m(kex) diffie-hellman-group18-sha512 -- [info] available since OpenSSH 7.3[0m
|
||||||
[0;32m(kex) diffie-hellman-group14-sha256 -- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73[0m
|
[0;33m(kex) diffie-hellman-group14-sha256 -- [warn] 2048-bit modulus only provides 112-bits of symmetric strength[0m
|
||||||
[0;33m(kex) diffie-hellman-group14-sha1 -- [warn] using weak hashing algorithm[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
|
||||||
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
|
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
|
||||||
|
|
||||||
[0;36m# host-key algorithms[0m
|
[0;36m# host-key algorithms[0m
|
||||||
[0;32m(key) rsa-sha2-512 (3072-bit) -- [info] available since OpenSSH 7.2[0m
|
[0;32m(key) rsa-sha2-512 (3072-bit) -- [info] available since OpenSSH 7.2[0m
|
||||||
[0;32m(key) rsa-sha2-256 (3072-bit) -- [info] available since OpenSSH 7.2[0m
|
[0;32m(key) rsa-sha2-256 (3072-bit) -- [info] available since OpenSSH 7.2[0m
|
||||||
[0;31m(key) ssh-rsa (3072-bit) -- [fail] using weak hashing algorithm[0m
|
[0;31m(key) ssh-rsa (3072-bit) -- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
|
||||||
`- [info] a future deprecation notice has been issued in OpenSSH 8.2: https://www.openssh.com/txt/release-8.2
|
`- [info] deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8
|
||||||
[0;31m(key) ecdsa-sha2-nistp256 -- [fail] using weak elliptic curves[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
|
||||||
[0;33m `- [warn] using weak random number generator could reveal the key[0m
|
[0;33m `- [warn] using weak random number generator could reveal the key[0m
|
||||||
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
|
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
|
||||||
[0;32m(key) ssh-ed25519 -- [info] available since OpenSSH 6.5[0m
|
[0;32m(key) ssh-ed25519 -- [info] available since OpenSSH 6.5[0m
|
||||||
|
|
||||||
[0;36m# encryption algorithms (ciphers)[0m
|
[0;36m# encryption algorithms (ciphers)[0m
|
||||||
[0;32m(enc) chacha20-poly1305@openssh.com -- [info] available since OpenSSH 6.5[0m
|
[0;32m(enc) chacha20-poly1305@openssh.com -- [info] available since OpenSSH 6.5[0m
|
||||||
`- [info] default cipher since OpenSSH 6.9.
|
`- [info] default cipher since OpenSSH 6.9
|
||||||
[0;32m(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
[0;32m(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
||||||
[0;32m(enc) aes192-ctr -- [info] available since OpenSSH 3.7[0m
|
[0;32m(enc) aes192-ctr -- [info] available since OpenSSH 3.7[0m
|
||||||
[0;32m(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
[0;32m(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
||||||
@ -46,7 +58,7 @@
|
|||||||
[0;32m(mac) umac-128-etm@openssh.com -- [info] available since OpenSSH 6.2[0m
|
[0;32m(mac) umac-128-etm@openssh.com -- [info] available since OpenSSH 6.2[0m
|
||||||
[0;32m(mac) hmac-sha2-256-etm@openssh.com -- [info] available since OpenSSH 6.2[0m
|
[0;32m(mac) hmac-sha2-256-etm@openssh.com -- [info] available since OpenSSH 6.2[0m
|
||||||
[0;32m(mac) hmac-sha2-512-etm@openssh.com -- [info] available since OpenSSH 6.2[0m
|
[0;32m(mac) hmac-sha2-512-etm@openssh.com -- [info] available since OpenSSH 6.2[0m
|
||||||
[0;33m(mac) hmac-sha1-etm@openssh.com -- [warn] using weak hashing algorithm[0m
|
[0;31m(mac) hmac-sha1-etm@openssh.com -- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
`- [info] available since OpenSSH 6.2
|
`- [info] available since OpenSSH 6.2
|
||||||
[0;33m(mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode[0m
|
[0;33m(mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode[0m
|
||||||
[0;33m `- [warn] using small 64-bit tag size[0m
|
[0;33m `- [warn] using small 64-bit tag size[0m
|
||||||
@ -57,8 +69,8 @@
|
|||||||
`- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56
|
`- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56
|
||||||
[0;33m(mac) hmac-sha2-512 -- [warn] using encrypt-and-MAC mode[0m
|
[0;33m(mac) hmac-sha2-512 -- [warn] using encrypt-and-MAC mode[0m
|
||||||
`- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56
|
`- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56
|
||||||
[0;33m(mac) hmac-sha1 -- [warn] using encrypt-and-MAC mode[0m
|
[0;31m(mac) hmac-sha1 -- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
||||||
|
|
||||||
[0;36m# fingerprints[0m
|
[0;36m# fingerprints[0m
|
||||||
@ -66,14 +78,15 @@
|
|||||||
[0;32m(fin) ssh-rsa: SHA256:nsWtdJ9Z67Vrf7OsUzQov7esXhsWAfVppArGh25u244[0m
|
[0;32m(fin) ssh-rsa: SHA256:nsWtdJ9Z67Vrf7OsUzQov7esXhsWAfVppArGh25u244[0m
|
||||||
|
|
||||||
[0;36m# algorithm recommendations (for OpenSSH 8.0)[0m
|
[0;36m# algorithm recommendations (for OpenSSH 8.0)[0m
|
||||||
|
[0;31m(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove [0m
|
||||||
[0;31m(rec) -ecdh-sha2-nistp256 -- kex algorithm to remove [0m
|
[0;31m(rec) -ecdh-sha2-nistp256 -- kex algorithm to remove [0m
|
||||||
[0;31m(rec) -ecdh-sha2-nistp384 -- kex algorithm to remove [0m
|
[0;31m(rec) -ecdh-sha2-nistp384 -- kex algorithm to remove [0m
|
||||||
[0;31m(rec) -ecdh-sha2-nistp521 -- kex algorithm to remove [0m
|
[0;31m(rec) -ecdh-sha2-nistp521 -- kex algorithm to remove [0m
|
||||||
[0;31m(rec) -ecdsa-sha2-nistp256 -- key algorithm to remove [0m
|
[0;31m(rec) -ecdsa-sha2-nistp256 -- key algorithm to remove [0m
|
||||||
|
[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;31m(rec) -ssh-rsa -- key algorithm to remove [0m
|
||||||
[0;33m(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove [0m
|
[0;33m(rec) -diffie-hellman-group14-sha256 -- kex algorithm to remove [0m
|
||||||
[0;33m(rec) -hmac-sha1 -- mac algorithm to remove [0m
|
|
||||||
[0;33m(rec) -hmac-sha1-etm@openssh.com -- mac algorithm to remove [0m
|
|
||||||
[0;33m(rec) -hmac-sha2-256 -- mac 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) -hmac-sha2-512 -- mac algorithm to remove [0m
|
||||||
[0;33m(rec) -umac-128@openssh.com -- mac algorithm to remove [0m
|
[0;33m(rec) -umac-128@openssh.com -- mac algorithm to remove [0m
|
||||||
|
@ -1 +1,193 @@
|
|||||||
{"banner": {"comments": null, "protocol": [2, 0], "raw": "SSH-2.0-OpenSSH_8.0", "software": "OpenSSH_8.0"}, "compression": ["none", "zlib@openssh.com"], "enc": ["chacha20-poly1305@openssh.com", "aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-gcm@openssh.com", "aes256-gcm@openssh.com"], "fingerprints": [{"hash": "UrnXIVH+7dlw8UqYocl48yUEcKrthGDQG2CPCgp7MxU", "hash_alg": "SHA256", "hostkey": "ssh-ed25519"}, {"hash": "1e:0c:7b:34:73:bf:52:41:b0:f9:d1:a9:ab:98:c7:c9", "hash_alg": "MD5", "hostkey": "ssh-ed25519"}], "kex": [{"algorithm": "curve25519-sha256"}, {"algorithm": "curve25519-sha256@libssh.org"}, {"algorithm": "ecdh-sha2-nistp256"}, {"algorithm": "ecdh-sha2-nistp384"}, {"algorithm": "ecdh-sha2-nistp521"}, {"algorithm": "diffie-hellman-group-exchange-sha256", "keysize": 2048}, {"algorithm": "diffie-hellman-group16-sha512"}, {"algorithm": "diffie-hellman-group18-sha512"}, {"algorithm": "diffie-hellman-group14-sha256"}, {"algorithm": "diffie-hellman-group14-sha1"}], "key": [{"algorithm": "ssh-ed25519"}, {"algorithm": "ssh-ed25519-cert-v01@openssh.com"}], "mac": ["umac-64-etm@openssh.com", "umac-128-etm@openssh.com", "hmac-sha2-256-etm@openssh.com", "hmac-sha2-512-etm@openssh.com", "hmac-sha1-etm@openssh.com", "umac-64@openssh.com", "umac-128@openssh.com", "hmac-sha2-256", "hmac-sha2-512", "hmac-sha1"], "target": "localhost"}
|
{
|
||||||
|
"banner": {
|
||||||
|
"comments": null,
|
||||||
|
"protocol": [
|
||||||
|
2,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"raw": "SSH-2.0-OpenSSH_8.0",
|
||||||
|
"software": "OpenSSH_8.0"
|
||||||
|
},
|
||||||
|
"compression": [
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"enc": [
|
||||||
|
"chacha20-poly1305@openssh.com",
|
||||||
|
"aes128-ctr",
|
||||||
|
"aes192-ctr",
|
||||||
|
"aes256-ctr",
|
||||||
|
"aes128-gcm@openssh.com",
|
||||||
|
"aes256-gcm@openssh.com"
|
||||||
|
],
|
||||||
|
"fingerprints": [
|
||||||
|
{
|
||||||
|
"hash": "UrnXIVH+7dlw8UqYocl48yUEcKrthGDQG2CPCgp7MxU",
|
||||||
|
"hash_alg": "SHA256",
|
||||||
|
"hostkey": "ssh-ed25519"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hash": "1e:0c:7b:34:73:bf:52:41:b0:f9:d1:a9:ab:98:c7:c9",
|
||||||
|
"hash_alg": "MD5",
|
||||||
|
"hostkey": "ssh-ed25519"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"kex": [
|
||||||
|
{
|
||||||
|
"algorithm": "curve25519-sha256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "curve25519-sha256@libssh.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "ecdh-sha2-nistp256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "ecdh-sha2-nistp384"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "ecdh-sha2-nistp521"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group-exchange-sha256",
|
||||||
|
"keysize": 2048
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group16-sha512"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group18-sha512"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group14-sha256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group14-sha1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"key": [
|
||||||
|
{
|
||||||
|
"algorithm": "ssh-ed25519"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "ssh-ed25519-cert-v01@openssh.com",
|
||||||
|
"ca_algorithm": "ssh-ed25519",
|
||||||
|
"casize": 256
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mac": [
|
||||||
|
"umac-64-etm@openssh.com",
|
||||||
|
"umac-128-etm@openssh.com",
|
||||||
|
"hmac-sha2-256-etm@openssh.com",
|
||||||
|
"hmac-sha2-512-etm@openssh.com",
|
||||||
|
"hmac-sha1-etm@openssh.com",
|
||||||
|
"umac-64@openssh.com",
|
||||||
|
"umac-128@openssh.com",
|
||||||
|
"hmac-sha2-256",
|
||||||
|
"hmac-sha2-512",
|
||||||
|
"hmac-sha1"
|
||||||
|
],
|
||||||
|
"recommendations": {
|
||||||
|
"critical": {
|
||||||
|
"del": {
|
||||||
|
"kex": [
|
||||||
|
{
|
||||||
|
"name": "diffie-hellman-group14-sha1",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ecdh-sha2-nistp256",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ecdh-sha2-nistp384",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ecdh-sha2-nistp521",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mac": [
|
||||||
|
{
|
||||||
|
"name": "hmac-sha1",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-sha1-etm@openssh.com",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"informational": {
|
||||||
|
"add": {
|
||||||
|
"key": [
|
||||||
|
{
|
||||||
|
"name": "rsa-sha2-256",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rsa-sha2-512",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"warning": {
|
||||||
|
"del": {
|
||||||
|
"kex": [
|
||||||
|
{
|
||||||
|
"name": "diffie-hellman-group14-sha256",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mac": [
|
||||||
|
{
|
||||||
|
"name": "hmac-sha2-256",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hmac-sha2-512",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "umac-128@openssh.com",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "umac-64-etm@openssh.com",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "umac-64@openssh.com",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"target": "localhost:2222"
|
||||||
|
}
|
||||||
|
@ -4,29 +4,41 @@
|
|||||||
[0;32m(gen) compatibility: OpenSSH 7.4+, Dropbear SSH 2018.76+[0m
|
[0;32m(gen) compatibility: OpenSSH 7.4+, Dropbear SSH 2018.76+[0m
|
||||||
[0;32m(gen) compression: enabled (zlib@openssh.com)[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;36m# key exchange algorithms[0m
|
||||||
[0;32m(kex) curve25519-sha256 -- [info] available since OpenSSH 7.4, Dropbear SSH 2018.76[0m
|
[0;32m(kex) curve25519-sha256 -- [info] available since OpenSSH 7.4, Dropbear SSH 2018.76[0m
|
||||||
[0;32m(kex) curve25519-sha256@libssh.org -- [info] available since OpenSSH 6.5, Dropbear SSH 2013.62[0m
|
`- [info] default key exchange since OpenSSH 6.4
|
||||||
[0;31m(kex) ecdh-sha2-nistp256 -- [fail] using weak elliptic curves[0m
|
[0;32m(kex) curve25519-sha256@libssh.org -- [info] available since OpenSSH 6.4, Dropbear SSH 2013.62[0m
|
||||||
|
`- [info] default key exchange since OpenSSH 6.4
|
||||||
|
[0;31m(kex) ecdh-sha2-nistp256 -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency[0m
|
||||||
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
|
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
|
||||||
[0;31m(kex) ecdh-sha2-nistp384 -- [fail] using weak elliptic curves[0m
|
[0;31m(kex) ecdh-sha2-nistp384 -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency[0m
|
||||||
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
|
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
|
||||||
[0;31m(kex) ecdh-sha2-nistp521 -- [fail] using weak elliptic curves[0m
|
[0;31m(kex) ecdh-sha2-nistp521 -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency[0m
|
||||||
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
|
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
|
||||||
[0;32m(kex) diffie-hellman-group-exchange-sha256 (2048-bit) -- [info] available since OpenSSH 4.4[0m
|
[0;33m(kex) diffie-hellman-group-exchange-sha256 (2048-bit) -- [warn] 2048-bit modulus only provides 112-bits of symmetric strength[0m
|
||||||
|
`- [info] available since OpenSSH 4.4
|
||||||
|
`- [info] A bug in OpenSSH causes it to fall back to a 2048-bit modulus regardless of server configuration (https://bugzilla.mindrot.org/show_bug.cgi?id=2793)
|
||||||
[0;32m(kex) diffie-hellman-group16-sha512 -- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73[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;32m(kex) diffie-hellman-group18-sha512 -- [info] available since OpenSSH 7.3[0m
|
||||||
[0;32m(kex) diffie-hellman-group14-sha256 -- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73[0m
|
[0;33m(kex) diffie-hellman-group14-sha256 -- [warn] 2048-bit modulus only provides 112-bits of symmetric strength[0m
|
||||||
[0;33m(kex) diffie-hellman-group14-sha1 -- [warn] using weak hashing algorithm[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
|
||||||
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
|
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
|
||||||
|
|
||||||
[0;36m# host-key algorithms[0m
|
[0;36m# host-key algorithms[0m
|
||||||
[0;32m(key) ssh-ed25519 -- [info] available since OpenSSH 6.5[0m
|
[0;32m(key) ssh-ed25519 -- [info] available since OpenSSH 6.5[0m
|
||||||
[0;32m(key) ssh-ed25519-cert-v01@openssh.com -- [info] available since OpenSSH 6.5[0m
|
[0;32m(key) ssh-ed25519-cert-v01@openssh.com (256-bit cert/256-bit ssh-ed25519 CA) -- [info] available since OpenSSH 6.5[0m
|
||||||
|
|
||||||
[0;36m# encryption algorithms (ciphers)[0m
|
[0;36m# encryption algorithms (ciphers)[0m
|
||||||
[0;32m(enc) chacha20-poly1305@openssh.com -- [info] available since OpenSSH 6.5[0m
|
[0;32m(enc) chacha20-poly1305@openssh.com -- [info] available since OpenSSH 6.5[0m
|
||||||
`- [info] default cipher since OpenSSH 6.9.
|
`- [info] default cipher since OpenSSH 6.9
|
||||||
[0;32m(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
[0;32m(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
||||||
[0;32m(enc) aes192-ctr -- [info] available since OpenSSH 3.7[0m
|
[0;32m(enc) aes192-ctr -- [info] available since OpenSSH 3.7[0m
|
||||||
[0;32m(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
[0;32m(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
||||||
@ -39,7 +51,7 @@
|
|||||||
[0;32m(mac) umac-128-etm@openssh.com -- [info] available since OpenSSH 6.2[0m
|
[0;32m(mac) umac-128-etm@openssh.com -- [info] available since OpenSSH 6.2[0m
|
||||||
[0;32m(mac) hmac-sha2-256-etm@openssh.com -- [info] available since OpenSSH 6.2[0m
|
[0;32m(mac) hmac-sha2-256-etm@openssh.com -- [info] available since OpenSSH 6.2[0m
|
||||||
[0;32m(mac) hmac-sha2-512-etm@openssh.com -- [info] available since OpenSSH 6.2[0m
|
[0;32m(mac) hmac-sha2-512-etm@openssh.com -- [info] available since OpenSSH 6.2[0m
|
||||||
[0;33m(mac) hmac-sha1-etm@openssh.com -- [warn] using weak hashing algorithm[0m
|
[0;31m(mac) hmac-sha1-etm@openssh.com -- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
`- [info] available since OpenSSH 6.2
|
`- [info] available since OpenSSH 6.2
|
||||||
[0;33m(mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode[0m
|
[0;33m(mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode[0m
|
||||||
[0;33m `- [warn] using small 64-bit tag size[0m
|
[0;33m `- [warn] using small 64-bit tag size[0m
|
||||||
@ -50,22 +62,23 @@
|
|||||||
`- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56
|
`- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56
|
||||||
[0;33m(mac) hmac-sha2-512 -- [warn] using encrypt-and-MAC mode[0m
|
[0;33m(mac) hmac-sha2-512 -- [warn] using encrypt-and-MAC mode[0m
|
||||||
`- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56
|
`- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56
|
||||||
[0;33m(mac) hmac-sha1 -- [warn] using encrypt-and-MAC mode[0m
|
[0;31m(mac) hmac-sha1 -- [fail] using broken SHA-1 hash algorithm[0m
|
||||||
[0;33m `- [warn] using weak hashing algorithm[0m
|
[0;33m `- [warn] using encrypt-and-MAC mode[0m
|
||||||
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
|
||||||
|
|
||||||
[0;36m# fingerprints[0m
|
[0;36m# fingerprints[0m
|
||||||
[0;32m(fin) ssh-ed25519: SHA256:UrnXIVH+7dlw8UqYocl48yUEcKrthGDQG2CPCgp7MxU[0m
|
[0;32m(fin) ssh-ed25519: SHA256:UrnXIVH+7dlw8UqYocl48yUEcKrthGDQG2CPCgp7MxU[0m
|
||||||
|
|
||||||
[0;36m# algorithm recommendations (for OpenSSH 8.0)[0m
|
[0;36m# algorithm recommendations (for OpenSSH 8.0)[0m
|
||||||
|
[0;31m(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove [0m
|
||||||
[0;31m(rec) -ecdh-sha2-nistp256 -- kex algorithm to remove [0m
|
[0;31m(rec) -ecdh-sha2-nistp256 -- kex algorithm to remove [0m
|
||||||
[0;31m(rec) -ecdh-sha2-nistp384 -- kex algorithm to remove [0m
|
[0;31m(rec) -ecdh-sha2-nistp384 -- kex algorithm to remove [0m
|
||||||
[0;31m(rec) -ecdh-sha2-nistp521 -- kex algorithm to remove [0m
|
[0;31m(rec) -ecdh-sha2-nistp521 -- kex algorithm to remove [0m
|
||||||
|
[0;31m(rec) -hmac-sha1 -- mac algorithm to remove [0m
|
||||||
|
[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-256 -- key algorithm to append [0m
|
||||||
[0;32m(rec) +rsa-sha2-512 -- key algorithm to append [0m
|
[0;32m(rec) +rsa-sha2-512 -- key algorithm to append [0m
|
||||||
[0;33m(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove [0m
|
[0;33m(rec) -diffie-hellman-group14-sha256 -- kex algorithm to remove [0m
|
||||||
[0;33m(rec) -hmac-sha1 -- mac algorithm to remove [0m
|
|
||||||
[0;33m(rec) -hmac-sha1-etm@openssh.com -- mac algorithm to remove [0m
|
|
||||||
[0;33m(rec) -hmac-sha2-256 -- mac 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) -hmac-sha2-512 -- mac algorithm to remove [0m
|
||||||
[0;33m(rec) -umac-128@openssh.com -- mac algorithm to remove [0m
|
[0;33m(rec) -umac-128@openssh.com -- mac algorithm to remove [0m
|
||||||
|
@ -1 +1,106 @@
|
|||||||
{"banner": {"comments": null, "protocol": [2, 0], "raw": "SSH-2.0-OpenSSH_8.0", "software": "OpenSSH_8.0"}, "compression": ["none", "zlib@openssh.com"], "enc": ["chacha20-poly1305@openssh.com", "aes256-gcm@openssh.com", "aes128-gcm@openssh.com", "aes256-ctr", "aes192-ctr", "aes128-ctr"], "fingerprints": [{"hash": "UrnXIVH+7dlw8UqYocl48yUEcKrthGDQG2CPCgp7MxU", "hash_alg": "SHA256", "hostkey": "ssh-ed25519"}, {"hash": "1e:0c:7b:34:73:bf:52:41:b0:f9:d1:a9:ab:98:c7:c9", "hash_alg": "MD5", "hostkey": "ssh-ed25519"}], "kex": [{"algorithm": "curve25519-sha256"}, {"algorithm": "curve25519-sha256@libssh.org"}, {"algorithm": "diffie-hellman-group-exchange-sha256", "keysize": 2048}], "key": [{"algorithm": "ssh-ed25519"}], "mac": ["hmac-sha2-256-etm@openssh.com", "hmac-sha2-512-etm@openssh.com", "umac-128-etm@openssh.com"], "target": "localhost"}
|
{
|
||||||
|
"banner": {
|
||||||
|
"comments": null,
|
||||||
|
"protocol": [
|
||||||
|
2,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"raw": "SSH-2.0-OpenSSH_8.0",
|
||||||
|
"software": "OpenSSH_8.0"
|
||||||
|
},
|
||||||
|
"compression": [
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"enc": [
|
||||||
|
"chacha20-poly1305@openssh.com",
|
||||||
|
"aes256-gcm@openssh.com",
|
||||||
|
"aes128-gcm@openssh.com",
|
||||||
|
"aes256-ctr",
|
||||||
|
"aes192-ctr",
|
||||||
|
"aes128-ctr"
|
||||||
|
],
|
||||||
|
"fingerprints": [
|
||||||
|
{
|
||||||
|
"hash": "UrnXIVH+7dlw8UqYocl48yUEcKrthGDQG2CPCgp7MxU",
|
||||||
|
"hash_alg": "SHA256",
|
||||||
|
"hostkey": "ssh-ed25519"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hash": "1e:0c:7b:34:73:bf:52:41:b0:f9:d1:a9:ab:98:c7:c9",
|
||||||
|
"hash_alg": "MD5",
|
||||||
|
"hostkey": "ssh-ed25519"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"kex": [
|
||||||
|
{
|
||||||
|
"algorithm": "curve25519-sha256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "curve25519-sha256@libssh.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "diffie-hellman-group-exchange-sha256",
|
||||||
|
"keysize": 2048
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"key": [
|
||||||
|
{
|
||||||
|
"algorithm": "ssh-ed25519"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mac": [
|
||||||
|
"hmac-sha2-256-etm@openssh.com",
|
||||||
|
"hmac-sha2-512-etm@openssh.com",
|
||||||
|
"umac-128-etm@openssh.com"
|
||||||
|
],
|
||||||
|
"recommendations": {
|
||||||
|
"informational": {
|
||||||
|
"add": {
|
||||||
|
"kex": [
|
||||||
|
{
|
||||||
|
"name": "diffie-hellman-group16-sha512",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "diffie-hellman-group18-sha512",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"key": [
|
||||||
|
{
|
||||||
|
"name": "rsa-sha2-256",
|
||||||
|
"notes": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rsa-sha2-512",
|
||||||
|
"notes": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"target": "localhost:2222"
|
||||||
|
}
|
||||||
|
@ -4,17 +4,27 @@
|
|||||||
[0;32m(gen) compatibility: OpenSSH 7.4+, Dropbear SSH 2018.76+[0m
|
[0;32m(gen) compatibility: OpenSSH 7.4+, Dropbear SSH 2018.76+[0m
|
||||||
[0;32m(gen) compression: enabled (zlib@openssh.com)[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;36m# key exchange algorithms[0m
|
||||||
[0;32m(kex) curve25519-sha256 -- [info] available since OpenSSH 7.4, Dropbear SSH 2018.76[0m
|
[0;32m(kex) curve25519-sha256 -- [info] available since OpenSSH 7.4, Dropbear SSH 2018.76[0m
|
||||||
[0;32m(kex) curve25519-sha256@libssh.org -- [info] available since OpenSSH 6.5, Dropbear SSH 2013.62[0m
|
`- [info] default key exchange since OpenSSH 6.4
|
||||||
[0;32m(kex) diffie-hellman-group-exchange-sha256 (2048-bit) -- [info] available since OpenSSH 4.4[0m
|
[0;32m(kex) curve25519-sha256@libssh.org -- [info] available since OpenSSH 6.4, Dropbear SSH 2013.62[0m
|
||||||
|
`- [info] default key exchange since OpenSSH 6.4
|
||||||
|
[0;33m(kex) diffie-hellman-group-exchange-sha256 (2048-bit) -- [warn] 2048-bit modulus only provides 112-bits of symmetric strength[0m
|
||||||
|
`- [info] available since OpenSSH 4.4
|
||||||
|
`- [info] A bug in OpenSSH causes it to fall back to a 2048-bit modulus regardless of server configuration (https://bugzilla.mindrot.org/show_bug.cgi?id=2793)
|
||||||
|
|
||||||
[0;36m# host-key algorithms[0m
|
[0;36m# host-key algorithms[0m
|
||||||
[0;32m(key) ssh-ed25519 -- [info] available since OpenSSH 6.5[0m
|
[0;32m(key) ssh-ed25519 -- [info] available since OpenSSH 6.5[0m
|
||||||
|
|
||||||
[0;36m# encryption algorithms (ciphers)[0m
|
[0;36m# encryption algorithms (ciphers)[0m
|
||||||
[0;32m(enc) chacha20-poly1305@openssh.com -- [info] available since OpenSSH 6.5[0m
|
[0;32m(enc) chacha20-poly1305@openssh.com -- [info] available since OpenSSH 6.5[0m
|
||||||
`- [info] default cipher since OpenSSH 6.9.
|
`- [info] default cipher since OpenSSH 6.9
|
||||||
[0;32m(enc) aes256-gcm@openssh.com -- [info] available since OpenSSH 6.2[0m
|
[0;32m(enc) aes256-gcm@openssh.com -- [info] available since OpenSSH 6.2[0m
|
||||||
[0;32m(enc) aes128-gcm@openssh.com -- [info] available since OpenSSH 6.2[0m
|
[0;32m(enc) aes128-gcm@openssh.com -- [info] available since OpenSSH 6.2[0m
|
||||||
[0;32m(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
[0;32m(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52[0m
|
||||||
@ -30,7 +40,6 @@
|
|||||||
[0;32m(fin) ssh-ed25519: SHA256:UrnXIVH+7dlw8UqYocl48yUEcKrthGDQG2CPCgp7MxU[0m
|
[0;32m(fin) ssh-ed25519: SHA256:UrnXIVH+7dlw8UqYocl48yUEcKrthGDQG2CPCgp7MxU[0m
|
||||||
|
|
||||||
[0;36m# algorithm recommendations (for OpenSSH 8.0)[0m
|
[0;36m# algorithm recommendations (for OpenSSH 8.0)[0m
|
||||||
[0;32m(rec) +diffie-hellman-group14-sha256 -- kex algorithm to append [0m
|
|
||||||
[0;32m(rec) +diffie-hellman-group16-sha512 -- kex algorithm to append [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) +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-256 -- key algorithm to append [0m
|
||||||
|
@ -1 +1,51 @@
|
|||||||
{"banner": {"comments": "", "protocol": [2, 0], "raw": "", "software": "tinyssh_noversion"}, "compression": ["none"], "enc": ["chacha20-poly1305@openssh.com"], "fingerprints": [{"hash": "89ocln1x7KNqnMgWffGoYtD70ksJ4FrH7BMJHa7SrwU", "hash_alg": "SHA256", "hostkey": "ssh-ed25519"}, {"hash": "dd:9c:6d:f9:b0:8c:af:fa:c2:65:81:5d:5d:56:f8:21", "hash_alg": "MD5", "hostkey": "ssh-ed25519"}], "kex": [{"algorithm": "curve25519-sha256"}, {"algorithm": "curve25519-sha256@libssh.org"}, {"algorithm": "sntrup4591761x25519-sha512@tinyssh.org"}], "key": [{"algorithm": "ssh-ed25519"}], "mac": ["hmac-sha2-256"], "target": "localhost"}
|
{
|
||||||
|
"banner": {
|
||||||
|
"comments": "",
|
||||||
|
"protocol": [
|
||||||
|
2,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"raw": "",
|
||||||
|
"software": "tinyssh_noversion"
|
||||||
|
},
|
||||||
|
"compression": [
|
||||||
|
"none"
|
||||||
|
],
|
||||||
|
"cves": [],
|
||||||
|
"enc": [
|
||||||
|
"chacha20-poly1305@openssh.com"
|
||||||
|
],
|
||||||
|
"fingerprints": [
|
||||||
|
{
|
||||||
|
"hash": "89ocln1x7KNqnMgWffGoYtD70ksJ4FrH7BMJHa7SrwU",
|
||||||
|
"hash_alg": "SHA256",
|
||||||
|
"hostkey": "ssh-ed25519"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hash": "dd:9c:6d:f9:b0:8c:af:fa:c2:65:81:5d:5d:56:f8:21",
|
||||||
|
"hash_alg": "MD5",
|
||||||
|
"hostkey": "ssh-ed25519"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"kex": [
|
||||||
|
{
|
||||||
|
"algorithm": "curve25519-sha256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "curve25519-sha256@libssh.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"algorithm": "sntrup4591761x25519-sha512@tinyssh.org"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"key": [
|
||||||
|
{
|
||||||
|
"algorithm": "ssh-ed25519"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mac": [
|
||||||
|
"hmac-sha2-256"
|
||||||
|
],
|
||||||
|
"recommendations": {},
|
||||||
|
"target": "localhost:2222"
|
||||||
|
}
|
||||||
|
@ -5,16 +5,19 @@
|
|||||||
|
|
||||||
[0;36m# key exchange algorithms[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(kex) curve25519-sha256 -- [info] available since OpenSSH 7.4, Dropbear SSH 2018.76[0m
|
||||||
[0;32m(kex) curve25519-sha256@libssh.org -- [info] available since OpenSSH 6.5, Dropbear SSH 2013.62[0m
|
`- [info] default key exchange since OpenSSH 6.4
|
||||||
|
[0;32m(kex) curve25519-sha256@libssh.org -- [info] available since OpenSSH 6.4, Dropbear SSH 2013.62[0m
|
||||||
|
`- [info] default key exchange since OpenSSH 6.4
|
||||||
[0;33m(kex) sntrup4591761x25519-sha512@tinyssh.org -- [warn] using experimental algorithm[0m
|
[0;33m(kex) sntrup4591761x25519-sha512@tinyssh.org -- [warn] using experimental algorithm[0m
|
||||||
`- [info] available since OpenSSH 8.0
|
`- [info] available since OpenSSH 8.0
|
||||||
|
`- [info] the sntrup4591761 algorithm was withdrawn, as it may not provide strong post-quantum security
|
||||||
|
|
||||||
[0;36m# host-key algorithms[0m
|
[0;36m# host-key algorithms[0m
|
||||||
[0;32m(key) ssh-ed25519 -- [info] available since OpenSSH 6.5[0m
|
[0;32m(key) ssh-ed25519 -- [info] available since OpenSSH 6.5[0m
|
||||||
|
|
||||||
[0;36m# encryption algorithms (ciphers)[0m
|
[0;36m# encryption algorithms (ciphers)[0m
|
||||||
[0;32m(enc) chacha20-poly1305@openssh.com -- [info] available since OpenSSH 6.5[0m
|
[0;32m(enc) chacha20-poly1305@openssh.com -- [info] available since OpenSSH 6.5[0m
|
||||||
`- [info] default cipher since OpenSSH 6.9.
|
`- [info] default cipher since OpenSSH 6.9
|
||||||
|
|
||||||
[0;36m# message authentication code algorithms[0m
|
[0;36m# message authentication code algorithms[0m
|
||||||
[0;33m(mac) hmac-sha2-256 -- [warn] using encrypt-and-MAC mode[0m
|
[0;33m(mac) hmac-sha2-256 -- [warn] using encrypt-and-MAC mode[0m
|
||||||
|
@ -7,7 +7,7 @@ class TestAuditConf:
|
|||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def init(self, ssh_audit):
|
def init(self, ssh_audit):
|
||||||
self.AuditConf = ssh_audit.AuditConf
|
self.AuditConf = ssh_audit.AuditConf
|
||||||
self.OutputBuffer = ssh_audit.OutputBuffer
|
self.OutputBuffer = ssh_audit.OutputBuffer()
|
||||||
self.usage = ssh_audit.usage
|
self.usage = ssh_audit.usage
|
||||||
self.process_commandline = process_commandline
|
self.process_commandline = process_commandline
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import os
|
import os
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
from ssh_audit.outputbuffer import OutputBuffer
|
||||||
from ssh_audit.ssh2_kex import SSH2_Kex
|
from ssh_audit.ssh2_kex import SSH2_Kex
|
||||||
from ssh_audit.ssh2_kexparty import SSH2_KexParty
|
from ssh_audit.ssh2_kexparty import SSH2_KexParty
|
||||||
|
|
||||||
@ -13,7 +14,7 @@ def kex(ssh_audit):
|
|||||||
enc, mac, compression, languages = [], [], ['none'], []
|
enc, mac, compression, languages = [], [], ['none'], []
|
||||||
srv = SSH2_KexParty(enc, mac, compression, languages)
|
srv = SSH2_KexParty(enc, mac, compression, languages)
|
||||||
cookie = os.urandom(16)
|
cookie = os.urandom(16)
|
||||||
kex = SSH2_Kex(cookie, kex_algs, key_algs, cli, srv, 0)
|
kex = SSH2_Kex(OutputBuffer, cookie, kex_algs, key_algs, cli, srv, 0)
|
||||||
return kex
|
return kex
|
||||||
|
|
||||||
|
|
||||||
@ -25,17 +26,17 @@ def test_prevent_runtime_error_regression(ssh_audit, kex):
|
|||||||
keys, and an error occurred when iterating and modifying them at the
|
keys, and an error occurred when iterating and modifying them at the
|
||||||
same time.
|
same time.
|
||||||
"""
|
"""
|
||||||
kex.set_host_key("ssh-rsa", b"\x00\x00\x00\x07ssh-rsa\x00\x00\x00")
|
kex.set_host_key("ssh-rsa", b"\x00\x00\x00\x07ssh-rsa\x00\x00\x00", 1024, '', 0)
|
||||||
kex.set_host_key("ssh-rsa1", b"\x00\x00\x00\x07ssh-rsa\x00\x00\x00")
|
kex.set_host_key("ssh-rsa1", b"\x00\x00\x00\x07ssh-rsa\x00\x00\x00", 1024, '', 0)
|
||||||
kex.set_host_key("ssh-rsa2", b"\x00\x00\x00\x07ssh-rsa\x00\x00\x00")
|
kex.set_host_key("ssh-rsa2", b"\x00\x00\x00\x07ssh-rsa\x00\x00\x00", 1024, '', 0)
|
||||||
kex.set_host_key("ssh-rsa3", b"\x00\x00\x00\x07ssh-rsa\x00\x00\x00")
|
kex.set_host_key("ssh-rsa3", b"\x00\x00\x00\x07ssh-rsa\x00\x00\x00", 1024, '', 0)
|
||||||
kex.set_host_key("ssh-rsa4", b"\x00\x00\x00\x07ssh-rsa\x00\x00\x00")
|
kex.set_host_key("ssh-rsa4", b"\x00\x00\x00\x07ssh-rsa\x00\x00\x00", 1024, '', 0)
|
||||||
kex.set_host_key("ssh-rsa5", b"\x00\x00\x00\x07ssh-rsa\x00\x00\x00")
|
kex.set_host_key("ssh-rsa5", b"\x00\x00\x00\x07ssh-rsa\x00\x00\x00", 1024, '', 0)
|
||||||
kex.set_host_key("ssh-rsa6", b"\x00\x00\x00\x07ssh-rsa\x00\x00\x00")
|
kex.set_host_key("ssh-rsa6", b"\x00\x00\x00\x07ssh-rsa\x00\x00\x00", 1024, '', 0)
|
||||||
kex.set_host_key("ssh-rsa7", b"\x00\x00\x00\x07ssh-rsa\x00\x00\x00")
|
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")
|
kex.set_host_key("ssh-rsa8", b"\x00\x00\x00\x07ssh-rsa\x00\x00\x00", 1024, '', 0)
|
||||||
|
|
||||||
rv = ssh_audit.build_struct('localhost', banner=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.
|
assert len(rv["fingerprints"]) == (9 * 2) # Each host key generates two hash fingerprints: one using SHA256, and one using MD5.
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ import hashlib
|
|||||||
import pytest
|
import pytest
|
||||||
from datetime import date
|
from datetime import date
|
||||||
|
|
||||||
|
from ssh_audit.outputbuffer import OutputBuffer
|
||||||
from ssh_audit.policy import Policy
|
from ssh_audit.policy import Policy
|
||||||
from ssh_audit.ssh2_kex import SSH2_Kex
|
from ssh_audit.ssh2_kex import SSH2_Kex
|
||||||
from ssh_audit.writebuf import WriteBuf
|
from ssh_audit.writebuf import WriteBuf
|
||||||
@ -10,6 +11,7 @@ from ssh_audit.writebuf import WriteBuf
|
|||||||
class TestPolicy:
|
class TestPolicy:
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def init(self, ssh_audit):
|
def init(self, ssh_audit):
|
||||||
|
self.OutputBuffer = OutputBuffer
|
||||||
self.Policy = Policy
|
self.Policy = Policy
|
||||||
self.wbuf = WriteBuf
|
self.wbuf = WriteBuf
|
||||||
self.ssh2_kex = SSH2_Kex
|
self.ssh2_kex = SSH2_Kex
|
||||||
@ -32,7 +34,7 @@ class TestPolicy:
|
|||||||
w.write_list([''])
|
w.write_list([''])
|
||||||
w.write_byte(False)
|
w.write_byte(False)
|
||||||
w.write_int(0)
|
w.write_int(0)
|
||||||
return self.ssh2_kex.parse(w.write_flush())
|
return self.ssh2_kex.parse(self.OutputBuffer, w.write_flush())
|
||||||
|
|
||||||
|
|
||||||
def test_builtin_policy_consistency(self):
|
def test_builtin_policy_consistency(self):
|
||||||
@ -41,15 +43,91 @@ class TestPolicy:
|
|||||||
for policy_name in Policy.BUILTIN_POLICIES:
|
for policy_name in Policy.BUILTIN_POLICIES:
|
||||||
# Ensure that the policy name ends with " (version X)", where X is the 'version' field.
|
# Ensure that the policy name ends with " (version X)", where X is the 'version' field.
|
||||||
version_str = " (version %s)" % Policy.BUILTIN_POLICIES[policy_name]['version']
|
version_str = " (version %s)" % Policy.BUILTIN_POLICIES[policy_name]['version']
|
||||||
assert(policy_name.endswith(version_str))
|
assert policy_name.endswith(version_str)
|
||||||
|
|
||||||
|
# Ensure that all required fields are present.
|
||||||
|
required_fields = ['version', 'banner', 'compressions', 'host_keys', 'optional_host_keys', 'kex', 'ciphers', 'macs', 'hostkey_sizes', 'dh_modulus_sizes', 'server_policy']
|
||||||
|
for field in required_fields:
|
||||||
|
assert field in Policy.BUILTIN_POLICIES[policy_name]
|
||||||
|
|
||||||
|
# Ensure no extra fields are present.
|
||||||
|
assert len(required_fields) == len(Policy.BUILTIN_POLICIES[policy_name])
|
||||||
|
|
||||||
|
# Ensure that at least one host key is defined.
|
||||||
|
assert type(Policy.BUILTIN_POLICIES[policy_name]['host_keys']) == list
|
||||||
|
assert len(Policy.BUILTIN_POLICIES[policy_name]['host_keys']) > 0
|
||||||
|
|
||||||
|
# Ensure that at least one key exchange is defined.
|
||||||
|
assert type(Policy.BUILTIN_POLICIES[policy_name]['kex']) == list
|
||||||
|
assert len(Policy.BUILTIN_POLICIES[policy_name]['kex']) > 0
|
||||||
|
|
||||||
|
# Ensure that at least one cipher is defined.
|
||||||
|
assert type(Policy.BUILTIN_POLICIES[policy_name]['ciphers']) == list
|
||||||
|
assert len(Policy.BUILTIN_POLICIES[policy_name]['ciphers']) > 0
|
||||||
|
|
||||||
|
# Ensure that at least one MAC is defined
|
||||||
|
assert type(Policy.BUILTIN_POLICIES[policy_name]['macs']) == list
|
||||||
|
assert len(Policy.BUILTIN_POLICIES[policy_name]['macs']) > 0
|
||||||
|
|
||||||
|
# These tests apply to server policies only.
|
||||||
|
if Policy.BUILTIN_POLICIES[policy_name]['server_policy']:
|
||||||
|
assert type(Policy.BUILTIN_POLICIES[policy_name]['hostkey_sizes']) == dict
|
||||||
|
assert len(Policy.BUILTIN_POLICIES[policy_name]['hostkey_sizes']) > 0
|
||||||
|
|
||||||
|
# Examine all the hostkey_sizes entries...
|
||||||
|
for hostkey_type in Policy.BUILTIN_POLICIES[policy_name]['hostkey_sizes']:
|
||||||
|
hostkey_data = Policy.BUILTIN_POLICIES[policy_name]['hostkey_sizes'][hostkey_type]
|
||||||
|
|
||||||
|
# Ensure that 'hostkey_size' is always included and that it is an integer.
|
||||||
|
assert 'hostkey_size' in hostkey_data
|
||||||
|
assert type(hostkey_data['hostkey_size']) == int
|
||||||
|
|
||||||
|
# If this is an ed25519 host key, ensure its size is fixed at 256. If its an RSA host key, ensure the size is 4096.
|
||||||
|
if hostkey_type.find('ed25519') != -1:
|
||||||
|
assert int(hostkey_data['hostkey_size']) == 256
|
||||||
|
elif hostkey_type.startswith('rsa-'):
|
||||||
|
assert int(hostkey_data['hostkey_size']) == 4096
|
||||||
|
else: # Catch unexpected host key types.
|
||||||
|
assert False
|
||||||
|
|
||||||
|
# Ensure either that 'ca_key_type' and 'ca_key_size' are both present, or neither are. Fail cases when only one of the fields are present.
|
||||||
|
assert (('ca_key_type' in hostkey_data) and ('ca_key_size' in hostkey_data)) or (('ca_key_type' not in hostkey_data) and ('ca_key_size' not in hostkey_data))
|
||||||
|
|
||||||
|
# Ensure that the ca_key_type is either ssh-rsa or ssh-ed25519.
|
||||||
|
if 'ca_key_type' in hostkey_data:
|
||||||
|
assert hostkey_data['ca_key_type'] in ['ssh-rsa', 'ssh-ed25519']
|
||||||
|
|
||||||
|
# Ensure RSA CA key sizes are fixed at 4096. Ensure ED25519 CA keys are 256.
|
||||||
|
if 'ca_key_size' in hostkey_data:
|
||||||
|
if 'ca_key_type' == 'ssh-rsa':
|
||||||
|
assert hostkey_data['ca_key_size'] == 4096
|
||||||
|
elif 'ca_key_type' == 'ssh-ed25519':
|
||||||
|
assert hostkey_data['ca_key_size'] == 256
|
||||||
|
|
||||||
|
# Ensure that the 'dh_modulus_size' field is a dict.
|
||||||
|
assert type(Policy.BUILTIN_POLICIES[policy_name]['dh_modulus_sizes']) == dict
|
||||||
|
|
||||||
|
# The 'dh_modulus_size' field should have either one entry, or be empty.
|
||||||
|
assert len(Policy.BUILTIN_POLICIES[policy_name]['dh_modulus_sizes']) in range(0, 2) # The endpoint in range() is not inclusive
|
||||||
|
|
||||||
|
# If 'diffie-hellman-group-exchange-sha256' is in the kex list, ensure that it exists in the 'dh_modulus_sizes' entry. That entry must be defined for 2048 bits or larger.
|
||||||
|
if 'diffie-hellman-group-exchange-sha256' in Policy.BUILTIN_POLICIES[policy_name]['kex']:
|
||||||
|
assert 'diffie-hellman-group-exchange-sha256' in Policy.BUILTIN_POLICIES[policy_name]['dh_modulus_sizes']
|
||||||
|
assert int(Policy.BUILTIN_POLICIES[policy_name]['dh_modulus_sizes']['diffie-hellman-group-exchange-sha256']) >= 2048
|
||||||
|
|
||||||
|
else: # Client-specific tests.
|
||||||
|
|
||||||
|
# These must be set to None for client policies, since they have no meaning otherwise.
|
||||||
|
assert Policy.BUILTIN_POLICIES[policy_name]['hostkey_sizes'] is None
|
||||||
|
assert Policy.BUILTIN_POLICIES[policy_name]['dh_modulus_sizes'] is None
|
||||||
|
|
||||||
# Ensure that each built-in policy can be loaded with Policy.load_builtin_policy().
|
# Ensure that each built-in policy can be loaded with Policy.load_builtin_policy().
|
||||||
assert(Policy.load_builtin_policy(policy_name) is not None)
|
assert Policy.load_builtin_policy(policy_name) is not None
|
||||||
|
|
||||||
# Ensure that both server and client policy names are returned.
|
# Ensure that both server and client policy names are returned.
|
||||||
server_policy_names, client_policy_names = Policy.list_builtin_policies()
|
server_policy_names, client_policy_names = Policy.list_builtin_policies()
|
||||||
assert(len(server_policy_names) > 0)
|
assert len(server_policy_names) > 0
|
||||||
assert(len(client_policy_names) > 0)
|
assert len(client_policy_names) > 0
|
||||||
|
|
||||||
|
|
||||||
def test_policy_basic(self):
|
def test_policy_basic(self):
|
||||||
@ -66,7 +144,7 @@ ciphers = cipher_alg1, cipher_alg2, cipher_alg3
|
|||||||
macs = mac_alg1, mac_alg2, mac_alg3'''
|
macs = mac_alg1, mac_alg2, mac_alg3'''
|
||||||
|
|
||||||
policy = self.Policy(policy_data=policy_data)
|
policy = self.Policy(policy_data=policy_data)
|
||||||
assert str(policy) == "Name: [Test Policy]\nVersion: [1]\nBanner: {undefined}\nCompressions: comp_alg1\nHost Keys: key_alg1\nOptional Host Keys: {undefined}\nKey Exchanges: kex_alg1, kex_alg2\nCiphers: cipher_alg1, cipher_alg2, cipher_alg3\nMACs: mac_alg1, mac_alg2, mac_alg3\nHost Key Sizes: {undefined}\nCA Key Sizes: {undefined}\nDH Modulus Sizes: {undefined}\nServer Policy: True"
|
assert str(policy) == "Name: [Test Policy]\nVersion: [1]\nBanner: {undefined}\nCompressions: comp_alg1\nHost Keys: key_alg1\nOptional Host Keys: {undefined}\nKey Exchanges: kex_alg1, kex_alg2\nCiphers: cipher_alg1, cipher_alg2, cipher_alg3\nMACs: mac_alg1, mac_alg2, mac_alg3\nHost Key Sizes: {undefined}\nDH Modulus Sizes: {undefined}\nServer Policy: True"
|
||||||
|
|
||||||
|
|
||||||
def test_policy_invalid_1(self):
|
def test_policy_invalid_1(self):
|
||||||
|
@ -138,7 +138,7 @@ class TestSSH1:
|
|||||||
self.audit(out, self._conf())
|
self.audit(out, self._conf())
|
||||||
out.write()
|
out.write()
|
||||||
lines = output_spy.flush()
|
lines = output_spy.flush()
|
||||||
assert len(lines) == 17
|
assert len(lines) == 21
|
||||||
|
|
||||||
def test_ssh1_server_invalid_first_packet(self, output_spy, virtual_socket):
|
def test_ssh1_server_invalid_first_packet(self, output_spy, virtual_socket):
|
||||||
vsocket = virtual_socket
|
vsocket = virtual_socket
|
||||||
@ -153,7 +153,7 @@ class TestSSH1:
|
|||||||
out.write()
|
out.write()
|
||||||
assert ret != 0
|
assert ret != 0
|
||||||
lines = output_spy.flush()
|
lines = output_spy.flush()
|
||||||
assert len(lines) == 10
|
assert len(lines) == 14
|
||||||
assert 'unknown message' in lines[-1]
|
assert 'unknown message' in lines[-1]
|
||||||
|
|
||||||
def test_ssh1_server_invalid_checksum(self, output_spy, virtual_socket):
|
def test_ssh1_server_invalid_checksum(self, output_spy, virtual_socket):
|
||||||
|
@ -61,8 +61,25 @@ class TestSSH2:
|
|||||||
w.write_int(0)
|
w.write_int(0)
|
||||||
return w.write_flush()
|
return w.write_flush()
|
||||||
|
|
||||||
|
def _kex_payload_with_gss(self):
|
||||||
|
w = self.wbuf()
|
||||||
|
w.write(b'\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff')
|
||||||
|
w.write_list(['gss-gex-sha1-dZuIebMjgUqaxvbF7hDbAw==', 'gss-gex-sha1-vz8J1E9PzLr8b1K+0remTg==', 'gss-group14-sha1-dZuIebMjgUqaxvbF7hDbAw==', 'gss-group14-sha1-vz8J1E9PzLr8b1K+0remTg==', 'gss-group14-sha256-dZuIebMjgUqaxvbF7hDbAw==', 'gss-group14-sha256-vz8J1E9PzLr8b1K+0remTg==', 'gss-group16-sha512-dZuIebMjgUqaxvbF7hDbAw==', 'gss-group16-sha512-vz8J1E9PzLr8b1K+0remTg==', 'gss-group18-sha512-dZuIebMjgUqaxvbF7hDbAw==', 'gss-group18-sha512-vz8J1E9PzLr8b1K+0remTg==', 'gss-group1-sha1-dZuIebMjgUqaxvbF7hDbAw==', 'gss-group1-sha1-vz8J1E9PzLr8b1K+0remTg==', 'gss-curve448-sha512-XXX'])
|
||||||
|
w.write_list(['ssh-ed25519'])
|
||||||
|
w.write_list(['chacha20-poly1305@openssh.com'])
|
||||||
|
w.write_list(['chacha20-poly1305@openssh.com'])
|
||||||
|
w.write_list(['hmac-sha2-512-etm@openssh.com'])
|
||||||
|
w.write_list(['hmac-sha2-512-etm@openssh.com'])
|
||||||
|
w.write_list(['none', 'zlib@openssh.com'])
|
||||||
|
w.write_list(['none', 'zlib@openssh.com'])
|
||||||
|
w.write_list([''])
|
||||||
|
w.write_list([''])
|
||||||
|
w.write_byte(False)
|
||||||
|
w.write_int(0)
|
||||||
|
return w.write_flush()
|
||||||
|
|
||||||
def test_kex_read(self):
|
def test_kex_read(self):
|
||||||
kex = self.ssh2_kex.parse(self._kex_payload())
|
kex = self.ssh2_kex.parse(self.OutputBuffer, self._kex_payload())
|
||||||
assert kex is not None
|
assert kex is not None
|
||||||
assert kex.cookie == b'\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff'
|
assert kex.cookie == b'\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff'
|
||||||
assert kex.kex_algorithms == ['bogus_kex1', 'bogus_kex2']
|
assert kex.kex_algorithms == ['bogus_kex1', 'bogus_kex2']
|
||||||
@ -88,7 +105,7 @@ class TestSSH2:
|
|||||||
srv = self.ssh2_kexparty(enc, mac, compression, languages)
|
srv = self.ssh2_kexparty(enc, mac, compression, languages)
|
||||||
if cookie is None:
|
if cookie is None:
|
||||||
cookie = os.urandom(16)
|
cookie = os.urandom(16)
|
||||||
kex = self.ssh2_kex(cookie, kex_algs, key_algs, cli, srv, 0)
|
kex = self.ssh2_kex(self.OutputBuffer, cookie, kex_algs, key_algs, cli, srv, 0)
|
||||||
return kex
|
return kex
|
||||||
|
|
||||||
def _get_kex_variat1(self):
|
def _get_kex_variat1(self):
|
||||||
@ -132,7 +149,7 @@ class TestSSH2:
|
|||||||
|
|
||||||
def test_key_payload(self):
|
def test_key_payload(self):
|
||||||
kex1 = self._get_kex_variat1()
|
kex1 = self._get_kex_variat1()
|
||||||
kex2 = self.ssh2_kex.parse(self._kex_payload())
|
kex2 = self.ssh2_kex.parse(self.OutputBuffer, self._kex_payload())
|
||||||
assert kex1.payload == kex2.payload
|
assert kex1.payload == kex2.payload
|
||||||
|
|
||||||
def test_ssh2_server_simple(self, output_spy, virtual_socket):
|
def test_ssh2_server_simple(self, output_spy, virtual_socket):
|
||||||
@ -161,5 +178,24 @@ class TestSSH2:
|
|||||||
out.write()
|
out.write()
|
||||||
assert ret != 0
|
assert ret != 0
|
||||||
lines = output_spy.flush()
|
lines = output_spy.flush()
|
||||||
assert len(lines) == 5
|
assert len(lines) == 9
|
||||||
assert 'unknown message' in lines[-1]
|
assert 'unknown message' in lines[-1]
|
||||||
|
|
||||||
|
def test_ssh2_gss_kex(self, output_spy, virtual_socket):
|
||||||
|
'''Ensure that GSS kex algorithms are properly parsed.'''
|
||||||
|
|
||||||
|
vsocket = virtual_socket
|
||||||
|
w = self.wbuf()
|
||||||
|
w.write_byte(self.protocol.MSG_KEXINIT)
|
||||||
|
w.write(self._kex_payload_with_gss()) # Use the kex with GSS algorithms.
|
||||||
|
vsocket.rdata.append(b'SSH-2.0-OpenSSH_7.3 ssh-audit-test\r\n')
|
||||||
|
vsocket.rdata.append(self._create_ssh2_packet(w.write_flush()))
|
||||||
|
output_spy.begin()
|
||||||
|
out = self.OutputBuffer()
|
||||||
|
self.audit(out, self._conf())
|
||||||
|
out.write()
|
||||||
|
lines = output_spy.flush()
|
||||||
|
|
||||||
|
# Ensure that none of the lines are reported as "unknown algorithm".
|
||||||
|
for line in lines:
|
||||||
|
assert line.find('unknown algorithm') == -1
|
||||||
|
35
test/test_ssh2_kexdb.py
Normal file
35
test/test_ssh2_kexdb.py
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
from ssh_audit.ssh2_kexdb import SSH2_KexDB
|
||||||
|
|
||||||
|
|
||||||
|
class Test_SSH2_KexDB:
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def init(self):
|
||||||
|
self.db = SSH2_KexDB.ALGORITHMS
|
||||||
|
|
||||||
|
def test_ssh2_kexdb(self):
|
||||||
|
'''Ensures that the SSH2_KexDB.ALGORITHMS dictionary is in the right format.'''
|
||||||
|
|
||||||
|
db_keys = list(self.db.keys())
|
||||||
|
db_keys.sort()
|
||||||
|
|
||||||
|
# Ensure only these keys exist in the database.
|
||||||
|
assert db_keys == ['enc', 'kex', 'key', 'mac']
|
||||||
|
|
||||||
|
# For 'enc', 'kex', etc...
|
||||||
|
for alg_type in self.db:
|
||||||
|
|
||||||
|
# Iterate over algorithms within this type (i.e.: all 'enc' algorithms, all 'kex' algorithms, etc).
|
||||||
|
for alg_name in self.db[alg_type]:
|
||||||
|
|
||||||
|
# Get the list of failures, warnings, etc., for this algorithm.
|
||||||
|
alg_data = self.db[alg_type][alg_name]
|
||||||
|
|
||||||
|
# This list must be between 1 and 4 entries long.
|
||||||
|
assert 1 <= len(alg_data) <= 4
|
||||||
|
|
||||||
|
# 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
|
34
tox.ini
34
tox.ini
@ -1,19 +1,19 @@
|
|||||||
[tox]
|
[tox]
|
||||||
envlist =
|
envlist =
|
||||||
py{py3}-{test,pylint,flake8,vulture}
|
py{py3}-{test,pylint,flake8,vulture}
|
||||||
py{36,37,38,39}-{test,mypy,pylint,flake8,vulture}
|
py{37,38,39,310,311}-{test,mypy,pylint,flake8,vulture}
|
||||||
cov
|
cov
|
||||||
skip_missing_interpreters = true
|
skip_missing_interpreters = true
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
deps =
|
deps =
|
||||||
test: pytest<6.0
|
test: pytest
|
||||||
test,cov: {[testenv:cov]deps}
|
test,cov: {[testenv:cov]deps}
|
||||||
test,py{36,37,38,39}-{type,mypy}: colorama
|
test,py{37,38,39,310,311}-{type,mypy}: colorama
|
||||||
py{36,37,38,39}-{type,mypy}: {[testenv:mypy]deps}
|
py{37,38,39,310,311}-{type,mypy}: {[testenv:mypy]deps}
|
||||||
py{py3,36,37,38,39}-{lint,pylint},lint: {[testenv:pylint]deps}
|
py{py3,37,38,39,310,311}-{lint,pylint},lint: {[testenv:pylint]deps}
|
||||||
py{py3,36,37,38,39}-{lint,flake8},lint: {[testenv:flake8]deps}
|
py{py3,37,38,39,310,311}-{lint,flake8},lint: {[testenv:flake8]deps}
|
||||||
py{py3,36,37,38,39}-{lint,vulture},lint: {[testenv:vulture]deps}
|
py{py3,37,38,39,310,311}-{lint,vulture},lint: {[testenv:vulture]deps}
|
||||||
setenv =
|
setenv =
|
||||||
SSHAUDIT = {toxinidir}/src
|
SSHAUDIT = {toxinidir}/src
|
||||||
test: COVERAGE_FILE = {toxinidir}/.coverage.{envname}
|
test: COVERAGE_FILE = {toxinidir}/.coverage.{envname}
|
||||||
@ -25,10 +25,10 @@ commands =
|
|||||||
test: coverage combine
|
test: coverage combine
|
||||||
test: coverage report --show-missing
|
test: coverage report --show-missing
|
||||||
test: coverage html -d {toxinidir}/reports/html/coverage.{envname}
|
test: coverage html -d {toxinidir}/reports/html/coverage.{envname}
|
||||||
py{36,37,38,39}-{type,mypy}: {[testenv:mypy]commands}
|
py{37,38,39,310,311}-{type,mypy}: {[testenv:mypy]commands}
|
||||||
py{py3,36,37,38,39}-{lint,pylint},lint: {[testenv:pylint]commands}
|
py{py3,37,38,39,310,311}-{lint,pylint},lint: {[testenv:pylint]commands}
|
||||||
py{py3,36,37,38,39}-{lint,flake8},lint: {[testenv:flake8]commands}
|
py{py3,37,38,39,310,311}-{lint,flake8},lint: {[testenv:flake8]commands}
|
||||||
py{py3,36,37,38,39}-{lint,vulture},lint: {[testenv:vulture]commands}
|
py{py3,37,38,39,310,311}-{lint,vulture},lint: {[testenv:vulture]commands}
|
||||||
#ignore_outcome =
|
#ignore_outcome =
|
||||||
# type: true
|
# type: true
|
||||||
# lint: true
|
# lint: true
|
||||||
@ -91,14 +91,12 @@ reports = no
|
|||||||
#output-format = colorized
|
#output-format = colorized
|
||||||
indent-string = " "
|
indent-string = " "
|
||||||
disable =
|
disable =
|
||||||
bad-continuation,
|
|
||||||
broad-except,
|
broad-except,
|
||||||
duplicate-code,
|
duplicate-code,
|
||||||
fixme,
|
fixme,
|
||||||
invalid-name,
|
invalid-name,
|
||||||
line-too-long,
|
line-too-long,
|
||||||
missing-docstring,
|
missing-docstring,
|
||||||
mixed-indentation,
|
|
||||||
no-else-raise,
|
no-else-raise,
|
||||||
no-else-return,
|
no-else-return,
|
||||||
super-with-arguments, # Can be re-factored, at some point.
|
super-with-arguments, # Can be re-factored, at some point.
|
||||||
@ -109,7 +107,7 @@ disable =
|
|||||||
too-many-lines,
|
too-many-lines,
|
||||||
too-many-locals,
|
too-many-locals,
|
||||||
too-many-statements,
|
too-many-statements,
|
||||||
unsubscriptable-object # This seems to be a local issue on the maintainer's machine only. Could be removed, perhaps, in Jan 2021.
|
consider-using-f-string
|
||||||
max-complexity = 15
|
max-complexity = 15
|
||||||
max-args = 8
|
max-args = 8
|
||||||
max-locals = 20
|
max-locals = 20
|
||||||
@ -127,10 +125,10 @@ ignore-long-lines = ^\s*(#\s+type:\s+.*|[A-Z0-9_]+\s+=\s+.*|('.*':\s+)?\[.*\],?|
|
|||||||
max-module-lines = 2500
|
max-module-lines = 2500
|
||||||
|
|
||||||
[flake8]
|
[flake8]
|
||||||
ignore =
|
# E241 = multiple spaces after operator; should be kept for tabular data
|
||||||
E241, # multiple spaces after operator; should be kept for tabular data
|
# E303 = too many blank lines
|
||||||
E303, # too many blank lines
|
# E501 = line too long
|
||||||
E501, # line too long
|
ignore = E241, E303, E501
|
||||||
|
|
||||||
[pytest]
|
[pytest]
|
||||||
junit_family = xunit1
|
junit_family = xunit1
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
#
|
#
|
||||||
# The MIT License (MIT)
|
# The MIT License (MIT)
|
||||||
@ -45,7 +45,7 @@
|
|||||||
#
|
#
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
function usage {
|
usage() {
|
||||||
echo >&2 "Usage: $0 [-m <path-to-man-page>] [-g <path-to-globals.py>] [-h]"
|
echo >&2 "Usage: $0 [-m <path-to-man-page>] [-g <path-to-globals.py>] [-h]"
|
||||||
echo >&2 " -m Specify an alternate man page path (default: ./ssh-audit.1)"
|
echo >&2 " -m Specify an alternate man page path (default: ./ssh-audit.1)"
|
||||||
echo >&2 " -g Specify an alternate globals.py path (default: ./src/ssh_audit/globals.py)"
|
echo >&2 " -g Specify an alternate globals.py path (default: ./src/ssh_audit/globals.py)"
|
||||||
@ -57,7 +57,8 @@ PLATFORM="$(uname -s)"
|
|||||||
# This script is intended for use on Linux and Cygwin only.
|
# This script is intended for use on Linux and Cygwin only.
|
||||||
case "$PLATFORM" in
|
case "$PLATFORM" in
|
||||||
Linux | CYGWIN*) ;;
|
Linux | CYGWIN*) ;;
|
||||||
*) echo "Platform not supported: $PLATFORM"
|
*)
|
||||||
|
echo "Platform not supported: $PLATFORM"
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@ -65,8 +66,7 @@ esac
|
|||||||
MAN_PAGE=./ssh-audit.1
|
MAN_PAGE=./ssh-audit.1
|
||||||
GLOBALS_PY=./src/ssh_audit/globals.py
|
GLOBALS_PY=./src/ssh_audit/globals.py
|
||||||
|
|
||||||
while getopts "m: g: h" OPTION
|
while getopts "m: g: h" OPTION; do
|
||||||
do
|
|
||||||
case "$OPTION" in
|
case "$OPTION" in
|
||||||
m)
|
m)
|
||||||
MAN_PAGE="$OPTARG"
|
MAN_PAGE="$OPTARG"
|
||||||
@ -87,11 +87,11 @@ do
|
|||||||
done
|
done
|
||||||
|
|
||||||
# Check that the specified files exist.
|
# Check that the specified files exist.
|
||||||
[ -f "$MAN_PAGE" ] || { echo >&2 "man page file not found: $MAN_PAGE"; exit 1; }
|
[[ -f "$MAN_PAGE" ]] || { echo >&2 "man page file not found: $MAN_PAGE"; exit 1; }
|
||||||
[ -f "$GLOBALS_PY" ] || { echo >&2 "globals.py file not found: $GLOBALS_PY"; exit 1; }
|
[[ -f "$GLOBALS_PY" ]] || { echo >&2 "globals.py file not found: $GLOBALS_PY"; exit 1; }
|
||||||
|
|
||||||
# Check that the 'ul' (do underlining) binary exists.
|
# Check that the 'ul' (do underlining) binary exists.
|
||||||
if [[ "$PLATFORM" = Linux ]]; then
|
if [[ "$PLATFORM" == "Linux" ]]; then
|
||||||
command -v ul >/dev/null 2>&1 || { echo >&2 "ul not found."; exit 1; }
|
command -v ul >/dev/null 2>&1 || { echo >&2 "ul not found."; exit 1; }
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -118,7 +118,7 @@ echo "Processing man page at ${MAN_PAGE} and placing output into ${GLOBALS_PY}..
|
|||||||
|
|
||||||
echo WINDOWS_MAN_PAGE = '"""' >> "$GLOBALS_PY"
|
echo WINDOWS_MAN_PAGE = '"""' >> "$GLOBALS_PY"
|
||||||
|
|
||||||
if [[ "$PLATFORM" = CYGWIN* ]]; then
|
if [[ "$PLATFORM" == CYGWIN* ]]; then
|
||||||
MANWIDTH=80 MAN_KEEP_FORMATTING=1 man "$MAN_PAGE" | sed $'s/\u2010/-/g' >> "$GLOBALS_PY"
|
MANWIDTH=80 MAN_KEEP_FORMATTING=1 man "$MAN_PAGE" | sed $'s/\u2010/-/g' >> "$GLOBALS_PY"
|
||||||
else
|
else
|
||||||
MANWIDTH=80 MAN_KEEP_FORMATTING=1 man "$MAN_PAGE" | ul | sed $'s/\u2010/-/g' >> "$GLOBALS_PY"
|
MANWIDTH=80 MAN_KEEP_FORMATTING=1 man "$MAN_PAGE" | ul | sed $'s/\u2010/-/g' >> "$GLOBALS_PY"
|
||||||
|
Reference in New Issue
Block a user