1
0
mirror of https://github.com/jtesta/ssh-audit.git synced 2025-07-06 05:57:50 -05:00

217 Commits

Author SHA1 Message Date
68cf05d0ff Set version to 3.2.0 for release. 2024-04-22 16:32:57 -04:00
2d9ddabcad Updated DHEat rate connection warning message. 2024-04-22 16:26:03 -04:00
986f83653d Added multi-line real-time output for connection rate testing. 2024-04-22 13:56:50 -04:00
3c459f1428 Revised connection rate warning during standard audits. 2024-04-22 11:58:52 -04:00
46b89fff2e Sockets now time out after 30 seconds during connection rate testing. 2024-04-21 17:05:57 -04:00
81718d1948 Fixed non-interactive connection rate tests. Revised warning for lack of connection throttling. 2024-04-21 15:08:38 -04:00
8124c8e443 Added aes128-ocb@libassh.org cipher. 2024-04-18 21:09:02 -04:00
b9f569fdf8 Added warnings for Windows platform. 2024-04-18 20:51:14 -04:00
9126ae7d9c Improved DHEat statistics output. 2024-04-18 20:01:28 -04:00
d2f1a295a1 Removed vulture from Tox (it rarely made any findings, and when it did, pylint reported the same issues). 2024-04-18 19:36:13 -04:00
8190fe59d0 Added implementation for DHEat denial-of-service attack (CVE-2002-20001). (#211, #217) 2024-04-18 13:58:13 -04:00
d7f8bf3e6d Updated notes on OpenSSH default key exchanges. (#258) 2024-03-19 18:24:22 -04:00
3d403b1d70 Updated availability of algorithms in Dropbear. (#257) 2024-03-19 15:47:09 -04:00
9fae870260 Added allow_larger_keys flag to custom policies to control whether targets can have larger keys, and added Docker tests to complete work started in PR #242. 2024-03-19 14:45:19 -04:00
20873db596 use less-than instead of not-equal when comparing key sizes (#242)
When evaluating policy compliance, use less-than operator so keys bigger
than expected (and hence very often better) don't fail policy
evaulation. This change reduces the amount of false-positives and allows
for more flexibility when hardening SSH installations.

Signed-off-by: szubersk <szuberskidamian@gmail.com>
2024-03-19 14:38:27 -04:00
3c31934ac7 Added tests and other cleanups resulting from merging PR #252. 2024-03-18 17:48:50 -04:00
5bd925ffc6 [WIP] Adding allowed algorithms (#252)
* Added allowed policy fields

Added allowed fields for host keys kex ciphers and macs

* Adapted policy.py to newest dev version

* Added allow_algorithm_subset_and_reordering flag

* Removed allowed policy entries as they are redundant now

* Fixed call to append_error
2024-03-18 17:41:17 -04:00
7b3402b207 Added note that sntrup761x25519-sha512@openssh.com is the default OpenSSH kex since version 9.0. 2024-03-15 17:24:21 -04:00
b2f46eb71a Added extra GSS wildcard matching test. 2024-03-15 17:05:40 -04:00
ab41ca1023 Re-organized README. 2024-03-15 16:28:10 -04:00
b70fb0bc4c Added built-in policies for Amazon Linux 2023, Debian 12, and Rocky Linux 9. 2024-03-15 16:24:36 -04:00
db5104ecb8 Built-in policy change logs no longer printed within quotes. 2024-03-14 18:13:53 -04:00
15078aaea9 Built-in policies now include a change log. 2024-03-14 17:58:16 -04:00
f0874af4cd Split built-in policies from policy.py to builtin_policies.py. 2024-03-14 17:24:40 -04:00
064b55e0c2 Added 1 new key exchange algorithm: gss-nistp384-sha384-* 2024-03-14 16:01:48 -04:00
a4f508374a Updated README. 2024-03-12 21:13:10 -04:00
6f39407a8c use alpine, reduce layers (#249)
Signed-off-by: Daniel Thamdrup <dallemon@protonmail.com>
2024-03-12 21:02:26 -04:00
cb0f6b63d7 Fixed new pylint warnings. 2024-03-12 20:46:39 -04:00
3313046714 Added built-in policy for OpenSSH 9.7. 2024-03-12 20:23:55 -04:00
8ee0deade1 Properly upgrade packages and clean up apt cache in Dockerfile (#218)
Result:
```
REPOSITORY     TAG       IMAGE ID       CREATED              SIZE
ssh-audit      after     03e247aee0cc   About a minute ago   131MB
ssh-audit      before    609962ceafb1   About a minute ago   150MB
```
2024-02-18 10:25:14 -05:00
699739d42a Gracefully handle rare exceptions (i.e.: crashes) while performing GEX tests. 2024-02-17 13:44:06 -05:00
a958fd1fec Snap builds are now architecture-independent. (#232) 2024-02-17 12:54:28 -05:00
c33f419224 Updated '-m', '--manual' description in README. 2024-02-16 23:16:07 -05:00
6ee4899b4f Bumped copyright year. 2024-02-16 23:13:55 -05:00
20fbb706b0 The built-in man page (, ) is now available on Docker, PyPI, and Snap builds, in addition to the Windows build. (#231) 2024-02-16 22:40:53 -05:00
73b669b49d Fixed parsing of ecdsa-sha2-nistp* CA signatures on host keys. Additionally, they are now flagged as potentially back-doored, just as standard host keys are. (#239) 2024-02-16 21:58:51 -05:00
f326d58068 Disable color when the NO_COLOR environment variable is set. (#234) 2024-01-28 18:17:49 -05:00
b72f6a420f Added note regarding general OpenSSH policies failing against platforms with back-ported features. (#236) 2024-01-28 17:37:21 -05:00
fe65b5df8a Added missing dev tag to Change Log: v3.2.0 -> v3.2.0-dev 2023-12-21 15:34:38 -05:00
44393c56b3 Expanded filter of CBC ciphers to flag for the Terrapin vulnerability. 2023-12-21 15:30:43 -05:00
164356e776 Spelling fixes (#233) 2023-12-21 08:58:12 -05:00
c8e075ad13 Bumped version number to v3.2.0-dev. 2023-12-20 15:41:03 -05:00
eebeac99a0 Updated packaging instructions and Docker build steps. 2023-12-20 15:40:01 -05:00
dd91c2a41a Bumped version to 3.1.0 in preparation for stable release. Updated Change Log in README. 2023-12-20 13:12:13 -05:00
bef8c6c0f7 Updated notes on fixing Terrapin vulnerability. 2023-12-20 12:11:55 -05:00
75dbc03a77 Added 'additional_notes' field to JSON output. 2023-12-19 18:03:07 -05:00
c9412cbb88 Added built-in policies for OpenSSH 9.5 and 9.6. 2023-12-19 17:42:43 -05:00
a0f99942a2 Don't recommend enabling the chacha & CBC ciphers, nor ETM MACs in case the user disabled them to address the Terrapin vulnerability. (#229) 2023-12-19 17:16:58 -05:00
c259a83782 Added note that when a target is properly configured against the Terrapin vulnerability that unpatched peers may still create vulnerable connections. Updated Ubuntu Server & Client 20.04 & 22.04 policies to include new key exchange markers related to Terrapin counter-measures. 2023-12-19 14:03:28 -05:00
8e972c5e94 Added test for the Terrapin vulnerability (CVE-2023-48795) (#227). 2023-12-18 18:24:49 -05:00
46eb970376 Removed Python 3.7 from Github Actions testing. 2023-11-27 23:39:48 -05:00
965bcb6b18 Dropped support for Python 3.7. 2023-11-27 23:35:40 -05:00
ba8e8a7e68 Re-organized option host key types for OpenSSH 9.2 to correspond with updated Debian 12 hardening guide. 2023-11-27 21:33:13 -05:00
bad2c9cd8e In Ubuntu 22.04 client policy, moved host key types and to the end of all certificate types. 2023-11-27 20:07:36 -05:00
69e1e121fd In server policies, reduced expected DH modulus sizes from 4096 to 3072 to match online hardening guides. 2023-11-27 19:15:18 -05:00
848052df68 Add cleanup for apt cache files (#215)
* Add cleanup for apt cache files

Adding this command decreases the size of the image.

ssh-audit-new                                           latest                 0c391ba567ee   39 minutes ago   157MB
ssh-audit-old                                           latest                 a425e0043125   40 minutes ago   176MB

* Fix Dockerfile

Forgot to add logical "and" (&&)
2023-10-23 13:51:47 -04:00
d62e4cd80c Added Python 3.12 to Tox tests. 2023-10-22 16:43:04 -04:00
2809ff464a Added --rm to docker run commands so stopped containers are automatically removed. 2023-09-12 08:38:07 -04:00
02ab487232 Bumped version to v3.1.0-dev. 2023-09-07 08:57:59 -04:00
d62acd688e Updated Docker Makefile and packaging instructions. 2023-09-07 08:57:39 -04:00
f517e03d9f Bumped version to v3.0.0. 2023-09-07 07:45:07 -04:00
6c64257d91 Updated README. 2023-09-06 22:37:06 -04:00
982c0b4c72 Docker: Build multi-arch container images for amd64, arm64 and arm/v7 (#194)
* builds multi-arch container images for linux/{amd64,arm64,arm/v7}

* adds local-build build target for easier local testing
2023-09-06 22:32:18 -04:00
e26597a7aa Marked all NIST K-, B-, and T-curves as unproven since they are so rarely used. Added 12 new host keys: 'ecdsa-sha2-curve25519', 'ecdsa-sha2-nistb233', 'ecdsa-sha2-nistb409', 'ecdsa-sha2-nistk163', 'ecdsa-sha2-nistk233', 'ecdsa-sha2-nistk283', 'ecdsa-sha2-nistk409', 'ecdsa-sha2-nistp224', 'ecdsa-sha2-nistp192', 'ecdsa-sha2-nistt571', 'ssh-dsa', 'x509v3-sign-rsa-sha256'. Added 15 key exchanges: 'curve448-sha512@libssh.org', 'ecdh-nistp256-kyber-512r3-sha256-d00@openquantumsafe.org', 'ecdh-nistp384-kyber-768r3-sha384-d00@openquantumsafe.org', 'ecdh-nistp521-kyber-1024r3-sha512-d00@openquantumsafe.org', 'ecdh-sha2-brainpoolp256r1@genua.de', 'ecdh-sha2-brainpoolp384r1@genua.de', 'ecdh-sha2-brainpoolp521r1@genua.de', 'kexAlgoDH14SHA1', 'kexAlgoDH1SHA1', 'kexAlgoECDH256', 'kexAlgoECDH384', 'kexAlgoECDH521', 'sm2kep-sha2-nistp256', 'x25519-kyber-512r3-sha256-d00@amazon.com', 'x25519-kyber512-sha512@aws.amazon.com'. Added 8 new ciphers: 'aes192-gcm@openssh.com', 'cast128-12-cbc', 'cast128-12-cfb', 'cast128-12-ecb', 'cast128-12-ofb', 'des-cfb', 'des-ecb', 'des-ofb'. Added 14 new MACs: 'cbcmac-3des', 'cbcmac-aes', 'cbcmac-blowfish', 'cbcmac-des', 'cbcmac-rijndael', 'cbcmac-twofish', 'hmac-sha256-96', 'md5', 'md5-8', 'ripemd160', 'ripemd160-8', 'sha1', 'sha1-8', 'umac-128'. 2023-09-05 20:10:37 -04:00
f8e29674a3 Refined JSON notes output. Fixed Docker & Tox tests. 2023-09-05 16:36:54 -04:00
d3dd5a9cac Improved JSON output (#185) 2023-09-05 16:16:23 -04:00
79ca4b2d8b Updated README. 2023-09-05 14:22:35 -04:00
884ef645f8 Prioritized certificate host key types for Ubuntu 22.04 client policy. (#193) 2023-09-05 14:01:51 -04:00
953683a762 Fixed most warnings from Shellcheck scans. (#197) 2023-09-05 13:14:21 -04:00
38f9c21760 The color of all notes will be printed in green when the related algorithm is rated good. 2023-09-03 19:14:25 -04:00
4e6169d0cb Added built-in policy for OpenSSH 9.4. 2023-09-03 18:12:16 -04:00
2867c65819 Perform full Docker image update when building. 2023-09-03 18:07:30 -04:00
77cdb969b9 Fixed flake8 tests. 2023-09-03 16:25:26 -04:00
199e75f6cd Refined GEX testing against OpenSSH servers: when the fallback mechanism is suspected of being triggered, perform an additional test to obtain more accurate results. 2023-09-03 16:13:00 -04:00
3f2fdbaa3d Fixed crash during GEX tests. 2023-07-11 11:08:42 -04:00
83e90729e2 Updated README. 2023-06-20 16:12:30 -04:00
83f9e48271 Recommendation output now respects level (#196) 2023-06-20 16:09:37 -04:00
e2fc60cbb4 Updated README and test for resolve function. 2023-06-20 09:26:43 -04:00
a74c3abdde Removed sys.exit from _resolve in ssh_socket.py (#187)
Changed (and documented) _resolve so the application does not quit when a hostname cannot be resolved.

Adapted connect function to expect incoming exceptions from _resolve

This fixes issue #186
2023-06-20 09:21:06 -04:00
e99cb0b579 Now prints the reason why socket listening operations fail. 2023-06-20 08:43:11 -04:00
639f11a5e5 Results from concurrent scans against multiple hosts are no longer improperly combined (#190). 2023-06-19 14:13:32 -04:00
521a50a796 Added 'curve448-sha512@libssh.org' kex. (#195) 2023-06-19 10:35:13 -04:00
2d5a97841f Bumped version to 3.0.0-dev. 2023-04-29 14:46:07 -04:00
54b8c7da02 Updated PyPI and Snap build processes. 2023-04-29 14:42:54 -04:00
3ba28b01e9 Added release date of v2.9.0. 2023-04-29 12:39:04 -04:00
3c1451cfdc Bumped version to v2.9.0. 2023-04-29 12:33:26 -04:00
929652c9b7 Simplified host key test logic. 2023-04-29 11:59:50 -04:00
e172932977 RSA key size comments duplicated for all RSA sig algs (#182)
* RSA key size comments duplicated for all RSA sig algs

* Save results on completion of testing a hostkey

* Revised list names because they operates against all keys now not just rsa.

* ensure all required fields added for non-rsa keys

* Correction to the saving of comments against non-rsa keys
2023-04-29 11:39:29 -04:00
c33e7d9b72 Added built-in policies for OpenSSH 8.8, 8.9, 9.0, 9.1, 9.2, and 9.3. 2023-04-27 21:40:47 -04:00
0074fcc1af Rolled back Windows multithreading crash fix, as upgrading from Python v3.9 to v3.11 may have fixed the root cause. (#152) 2023-04-26 21:55:40 -04:00
1eab4ab0e6 Updated README. 2023-04-26 15:49:45 -04:00
7f8d6b4d5b Fixed built-in policy formatting and filled in missing host key size information. 2023-04-26 15:47:58 -04:00
4c098b7d12 Windows build script now automatically installs/updates package dependencies. 2023-04-25 20:14:49 -04:00
0bfb5d6979 Updated snap base image. Now installing snapcraft tool from snap instead of apt. 2023-04-25 11:54:12 -04:00
a5f5e0dab2 Updated changelog. 2023-04-25 10:25:06 -04:00
05f159a152 Fixed Windows-specific crash when multiple threads are used (#152). 2023-04-25 10:18:45 -04:00
263267c5ad Added support for mixed host key/CA key types (i.e.: RSA host keys signed by ED25519 CAs) (#120). 2023-04-25 09:17:32 -04:00
4f31304b66 Alphabetized algorithm database. 2023-03-28 12:09:25 -04:00
6f05a2c6b5 Updated README. 2023-03-25 14:15:53 -04:00
784d412148 Added Repology table. 2023-03-24 19:22:45 -04:00
dc083de87e Added recommendations and CVE information to JSON output (#122). 2023-03-24 18:48:36 -04:00
7d5eb37a0f Updated colorama initialization. 2023-03-24 16:43:38 -04:00
5c1c447755 Updated testing descriptions. 2023-03-24 14:12:03 -04:00
cbb7d43006 Updated base image. Removed all suid & sgid bits from image. Drop root privileges by default. 2023-03-23 23:43:52 -04:00
cc9e4fbc4a Generic failure/warning messages replaced with more specific reasons. SHA-1 algorithms now cause failures. CBC mode ciphers are now warnings instead of failures. 2023-03-23 21:36:02 -04:00
992aa1b961 Added support for kex GSS wildcards (#143). 2023-03-21 22:17:23 -04:00
413dea60ae Fixed docker tests affected by previous commit. 2023-03-21 14:58:00 -04:00
e2a9896397 Deprecation of ssh-rsa signature algorithm in OpenSSH 8.8 (#171) 2023-03-21 14:52:23 -04:00
71feaa191e Add note regarding OpenSSH's 2048-bit GEX fallback, and suppress the related recommendation since the user cannot control it (partly related to #168). 2023-03-21 11:44:45 -04:00
c02ab8f170 Added --accept option to automatically update failed tests. 2023-03-21 11:28:52 -04:00
cdaee69642 Improved debugging output. 2023-03-21 10:48:58 -04:00
7bbf4cdff0 Fix tox tests. 2023-02-06 18:24:03 -05:00
e4d864c6c1 usage now respects no color (#162)
* usage now respects no color

* Removed superfluous parens after 'not'
2023-02-06 18:20:34 -05:00
1663e5bdcf Fixed setuptools config file. 2023-02-06 16:57:24 -05:00
5ecad8fac9 Bumped copyright year. 2023-02-06 16:49:25 -05:00
38ff225ed8 Updated supported Python versions. 2023-02-06 16:48:53 -05:00
c9dc9a9c10 Now issues a warning when 2048-bit moduli are encountered. 2023-02-06 16:27:30 -05:00
f9e00b6f2d Renamed WARN_CURVES_WEAK to FAIL_CURVES_WEAK. 2023-02-03 17:22:10 -05:00
433c7e779d Added 2 new ciphers: 'rijndael-cbc@ssh.com', 'cast128-12-cbc@ssh.com'. Added 21 new host key types: . 2023-02-02 18:57:53 -05:00
984ea1eee3 Added the following 9 new host key types: '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'. Added the following 22 new key exchange algorithms: 'diffie-hellman-group-exchange-sha224@ssh.com', 'diffie-hellman-group-exchange-sha384@ssh.com', 'diffie-hellman-group14-sha224@ssh.com', 'diffie-hellman_group17-sha512', 'ecmqv-sha2', 'gss-13.3.132.0.10-sha256-*', 'gss-curve25519-sha256-*', 'gss-curve448-sha512-*', 'gss-gex-sha1-*', 'gss-gex-sha256-*', 'gss-group1-sha1-*', 'gss-group14-sha1-*', 'gss-group14-sha256-*', 'gss-group15-sha512-*', 'gss-group16-sha512-*', 'gss-group17-sha512-*', 'gss-group18-sha512-*', 'gss-nistp256-sha256-*', 'gss-nistp384-sha256-*', 'gss-nistp521-sha512-*', 'm383-sha384@libassh.org', 'm511-sha512@libassh.org'. Added the following 26 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', 'idea-cfb', 'idea-ecb', 'idea-ofb', 'seed-ctr@ssh.com', 'serpent128-gcm@libassh.org', 'serpent256-gcm@libassh.org', 'twofish-cfb', 'twofish-ecb', 'twofish-ofb', 'twofish128-gcm@libassh.org', 'twofish256-gcm@libassh.org'. Added the following 4 new HMAC algorithms: 'hmac-sha224@ssh.com', 'hmac-sha256-2@ssh.com', 'hmac-sha384@ssh.com', 'hmac-whirlpool'. 2023-02-02 18:30:40 -05:00
0b905a7fdd Added Ubuntu Client 22.04 hardening policy. 2023-02-01 19:29:54 -05:00
6e9283e643 Removed unused CI configs. 2023-02-01 18:00:41 -05:00
32ff04c2cc Added Tox testing for Python 3.11. Fixed flake8 & pylint errors. 2023-02-01 17:56:54 -05:00
e50ac5c84d Gex test usage text (#158)
* Reformatted Usage Text for --gex-test in README.md

* Reformatted Usage Text for --gex-test in ssh_audit.py

Reformatted to adhere to a max line length of 80 characters.
2022-10-27 10:11:05 -04:00
29496b43d5 updated vulnerability database (#157)
* updated vulnerability database

* added info for CVE-2021-36367
2022-10-27 10:10:17 -04:00
3300c60aaa Added 'ssh-xmss@openssh.com' and 'ssh-xmss-cert-v01@openssh.com' experimental host keys (#146). 2022-10-14 23:21:09 -04:00
78a9475a32 Added hmac-sha1-96@openssh.com MAC. (#148) 2022-10-14 22:56:02 -04:00
8d861dcdc6 Removed pytest version pin from Tox. 2022-10-10 21:28:51 -04:00
c50cc040c2 Upgrade all Tox dependencies before running Tox. 2022-10-10 21:06:03 -04:00
93f0692444 Enabled Python 3.10 tests in Tox. 2022-10-10 21:00:05 -04:00
6e9945337e Removed CI tests for Python 3.6. 2022-10-10 20:52:46 -04:00
d429b543d0 Added support for host key 'webauthn-sk-ecdsa-sha2-nistp256@openssh.com' (#149). 2022-10-10 20:51:37 -04:00
b9520cbc25 Fixed pylint & flake8 warnings and errors. 2022-10-10 20:40:29 -04:00
0b8ecf2fb5 Added Ubuntu Server 22.04 LTS hardening policy. 2022-10-10 20:34:28 -04:00
eb4ae65b0a Usage now includes '-g' and '--gex-test' parameters 2022-04-10 12:37:48 -04:00
113d1de443 Removed experimental warning tag from sntrup761x25519-sha512@openssh.com. 2022-04-10 12:16:25 -04:00
4d89f9b30b Updated example. 2022-03-24 10:53:47 -04:00
11905ed44a Fixed pylint errors, consolidated error checking for granular GEX tests, renamed functions for better readability. 2022-03-24 10:53:47 -04:00
19f192d21f Corrected accidental text update and a minor typo. 2022-03-24 10:53:47 -04:00
5ac0ffa8f1 DH GEX Modulus Size Testing 2022-03-24 10:53:47 -04:00
0a6ac5de54 Updated CVE vulnerability flag. 2022-02-21 21:51:35 -05:00
c6b8dc97e1 Fixed tests. 2022-02-21 21:48:10 -05:00
1bdf7029b4 add a bunch of openssh CVEs (#126) 2022-02-21 21:41:44 -05:00
5fbcb1b90f Added 24 new key exchanges: 'ecdh-sha2-1.3.132.0.1', 'ecdh-sha2-1.2.840.10045.3.1.1', 'ecdh-sha2-1.3.132.0.33', 'ecdh-sha2-1.3.132.0.26', 'ecdh-sha2-1.3.132.0.27', 'ecdh-sha2-1.2.840.10045.3.1.7', 'ecdh-sha2-1.3.132.0.16', 'ecdh-sha2-1.3.132.0.34', 'ecdh-sha2-1.3.132.0.36', 'ecdh-sha2-1.3.132.0.37', 'ecdh-sha2-1.3.132.0.35', 'ecdh-sha2-1.3.132.0.38', 'ecdh-sha2-4MHB+NBt3AlaSRQ7MnB4cg==', 'ecdh-sha2-5pPrSUQtIaTjUSt5VZNBjg==', 'ecdh-sha2-VqBg4QRPjxx1EXZdV0GdWQ==', 'ecdh-sha2-zD/b3hu/71952ArpUG4OjQ==', 'ecdh-sha2-qCbG5Cn/jjsZ7nBeR7EnOA==', 'ecdh-sha2-9UzNcgwTlEnSCECZa7V1mw==', 'ecdh-sha2-wiRIU8TKjMZ418sMqlqtvQ==', 'ecdh-sha2-qcFQaMAMGhTziMT0z+Tuzw==', 'ecdh-sha2-m/FtSAmrV4j/Wy6RVUaK7A==', 'ecdh-sha2-D3FefCjYoJ/kfXgAyLddYA==', 'ecdh-sha2-h/SsxnLCtRBh7I9ATyeB3A==', 'ecdh-sha2-mNVwCXAoS1HGmHpLvBC94w=='. 2021-10-20 22:25:20 -04:00
b04acc3737 Updated README. 2021-10-15 00:19:04 -04:00
4ace52a190 Now prints a more user-friendly error message when installed as a Snap package and permission errors are encountered. Updated the Snap build process as well. 2021-10-14 23:56:03 -04:00
22a9559a82 Now supports Python 3.10. 2021-10-14 00:01:23 -04:00
57e6c0246d Updated pylint disable list. 2021-10-13 23:55:49 -04:00
80a718a5af Fixed broken Python 3.10 config. 2021-10-13 23:46:50 -04:00
1f0b3acff2 Complete "target" in the JSON output with the port (#123)
* Complete "target" in JSON output with the port

The JSON output was not showing the port of the target which was scanned. This could be problematic when scanning a host with more than one ssh service running.

* Docker tests completet with the port of the scan target in the JSON output
2021-10-13 23:44:55 -04:00
cdc379d6df Added Python 3.10 to Github Actions testing. 2021-10-07 11:06:32 -04:00
9f87acfc74 Bumped version to v2.6.0-dev. 2021-08-27 11:25:27 -04:00
597b500eba Minor cleanups (#116)
* docker_test.sh: fix shellcheck warnings

* docker_test.sh: unify style

No changes in functionality.

* docker_test.sh: whitespace fixes

* stop mixing tabs and spaces
* remove trailing whitespace

* invoke bash using /usr/bin/env

* build_windows_executable.sh: fix variable assignment

* update_windows_man_page.sh: unify style

No changes in functionality.

* whitespace fixes

* stop mixing tabs and spaces
* remove trailing whitespace

* fix spelling

* remove trailing whitespace
2021-08-27 11:19:18 -04:00
96efb3efb4 Bumped copyright year. 2021-08-26 16:44:06 -04:00
ce5939856c Removed Homebrew from list of pre-built packages. 2021-08-26 16:36:31 -04:00
7f74731351 Bumped version number. 2021-08-26 16:36:06 -04:00
8c4855ffa2 Updated Snap notes. 2021-08-26 16:35:53 -04:00
4f2f995b62 Bumped version to v2.5.0. 2021-08-26 15:24:34 -04:00
134236fa7f Fixed badge link. 2021-08-26 14:39:24 -04:00
a6b658d194 Updated badges. 2021-08-26 13:12:13 -04:00
297a807f88 Added Github Actions support. 2021-08-26 12:47:48 -04:00
20d94df400 Updated Windows packaging instructions. 2021-08-26 12:18:06 -04:00
b76060cf49 Updated Tox test section. 2021-08-26 12:16:39 -04:00
1cf1c874db Added Python 3.10 support. 2021-08-26 10:56:43 -04:00
992d8233c9 Remove cache files created during build. 2021-08-26 10:47:43 -04:00
f377b7cea3 Now prompts user for release version, cleans up cached files from previous invokation, and resets all local changes upon completion. 2021-08-26 10:39:11 -04:00
70d9ab2e6b Check if -dev is in version string. (#106) 2021-08-25 14:24:10 -04:00
e7d320f602 Fixed new pylint warnings. 2021-08-25 13:28:30 -04:00
682cb66f85 Added OpenSSH v8.6 & v8.7 policies. 2021-08-25 12:30:38 -04:00
076681a671 Added 3 new key exchanges: gss-gex-sha1-eipGX3TCiQSrx573bT1o1Q==, gss-group1-sha1-eipGX3TCiQSrx573bT1o1Q==, gss-group14-sha1-eipGX3TCiQSrx573bT1o1Q== 2021-07-08 10:18:25 -04:00
98a1fb0315 Added two new MACs: 'AEAD_AES_128_GCM', and 'AEAD_AES_256_GCM'. 2021-06-28 21:59:41 -04:00
45da9f20ae Added 'rsa-sha2-512' and 'rsa-sha2-256' to OpenSSH 8.1 (and earlier) policies. 2021-05-31 15:49:56 -04:00
aa21df29e7 Now handles exceptions during server KEX parsing more gracefully. 2021-05-24 19:50:25 -04:00
32ed9242af Now prints JSON with indents when is used (useful for debugging). 2021-05-20 19:04:35 -04:00
07862489c4 Added MD5 fingerprint hashes to verbose output. 2021-05-20 18:03:24 -04:00
e508a963e7 Added 1 new MAC: hmac-ripemd160-96. 2021-05-20 14:17:37 -04:00
2f1a2a60b1 Added ToC to README.md (#101) 2021-03-04 18:23:12 -05:00
5eb669e01c Updated README. 2021-03-02 11:27:40 -05:00
8e9fe20fac SSH_Socket's constructor now takes an OutputBuffer for verbose & debugging output. 2021-03-02 11:25:37 -05:00
83bd049486 Debug Logging and visibility of SSH Connection errors (#99)
* Debug Logging and visibility of SSH Connection errors

* Updated date in man page
2021-03-02 11:06:40 -05:00
c483fe1861 Fixed a crash while doing host key tests. 2021-02-26 16:01:30 -05:00
741bd631e2 Updated packaging instructions. 2021-02-24 10:18:12 -05:00
f96c0501e9 Bumped version number. 2021-02-23 20:39:18 -05:00
446a411424 Added build_windows_executable.sh. 2021-02-23 19:54:12 -05:00
b300ad1252 Refactored IPv4/6 preference logic to fix pylint warnings. 2021-02-23 16:05:01 -05:00
1bbc3feb57 Added OpenSSH 8.5 built-in policy. Added sntrup761x25519-sha512@openssh.com kex. 2021-02-23 16:02:20 -05:00
8f9771c4e6 Added markdown to PACKAGING. 2021-02-23 09:46:58 -05:00
8a8c284d9a Colour no longer disabled on older vers of Windows. If ssh-audit invoked with a manual parameter and the colorama library was not imported then colour output is disabled. (#95) 2021-02-18 14:52:08 -05:00
1b7cfbec71 Disable color output on Windows 8 and Windows Server 2012. 2021-02-06 11:03:39 -05:00
3c0fc8ead4 Updated README. 2021-02-05 22:12:27 -05:00
ef831d17e0 When -n/--no-colors is used, strip out color from Windows man page. 2021-02-05 21:45:56 -05:00
36094611ce Fixed unicode errors when printing the man page on Windows. 2021-02-05 20:39:12 -05:00
49cf91a902 No longer ignoring mypy and pylint results. 2021-02-05 16:26:14 -05:00
11e2e77585 Simplified Windows man page processing. Added Cygwin support to update_windows_man_page.sh. 2021-02-05 16:25:04 -05:00
090b5d760b Man Page on Windows (#93)
* Man Page on Windows

* Corrected typo in update_windows_man_page.sh

* Check that the 'sed' (stream editor) binary exists
2021-02-05 15:43:50 -05:00
7878d66a46 Now using Python 3.9 base image. 2021-02-02 13:25:52 -05:00
730d6904c2 Updated README. 2021-02-02 12:22:50 -05:00
e0f0956edc Added extra warnings for SSHv1. (#6) 2021-02-02 12:20:37 -05:00
d42725652f Updated README. 2021-02-02 09:54:10 -05:00
6b67a2efb3 Add your local server config to .gitignore (#84) 2021-02-01 19:26:57 -05:00
c49a0fb22f Upgraded SHA-1 key signatures from warnings to failures. Added deprecation warning to ssh-rsa-cert-v00@openssh.com, ssh-rsa-cert-v01@openssh.com, x509v3-sign-rsa, and x509v3-ssh-rsa host key types. 2021-02-01 19:19:46 -05:00
dbe14a075e Added future deprecation notice of ssh-rsa (#92) 2021-02-01 13:17:46 -05:00
13d15baa2a Added multi-threaded scanning support. 2021-02-01 13:10:06 -05:00
bbb81e24ab Streamlined sending of KEXINIT messages. 2021-01-21 11:23:40 -05:00
bbbd75ee69 Tox will now fail on pylint or typing problems. 2021-01-21 10:47:52 -05:00
60de5e55cb Transformed comment type annotations to variable declaration annotations. 2021-01-21 10:20:48 -05:00
4e2f9da632 Updated README. 2021-01-21 07:53:09 -05:00
287c551ff8 Removed Python 3.5 support. 2021-01-20 20:47:26 -05:00
d9a4b49560 Removed Python 3.5 support. Added ARM64 testing in Travis. 2021-01-20 15:58:48 -05:00
a4c78512d8 Add support to ppc64le (#88) 2021-01-20 15:54:55 -05:00
1ba4c7c7ca Send KEX before reading server's KEX during host key and GEX tests; this prevents deadlock against certain server implementations. 2021-01-20 15:27:38 -05:00
338ffc5adb Fixed crash when receiving unexpected response during host key test. 2020-11-05 20:29:39 -05:00
52d1e8f27b Fixed pylint warning. 2020-11-05 20:28:14 -05:00
00dc22b00b Delete output directory only upon successful run to make debugging easier. 2020-11-05 20:25:34 -05:00
0d9881966c Added version check for OpenSSH user enumeration (CVE-2018-15473). (#83) 2020-11-05 20:24:09 -05:00
5c8dc5105b Bumped version number. 2020-11-05 20:16:35 -05:00
75be333bd2 Updated packaging instructions and merged Windows instructions. 2020-10-28 21:01:47 -04:00
119 changed files with 11106 additions and 2139 deletions

View File

@ -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\*

24
.github/workflows/tox.yaml vendored Normal file
View File

@ -0,0 +1,24 @@
name: ssh-audit
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -U codecov coveralls flake8 mypy pylint pytest tox
- name: Run Tox
run: |
tox

3
.gitignore vendored
View File

@ -22,3 +22,6 @@ reports/
/snap/ /snap/
/stage/ /stage/
/ssh-audit_*.snap /ssh-audit_*.snap
# Your local server config
servers.txt

View File

@ -1,20 +0,0 @@
language: python
python:
- "3.5"
- "3.6"
- "3.7"
- "3.8"
- "3.9"
cache:
- pip
install:
- pip install -U pip tox tox-travis coveralls codecov
script:
- tox
after_success:
- codecov

View File

@ -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,34 +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/).
### Running tests on Ubuntu 18.04 and later 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.
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.
### Running tests on Ubuntu 16.04
For Ubuntu 16.04 (which is still supported until April 2021), a newer version of tox is needed. The easiest way is to use virtualenv:
```
$ sudo apt install python3-virtualenv
$ virtualenv -p /usr/bin/python3 ~/venv_ssh-audit
$ source ~/venv_ssh-audit/bin/activate
$ pip install tox
```
Then, to run the tox tests:
```
$ source ~/venv_ssh-audit/bin/activate
$ cd path/to/ssh-audit
$ tox
```
## 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

View File

@ -1,10 +1,24 @@
FROM python:3.8-slim # syntax=docker/dockerfile:latest
FROM scratch AS files
WORKDIR / # Copy ssh-audit code to temporary container
COPY ssh-audit.py /
COPY src/ /
COPY ssh-audit.py . FROM python:3-alpine AS runtime
COPY src/ .
# Update the image to remediate any vulnerabilities.
RUN apk upgrade -U --no-cache -a -l && \
# Remove suid & sgid bits from all files.
find / -xdev -perm /6000 -exec chmod ug-s {} \; 2> /dev/null || true
# Copy the ssh-audit code from files container.
COPY --from=files / /
# Allow listening on 2222/tcp for client auditing.
EXPOSE 2222
# Drop root privileges.
USER nobody:nogroup
ENTRYPOINT ["python3", "/ssh-audit.py"] ENTRYPOINT ["python3", "/ssh-audit.py"]
EXPOSE 2222

View File

@ -1,6 +1,6 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (C) 2017-2020 Joe Testa (jtesta@positronsecurity.com) Copyright (C) 2017-2024 Joe Testa (jtesta@positronsecurity.com)
Copyright (C) 2017 Andris Raugulis (moo@arthepsy.eu) Copyright (C) 2017 Andris Raugulis (moo@arthepsy.eu)

View File

@ -4,10 +4,25 @@ ifeq ($(VERSION),)
endif endif
all: all:
docker build -t positronsecurity/ssh-audit:${VERSION} . ./add_builtin_man_page.sh
docker tag positronsecurity/ssh-audit:${VERSION} positronsecurity/ssh-audit:latest docker buildx create --name multiarch --use || exit 0
docker buildx build \
--platform linux/amd64,linux/arm64,linux/arm/v7 \
--tag positronsecurity/ssh-audit:${VERSION} \
--tag positronsecurity/ssh-audit:latest \
.
docker buildx build \
--tag positronsecurity/ssh-audit:${VERSION} \
--tag positronsecurity/ssh-audit:latest \
--load \
--builder=multiarch \
.
upload: upload:
docker login docker login -u positronsecurity
docker push positronsecurity/ssh-audit:${VERSION} docker buildx build \
docker push positronsecurity/ssh-audit:latest --platform linux/amd64,linux/arm64,linux/arm/v7 \
--tag positronsecurity/ssh-audit:${VERSION} \
--tag positronsecurity/ssh-audit:latest \
--push \
.

View File

@ -1,12 +1,13 @@
all: all:
./add_builtin_man_page.sh
rm -rf /tmp/pypi_upload rm -rf /tmp/pypi_upload
virtualenv -p /usr/bin/python3 /tmp/pypi_upload/ virtualenv -p /usr/bin/python3 /tmp/pypi_upload/
cp -R src /tmp/pypi_upload/ cp -R src /tmp/pypi_upload/
cp setup.py setup.cfg README.md LICENSE /tmp/pypi_upload/ cp setup.py setup.cfg README.md LICENSE /tmp/pypi_upload/
/bin/bash -c "pushd /tmp/pypi_upload/; source bin/activate; pip3 install setuptools twine; python3 setup.py sdist bdist_wheel" /bin/bash -c "pushd /tmp/pypi_upload/; source bin/activate; pip3 install -U setuptools twine build; pip3 install -U requests_toolbelt; python3 -m build"
uploadtest: uploadtest:
/bin/bash -c "pushd /tmp/pypi_upload; source bin/activate; twine upload --repository-url https://test.pypi.org/legacy/ /tmp/pypi_upload/dist/*" /bin/bash -c "pushd /tmp/pypi_upload; source bin/activate; python3 -m twine upload --repository testpypi /tmp/pypi_upload/dist/*"
uploadprod: uploadprod:
/bin/bash -c "pushd /tmp/pypi_upload; source bin/activate; twine upload /tmp/pypi_upload/dist/*" /bin/bash -c "pushd /tmp/pypi_upload; source bin/activate; twine upload /tmp/pypi_upload/dist/*"

View File

@ -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

View File

@ -1,52 +0,0 @@
= PyPI =
To create package and upload to test server:
$ sudo apt install python3-virtualenv
$ make -f Makefile.pypi
$ make -f Makefile.pypi uploadtest
To download from test server and verify:
$ virtualenv -p /usr/bin/python3 /tmp/pypi_test
$ cd /tmp/pypi_test; source bin/activate
$ pip3 install --index-url https://test.pypi.org/simple ssh-audit
To upload to production server (hint: use username '__token__' and API token):
$ make -f Makefile.pypi uploadprod
To download from production server and verify:
$ virtualenv -p /usr/bin/python3 /tmp/pypi_prod
$ cd /tmp/pypi_prod; source bin/activate
$ pip3 install ssh-audit
----
= Snap =
To create the snap package, run a fully-updated Ubuntu Server 20.04 VM.
As root, run (leave all options default):
# lxd init
Bump the version number in snapcraft.yaml. Then run:
# make -f Makefile.snap
----
= Docker =
Build image with:
$ make -f Makefile.docker
Then upload them to Dockerhub with:
$ make -f Makefile.docker upload

83
PACKAGING.md Normal file
View File

@ -0,0 +1,83 @@
# Windows
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.x from https://www.python.org/. To make life easier, check the option to add Python to the PATH environment variable.
2.) Install Cygwin (https://www.cygwin.com/).
3.) Install/update package dependencies and create the executable with:
```
$ ./build_windows_executable.sh
```
# PyPI
To create package and upload to test server (hint: use username '\_\_token\_\_' and API token for test.pypi.org):
```
$ sudo apt install python3-virtualenv python3.10-venv
$ make -f Makefile.pypi
$ make -f Makefile.pypi uploadtest
```
To download from test server and verify:
```
$ virtualenv -p /usr/bin/python3 /tmp/pypi_test
$ cd /tmp/pypi_test; source bin/activate
$ pip3 install --index-url https://test.pypi.org/simple ssh-audit
```
To upload to production server (hint: use username '\_\_token\_\_' and API token for production pypi.org):
```
$ make -f Makefile.pypi uploadprod
```
To download from production server and verify:
```
$ virtualenv -p /usr/bin/python3 /tmp/pypi_prod
$ cd /tmp/pypi_prod; source bin/activate
$ pip3 install ssh-audit
```
# Snap
To create the snap package, run a fully-updated Ubuntu Server 22.04 VM.
Create the snap package with:
```
$ ./build_snap.sh
```
Upload the snap with:
```
$ snapcraft export-login ~/snap_creds.txt
$ export SNAPCRAFT_STORE_CREDENTIALS=$(cat ~/snap_creds.txt)
$ snapcraft upload --release=beta ssh-audit_*.snap
$ snapcraft status ssh-audit # Note the revision number of the beta channel.
$ snapcraft release ssh-audit X stable # Fill in with the revision number.
```
# Docker
Ensure that the buildx plugin is available by following the installation instructions available at: https://docs.docker.com/engine/install/ubuntu/
Build a local image with:
```
$ make -f Makefile.docker
```
Create a multi-architecture build and upload it to Dockerhub with (hint: use the API token as the password):
```
$ make -f Makefile.docker upload
```

203
README.md
View File

@ -1,14 +1,25 @@
# ssh-audit # ssh-audit
[![Build Status](https://travis-ci.org/jtesta/ssh-audit.svg?branch=master)](https://travis-ci.org/jtesta/ssh-audit) [![License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](https://github.com/jtesta/ssh-audit/blob/master/LICENSE)
<!-- [![PyPI Downloads](https://img.shields.io/pypi/dm/ssh-audit)](https://pypi.org/project/ssh-audit/)
[![appveyor build status](https://ci.appveyor.com/api/projects/status/4m5r73m0r023edil/branch/develop?svg=true)](https://ci.appveyor.com/project/arthepsy/ssh-audit) [![Docker Pulls](https://img.shields.io/docker/pulls/positronsecurity/ssh-audit)](https://hub.docker.com/r/positronsecurity/ssh-audit)
[![codecov](https://codecov.io/gh/arthepsy/ssh-audit/branch/develop/graph/badge.svg)](https://codecov.io/gh/arthepsy/ssh-audit) [![Build Status](https://github.com/jtesta/ssh-audit/actions/workflows/tox.yaml/badge.svg)](https://github.com/jtesta/ssh-audit/actions)
[![Quality Gate](https://sonarqube.com/api/badges/gate?key=arthepsy-github%3Assh-audit%3Adevelop&template=ROUNDED)](https://sq.evolutiongaming.com/dashboard?id=arthepsy-github%3Assh-audit%3Adevelop) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/jtesta/ssh-audit/blob/master/CONTRIBUTING.md)
-->
**ssh-audit** is a tool for ssh server & client configuration auditing. **ssh-audit** is a tool for ssh server & client configuration auditing.
[jtesta/ssh-audit](https://github.com/jtesta/ssh-audit/) (v2.0+) is the updated and maintained version of ssh-audit forked from [arthepsy/ssh-audit](https://github.com/arthepsy/ssh-audit) (v1.x) due to inactivity. [jtesta/ssh-audit](https://github.com/jtesta/ssh-audit/) (v2.0+) is the updated and maintained version of ssh-audit forked from [arthepsy/ssh-audit](https://github.com/arthepsy/ssh-audit) (v1.x) due to inactivity.
- [Features](#features)
- [Usage](#usage)
- [Screenshots](#screenshots)
- [Server Standard Audit Example](#server-standard-audit-example)
- [Server Policy Audit Example](#server-policy-audit-example)
- [Client Standard Audit Example](#client-standard-audit-example)
- [Hardening Guides](#hardening-guides)
- [Pre-Built Packages](#pre-built-packages)
- [Web Front-End](#web-front-end)
- [ChangeLog](#changelog)
## Features ## Features
- SSH1 and SSH2 protocol server support; - SSH1 and SSH2 protocol server support;
- analyze SSH client configuration; - analyze SSH client configuration;
@ -21,6 +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.8 - 3.12;
- no dependencies - no dependencies
## Usage ## Usage
@ -36,11 +48,33 @@ usage: ssh-audit.py [options] <host>
-c, --client-audit starts a server on port 2222 to audit client -c, --client-audit starts a server on port 2222 to audit client
software config (use -p to change port; software config (use -p to change port;
use -t to change timeout) use -t to change timeout)
-j, --json JSON output --conn-rate-test=N[:max_rate] perform a connection rate test (useful
for collecting metrics related to
susceptibility of the DHEat vuln).
Testing is conducted with N concurrent
sockets with an optional maximum rate
of connections per second.
-d, --debug Enable debug output.
--dheat=N[:kex[:e_len]] continuously perform the DHEat DoS attack
(CVE-2002-20001) against the target using N
concurrent sockets. Optionally, a specific
key exchange algorithm can be specified
instead of allowing it to be automatically
chosen. Additionally, a small length of
the fake e value sent to the server can
be chosen for a more efficient attack (such
as 4).
-g, --gex-test=<x[,y,...]> dh gex modulus size test
<min1:pref1:max1[,min2:pref2:max2,...]>
<x-y[:step]>
-j, --json JSON output (use -jj to enable indents)
-l, --level=<level> minimum output level (info|warn|fail) -l, --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. Use with -v
to view policy change logs.
--lookup=<alg1,alg2,...> looks up an algorithm(s) without --lookup=<alg1,alg2,...> looks up an algorithm(s) without
connecting to a server connecting to a server
-m, --manual print the man page (Docker, PyPI, Snap, and Windows
builds only)
-M, --make-policy=<policy.txt> creates a policy based on the target server -M, --make-policy=<policy.txt> creates a policy based on the target server
(i.e.: the target server has the ideal (i.e.: the target server has the ideal
configuration that other servers should configuration that other servers should
@ -49,15 +83,20 @@ usage: ssh-audit.py [options] <host>
-p, --port=<port> port to connect -p, --port=<port> port to connect
-P, --policy=<"policy name" | policy.txt> run a policy test using the -P, --policy=<"policy name" | policy.txt> run a policy test using the
specified policy specified policy
--skip-rate-test skip the connection rate test during standard audits
(used to safely infer whether the DHEat attack
is viable)
-t, --timeout=<secs> timeout (in seconds) for connection and reading -t, --timeout=<secs> timeout (in seconds) for connection and reading
(default: 5) (default: 5)
-T, --targets=<hosts.txt> a file containing a list of target hosts (one -T, --targets=<hosts.txt> a file containing a list of target hosts (one
per line, format HOST[:PORT]) per line, format HOST[:PORT])
--threads=<threads> number of threads to use when scanning multiple
targets (-T/--targets) (default: 32)
-v, --verbose verbose output -v, --verbose verbose output
``` ```
* if both IPv4 and IPv6 are used, order of precedence can be set by using either `-46` or `-64`. * if both IPv4 and IPv6 are used, order of precedence can be set by using either `-46` or `-64`.
* batch flag `-b` will output sections without header and without empty lines (implies verbose flag). * batch flag `-b` will output sections without header and without empty lines (implies verbose flag).
* verbose flag `-v` will prefix each line with section type and algorithm name. * verbose flag `-v` will prefix each line with section type and algorithm name.
* an exit code of 0 is returned when all algorithms are considered secure (for a standard audit), or when a policy check passes (for a policy audit). * an exit code of 0 is returned when all algorithms are considered secure (for a standard audit), or when a policy check passes (for a policy audit).
Basic server auditing: Basic server auditing:
@ -86,7 +125,7 @@ To audit a client configuration, with a listener on port 4567:
ssh-audit -c -p 4567 ssh-audit -c -p 4567
``` ```
To list all official built-in policies (hint: use resulting file paths with `-P`/`--policy`): To list all official built-in policies (hint: use resulting policy names with `-P`/`--policy`):
``` ```
ssh-audit -L ssh-audit -L
``` ```
@ -106,17 +145,34 @@ To run a policy audit against many servers:
ssh-audit -T servers.txt -P ["policy name" | path/to/server_policy.txt] ssh-audit -T servers.txt -P ["policy name" | path/to/server_policy.txt]
``` ```
To create a policy based on a target server (which can be manually edited; see official built-in policies for syntax examples): To create a policy based on a target server (which can be manually edited):
``` ```
ssh-audit -M new_policy.txt targetserver ssh-audit -M new_policy.txt targetserver
``` ```
To run the DHEat CPU exhaustion DoS attack ([CVE-2002-20001](https://nvd.nist.gov/vuln/detail/CVE-2002-20001)) against a target using 10 concurrent sockets:
```
ssh-audit --dheat=10 targetserver
```
To run the DHEat attack using the `diffie-hellman-group-exchange-sha256` key exchange algorithm:
```
ssh-audit --dheat=10:diffie-hellman-group-exchange-sha256 targetserver
```
To run the DHEat attack using the `diffie-hellman-group-exchange-sha256` key exchange algorithm along with very small but non-standard packet lengths (this may result in the same CPU exhaustion, but with many less bytes per second being sent):
```
ssh-audit --dheat=10:diffie-hellman-group-exchange-sha256:4 targetserver
```
## Screenshots
### Server Standard Audit Example ### Server Standard Audit Example
Below is a screen shot of the standard server-auditing output when connecting to an unhardened OpenSSH v5.3 service: Below is a screen shot of the standard server-auditing output when connecting to an unhardened OpenSSH v5.3 service:
![screenshot](https://user-images.githubusercontent.com/2982011/64388792-317e6f80-d00e-11e9-826e-a4934769bb07.png) ![screenshot](https://user-images.githubusercontent.com/2982011/64388792-317e6f80-d00e-11e9-826e-a4934769bb07.png)
### Server Policy Audit Example ### Server Policy Audit Example
Below is a screen shot of the policy auditing output when connecting to an un-hardened Ubuntu Server 20.04 machine: Below is a screen shot of the policy auditing output when connecting to an un-hardened Ubuntu Server 20.04 machine (hint: use `-L`/`--list-policies` to see names of built-in policies to use with `-P`/`--policy`):
![screenshot](https://user-images.githubusercontent.com/2982011/94370881-95178700-00c0-11eb-8705-3157a4669dc0.png) ![screenshot](https://user-images.githubusercontent.com/2982011/94370881-95178700-00c0-11eb-8705-3157a4669dc0.png)
After applying the steps in the hardening guide (see below), the output changes to the following: After applying the steps in the hardening guide (see below), the output changes to the following:
@ -126,11 +182,11 @@ After applying the steps in the hardening guide (see below), the output changes
Below is a screen shot of the client-auditing output when an unhardened OpenSSH v7.2 client connects: Below is a screen shot of the client-auditing output when an unhardened OpenSSH v7.2 client connects:
![client_screenshot](https://user-images.githubusercontent.com/2982011/68867998-b946c100-06c4-11ea-975f-1f47e4178a74.png) ![client_screenshot](https://user-images.githubusercontent.com/2982011/68867998-b946c100-06c4-11ea-975f-1f47e4178a74.png)
### Hardening Guides ## Hardening Guides
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](https://github.com/jtesta/ssh-audit/releases) page), PyPI, Snap, and Docker:
To install from PyPI: To install from PyPI:
``` ```
@ -142,21 +198,112 @@ 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`)
### Web Front-End 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
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
### v3.2.0 (2024-04-22)
- Added implementation of the DHEat denial-of-service attack (see `--dheat` option; [CVE-2002-20001](https://nvd.nist.gov/vuln/detail/CVE-2002-20001)).
- Expanded filter of CBC ciphers to flag for the Terrapin vulnerability. It now includes more rarely found ciphers.
- Fixed parsing of `ecdsa-sha2-nistp*` CA signatures on host keys. Additionally, they are now flagged as potentially back-doored, just as standard host keys are.
- Gracefully handle rare exceptions (i.e.: crashes) while performing GEX tests.
- The built-in man page (`-m`, `--manual`) is now available on Docker, PyPI, and Snap builds, in addition to the Windows build.
- Snap builds are now architecture-independent.
- Changed Docker base image from `python:3-slim` to `python:3-alpine`, resulting in a 59% reduction in image size; credit [Daniel Thamdrup](https://github.com/dallemon).
- Added built-in policies for Amazon Linux 2023, Debian 12, OpenSSH 9.7, and Rocky Linux 9.
- Built-in policies now include a change log (use `-L -v` to view them).
- Custom policies now support the `allow_algorithm_subset_and_reordering` directive to allow targets to pass with a subset and/or re-ordered list of host keys, kex, ciphers, and MACs. This allows for the creation of a baseline policy where targets can optionally implement stricter controls; partial credit [yannik1015](https://github.com/yannik1015).
- Custom policies now support the `allow_larger_keys` directive to allow targets to pass with larger host keys, CA keys, and Diffie-Hellman keys. This allows for the creation of a baseline policy where targets can optionally implement stricter controls; partial credit [Damian Szuberski](https://github.com/szubersk).
- Color output is disabled if the `NO_COLOR` environment variable is set (see https://no-color.org/).
- Added 1 new key exchange algorithm: `gss-nistp384-sha384-*`.
- Added 1 new cipher: `aes128-ocb@libassh.org`.
### v3.1.0 (2023-12-20)
- Added test for the Terrapin message prefix truncation vulnerability ([CVE-2023-48795](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-48795)).
- Dropped support for Python 3.7 (EOL was reached in June 2023).
- Added Python 3.12 support.
- In server policies, reduced expected DH modulus sizes from 4096 to 3072 to match the [online hardening guides](https://ssh-audit.com/hardening_guides.html) (note that 3072-bit moduli provide the equivalent of 128-bit symmetric security).
- In Ubuntu 22.04 client policy, moved host key types `sk-ssh-ed25519@openssh.com` and `ssh-ed25519` to the end of all certificate types.
- Updated Ubuntu Server & Client policies for 20.04 and 22.04 to account for key exchange list changes due to Terrapin vulnerability patches.
- Re-organized option host key types for OpenSSH 9.2 server policy to correspond with updated Debian 12 hardening guide.
- Added built-in policies for OpenSSH 9.5 and 9.6.
- Added an `additional_notes` field to the JSON output.
### v3.0.0 (2023-09-07)
- Results from concurrent scans against multiple hosts are no longer improperly combined; bug discovered by [Adam Russell](https://github.com/thecliguy).
- Hostname resolution failure no longer causes scans against multiple hosts to terminate unexpectedly; credit [Dani Cuesta](https://github.com/daniel-cues).
- Algorithm recommendations resulting from warnings are now printed in yellow instead of red; credit [Adam Russell](https://github.com/thecliguy).
- Added failure, warning, and info notes to JSON output (note that this results in a breaking change to the banner protocol, "enc", and "mac" fields); credit [Bareq Al-Azzawi](https://github.com/BareqAZ).
- Docker Makefile now creates multi-arch builds for amd64, arm64, and armv7; credit [Sebastian Cohnen](https://github.com/tisba).
- Fixed crash during GEX tests.
- Refined GEX testing against OpenSSH servers: when the fallback mechanism is suspected of being triggered, perform an additional test to obtain more accurate results.
- The color of all notes will be printed in green when the related algorithm is rated good.
- Prioritized host key certificate algorithms for Ubuntu 22.04 LTS client policy.
- Marked all NIST K-, B-, and T-curves as unproven since they are so rarely used.
- Added built-in policy for OpenSSH 9.4.
- Added 12 new host keys: `ecdsa-sha2-curve25519`, `ecdsa-sha2-nistb233`, `ecdsa-sha2-nistb409`, `ecdsa-sha2-nistk163`, `ecdsa-sha2-nistk233`, `ecdsa-sha2-nistk283`, `ecdsa-sha2-nistk409`, `ecdsa-sha2-nistp224`, `ecdsa-sha2-nistp192`, `ecdsa-sha2-nistt571`, `ssh-dsa`, `x509v3-sign-rsa-sha256`.
- Added 15 new key exchanges: `curve448-sha512@libssh.org`, `ecdh-nistp256-kyber-512r3-sha256-d00@openquantumsafe.org`, `ecdh-nistp384-kyber-768r3-sha384-d00@openquantumsafe.org`, `ecdh-nistp521-kyber-1024r3-sha512-d00@openquantumsafe.org`, `ecdh-sha2-brainpoolp256r1@genua.de`, `ecdh-sha2-brainpoolp384r1@genua.de`, `ecdh-sha2-brainpoolp521r1@genua.de`, `kexAlgoDH14SHA1`, `kexAlgoDH1SHA1`, `kexAlgoECDH256`, `kexAlgoECDH384`, `kexAlgoECDH521`, `sm2kep-sha2-nistp256`, `x25519-kyber-512r3-sha256-d00@amazon.com`, `x25519-kyber512-sha512@aws.amazon.com`.
- Added 8 new ciphers: `aes192-gcm@openssh.com`, `cast128-12-cbc`, `cast128-12-cfb`, `cast128-12-ecb`, `cast128-12-ofb`, `des-cfb`, `des-ecb`, `des-ofb`.
- Added 14 new MACs: `cbcmac-3des`, `cbcmac-aes`, `cbcmac-blowfish`, `cbcmac-des`, `cbcmac-rijndael`, `cbcmac-twofish`, `hmac-sha256-96`, `md5`, `md5-8`, `ripemd160`, `ripemd160-8`, `sha1`, `sha1-8`, `umac-128`.
### 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)
- Fixed crash when running host key tests.
- Handles server connection failures more gracefully.
- Now prints JSON with indents when `-jj` is used (useful for debugging).
- Added MD5 fingerprints to verbose output.
- Added `-d`/`--debug` option for getting debugging output; credit [Adam Russell](https://github.com/thecliguy).
- Updated JSON output to include MD5 fingerprints. Note that this results in a breaking change in the 'fingerprints' dictionary format.
- Updated OpenSSH 8.1 (and earlier) policies to include `rsa-sha2-512` and `rsa-sha2-256`.
- Added OpenSSH v8.6 & v8.7 policies.
- Added 3 new key exchanges: `gss-gex-sha1-eipGX3TCiQSrx573bT1o1Q==`, `gss-group1-sha1-eipGX3TCiQSrx573bT1o1Q==`, and `gss-group14-sha1-eipGX3TCiQSrx573bT1o1Q==`.
- Added 3 new MACs: `hmac-ripemd160-96`, `AEAD_AES_128_GCM`, and `AEAD_AES_256_GCM`.
### v2.4.0 (2021-02-23)
- Added multi-threaded scanning support.
- Added built-in Windows manual page (see `-m`/`--manual`); credit [Adam Russell](https://github.com/thecliguy).
- Added version check for OpenSSH user enumeration (CVE-2018-15473).
- Added deprecation note to host key types based on SHA-1.
- Added extra warnings for SSHv1.
- Added built-in hardened OpenSSH v8.5 policy.
- Upgraded warnings to failures for host key types based on SHA-1.
- Fixed crash when receiving unexpected response during host key test.
- Fixed hang against older Cisco devices during host key test & gex test.
- Fixed improper termination while scanning multiple targets when one target returns an error.
- Dropped support for Python 3.5 (which reached EOL in Sept. 2020).
- Added 1 new key exchange: `sntrup761x25519-sha512@openssh.com`.
### v2.3.1 (2020-10-28) ### v2.3.1 (2020-10-28)
- Now parses public key sizes for `rsa-sha2-256-cert-v01@openssh.com` and `rsa-sha2-512-cert-v01@openssh.com` host key types. - Now parses public key sizes for `rsa-sha2-256-cert-v01@openssh.com` and `rsa-sha2-512-cert-v01@openssh.com` host key types.
- Flag `ssh-rsa-cert-v01@openssh.com` as a failure due to SHA-1 hash. - Flag `ssh-rsa-cert-v01@openssh.com` as a failure due to SHA-1 hash.
@ -260,18 +407,18 @@ For convenience, a web front-end on top of the command-line tool is available at
### v1.0.20160207 ### v1.0.20160207
- use OpenSSH 7.2 banner - use OpenSSH 7.2 banner
- additional warnings for OpenSSH 7.2 - additional warnings for OpenSSH 7.2
- fix OpenSSH 7.0 failure messages - fix OpenSSH 7.0 failure messages
- add rijndael-cbc failure message from OpenSSH 6.7 - add rijndael-cbc failure message from OpenSSH 6.7
### v1.0.20160105 ### v1.0.20160105
- multiple additional warnings - multiple additional warnings
- support for none algorithm - support for none algorithm
- better compression handling - better compression handling
- ensure reading enough data (fixes few Linux SSH) - ensure reading enough data (fixes few Linux SSH)
### v1.0.20151230 ### v1.0.20151230
- Dropbear SSH support - Dropbear SSH support
### v1.0.20151223 ### v1.0.20151223
- initial version - initial version

129
add_builtin_man_page.sh Executable file
View File

@ -0,0 +1,129 @@
#!/usr/bin/env bash
#
# The MIT License (MIT)
#
# Copyright (C) 2021-2024 Joe Testa (jtesta@positronsecurity.com)
# Copyright (C) 2021 Adam Russell (<adam[at]thecliguy[dot]co[dot]uk>)
#
# 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.
#
################################################################################
# add_builtin_man_page.sh
#
# PURPOSE
# Since some platforms lack a manual reader it's necessary to provide an
# alternative means of reading the man page.
#
# This script should be run as part of the ssh-audit packaging process for
# Docker, PyPI, Snap, and Windows. It populates the 'BUILTIN_MAN_PAGE'
# variable in 'globals.py' with the contents of the man page. Users can then
# see the man page with "ssh-audit [--manual|-m]".
#
# Linux or Cygwin is required to run this script.
#
# USAGE
# add_builtin_man_page.sh [-m <path-to-man-page>] [-g <path-to-globals.py>]
#
################################################################################
usage() {
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 " -g Specify an alternate globals.py path (default: ./src/ssh_audit/globals.py)"
echo >&2 " -h This help message"
}
PLATFORM="$(uname -s)"
# This script is intended for use on Linux and Cygwin only.
case "${PLATFORM}" in
Linux | CYGWIN*) ;;
*)
echo "Platform not supported: ${PLATFORM}"
exit 1
;;
esac
MAN_PAGE=./ssh-audit.1
GLOBALS_PY=./src/ssh_audit/globals.py
while getopts "m: g: h" OPTION; do
case "${OPTION}" in
m)
MAN_PAGE="${OPTARG}"
;;
g)
GLOBALS_PY="${OPTARG}"
;;
h)
usage
exit 0
;;
*)
echo >&2 "Invalid parameter(s) provided"
usage
exit 1
;;
esac
done
# Check that the specified files exist.
[[ -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; }
# Check that the 'ul' (do underlining) binary exists.
if [[ "${PLATFORM}" == "Linux" ]]; then
command -v ul >/dev/null 2>&1 || { echo >&2 "ul not found."; exit 1; }
fi
# Check that the 'sed' (stream editor) binary exists.
command -v sed >/dev/null 2>&1 || { echo >&2 "sed not found."; exit 1; }
# Reset the globals.py file, in case it was modified from a prior run.
git checkout "${GLOBALS_PY}" > /dev/null 2>&1
# Remove the Windows man page placeholder from 'globals.py'.
sed -i '/^BUILTIN_MAN_PAGE/d' "${GLOBALS_PY}"
echo "Processing man page at ${MAN_PAGE} and placing output into ${GLOBALS_PY}..."
# Append the man page content to 'globals.py'.
# * man outputs a backspace-overwrite sequence rather than an ANSI escape
# sequence.
# * 'MAN_KEEP_FORMATTING' preserves the backspace-overwrite sequence when
# redirected to a file or a pipe.
# * sed converts unicode hyphens into an ASCI equivalent.
# * The 'ul' command converts the backspace-overwrite sequence to an ANSI
# escape sequence. Not required under Cygwin because man outputs ANSI escape
# codes automatically.
echo BUILTIN_MAN_PAGE = '"""' >> "${GLOBALS_PY}"
if [[ "${PLATFORM}" == CYGWIN* ]]; then
MANWIDTH=80 MAN_KEEP_FORMATTING=1 man "${MAN_PAGE}" | sed $'s/\u2010/-/g' >> "${GLOBALS_PY}"
else
MANWIDTH=80 MAN_KEEP_FORMATTING=1 man "${MAN_PAGE}" | ul | sed $'s/\u2010/-/g' >> "${GLOBALS_PY}"
fi
echo '"""' >> "${GLOBALS_PY}"
echo "Done."
exit 0

76
build_snap.sh Executable file
View File

@ -0,0 +1,76 @@
#!/usr/bin/env bash
#
# The MIT License (MIT)
#
# Copyright (C) 2021-2024 Joe Testa (jtesta@positronsecurity.com)
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# 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
# Add the built-in manual page.
./add_builtin_man_page.sh
# 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"

127
build_windows_executable.sh Executable file
View File

@ -0,0 +1,127 @@
#!/usr/bin/env bash
#
# The MIT License (MIT)
#
# Copyright (C) 2021-2024 Joe Testa (jtesta@positronsecurity.com)
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# 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_windows_executable.sh
#
# Builds a Windows executable using PyInstaller.
################################################################################
PLATFORM="$(uname -s)"
# This script is intended for use on Cygwin only.
case "${PLATFORM}" in
CYGWIN*) ;;
*)
echo "Platform not supported (${PLATFORM}). This must be run in Cygwin only."
exit 1
;;
esac
# Ensure that Python 3.x is installed.
if [[ "$(python -V)" != "Python 3."* ]]; then
echo "Python v3.x not found. Install the latest stable version from: https://www.python.org/"
exit 1
fi
# Install/update package dependencies.
echo "Installing/updating pyinstaller and colorama packages..."
pip install -U pyinstaller colorama
echo
# Prompt for the version to release.
echo -n "Enter the version to release, using format 'vX.X.X': "
read -r version
# Ensure that entered version fits required format.
if [[ ! $version =~ ^v[0-9]\.[0-9]\.[0-9]$ ]]; then
echo "Error: version string does not match format vX.X.X!"
exit 1
fi
# Verify that version is correct.
echo -n "Version will be set to '${version}'. Is this correct? (y/n): "
read -r yn
echo
if [[ $yn != "y" ]]; then
echo "Build cancelled."
exit 1
fi
# Reset any local changes made to globals.py from a previous run.
git checkout src/ssh_audit/globals.py 2> /dev/null
# Update the man page.
./add_builtin_man_page.sh
retval=$?
if [[ ${retval} != 0 ]]; then
echo "Failed to run ./update_windows_man_page.sh"
exit 1
fi
# Do all operations from this point from the main source directory.
pushd src/ssh_audit || exit > /dev/null
# Delete the existing VERSION variable and add the value that the user entered, above.
sed -i '/^VERSION/d' globals.py
echo "VERSION = '$version'" >> globals.py
# Delete cached files if they exist from a prior run.
rm -rf dist/ build/ ssh-audit.spec
# Create a hard link from ssh_audit.py to ssh-audit.py.
if [[ ! -f ssh-audit.py ]]; then
ln ssh_audit.py ssh-audit.py
fi
echo -e "\nRunning pyinstaller...\n"
pyinstaller -F --icon ../../windows_icon.ico ssh-audit.py
if [[ -f dist/ssh-audit.exe ]]; then
echo -e "\nExecutable created in $(pwd)/dist/ssh-audit.exe\n"
else
echo -e "\nFAILED to create $(pwd)/dist/ssh-audit.exe!\n"
exit 1
fi
# Ensure that the version string doesn't have '-dev' in it.
dist/ssh-audit.exe | grep -E 'ssh-audit.exe v.+\-dev' > /dev/null
retval=$?
if [[ ${retval} == 0 ]]; then
echo -e "\nError: executable's version number includes '-dev'."
exit 1
fi
# Remove the cache files created during the build process, along with the link we created, above.
rm -rf build/ ssh-audit.spec ssh-audit.py
# Reset the changes we made to globals.py.
git checkout globals.py 2> /dev/null
popd || exit > /dev/null
exit 0

File diff suppressed because it is too large Load Diff

View File

@ -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,11 +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.5
Programming Language :: Python :: 3.6
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 :: 3.12
Programming Language :: Python :: Implementation :: CPython Programming Language :: Python :: Implementation :: CPython
Programming Language :: Python :: Implementation :: PyPy Programming Language :: Python :: Implementation :: PyPy
Topic :: Security Topic :: Security
@ -32,7 +33,7 @@ classifiers =
packages = find: packages = find:
package_dir = package_dir =
= src = src
python_requires = >=3.5,<4 python_requires = >=3.8,<4
[options.packages.find] [options.packages.find]
where = src where = src

View File

@ -1,21 +1,23 @@
name: ssh-audit name: ssh-audit
version: '2.3.1-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
architectures:
- build-on: [amd64]
build-for: [all]
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: .

View File

@ -1,7 +1,7 @@
""" """
The MIT License (MIT) The MIT License (MIT)
Copyright (C) 2017-2020 Joe Testa (jtesta@positronsecurity.com) Copyright (C) 2017-2021 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
@ -54,8 +54,8 @@ class Algorithms:
def ssh1(self) -> Optional['Algorithms.Item']: def ssh1(self) -> Optional['Algorithms.Item']:
if self.ssh1kex is None: if self.ssh1kex is None:
return None return None
item = Algorithms.Item(1, SSH1_KexDB.ALGORITHMS) item = Algorithms.Item(1, SSH1_KexDB.get_db())
item.add('key', [u'ssh-rsa1']) item.add('key', ['ssh-rsa1'])
item.add('enc', self.ssh1kex.supported_ciphers) item.add('enc', self.ssh1kex.supported_ciphers)
item.add('aut', self.ssh1kex.supported_authentications) item.add('aut', self.ssh1kex.supported_authentications)
return item return item
@ -64,7 +64,7 @@ class Algorithms:
def ssh2(self) -> Optional['Algorithms.Item']: def ssh2(self) -> Optional['Algorithms.Item']:
if self.ssh2kex is None: if self.ssh2kex is None:
return None return None
item = Algorithms.Item(2, SSH2_KexDB.ALGORITHMS) item = Algorithms.Item(2, SSH2_KexDB.get_db())
item.add('kex', self.ssh2kex.kex_algorithms) item.add('kex', self.ssh2kex.kex_algorithms)
item.add('key', self.ssh2kex.key_algorithms) item.add('key', self.ssh2kex.key_algorithms)
item.add('enc', self.ssh2kex.server.encryption) item.add('enc', self.ssh2kex.server.encryption)
@ -131,7 +131,7 @@ class Algorithms:
# if version is not None: # if version is not None:
# software = SSH.Software(None, product, version, None, None) # software = SSH.Software(None, product, version, None, None)
# break # break
rec = {} # type: Dict[int, Dict[str, Dict[str, Dict[str, int]]]] rec: Dict[int, Dict[str, Dict[str, Dict[str, int]]]] = {}
if software is None: if software is None:
unknown_software = True unknown_software = True
for alg_pair in self.values: for alg_pair in self.values:
@ -206,7 +206,7 @@ class Algorithms:
def __init__(self, sshv: int, db: Dict[str, Dict[str, List[List[Optional[str]]]]]) -> None: def __init__(self, sshv: int, db: Dict[str, Dict[str, List[List[Optional[str]]]]]) -> None:
self.__sshv = sshv self.__sshv = sshv
self.__db = db self.__db = db
self.__storage = {} # type: Dict[str, List[str]] self.__storage: Dict[str, List[str]] = {}
@property @property
def sshv(self) -> int: def sshv(self) -> int:

View File

@ -1,7 +1,7 @@
""" """
The MIT License (MIT) The MIT License (MIT)
Copyright (C) 2017-2020 Joe Testa (jtesta@positronsecurity.com) Copyright (C) 2017-2024 Joe Testa (jtesta@positronsecurity.com)
Copyright (C) 2017 Andris Raugulis (moo@arthepsy.eu) 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
@ -41,45 +41,46 @@ class AuditConf:
self.client_audit = False self.client_audit = False
self.colors = True self.colors = True
self.json = False self.json = False
self.json_print_indent = False
self.verbose = False self.verbose = False
self.level = 'info' self.level = 'info'
self.ipvo = () # type: Sequence[int] self.ip_version_preference: List[int] = [] # Holds only 5 possible values: [] (no preference), [4] (use IPv4 only), [6] (use IPv6 only), [46] (use both IPv4 and IPv6, but prioritize v4), and [64] (use both IPv4 and IPv6, but prioritize v6).
self.ipv4 = False self.ipv4 = False
self.ipv6 = False self.ipv6 = False
self.make_policy = False # When True, creates a policy file from an audit scan. self.make_policy = False # When True, creates a policy file from an audit scan.
self.policy_file = None # type: Optional[str] # File system path to a policy self.policy_file: Optional[str] = None # File system path to a policy
self.policy = None # type: Optional[Policy] # Policy object self.policy: Optional[Policy] = None # Policy object
self.timeout = 5.0 self.timeout = 5.0
self.timeout_set = False # Set to True when the user explicitly sets it. self.timeout_set = False # Set to True when the user explicitly sets it.
self.target_file = None # type: Optional[str] self.target_file: Optional[str] = None
self.target_list = [] # type: List[str] self.target_list: List[str] = []
self.threads = 32
self.list_policies = False self.list_policies = False
self.lookup = '' self.lookup = ''
self.manual = False
self.debug = False
self.gex_test = ''
self.dheat: Optional[str] = None
self.dheat_concurrent_connections: int = 0
self.dheat_e_length: int = 0
self.dheat_target_alg: str = ""
self.skip_rate_test = False
self.conn_rate_test: str = "1:1"
self.conn_rate_test_enabled = False
self.conn_rate_test_threads = 0
self.conn_rate_test_target_rate = 0
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
if name in ['ssh1', 'ssh2', 'batch', 'client_audit', 'colors', 'verbose', 'timeout_set', 'json', 'make_policy', 'list_policies']: if name in ['batch', 'client_audit', 'colors', 'json', 'json_print_indent', 'list_policies', 'manual', 'make_policy', 'ssh1', 'ssh2', 'timeout_set', 'verbose', 'debug', 'skip_rate_test']:
valid, value = True, bool(value) valid, value = True, bool(value)
elif name in ['ipv4', 'ipv6']: elif name in ['ipv4', 'ipv6']:
valid = False valid, value = True, bool(value)
value = bool(value) if len(self.ip_version_preference) == 2: # Being called more than twice is not valid.
ipv = 4 if name == 'ipv4' else 6 valid = False
if value: elif value:
value = tuple(list(self.ipvo) + [ipv]) self.ip_version_preference.append(4 if name == 'ipv4' else 6)
else: # pylint: disable=else-if-used
if len(self.ipvo) == 0:
value = (6,) if ipv == 4 else (4,)
else:
value = tuple([x for x in self.ipvo if x != ipv])
self.__setattr__('ipvo', value)
elif name == 'ipvo':
if isinstance(value, (tuple, list)):
uniq_value = Utils.unique_seq(value)
value = tuple([x for x in uniq_value if x in (4, 6)])
valid = True
ipv_both = len(value) == 0
object.__setattr__(self, 'ipv4', ipv_both or 4 in value)
object.__setattr__(self, 'ipv6', ipv_both or 6 in value)
elif name == 'port': elif name == 'port':
valid, port = True, Utils.parse_int(value) valid, port = True, Utils.parse_int(value)
if port < 1 or port > 65535: if port < 1 or port > 65535:
@ -96,8 +97,96 @@ 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 ['policy_file', 'policy', 'target_file', 'target_list', 'lookup']: elif name in ['ip_version_preference', 'lookup', 'policy_file', 'policy', 'target_file', 'target_list', 'gex_test']:
valid = True valid = True
elif name == "threads":
valid, num_threads = True, Utils.parse_int(value)
if num_threads < 1:
raise ValueError('invalid number of threads: {}'.format(value))
value = num_threads
elif name == "dheat":
# Valid values:
# * None
# * "10" (concurrent-connections)
# * "10:diffie-hellman-group18-sha512" (concurrent-connections:target-alg)
# * "10:diffie-hellman-group18-sha512:100" (concurrent-connections:target-alg:e-length)
valid = True
if value is not None:
def _parse_concurrent_connections(s: str) -> int:
if Utils.parse_int(s) < 1:
raise ValueError("number of concurrent connections must be 1 or greater: {}".format(s))
return int(s)
def _parse_e_length(s: str) -> int:
s_int = Utils.parse_int(s)
if s_int < 2:
raise ValueError("length of e must not be less than 2: {}".format(s))
return s_int
def _parse_target_alg(s: str) -> str:
if len(s) == 0:
raise ValueError("target algorithm must not be the empty string.")
return s
value = str(value)
fields = value.split(':')
self.dheat_concurrent_connections = _parse_concurrent_connections(fields[0])
# Parse the target algorithm if present.
if len(fields) >= 2:
self.dheat_target_alg = _parse_target_alg(fields[1])
# Parse the length of e, if present.
if len(fields) == 3:
self.dheat_e_length = _parse_e_length(fields[2])
if len(fields) > 3:
raise ValueError("only three fields are expected instead of {}: {}".format(len(fields), value))
elif name in ["dheat_concurrent_connections", "dheat_e_length"]:
valid = True
if not isinstance(value, int):
valid = False
elif name == "dheat_target_alg":
valid = True
if not isinstance(value, str):
valid = False
elif name == "conn_rate_test":
# Valid values:
# * "4" (run rate test with 4 threads)
# * "4:100" (run rate test with 4 threads, targeting 100 connections/second)
error_msg = "valid format for {:s} is \"N\" or \"N:N\", where N is an integer.".format(name)
self.conn_rate_test_enabled = True
fields = str(value).split(":")
if len(fields) > 2 or len(fields) == 0:
raise ValueError(error_msg)
else:
self.conn_rate_test_threads = int(fields[0])
if self.conn_rate_test_threads < 1:
raise ValueError("number of threads must be 1 or greater.")
self.conn_rate_test_target_rate = 0
if len(fields) == 2:
self.conn_rate_test_target_rate = int(fields[1])
if self.conn_rate_test_target_rate < 1:
raise ValueError("rate target must be 1 or greater.")
elif name == "conn_rate_test_enabled":
valid = True
if not isinstance(value, bool):
valid = False
elif name in ["conn_rate_test_threads", "conn_rate_test_target_rate"]:
valid = True
if not isinstance(value, int):
valid = False
if valid: if valid:
object.__setattr__(self, name, value) object.__setattr__(self, name, value)

View File

@ -0,0 +1,124 @@
"""
The MIT License (MIT)
Copyright (C) 2020-2024 Joe Testa (jtesta@positronsecurity.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
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.
"""
from typing import Any, Dict, List, Optional, Union
# 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, Any]]]] = {
# Amazon Linux 2023
'Hardened Amazon Linux 2023 (version 1)': {'version': '1', 'changelog': 'Initial version', 'banner': None, 'compressions': None, 'host_keys': ['rsa-sha2-512', 'rsa-sha2-256', 'ssh-ed25519'], 'optional_host_keys': ['sk-ssh-ed25519@openssh.com', 'ssh-ed25519-cert-v01@openssh.com', 'sk-ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['sntrup761x25519-sha512@openssh.com', 'curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256', 'kex-strict-s-v00@openssh.com'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@openssh.com'], 'hostkey_sizes': {"rsa-sha2-256": {"hostkey_size": 4096}, "rsa-sha2-256-cert-v01@openssh.com": {"ca_key_size": 4096, "ca_key_type": "ssh-rsa", "hostkey_size": 4096}, "rsa-sha2-512": {"hostkey_size": 4096}, "rsa-sha2-512-cert-v01@openssh.com": {"ca_key_size": 4096, "ca_key_type": "ssh-rsa", "hostkey_size": 4096}, "sk-ssh-ed25519-cert-v01@openssh.com": {"ca_key_size": 256, "ca_key_type": "ssh-ed25519", "hostkey_size": 256}, "sk-ssh-ed25519@openssh.com": {"hostkey_size": 256}, "ssh-ed25519": {"hostkey_size": 256}, "ssh-ed25519-cert-v01@openssh.com": {"ca_key_size": 256, "ca_key_type": "ssh-ed25519", "hostkey_size": 256}}, 'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 3072}, 'server_policy': True},
# Debian Server 12
'Hardened Debian 12 (version 1)': {'version': '1', 'changelog': 'Initial version', 'banner': None, 'compressions': None, 'host_keys': ['rsa-sha2-512', 'rsa-sha2-256', 'ssh-ed25519'], 'optional_host_keys': ['sk-ssh-ed25519@openssh.com', 'ssh-ed25519-cert-v01@openssh.com', 'sk-ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['sntrup761x25519-sha512@openssh.com', 'curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256', 'kex-strict-s-v00@openssh.com'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@openssh.com'], 'hostkey_sizes': {"rsa-sha2-256": {"hostkey_size": 4096}, "rsa-sha2-256-cert-v01@openssh.com": {"ca_key_size": 4096, "ca_key_type": "ssh-rsa", "hostkey_size": 4096}, "rsa-sha2-512": {"hostkey_size": 4096}, "rsa-sha2-512-cert-v01@openssh.com": {"ca_key_size": 4096, "ca_key_type": "ssh-rsa", "hostkey_size": 4096}, "sk-ssh-ed25519-cert-v01@openssh.com": {"ca_key_size": 256, "ca_key_type": "ssh-ed25519", "hostkey_size": 256}, "sk-ssh-ed25519@openssh.com": {"hostkey_size": 256}, "ssh-ed25519": {"hostkey_size": 256}, "ssh-ed25519-cert-v01@openssh.com": {"ca_key_size": 256, "ca_key_type": "ssh-ed25519", "hostkey_size": 256}}, 'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 3072}, 'server_policy': True},
# Rocky Linux 9
'Hardened Rocky Linux 9 (version 1)': {'version': '1', 'changelog': 'Initial version', 'banner': None, 'compressions': None, 'host_keys': ['rsa-sha2-512', 'rsa-sha2-256', 'ssh-ed25519'], 'optional_host_keys': ['sk-ssh-ed25519@openssh.com', 'ssh-ed25519-cert-v01@openssh.com', 'sk-ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['sntrup761x25519-sha512@openssh.com', 'curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256', 'kex-strict-s-v00@openssh.com'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@openssh.com'], 'hostkey_sizes': {"rsa-sha2-256": {"hostkey_size": 4096}, "rsa-sha2-256-cert-v01@openssh.com": {"ca_key_size": 4096, "ca_key_type": "ssh-rsa", "hostkey_size": 4096}, "rsa-sha2-512": {"hostkey_size": 4096}, "rsa-sha2-512-cert-v01@openssh.com": {"ca_key_size": 4096, "ca_key_type": "ssh-rsa", "hostkey_size": 4096}, "sk-ssh-ed25519-cert-v01@openssh.com": {"ca_key_size": 256, "ca_key_type": "ssh-ed25519", "hostkey_size": 256}, "sk-ssh-ed25519@openssh.com": {"hostkey_size": 256}, "ssh-ed25519": {"hostkey_size": 256}, "ssh-ed25519-cert-v01@openssh.com": {"ca_key_size": 256, "ca_key_type": "ssh-ed25519", "hostkey_size": 256}}, 'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 3072}, 'server_policy': True},
# Ubuntu Server policies
'Hardened Ubuntu Server 16.04 LTS (version 4)': {'version': '4', 'changelog': 'No change log available.', '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': 3072}, 'server_policy': True},
'Hardened Ubuntu Server 18.04 LTS (version 4)': {'version': '4', 'changelog': 'No change log available.', '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': 3072}, 'server_policy': True},
'Hardened Ubuntu Server 20.04 LTS (version 5)': {'version': '5', 'changelog': 'Added kex-strict-s-v00@openssh.com to kex list.', 'banner': None, 'compressions': None, 'host_keys': ['rsa-sha2-512', 'rsa-sha2-256', 'ssh-ed25519'], 'optional_host_keys': ['sk-ssh-ed25519@openssh.com', 'ssh-ed25519-cert-v01@openssh.com', 'sk-ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256', 'kex-strict-s-v00@openssh.com'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@openssh.com'], 'hostkey_sizes': {"rsa-sha2-256": {"hostkey_size": 4096}, "rsa-sha2-256-cert-v01@openssh.com": {"ca_key_size": 4096, "ca_key_type": "ssh-rsa", "hostkey_size": 4096}, "rsa-sha2-512": {"hostkey_size": 4096}, "rsa-sha2-512-cert-v01@openssh.com": {"ca_key_size": 4096, "ca_key_type": "ssh-rsa", "hostkey_size": 4096}, "sk-ssh-ed25519-cert-v01@openssh.com": {"ca_key_size": 256, "ca_key_type": "ssh-ed25519", "hostkey_size": 256}, "sk-ssh-ed25519@openssh.com": {"hostkey_size": 256}, "ssh-ed25519": {"hostkey_size": 256}, "ssh-ed25519-cert-v01@openssh.com": {"ca_key_size": 256, "ca_key_type": "ssh-ed25519", "hostkey_size": 256}}, 'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 3072}, 'server_policy': True},
'Hardened Ubuntu Server 22.04 LTS (version 5)': {'version': '5', 'changelog': 'Added kex-strict-s-v00@openssh.com to kex list.', 'banner': None, 'compressions': None, 'host_keys': ['rsa-sha2-512', 'rsa-sha2-256', 'ssh-ed25519'], 'optional_host_keys': ['sk-ssh-ed25519@openssh.com', 'ssh-ed25519-cert-v01@openssh.com', 'sk-ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['sntrup761x25519-sha512@openssh.com', 'curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256', 'kex-strict-s-v00@openssh.com'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@openssh.com'], 'hostkey_sizes': {"rsa-sha2-256": {"hostkey_size": 4096}, "rsa-sha2-256-cert-v01@openssh.com": {"ca_key_size": 4096, "ca_key_type": "ssh-rsa", "hostkey_size": 4096}, "rsa-sha2-512": {"hostkey_size": 4096}, "rsa-sha2-512-cert-v01@openssh.com": {"ca_key_size": 4096, "ca_key_type": "ssh-rsa", "hostkey_size": 4096}, "sk-ssh-ed25519-cert-v01@openssh.com": {"ca_key_size": 256, "ca_key_type": "ssh-ed25519", "hostkey_size": 256}, "sk-ssh-ed25519@openssh.com": {"hostkey_size": 256}, "ssh-ed25519": {"hostkey_size": 256}, "ssh-ed25519-cert-v01@openssh.com": {"ca_key_size": 256, "ca_key_type": "ssh-ed25519", "hostkey_size": 256}}, 'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 3072}, 'server_policy': True},
# Generic OpenSSH Server policies
'Hardened OpenSSH Server v7.7 (version 4)': {'version': '4', 'changelog': 'No change log available.', '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': 3072}, 'server_policy': True},
'Hardened OpenSSH Server v7.8 (version 4)': {'version': '4', 'changelog': 'No change log available.', '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': 3072}, 'server_policy': True},
'Hardened OpenSSH Server v7.9 (version 4)': {'version': '4', 'changelog': 'No change log available.', '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': 3072}, 'server_policy': True},
'Hardened OpenSSH Server v8.0 (version 4)': {'version': '4', 'changelog': 'No change log available.', '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': 3072}, 'server_policy': True},
'Hardened OpenSSH Server v8.1 (version 4)': {'version': '4', 'changelog': 'No change log available.', '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': 3072}, 'server_policy': True},
'Hardened OpenSSH Server v8.2 (version 4)': {'version': '4', 'changelog': 'No change log available.', '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': 3072}, 'server_policy': True},
'Hardened OpenSSH Server v8.3 (version 4)': {'version': '4', 'changelog': 'No change log available.', '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': 3072}, 'server_policy': True},
'Hardened OpenSSH Server v8.4 (version 4)': {'version': '4', 'changelog': 'No change log available.', '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': 3072}, 'server_policy': True},
'Hardened OpenSSH Server v8.5 (version 4)': {'version': '4', 'changelog': 'No change log available.', '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': 3072}, 'server_policy': True},
'Hardened OpenSSH Server v8.6 (version 4)': {'version': '4', 'changelog': 'No change log available.', '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': 3072}, 'server_policy': True},
'Hardened OpenSSH Server v8.7 (version 4)': {'version': '4', 'changelog': 'No change log available.', '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': 3072}, 'server_policy': True},
'Hardened OpenSSH Server v8.8 (version 3)': {'version': '3', 'changelog': 'No change log available.', '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': 3072}, 'server_policy': True},
'Hardened OpenSSH Server v8.9 (version 3)': {'version': '3', 'changelog': 'No change log available.', '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': 3072}, 'server_policy': True},
'Hardened OpenSSH Server v9.0 (version 3)': {'version': '3', 'changelog': 'No change log available.', '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': 3072}, 'server_policy': True},
'Hardened OpenSSH Server v9.1 (version 3)': {'version': '3', 'changelog': 'No change log available.', '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': 3072}, 'server_policy': True},
'Hardened OpenSSH Server v9.2 (version 3)': {'version': '3', 'changelog': 'No change log available.', 'banner': None, 'compressions': None, 'host_keys': ['rsa-sha2-512', 'rsa-sha2-256', 'ssh-ed25519'], 'optional_host_keys': ['sk-ssh-ed25519-cert-v01@openssh.com', 'ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'sk-ssh-ed25519@openssh.com'], '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': 3072}, 'server_policy': True},
'Hardened OpenSSH Server v9.3 (version 3)': {'version': '3', 'changelog': 'No change log available.', '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': 3072}, 'server_policy': True},
'Hardened OpenSSH Server v9.4 (version 2)': {'version': '2', 'changelog': 'No change log available.', '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': 3072}, 'server_policy': True},
'Hardened OpenSSH Server v9.5 (version 1)': {'version': '1', 'changelog': 'Initial version.', 'banner': None, 'compressions': None, 'host_keys': ['rsa-sha2-512', 'rsa-sha2-256', 'ssh-ed25519'], 'optional_host_keys': ['sk-ssh-ed25519@openssh.com', 'ssh-ed25519-cert-v01@openssh.com', 'sk-ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['sntrup761x25519-sha512@openssh.com', 'curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@openssh.com'], 'hostkey_sizes': {"rsa-sha2-256": {"hostkey_size": 4096}, "rsa-sha2-256-cert-v01@openssh.com": {"ca_key_size": 4096, "ca_key_type": "ssh-rsa", "hostkey_size": 4096}, "rsa-sha2-512": {"hostkey_size": 4096}, "rsa-sha2-512-cert-v01@openssh.com": {"ca_key_size": 4096, "ca_key_type": "ssh-rsa", "hostkey_size": 4096}, "sk-ssh-ed25519-cert-v01@openssh.com": {"ca_key_size": 256, "ca_key_type": "ssh-ed25519", "hostkey_size": 256}, "sk-ssh-ed25519@openssh.com": {"hostkey_size": 256}, "ssh-ed25519": {"hostkey_size": 256}, "ssh-ed25519-cert-v01@openssh.com": {"ca_key_size": 256, "ca_key_type": "ssh-ed25519", "hostkey_size": 256}}, 'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 3072}, 'server_policy': True},
'Hardened OpenSSH Server v9.6 (version 1)': {'version': '1', 'changelog': 'Initial version.', 'banner': None, 'compressions': None, 'host_keys': ['rsa-sha2-512', 'rsa-sha2-256', 'ssh-ed25519'], 'optional_host_keys': ['sk-ssh-ed25519@openssh.com', 'ssh-ed25519-cert-v01@openssh.com', 'sk-ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['sntrup761x25519-sha512@openssh.com', 'curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256', 'ext-info-s', 'kex-strict-s-v00@openssh.com'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@openssh.com'], 'hostkey_sizes': {"rsa-sha2-256": {"hostkey_size": 4096}, "rsa-sha2-256-cert-v01@openssh.com": {"ca_key_size": 4096, "ca_key_type": "ssh-rsa", "hostkey_size": 4096}, "rsa-sha2-512": {"hostkey_size": 4096}, "rsa-sha2-512-cert-v01@openssh.com": {"ca_key_size": 4096, "ca_key_type": "ssh-rsa", "hostkey_size": 4096}, "sk-ssh-ed25519-cert-v01@openssh.com": {"ca_key_size": 256, "ca_key_type": "ssh-ed25519", "hostkey_size": 256}, "sk-ssh-ed25519@openssh.com": {"hostkey_size": 256}, "ssh-ed25519": {"hostkey_size": 256}, "ssh-ed25519-cert-v01@openssh.com": {"ca_key_size": 256, "ca_key_type": "ssh-ed25519", "hostkey_size": 256}}, 'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 3072}, 'server_policy': True},
'Hardened OpenSSH Server v9.7 (version 1)': {'version': '1', 'changelog': 'Initial version.', 'banner': None, 'compressions': None, 'host_keys': ['rsa-sha2-512', 'rsa-sha2-256', 'ssh-ed25519'], 'optional_host_keys': ['sk-ssh-ed25519@openssh.com', 'ssh-ed25519-cert-v01@openssh.com', 'sk-ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com'], 'kex': ['sntrup761x25519-sha512@openssh.com', 'curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256', 'ext-info-s', 'kex-strict-s-v00@openssh.com'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@openssh.com'], 'hostkey_sizes': {"rsa-sha2-256": {"hostkey_size": 4096}, "rsa-sha2-256-cert-v01@openssh.com": {"ca_key_size": 4096, "ca_key_type": "ssh-rsa", "hostkey_size": 4096}, "rsa-sha2-512": {"hostkey_size": 4096}, "rsa-sha2-512-cert-v01@openssh.com": {"ca_key_size": 4096, "ca_key_type": "ssh-rsa", "hostkey_size": 4096}, "sk-ssh-ed25519-cert-v01@openssh.com": {"ca_key_size": 256, "ca_key_type": "ssh-ed25519", "hostkey_size": 256}, "sk-ssh-ed25519@openssh.com": {"hostkey_size": 256}, "ssh-ed25519": {"hostkey_size": 256}, "ssh-ed25519-cert-v01@openssh.com": {"ca_key_size": 256, "ca_key_type": "ssh-ed25519", "hostkey_size": 256}}, 'dh_modulus_sizes': {'diffie-hellman-group-exchange-sha256': 3072}, 'server_policy': True},
# Amazon Linux Policies
'Hardened Amazon Linux Client 2023 (version 1)': {'version': '1', 'changelog': 'Initial version.', 'banner': None, 'compressions': None, 'host_keys': ['sk-ssh-ed25519-cert-v01@openssh.com', 'ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'sk-ssh-ed25519@openssh.com', 'ssh-ed25519', 'rsa-sha2-512', 'rsa-sha2-256'], 'optional_host_keys': None, 'kex': ['sntrup761x25519-sha512@openssh.com', 'curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256', 'ext-info-c', 'kex-strict-c-v00@openssh.com'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@openssh.com'], 'hostkey_sizes': None, 'dh_modulus_sizes': None, 'server_policy': False},
# Debian Client Policies
'Hardened Debian Client 12 (version 1)': {'version': '1', 'changelog': 'Initial version.', 'banner': None, 'compressions': None, 'host_keys': ['sk-ssh-ed25519-cert-v01@openssh.com', 'ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'sk-ssh-ed25519@openssh.com', 'ssh-ed25519', 'rsa-sha2-512', 'rsa-sha2-256'], 'optional_host_keys': None, 'kex': ['sntrup761x25519-sha512@openssh.com', 'curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256', 'ext-info-c', 'kex-strict-c-v00@openssh.com'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@openssh.com'], 'hostkey_sizes': None, 'dh_modulus_sizes': None, 'server_policy': False},
# Rocky Linux Policies
'Hardened Rocky Linux Client 9 (version 1)': {'version': '1', 'changelog': 'Initial version.', 'banner': None, 'compressions': None, 'host_keys': ['sk-ssh-ed25519-cert-v01@openssh.com', 'ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'sk-ssh-ed25519@openssh.com', 'ssh-ed25519', 'rsa-sha2-512', 'rsa-sha2-256'], 'optional_host_keys': None, 'kex': ['sntrup761x25519-sha512@openssh.com', 'curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256', 'ext-info-c', 'kex-strict-c-v00@openssh.com'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@openssh.com'], 'hostkey_sizes': None, 'dh_modulus_sizes': None, 'server_policy': False},
# Ubuntu Client policies
'Hardened Ubuntu Client 16.04 LTS (version 2)': {'version': '2', 'changelog': 'No change log available.', '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', 'changelog': 'No change log available.', '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 3)': {'version': '3', 'changelog': 'Added kex-strict-c-v00@openssh.com to kex list.', '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', 'kex-strict-c-v00@openssh.com'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@openssh.com'], 'hostkey_sizes': None, 'dh_modulus_sizes': None, 'server_policy': False},
'Hardened Ubuntu Client 22.04 LTS (version 4)': {'version': '4', 'changelog': 'Added kex-strict-c-v00@openssh.com to kex list.', 'banner': None, 'compressions': None, 'host_keys': ['sk-ssh-ed25519-cert-v01@openssh.com', 'ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-512-cert-v01@openssh.com', 'rsa-sha2-256-cert-v01@openssh.com', 'sk-ssh-ed25519@openssh.com', 'ssh-ed25519', 'rsa-sha2-512', 'rsa-sha2-256'], 'optional_host_keys': None, 'kex': ['sntrup761x25519-sha512@openssh.com', 'curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256', 'ext-info-c', 'kex-strict-c-v00@openssh.com'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@openssh.com'], 'hostkey_sizes': None, 'dh_modulus_sizes': None, 'server_policy': False},
}

1064
src/ssh_audit/dheat.py Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
""" """
The MIT License (MIT) The MIT License (MIT)
Copyright (C) 2017-2020 Joe Testa (jtesta@positronsecurity.com) Copyright (C) 2017-2021 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
@ -33,11 +33,11 @@ class Fingerprint:
@property @property
def md5(self) -> str: def md5(self) -> str:
h = hashlib.md5(self.__fpd).hexdigest() h = hashlib.md5(self.__fpd).hexdigest()
r = u':'.join(h[i:i + 2] for i in range(0, len(h), 2)) r = ':'.join(h[i:i + 2] for i in range(0, len(h), 2))
return u'MD5:{}'.format(r) return 'MD5:{}'.format(r)
@property @property
def sha256(self) -> str: def sha256(self) -> str:
h = base64.b64encode(hashlib.sha256(self.__fpd).digest()) h = base64.b64encode(hashlib.sha256(self.__fpd).digest())
r = h.decode('ascii').rstrip('=') r = h.decode('ascii').rstrip('=')
return u'SHA256:{}'.format(r) return 'SHA256:{}'.format(r)

View File

@ -1,7 +1,7 @@
""" """
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)
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,17 +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.
""" """
import os import struct
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
from ssh_audit.kexdh import KexGroupExchange_SHA1, KexGroupExchange_SHA256 from ssh_audit.banner import Banner
from ssh_audit.protocol import Protocol from ssh_audit.kexdh import KexDHException, KexGroupExchange, 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 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
@ -40,37 +43,88 @@ class GEXTest:
# Creates a new connection to the server. Returns True on success, or False. # Creates a new connection to the server. Returns True on success, or False.
@staticmethod @staticmethod
def reconnect(s: 'SSH_Socket', gex_alg: str) -> bool: def reconnect(out: 'OutputBuffer', s: 'SSH_Socket', kex: 'SSH2_Kex', gex_alg: str) -> bool:
if s.is_connected(): if s.is_connected():
return True return True
err = s.connect() err = s.connect()
if err is not None: if err is not None:
out.v(err, write_now=True)
return False return False
unused = None # pylint: disable=unused-variable _, _, err = s.get_banner()
unused2 = None # pylint: disable=unused-variable
unused, unused2, err = s.get_banner()
if err is not None: if err is not None:
out.v(err, write_now=True)
s.close() s.close()
return False return False
# Parse the server's initial KEX.
packet_type = 0 # pylint: disable=unused-variable
packet_type, payload = s.read_packet(2)
kex = SSH2_Kex.parse(payload)
# Send our KEX using the specified group-exchange and most of the # Send our KEX using the specified group-exchange and most of the
# server's own values. # server's own values.
client_kex = SSH2_Kex(os.urandom(16), [gex_alg], kex.key_algorithms, kex.client, kex.server, False, 0) s.send_kexinit(key_exchanges=[gex_alg], hostkeys=kex.key_algorithms, ciphers=kex.server.encryption, macs=kex.server.mac, compressions=kex.server.compression, languages=kex.server.languages)
s.write_byte(Protocol.MSG_KEXINIT)
client_kex.write(s) try:
s.send_packet() # Parse the server's KEX.
_, payload = s.read_packet(2)
SSH2_Kex.parse(out, payload)
except (KexDHException, struct.error):
out.v("Failed to parse server's kex. Stack trace:\n%s" % str(traceback.format_exc()), write_now=True)
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.
modulus_size_returned, reconnect_failed = GEXTest._send_init(out, s, kex_group, kex, gex_alg, bits_min, bits_pref, bits_max)
if reconnect_failed:
out.fail('Reconnect failed.')
return exitcodes.FAILURE
if modulus_size_returned > 0:
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(s: 'SSH_Socket', kex: 'SSH2_Kex') -> None: def run(out: 'OutputBuffer', s: 'SSH_Socket', banner: Optional['Banner'], kex: 'SSH2_Kex') -> None:
GEX_ALGS = { GEX_ALGS = {
'diffie-hellman-group-exchange-sha1': KexGroupExchange_SHA1, 'diffie-hellman-group-exchange-sha1': KexGroupExchange_SHA1,
'diffie-hellman-group-exchange-sha256': KexGroupExchange_SHA256, 'diffie-hellman-group-exchange-sha256': KexGroupExchange_SHA256,
@ -84,30 +138,15 @@ class GEXTest:
# Check if the server supports any of the group-exchange # Check if the server supports any of the group-exchange
# algorithms. If so, test each one. # algorithms. If so, test each one.
for gex_alg in GEX_ALGS: for gex_alg, kex_group_class in GEX_ALGS.items(): # pylint: disable=too-many-nested-blocks
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 + ' with min, pref and max modulus sizes of 512 bits, 1024 bits and 1536 bits...', write_now=True)
if GEXTest.reconnect(s, gex_alg) is False: kex_group = kex_group_class(out)
smallest_modulus, reconnect_failed = GEXTest._send_init(out, s, kex_group, kex, gex_alg, 512, 1024, 1536)
if reconnect_failed:
break break
kex_group = GEX_ALGS[gex_alg]()
smallest_modulus = -1
# First try a range of weak sizes.
try:
kex_group.send_init_gex(s, 512, 1024, 1536)
kex_group.recv_reply(s, False)
# Its been observed that servers will return a group
# larger than the requested max. So just because we
# got here, doesn't mean the server is vulnerable...
smallest_modulus = kex_group.get_dh_modulus_size()
except Exception:
pass
finally:
s.close()
# Try an array of specific modulus sizes... one at a time. # Try an array of specific modulus sizes... one at a time.
reconnect_failed = False reconnect_failed = False
for bits in [512, 768, 1024, 1536, 2048, 3072, 4096]: for bits in [512, 768, 1024, 1536, 2048, 3072, 4096]:
@ -117,31 +156,25 @@ class GEXTest:
if bits >= smallest_modulus > 0: if bits >= smallest_modulus > 0:
break break
if GEXTest.reconnect(s, gex_alg) is False: smallest_modulus, reconnect_failed = GEXTest._send_init(out, s, kex_group, kex, gex_alg, bits, bits, bits)
reconnect_failed = True
break
try: # If the smallest modulus is 2048 and the server is OpenSSH, then we may have triggered the fallback mechanism, which tends to happen in testing scenarios such as this but not in most real-world conditions (see X). To better test this condition, we will do an additional check to see if the server supports sizes between 2048 and 4096, and consider this the definitive result.
kex_group.send_init_gex(s, bits, bits, bits) openssh_test_updated = False
kex_group.recv_reply(s, False) if (smallest_modulus == 2048) and (banner is not None) and (banner.software is not None) and (banner.software.find('OpenSSH') != -1):
smallest_modulus = kex_group.get_dh_modulus_size() out.d('First pass found a minimum GEX modulus of 2048 against OpenSSH server. Performing a second pass to get a more accurate result...')
except Exception: smallest_modulus, _ = GEXTest._send_init(out, s, kex_group, kex, gex_alg, 2048, 3072, 4096)
# import traceback out.d('Modulus size returned by server during second pass: %d bits' % smallest_modulus, write_now=True)
# print(traceback.format_exc()) openssh_test_updated = bool((smallest_modulus > 0) and (smallest_modulus != 2048))
pass
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 smallest_modulus > 0: if smallest_modulus > 0:
kex.set_dh_modulus_size(gex_alg, smallest_modulus) kex.set_dh_modulus_size(gex_alg, smallest_modulus)
lst = SSH2_KexDB.get_db()['kex'][gex_alg]
# We flag moduli smaller than 2048 as a failure. # We flag moduli smaller than 2048 as a failure.
if smallest_modulus < 2048: if smallest_modulus < 2048:
text = 'using small %d-bit modulus' % smallest_modulus text = 'using small %d-bit modulus' % smallest_modulus
lst = SSH2_KexDB.ALGORITHMS['kex'][gex_alg]
# For 'diffie-hellman-group-exchange-sha256', add # For 'diffie-hellman-group-exchange-sha256', add
# a failure reason. # a failure reason.
if len(lst) == 1: if len(lst) == 1:
@ -153,5 +186,51 @@ 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:
# 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 we retested against OpenSSH (because its fallback mechanism was triggered), add a special note for the user.
if openssh_test_updated:
text = "OpenSSH's GEX fallback mechanism was triggered during testing. Very old SSH clients will still be able to create connections using a 2048-bit modulus, though modern clients will use %u. This can only be disabled by recompiling the code (see https://github.com/openssh/openssh-portable/blob/V_9_4/dh.c#L477)." % smallest_modulus
# Ensure that an info list exists for us to append to, below.
while len(lst) < 4:
lst.append([])
# Ensure this is only added once.
if text not in lst[3]:
lst[3].append(text)
if reconnect_failed: if reconnect_failed:
break break
@staticmethod
def _send_init(out: 'OutputBuffer', s: 'SSH_Socket', kex_group: 'KexGroupExchange', kex: 'SSH2_Kex', gex_alg: str, min_bits: int, pref_bits: int, max_bits: int) -> Tuple[int, bool]:
'''Internal function for sending the GEX initialization to the server with the minimum, preferred, and maximum modulus bits. Returns a Tuple of the modulus size received from the server (or -1 on error) and boolean signifying that the connection to the server failed.'''
smallest_modulus = -1
reconnect_failed = False
try:
if GEXTest.reconnect(out, s, kex, gex_alg) is False:
reconnect_failed = True
out.d('GEXTest._send_init(%s, %u, %u, %u): reconnection failed.' % (gex_alg, min_bits, pref_bits, max_bits), write_now=True)
else:
kex_group.send_init_gex(s, min_bits, pref_bits, max_bits)
kex_group.recv_reply(s, False)
smallest_modulus = kex_group.get_dh_modulus_size()
out.d('GEXTest._send_init(%s, %u, %u, %u): received modulus size: %d' % (gex_alg, min_bits, pref_bits, max_bits, smallest_modulus), write_now=True)
except KexDHException as e:
out.d('GEXTest._send_init(%s, %u, %u, %u): exception when performing DH group exchange init: %s' % (gex_alg, min_bits, pref_bits, max_bits, str(e)), write_now=True)
finally:
s.close()
return smallest_modulus, reconnect_failed

View File

@ -1,7 +1,7 @@
""" """
The MIT License (MIT) The MIT License (MIT)
Copyright (C) 2017-2020 Joe Testa (jtesta@positronsecurity.com) Copyright (C) 2017-2024 Joe Testa (jtesta@positronsecurity.com)
Permission is hereby granted, free of charge, to any person obtaining a copy 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,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.3.1' # The version to display.
SSH_HEADER = 'SSH-{0}-OpenSSH_8.2' # SSH software to impersonate VERSION = 'v3.2.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 Docker, PyPI, Snap, and Windows builds.
BUILTIN_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"'

View File

@ -1,7 +1,7 @@
""" """
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)
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,17 +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 os
# 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
from ssh_audit.kexdh import KexDH, KexGroup1, KexGroup14_SHA1, KexGroup14_SHA256, KexCurve25519_SHA256, KexGroup16_SHA512, KexGroup18_SHA512, KexGroupExchange_SHA1, KexGroupExchange_SHA256, KexNISTP256, KexNISTP384, KexNISTP521 import traceback
from ssh_audit.protocol import Protocol
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
from ssh_audit.outputbuffer import OutputBuffer
# Obtains host keys, checks their size, and derives their fingerprints. # Obtains host keys, checks their size, and derives their fingerprints.
@ -53,8 +54,12 @@ 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(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 = {
'diffie-hellman-group1-sha1': KexGroup1, 'diffie-hellman-group1-sha1': KexGroup1,
'diffie-hellman-group14-sha1': KexGroup14_SHA1, 'diffie-hellman-group14-sha1': KexGroup14_SHA1,
@ -78,14 +83,14 @@ 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:
HostKeyTest.perform_test(s, server_kex, kex_str, kex_group, HostKeyTest.HOST_KEY_TYPES) HostKeyTest.perform_test(out, s, server_kex, kex_str, kex_group, HostKeyTest.HOST_KEY_TYPES)
@staticmethod @staticmethod
def perform_test(s: 'SSH_Socket', server_kex: 'SSH2_Kex', kex_str: str, kex_group: 'KexDH', host_key_types: Dict[str, Dict[str, bool]]) -> None: def perform_test(out: 'OutputBuffer', s: 'SSH_Socket', server_kex: 'SSH2_Kex', kex_str: str, kex_group: 'KexDH', host_key_types: Dict[str, Dict[str, bool]]) -> None:
hostkey_modulus_size = 0 hostkey_modulus_size = 0
ca_modulus_size = 0 ca_modulus_size = 0
@ -97,50 +102,69 @@ 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
# If this host key type is supported by the server, we test it. # If this host key type is supported by the server, we test it.
if host_key_type in server_kex.key_algorithms: if host_key_type in server_kex.key_algorithms:
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():
err = s.connect() err = s.connect()
if err is not None: if err is not None:
out.v(err, write_now=True)
return return
_, _, err = s.get_banner() _, _, err = s.get_banner()
if err is not None: if err is not None:
out.v(err, write_now=True)
s.close() s.close()
return return
# Parse the server's initial KEX. # Send our KEX using the specified group-exchange and most of the server's own values.
packet_type = 0 # pylint: disable=unused-variable s.send_kexinit(key_exchanges=[kex_str], hostkeys=[host_key_type], ciphers=server_kex.server.encryption, macs=server_kex.server.mac, compressions=server_kex.server.compression, languages=server_kex.server.languages)
packet_type, payload = s.read_packet()
SSH2_Kex.parse(payload)
# Send the server our KEXINIT message, using only our try:
# selected kex and host key type. Send the server's own # Parse the server's KEX.
# list of ciphers and MACs back to it (this doesn't _, payload = s.read_packet()
# matter, really). SSH2_Kex.parse(out, payload)
client_kex = SSH2_Kex(os.urandom(16), [kex_str], [host_key_type], server_kex.client, server_kex.server, False, 0) except Exception:
out.v("Failed to parse server's kex. Stack trace:\n%s" % str(traceback.format_exc()), write_now=True)
s.write_byte(Protocol.MSG_KEXINIT) return
client_kex.write(s)
s.send_packet()
# 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)
host_key = kex_group.recv_reply(s, variable_key_len) raw_hostkey_bytes = b''
if host_key is not None: try:
server_kex.set_host_key(host_key_type, host_key) kex_reply = kex_group.recv_reply(s)
raw_hostkey_bytes = kex_reply if kex_reply is not None else b''
except KexDHException:
out.v("Failed to parse server's host key. Stack trace:\n%s" % str(traceback.format_exc()), write_now=True)
# 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.
@ -148,29 +172,66 @@ 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 ca_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 the key is under 2048, add to the failure list.
alg_list.append(['using small %d-bit modulus' % hostkey_modulus_size]) if hostkey_modulus_size < hostkey_min_warn:
elif (cert is True) and ((hostkey_modulus_size < 2048) or (ca_modulus_size > 0 and ca_modulus_size < 2048)): # pylint: disable=chained-comparison key_fail_comments.append('using small %d-bit modulus' % hostkey_modulus_size)
alg_list = SSH2_KexDB.ALGORITHMS['key'][host_key_type] elif hostkey_warn_str not in key_warn_comments: # Issue a warning about 2048-bit moduli.
min_modulus = min(hostkey_modulus_size, ca_modulus_size) key_warn_comments.append(hostkey_warn_str)
min_modulus = min_modulus if min_modulus > 0 else max(hostkey_modulus_size, ca_modulus_size)
alg_list.append(['using small %d-bit modulus' % min_modulus]) elif (cert is True) and ((hostkey_modulus_size < hostkey_min_good) or (0 < ca_modulus_size < cakey_min_good)):
# If the host key is smaller than 2048-bit/224-bit, flag this as a failure.
if hostkey_modulus_size < hostkey_min_warn:
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 the CA key type uses ECDSA with a NIST P-curve, fail it for possibly being back-doored.
if ca_key_type.startswith('ecdsa-sha2-nistp'):
key_fail_comments.append('CA key uses elliptic curves that are suspected as being backdoored by the U.S. National Security Agency')
# 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.
db = SSH2_KexDB.get_db()
while len(db['key'][rsa_type]) < 3:
db['key'][rsa_type].append([])
db['key'][rsa_type][1].extend(key_fail_comments)
db['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
db = SSH2_KexDB.get_db()
while len(db['key'][host_key_type]) < 3:
db['key'][host_key_type].append([])
db['key'][host_key_type][1].extend(key_fail_comments)
db['key'][host_key_type][2].extend(key_warn_comments)

View File

@ -1,7 +1,7 @@
""" """
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)
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
@ -26,19 +26,26 @@ import binascii
import os import os
import random import random
import struct import struct
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
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.__kex_name = kex_name self.out = out
self.__hash_alg = hash_alg self.__kex_name = kex_name # pylint: disable=unused-private-member
self.__hash_alg = hash_alg # pylint: disable=unused-private-member
self.__g = 0 self.__g = 0
self.__p = 0 self.__p = 0
self.__q = 0 self.__q = 0
@ -46,11 +53,12 @@ class KexDH: # pragma: nocover
self.__e = 0 self.__e = 0
self.set_params(g, p) self.set_params(g, p)
self.__ed25519_pubkey = None # type: Optional[bytes] self.__ed25519_pubkey: Optional[bytes] = None # pylint: disable=unused-private-member
self.__hostkey_type = None # type: Optional[bytes] self.__hostkey_type = ''
self.__hostkey_e = 0 self.__hostkey_e = 0 # pylint: disable=unused-private-member
self.__hostkey_n = 0 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 +80,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 invocation.
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 +95,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 package_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,76 +117,115 @@ 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) self.__hostkey_e = int(binascii.hexlify(hostkey_e), 16) # pylint: disable=unused-private-member
# Here is the modulus size & actual modulus of the host key public key. # ED25519 moduli are fixed at 32 bytes.
hostkey_n, self.__hostkey_n_len, ptr = KexDH.__get_bytes(hostkey, ptr) if self.__hostkey_type == 'ssh-ed25519':
self.__hostkey_n = int(binascii.hexlify(hostkey_n), 16) 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.
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
# 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.
# Skip over the serial number. self.__ca_key_type, self.__ca_n_len = self.__parse_ca_key(hostkey, self.__hostkey_type, ptr)
ptr += 8 self.out.d("KexDH.__parse_ca_key(): CA key type: [%s]; CA key length: %u" % (self.__ca_key_type, self.__ca_n_len))
# Get the certificate type.
cert_type = int(binascii.hexlify(hostkey[ptr:ptr + 4]), 16)
ptr += 4
# Only SSH2_CERT_TYPE_HOST (2) makes sense in this context.
if cert_type == 2:
# Skip the key ID (this is the serial number of the
# certificate).
key_id, key_id_len, ptr = KexDH.__get_bytes(hostkey, ptr)
# The principles, which are... I don't know what.
principles, principles_len, ptr = KexDH.__get_bytes(hostkey, ptr)
# Skip over the timestamp that this certificate is valid after.
ptr += 8
# Skip over the timestamp that this certificate is valid before.
ptr += 8
# TODO: validate the principles, and time range.
# The critical options.
critical_options, critical_options_len, ptr = KexDH.__get_bytes(hostkey, ptr)
# Certificate extensions.
extensions, extensions_len, ptr = KexDH.__get_bytes(hostkey, ptr)
# Another nonce.
nonce, nonce_len, ptr = KexDH.__get_bytes(hostkey, ptr)
# Finally, we get to the CA key.
ca_key, ca_key_len, ptr = KexDH.__get_bytes(hostkey, ptr)
# Last in the host key blob is the CA signature. It isn't
# interesting to us, so we won't bother parsing any further.
# The CA key has the modulus, however...
ptr = 0
# 'ssh-rsa', 'rsa-sha2-256', etc.
ca_key_type, ca_key_type_len, ptr = KexDH.__get_bytes(ca_key, ptr)
# CA's public key exponent.
ca_key_e, ca_key_e_len, ptr = KexDH.__get_bytes(ca_key, ptr)
# CA's modulus. Bingo.
ca_key_n, self.__ca_n_len, ptr = KexDH.__get_bytes(ca_key, ptr)
return hostkey 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.
ptr += 8
# Get the certificate type.
cert_type = int(binascii.hexlify(hostkey[ptr:ptr + 4]), 16)
ptr += 4
# Only SSH2_CERT_TYPE_HOST (2) makes sense in this context.
if cert_type == 2:
# Skip the key ID (this is the serial number of the
# certificate).
key_id, key_id_len, ptr = KexDH.__get_bytes(hostkey, ptr) # pylint: disable=unused-variable
# The principles, which are... I don't know what.
principles, principles_len, ptr = KexDH.__get_bytes(hostkey, ptr) # pylint: disable=unused-variable
# Skip over the timestamp that this certificate is valid after.
ptr += 8
# Skip over the timestamp that this certificate is valid before.
ptr += 8
# TODO: validate the principles, and time range.
# The critical options.
critical_options, critical_options_len, ptr = KexDH.__get_bytes(hostkey, ptr) # pylint: disable=unused-variable
# Certificate extensions.
extensions, extensions_len, ptr = KexDH.__get_bytes(hostkey, ptr) # pylint: disable=unused-variable
# Another nonce.
nonce, nonce_len, ptr = KexDH.__get_bytes(hostkey, ptr) # pylint: disable=unused-variable
# Finally, we get to the CA key.
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
# interesting to us, so we won't bother parsing any further.
# The CA key has the modulus, however...
ptr = 0
# 'ssh-rsa', 'rsa-sha2-256', etc.
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_key_e, ca_key_e_len, ptr = KexDH.__get_bytes(ca_key, ptr) # pylint: disable=unused-variable
# CA's modulus. Bingo.
ca_key_n, ca_key_n_len, ptr = KexDH.__get_bytes(ca_key, ptr) # pylint: disable=unused-variable
if ca_key_type.startswith("ecdsa-sha2-nistp") and ca_key_n_len > 0:
self.out.d("Found ecdsa-sha2-nistp* CA key type.")
# 0x04 signifies that this is an uncompressed public key (meaning that full X and Y values are provided in ca_key_n.
if ca_key_n[0] == 4:
ca_key_n_len = ca_key_n_len - 1 # Subtract the 0x04 byte.
ca_key_n_len = int(ca_key_n_len / 2) # Divide by 2 since the modulus is the size of either the X or Y value.
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]:
num_bytes = struct.unpack('>I', buf[ptr:ptr + 4])[0] num_bytes = struct.unpack('>I', buf[ptr:ptr + 4])[0]
@ -202,10 +245,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 +268,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 +319,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 +334,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 +345,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 +356,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)
@ -327,27 +378,29 @@ class KexGroupExchange(KexDH):
s.send_packet() s.send_packet()
packet_type, payload = s.read_packet(2) packet_type, payload = s.read_packet(2)
if (packet_type != Protocol.MSG_KEXDH_GEX_GROUP) and (packet_type != Protocol.MSG_DEBUG): # pylint: disable=consider-using-in 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:
packet_type, payload = s.read_packet(2) packet_type, payload = s.read_packet(2)
# Parse the modulus (p) and generator (g) values from the server. try:
ptr = 0 # Parse the modulus (p) and generator (g) values from the server.
p_len = struct.unpack('>I', payload[ptr:ptr + 4])[0] ptr = 0
ptr += 4 p_len = struct.unpack('>I', payload[ptr:ptr + 4])[0]
ptr += 4
p = int(binascii.hexlify(payload[ptr:ptr + p_len]), 16) p = int(binascii.hexlify(payload[ptr:ptr + p_len]), 16)
ptr += p_len ptr += p_len
g_len = struct.unpack('>I', payload[ptr:ptr + 4])[0] g_len = struct.unpack('>I', payload[ptr:ptr + 4])[0]
ptr += 4 ptr += 4
g = int(binascii.hexlify(payload[ptr:ptr + g_len]), 16) g = int(binascii.hexlify(payload[ptr:ptr + g_len]), 16)
ptr += g_len ptr += g_len
except struct.error:
raise KexDHException("Error while parsing modulus and generator during GEX init: %s" % str(traceback.format_exc())) from None
# Now that we got the generator and modulus, perform the DH exchange # Now that we got the generator and modulus, perform the DH exchange
# like usual. # like usual.
@ -356,10 +409,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')

View File

@ -1,87 +0,0 @@
"""
The MIT License (MIT)
Copyright (C) 2017 Andris Raugulis (moo@arthepsy.eu)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
import os
import sys
# pylint: disable=unused-import
from typing import Dict, List, Set, Sequence, Tuple, Iterable # noqa: F401
from typing import Callable, Optional, Union, Any # noqa: F401
from ssh_audit.utils import Utils
class Output:
LEVELS = ('info', 'warn', 'fail') # type: Sequence[str]
COLORS = {'head': 36, 'good': 32, 'warn': 33, 'fail': 31}
# Use brighter colors on Windows for better readability.
if Utils.is_windows():
COLORS = {'head': 96, 'good': 92, 'warn': 93, 'fail': 91}
def __init__(self) -> None:
self.batch = False
self.verbose = False
self.use_colors = True
self.json = False
self.__level = 0
self.__colsupport = 'colorama' in sys.modules or os.name == 'posix'
@property
def level(self) -> str:
if self.__level < len(self.LEVELS):
return self.LEVELS[self.__level]
return 'unknown'
@level.setter
def level(self, name: str) -> None:
self.__level = self.get_level(name)
def get_level(self, name: str) -> int:
cname = 'info' if name == 'good' else name
if cname not in self.LEVELS:
return sys.maxsize
return self.LEVELS.index(cname)
def sep(self) -> None:
if not self.batch:
print()
@property
def colors_supported(self) -> bool:
return self.__colsupport
@staticmethod
def _colorized(color: str) -> Callable[[str], None]:
return lambda x: print(u'{}{}\033[0m'.format(color, x))
def __getattr__(self, name: str) -> Callable[[str], None]:
if name == 'head' and self.batch:
return lambda x: None
if not self.get_level(name) >= self.__level:
return lambda x: None
if self.use_colors and self.colors_supported and name in self.COLORS:
color = '\033[0;{}m'.format(self.COLORS[name])
return self._colorized(color)
else:
return lambda x: print(u'{}'.format(x))

View File

@ -1,7 +1,7 @@
""" """
The MIT License (MIT) The MIT License (MIT)
Copyright (C) 2017-2020 Joe Testa (jtesta@positronsecurity.com) Copyright (C) 2021 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
@ -22,29 +22,164 @@
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 io import os
import sys import sys
# 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
from ssh_audit.utils import Utils
class OutputBuffer(List[str]):
class OutputBuffer:
LEVELS: Sequence[str] = ('info', 'warn', 'fail')
COLORS = {'head': 36, 'good': 32, 'warn': 33, 'fail': 31}
# Use brighter colors on Windows for better readability.
if Utils.is_windows():
COLORS = {'head': 96, 'good': 92, 'warn': 93, 'fail': 91}
def __init__(self, buffer_output: bool = True) -> None:
self.buffer_output = buffer_output
self.buffer: List[str] = []
self.in_section = False
self.section: List[str] = []
self.batch = False
self.verbose = False
self.debug = False
self.use_colors = True
self.json = False
self.__level = 0
self.__is_color_supported = ('colorama' in sys.modules) or (os.name == 'posix')
self.line_ended = True
def _print(self, level: str, s: str = '', line_ended: bool = True) -> None:
'''Saves output to buffer (if in buffered mode), or immediately prints to stdout otherwise.'''
# If we're logging only 'warn' or above, and this is an 'info', ignore message.
if self.get_level(level) < self.__level:
return
if self.use_colors and self.colors_supported and len(s) > 0 and level != 'info':
s = "\033[0;%dm%s\033[0m" % (self.COLORS[level], s)
if self.buffer_output:
# Select which list to add to. If we are in a 'with' statement, then this goes in the section buffer, otherwise the general buffer.
buf = self.section if self.in_section else self.buffer
# Determine if a new line should be added, or if the last line should be appended.
if not self.line_ended:
last_entry = -1 if len(buf) > 0 else 0
buf[last_entry] = buf[last_entry] + s
else:
buf.append(s)
# When False, this tells the next call to append to the last line we just added.
self.line_ended = line_ended
else:
print(s)
def get_buffer(self) -> str:
'''Returns all buffered output, then clears the buffer.'''
self.flush_section()
buffer_str = "\n".join(self.buffer)
self.buffer = []
return buffer_str
def write(self) -> None:
'''Writes the output to stdout.'''
self.flush_section()
print(self.get_buffer(), flush=True)
def reset(self) -> None:
self.flush_section()
self.get_buffer()
@property
def level(self) -> str:
'''Returns the minimum level for output.'''
if self.__level < len(self.LEVELS):
return self.LEVELS[self.__level]
return 'unknown'
@level.setter
def level(self, name: str) -> None:
'''Sets the minimum level for output (one of: 'info', 'warn', 'fail').'''
self.__level = self.get_level(name)
def get_level(self, name: str) -> int:
cname = 'info' if name == 'good' else name
if cname not in self.LEVELS:
return sys.maxsize
return self.LEVELS.index(cname)
@property
def colors_supported(self) -> bool:
'''Returns True if the system supports color output.'''
return self.__is_color_supported
# When used in a 'with' block, the output to goes into a section; this can be sorted separately when add_section_to_buffer() is later called.
def __enter__(self) -> 'OutputBuffer': def __enter__(self) -> 'OutputBuffer':
# pylint: disable=attribute-defined-outside-init self.in_section = True
self.__buf = io.StringIO()
self.__stdout = sys.stdout
sys.stdout = self.__buf
return self return self
def flush(self, sort_lines: bool = False) -> None:
# Lines must be sorted in some cases to ensure consistent testing.
if sort_lines:
self.sort() # pylint: disable=no-member
for line in self: # pylint: disable=not-an-iterable
print(line)
def __exit__(self, *args: Any) -> None: def __exit__(self, *args: Any) -> None:
self.extend(self.__buf.getvalue().splitlines()) # pylint: disable=no-member self.in_section = False
sys.stdout = self.__stdout
def flush_section(self, sort_section: bool = False) -> None:
'''Appends section output (optionally sorting it first) to the end of the buffer, then clears the section output.'''
if sort_section:
self.section.sort()
self.buffer.extend(self.section)
self.section = []
def is_section_empty(self) -> bool:
'''Returns True if the section buffer is empty, otherwise False.'''
return len(self.section) == 0
def head(self, s: str, line_ended: bool = True) -> 'OutputBuffer':
if not self.batch:
self._print('head', s, line_ended)
return self
def fail(self, s: str, line_ended: bool = True) -> 'OutputBuffer':
self._print('fail', s, line_ended)
return self
def warn(self, s: str, line_ended: bool = True) -> 'OutputBuffer':
self._print('warn', s, line_ended)
return self
def info(self, s: str, line_ended: bool = True) -> 'OutputBuffer':
self._print('info', s, line_ended)
return self
def good(self, s: str, line_ended: bool = True) -> 'OutputBuffer':
self._print('good', s, line_ended)
return self
def sep(self) -> 'OutputBuffer':
if not self.batch:
self._print('info')
return self
def v(self, s: str, write_now: bool = False) -> 'OutputBuffer':
'''Prints a message if verbose output is enabled.'''
if self.verbose or self.debug:
self.info(s)
if write_now:
self.write()
return self
def d(self, s: str, write_now: bool = False) -> 'OutputBuffer':
'''Prints a message if verbose output is enabled.'''
if self.debug:
self.info(s)
if write_now:
self.write()
return self

View File

@ -1,7 +1,7 @@
""" """
The MIT License (MIT) The MIT License (MIT)
Copyright (C) 2020 Joe Testa (jtesta@positronsecurity.com) Copyright (C) 2020-2024 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,71 +30,41 @@ 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.builtin_policies import BUILTIN_POLICIES
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. 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"
BUILTIN_POLICIES = {
# Ubuntu Server policies 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
'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}, self._version: Optional[str] = None
self._banner: Optional[str] = None
'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}, self._compressions: Optional[List[str]] = None
self._host_keys: Optional[List[str]] = None
'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}, self._optional_host_keys: Optional[List[str]] = None
self._kex: Optional[List[str]] = None
self._ciphers: Optional[List[str]] = None
# Generic OpenSSH Server policies self._macs: Optional[List[str]] = None
self._hostkey_sizes: Optional[Dict[str, Dict[str, Union[int, str, bytes]]]] = None
'Hardened OpenSSH Server v7.7 (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}, self._dh_modulus_sizes: Optional[Dict[str, int]] = None
'Hardened OpenSSH Server v7.8 (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 OpenSSH Server v7.9 (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 OpenSSH Server v8.0 (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 OpenSSH Server v8.1 (version 1)': {'version': '1', 'banner': None, 'compressions': None, 'host_keys': ['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.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.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.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},
# 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 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 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},
} # type: Dict[str, Dict[str, Union[Optional[str], Optional[List[str]], bool, Dict[str, int]]]]
def __init__(self, policy_file: Optional[str] = None, policy_data: Optional[str] = None, manual_load: bool = False) -> None:
self._name = None # type: Optional[str]
self._version = None # type: Optional[str]
self._banner = None # type: Optional[str]
self._compressions = None # type: Optional[List[str]]
self._host_keys = None # type: Optional[List[str]]
self._optional_host_keys = None # type: Optional[List[str]]
self._kex = None # type: Optional[List[str]]
self._ciphers = None # type: Optional[List[str]]
self._macs = None # type: Optional[List[str]]
self._hostkey_sizes = None # type: Optional[Dict[str, int]]
self._cakey_sizes = None # type: Optional[Dict[str, int]]
self._dh_modulus_sizes = None # type: Optional[Dict[str, int]]
self._server_policy = True self._server_policy = True
self._allow_algorithm_subset_and_reordering = False
self._allow_larger_keys = False
self._errors: List[Any] = []
self._name_and_version = '' # type: 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
@ -111,11 +83,18 @@ class Policy:
if policy_file is not None: if policy_file is not None:
try: try:
with open(policy_file, "r") as f: with open(policy_file, "r", encoding='utf-8') as f:
policy_data = f.read() policy_data = f.read()
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:
@ -136,7 +115,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', 'allow_algorithm_subset_and_reordering', 'allow_larger_keys'] 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']:
@ -155,8 +134,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(',')
@ -179,24 +160,58 @@ 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
elif key == 'allow_algorithm_subset_and_reordering' and val.lower() == 'true':
self._allow_algorithm_subset_and_reordering = True
elif key == 'allow_larger_keys' and val.lower() == 'true':
self._allow_larger_keys = True
if self._name is None: if self._name is None:
raise ValueError('The policy does not have a name field.') raise ValueError('The policy does not have a name field.')
@ -206,13 +221,25 @@ class Policy:
self._name_and_version = "%s (version %s)" % (self._name, self._version) self._name_and_version = "%s (version %s)" % (self._name, self._version)
@staticmethod def _append_error(self, mismatched_field: str, expected_required: Optional[List[str]], expected_optional: Optional[List[str]], actual: List[str]) -> None:
def _append_error(errors: List[Any], mismatched_field: str, expected_required: Optional[List[str]], expected_optional: Optional[List[str]], actual: List[str]) -> None:
if expected_required is None: if expected_required is None:
expected_required = [''] expected_required = ['']
if expected_optional is None: if expected_optional is None:
expected_optional = [''] expected_optional = ['']
errors.append({'mismatched_field': mismatched_field, 'expected_required': expected_required, 'expected_optional': expected_optional, 'actual': actual}) self._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
@ -225,10 +252,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"
@ -244,26 +270,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 = '''#
@ -276,12 +299,18 @@ name = "Custom Policy (based on %s on %s)"
# The version of this policy (displayed in the output during scans). Not parsed, and may be any value, including strings. # The version of this policy (displayed in the output during scans). Not parsed, and may be any value, including strings.
version = 1 version = 1
# When false, host keys, kex, ciphers, and MAC lists must match exactly. When true, the target host may support a subset of the specified algorithms and/or algorithms may appear in a different order; this feature is useful for specifying a baseline and allowing some hosts the option to implement stricter controls.
allow_algorithm_subset_and_reordering = false
# When false, host keys, CA keys, and Diffie-Hellman key sizes must exactly match what's specified in this policy. When true, target systems are allowed to have larger keys; this feature is useful for specifying a baseline and allowing some hosts the option to implement stricter controls.
allow_larger_keys = false
# The banner that must match exactly. Commented out to ignore banners, since minor variability in the banner is sometimes normal. # The banner that must match exactly. Commented out to ignore banners, since minor variability in the banner is sometimes normal.
# banner = "%s" # banner = "%s"
# 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
@ -296,7 +325,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
@ -305,63 +334,118 @@ macs = %s
'''Evaluates a server configuration against this policy. Returns a tuple of a boolean (True if server adheres to policy) and an array of strings that holds error messages.''' '''Evaluates a server configuration against this policy. Returns a tuple of a boolean (True if server adheres to policy) and an array of strings that holds error messages.'''
ret = True ret = True
errors = [] # type: List[Any]
banner_str = str(banner) banner_str = str(banner)
if (self._banner is not None) and (banner_str != self._banner): if (self._banner is not None) and (banner_str != self._banner):
ret = False ret = False
self._append_error(errors, 'Banner', [self._banner], None, [banner_str]) self._append_error('Banner', [self._banner], None, [banner_str])
# All subsequent tests require a valid kex, so end here if we don't have one. # All subsequent tests require a valid kex, so end here if we don't have one.
if kex is None: if kex is None:
return ret, errors, self._get_error_str(errors) error_list, error_str = self._get_errors()
return ret, error_list, error_str
if (self._compressions is not None) and (kex.server.compression != self._compressions): if (self._compressions is not None) and (kex.server.compression != self._compressions):
ret = False ret = False
self._append_error(errors, 'Compression', self._compressions, None, kex.server.compression) self._append_error('Compression', self._compressions, None, kex.server.compression)
# If a list of optional host keys was given in the policy, remove any of its entries from the list retrieved from the server. This allows us to do an exact comparison with the expected list below. # If a list of optional host keys was given in the policy, remove any of its entries from the list retrieved from the server. This allows us to do an exact comparison with the expected list below.
pruned_host_keys = kex.key_algorithms pruned_host_keys = kex.key_algorithms
if self._optional_host_keys is not None: if self._optional_host_keys is not None:
pruned_host_keys = [x for x in kex.key_algorithms if x not in self._optional_host_keys] pruned_host_keys = [x for x in kex.key_algorithms if x not in self._optional_host_keys]
if (self._host_keys is not None) and (pruned_host_keys != self._host_keys): # Check host keys.
ret = False if self._host_keys is not None:
self._append_error(errors, 'Host keys', self._host_keys, self._optional_host_keys, kex.key_algorithms) # If the policy allows subsets and re-ordered algorithms...
if self._allow_algorithm_subset_and_reordering:
for hostkey_t in kex.key_algorithms:
if hostkey_t not in self._host_keys:
ret = False
self._append_error('Host keys', self._host_keys, self._optional_host_keys, kex.key_algorithms)
break
# The policy requires exact matching of algorithms.
elif pruned_host_keys != self._host_keys:
ret = False
self._append_error('Host keys', self._host_keys, self._optional_host_keys, kex.key_algorithms)
# Check host key sizes.
if self._hostkey_sizes is not None: if self._hostkey_sizes is not None:
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 = cast(int, 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:
if actual_hostkey_size != expected_hostkey_size: actual_hostkey_size = cast(int, server_host_keys[hostkey_type]['hostkey_size'])
if (self._allow_larger_keys and actual_hostkey_size < expected_hostkey_size) or \
(not self._allow_larger_keys and 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('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
self._append_error('CA signature type', [expected_ca_key_type], None, [actual_ca_key_type])
# Ensure that the actual and expected signature sizes match.
elif (self._allow_larger_keys and actual_ca_key_size < expected_ca_key_size) or \
(not self._allow_larger_keys and actual_ca_key_size != expected_ca_key_size):
ret = False
self._append_error('CA signature size (%s)' % actual_ca_key_type, [str(expected_ca_key_size)], None, [str(actual_ca_key_size)])
# Check key exchanges.
if self._kex is not None:
# If the policy allows subsets and re-ordered algorithms...
if self._allow_algorithm_subset_and_reordering:
for kex_t in kex.kex_algorithms:
if kex_t not in self._kex:
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('Key exchanges', self._kex, None, kex.kex_algorithms)
break
# If kex-strict-?-v00@openssh.com is in the policy (i.e. the Terrapin vulnerability countermeasure), then it must appear in the server's list, regardless of the "allow_algorithm_subset_and_reordering" flag.
if ('kex-strict-s-v00@openssh.com' in self._kex and 'kex-strict-s-v00@openssh.com' not in kex.kex_algorithms) or \
('kex-strict-c-v00@openssh.com' in self._kex and 'kex-strict-c-v00@openssh.com' not in kex.kex_algorithms):
ret = False
self._append_error('Key exchanges', self._kex, None, kex.kex_algorithms)
if kex.kex_algorithms != self._kex: # The policy requires exact matching of algorithms.
ret = False elif kex.kex_algorithms != self._kex:
self._append_error(errors, 'Key exchanges', self._kex, None, kex.kex_algorithms) ret = False
self._append_error('Key exchanges', self._kex, None, kex.kex_algorithms)
if (self._ciphers is not None) and (kex.server.encryption != self._ciphers): # Checking Ciphers
ret = False if self._ciphers is not None:
self._append_error(errors, 'Ciphers', self._ciphers, None, kex.server.encryption) # If the policy allows subsets and re-ordered algorithms...
if self._allow_algorithm_subset_and_reordering:
for cipher_t in kex.server.encryption:
if cipher_t not in self._ciphers:
ret = False
self._append_error('Ciphers', self._ciphers, None, kex.server.encryption)
break
# The policy requires exact matching of algorithms.
elif kex.server.encryption != self._ciphers:
ret = False
self._append_error('Ciphers', self._ciphers, None, kex.server.encryption)
if (self._macs is not None) and (kex.server.mac != self._macs): # Checking MACs
ret = False if self._macs is not None:
self._append_error(errors, 'MACs', self._macs, None, kex.server.mac) # If the policy allows subsets and re-ordered algorithms...
if self._allow_algorithm_subset_and_reordering:
for mac_t in kex.server.mac:
if mac_t not in self._macs:
ret = False
self._append_error('MACs', self._macs, None, kex.server.mac)
break
# The policy requires exact matching of algorithms.
elif kex.server.mac != self._macs:
ret = False
self._append_error('MACs', self._macs, None, kex.server.mac)
if self._dh_modulus_sizes is not None: if self._dh_modulus_sizes is not None:
dh_modulus_types = list(self._dh_modulus_sizes.keys()) dh_modulus_types = list(self._dh_modulus_sizes.keys())
@ -369,27 +453,31 @@ 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 (self._allow_larger_keys and actual_dh_modulus_size < expected_dh_modulus_size) or \
(not self._allow_larger_keys and actual_dh_modulus_size != expected_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('Group exchange (%s) modulus sizes' % dh_modulus_type, [str(expected_dh_modulus_size)], None, [str(actual_dh_modulus_size)])
return ret, errors, self._get_error_str(errors) error_list, error_str = self._get_errors()
return ret, error_list, error_str
@staticmethod def _get_errors(self) -> Tuple[List[Any], str]:
def _get_error_str(errors: List[Any]) -> str: '''Returns the list of errors, along with the string representation of those errors.'''
'''Transforms an error struct to a flat string of error messages.'''
subset_and_reordering_semicolon = "; subset and/or reordering allowed" if self._allow_algorithm_subset_and_reordering else "; exact match"
subset_and_reordering_parens = " (subset and/or reordering allowed)" if self._allow_algorithm_subset_and_reordering else ""
error_list = [] error_list = []
spacer = '' spacer = ''
for e in errors: for e in self._errors:
e_str = " * %s did not match.\n" % e['mismatched_field'] e_str = " * %s did not match.\n" % e['mismatched_field']
if ('expected_optional' in e) and (e['expected_optional'] != ['']): if ('expected_optional' in e) and (e['expected_optional'] != ['']):
e_str += " - Expected (required): %s\n - Expected (optional): %s\n" % (Policy._normalize_error_field(e['expected_required']), Policy._normalize_error_field(e['expected_optional'])) e_str += " - Expected (required%s): %s\n - Expected (optional): %s\n" % (subset_and_reordering_semicolon, Policy._normalize_error_field(e['expected_required']), Policy._normalize_error_field(e['expected_optional']))
spacer = ' ' spacer = ' '
else: else:
e_str += " - Expected: %s\n" % Policy._normalize_error_field(e['expected_required']) e_str += " - Expected%s: %s\n" % (subset_and_reordering_parens, Policy._normalize_error_field(e['expected_required']))
spacer = ' ' spacer = ' '
e_str += " - Actual:%s%s\n" % (spacer, Policy._normalize_error_field(e['actual'])) e_str += " - Actual:%s%s\n" % (spacer, Policy._normalize_error_field(e['actual']))
error_list.append(e_str) error_list.append(e_str)
@ -400,7 +488,7 @@ macs = %s
if len(error_list) > 0: if len(error_list) > 0:
error_str = "\n".join(error_list) error_str = "\n".join(error_list)
return error_str return self._errors, error_str
def get_name_and_version(self) -> str: def get_name_and_version(self) -> str:
@ -414,29 +502,35 @@ macs = %s
@staticmethod @staticmethod
def list_builtin_policies() -> Tuple[List[str], List[str]]: def list_builtin_policies(verbose: bool) -> Tuple[List[str], List[str]]:
'''Returns two lists: a list of names of built-in server policies, and a list of names of built-in client policies, respectively.''' '''Returns two lists: a list of names of built-in server policies, and a list of names of built-in client policies, respectively.'''
server_policy_names = [] server_policy_descriptions = []
client_policy_names = [] client_policy_descriptions = []
for policy_name in Policy.BUILTIN_POLICIES: for policy_name, policy in BUILTIN_POLICIES.items():
if Policy.BUILTIN_POLICIES[policy_name]['server_policy']: policy_description = ""
server_policy_names.append(policy_name) if verbose:
policy_description = "\"{:s}\": {:s}".format(policy_name, policy['changelog'])
else: else:
client_policy_names.append(policy_name) policy_description = "\"{:s}\"".format(policy_name)
server_policy_names.sort() if policy['server_policy']:
client_policy_names.sort() server_policy_descriptions.append(policy_description)
return server_policy_names, client_policy_names else:
client_policy_descriptions.append(policy_description)
server_policy_descriptions.sort()
client_policy_descriptions.sort()
return server_policy_descriptions, client_policy_descriptions
@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 BUILTIN_POLICIES:
policy_struct = Policy.BUILTIN_POLICIES[policy_name] policy_struct = 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
@ -447,13 +541,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
@ -482,7 +577,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
@ -507,9 +601,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\nAllow Algorithm Subset and/or Reordering: %r\nBanner: %s\nCompressions: %s\nHost Keys: %s\nOptional Host Keys: %s\nKey Exchanges: %s\nCiphers: %s\nMACs: %s\nHost Key Sizes: %s\nDH Modulus Sizes: %s\nServer Policy: %r" % (name, version, self._allow_algorithm_subset_and_reordering, banner, compressions_str, host_keys_str, optional_host_keys_str, kex_str, ciphers_str, macs_str, hostkey_sizes_str, dh_modulus_sizes_str, self._server_policy)

View File

@ -43,14 +43,14 @@ class ReadBuf:
return self._buf.read(size) return self._buf.read(size)
def read_byte(self) -> int: def read_byte(self) -> int:
v = struct.unpack('B', self.read(1))[0] # type: int v: int = struct.unpack('B', self.read(1))[0]
return v return v
def read_bool(self) -> bool: def read_bool(self) -> bool:
return self.read_byte() != 0 return self.read_byte() != 0
def read_int(self) -> int: def read_int(self) -> int:
v = struct.unpack('>I', self.read(4))[0] # type: int v: int = struct.unpack('>I', self.read(4))[0]
return v return v
def read_list(self) -> List[str]: def read_list(self) -> List[str]:

View File

@ -180,7 +180,7 @@ class Software:
# pylint: disable=too-many-return-statements # pylint: disable=too-many-return-statements
software = str(banner.software) software = str(banner.software)
mx = re.match(r'^dropbear_([\d\.]+\d+)(.*)', software) mx = re.match(r'^dropbear_([\d\.]+\d+)(.*)', software)
v = None # type: Optional[str] v: Optional[str] = None
if mx is not None: if mx is not None:
patch = cls._fix_patch(mx.group(2)) patch = cls._fix_patch(mx.group(2))
v, p = 'Matt Johnston', Product.DropbearSSH v, p = 'Matt Johnston', Product.DropbearSSH

View File

@ -29,7 +29,7 @@ from ssh_audit.ssh1_crc32 import SSH1_CRC32
class SSH1: class SSH1:
_crc32 = None # type: Optional[SSH1_CRC32] _crc32: Optional[SSH1_CRC32] = None
CIPHERS = ['none', 'idea', 'des', '3des', 'tss', 'rc4', 'blowfish'] CIPHERS = ['none', 'idea', 'des', '3des', 'tss', 'rc4', 'blowfish']
AUTHS = ['none', 'rhosts', 'rsa', 'password', 'rhosts_rsa', 'tis', 'kerberos'] AUTHS = ['none', 'rhosts', 'rsa', 'password', 'rhosts_rsa', 'tis', 'kerberos']

View File

@ -22,6 +22,9 @@
THE SOFTWARE. THE SOFTWARE.
""" """
# pylint: disable=unused-import # pylint: disable=unused-import
import copy
import threading
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
@ -34,7 +37,9 @@ class SSH1_KexDB: # pylint: disable=too-few-public-methods
FAIL_NA_UNSAFE = 'not implemented in OpenSSH (server), unsafe algorithm' FAIL_NA_UNSAFE = 'not implemented in OpenSSH (server), unsafe algorithm'
TEXT_CIPHER_IDEA = 'cipher used by commercial SSH' TEXT_CIPHER_IDEA = 'cipher used by commercial SSH'
ALGORITHMS = { DB_PER_THREAD: Dict[int, Dict[str, Dict[str, List[List[Optional[str]]]]]] = {}
MASTER_DB: Dict[str, Dict[str, List[List[Optional[str]]]]] = {
'key': { 'key': {
'ssh-rsa1': [['1.2.2']], 'ssh-rsa1': [['1.2.2']],
}, },
@ -55,4 +60,25 @@ class SSH1_KexDB: # pylint: disable=too-few-public-methods
'tis': [['1.2.2']], 'tis': [['1.2.2']],
'kerberos': [['1.2.2', '3.6'], [FAIL_OPENSSH37_REMOVE]], 'kerberos': [['1.2.2', '3.6'], [FAIL_OPENSSH37_REMOVE]],
} }
} # type: Dict[str, Dict[str, List[List[Optional[str]]]]] }
@staticmethod
def get_db() -> Dict[str, Dict[str, List[List[Optional[str]]]]]:
'''Returns a copy of the MASTER_DB that is private to the calling thread. This prevents multiple threads from polluting the results of other threads.'''
calling_thread_id = threading.get_ident()
if calling_thread_id not in SSH1_KexDB.DB_PER_THREAD:
SSH1_KexDB.DB_PER_THREAD[calling_thread_id] = copy.deepcopy(SSH1_KexDB.MASTER_DB)
return SSH1_KexDB.DB_PER_THREAD[calling_thread_id]
@staticmethod
def thread_exit() -> None:
'''Deletes the calling thread's copy of the MASTER_DB. This is needed because, in rare circumstances, a terminated thread's ID can be re-used by new threads.'''
calling_thread_id = threading.get_ident()
if calling_thread_id in SSH1_KexDB.DB_PER_THREAD:
del SSH1_KexDB.DB_PER_THREAD[calling_thread_id]

View File

@ -90,7 +90,7 @@ class SSH1_PublicKeyMessage:
@property @property
def supported_ciphers(self) -> List[str]: def supported_ciphers(self) -> List[str]:
ciphers = [] ciphers = []
for i in range(len(SSH1.CIPHERS)): for i in range(len(SSH1.CIPHERS)): # pylint: disable=consider-using-enumerate
if self.__supported_ciphers_mask & (1 << i) != 0: if self.__supported_ciphers_mask & (1 << i) != 0:
ciphers.append(Utils.to_text(SSH1.CIPHERS[i])) ciphers.append(Utils.to_text(SSH1.CIPHERS[i]))
return ciphers return ciphers

View File

@ -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 = {} # type: Dict[str, Tuple[int, int]] self.__dh_modulus_sizes: Dict[str, int] = {}
self.__dh_modulus_sizes = {} # type: Dict[str, Tuple[int, int]] self.__host_keys: Dict[str, Dict[str, Union[bytes, str, int]]] = {}
self.__host_keys = {} # type: 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

View File

@ -1,7 +1,7 @@
""" """
The MIT License (MIT) The MIT License (MIT)
Copyright (C) 2017-2020 Joe Testa (jtesta@positronsecurity.com) Copyright (C) 2017-2024 Joe Testa (jtesta@positronsecurity.com)
Copyright (C) 2017 Andris Raugulis (moo@arthepsy.eu) 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
@ -23,63 +23,74 @@
THE SOFTWARE. THE SOFTWARE.
""" """
# pylint: disable=unused-import # pylint: disable=unused-import
import copy
import threading
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
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'
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'
WARN_CURVES_WEAK = 'using weak elliptic curves' FAIL_UNTRUSTED = 'using untrusted algorithm developed in secret by a government entity'
WARN_RNDSIG_KEY = 'using weak random number generator could reveal the key'
WARN_HASH_WEAK = 'using weak hashing algorithm' WARN_2048BIT_MODULUS = '2048-bit modulus only provides 112-bits of symmetric strength'
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'
WARN_UNTRUSTED = 'using untrusted algorithm'
ALGORITHMS = { INFO_DEFAULT_OPENSSH_CIPHER = 'default cipher since OpenSSH 6.9'
# Format: 'algorithm_name': [['version_first_appeared_in'], [reason_for_failure1, reason_for_failure2, ...], [warning1, warning2, ...]] INFO_DEFAULT_OPENSSH_KEX_65_TO_73 = 'default key exchange from OpenSSH 6.5 to 7.3'
INFO_DEFAULT_OPENSSH_KEX_74_TO_89 = 'default key exchange from OpenSSH 7.4 to 8.9'
INFO_DEFAULT_OPENSSH_KEX_90 = 'default key exchange since OpenSSH 9.0'
INFO_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'
INFO_EXTENSION_NEGOTIATION = 'pseudo-algorithm that denotes the peer supports RFC8308 extensions'
INFO_STRICT_KEX = 'pseudo-algorithm that denotes the peer supports a stricter key exchange method as a counter-measure to the Terrapin attack (CVE-2023-48795)'
# Maintains a dictionary per calling thread that yields its own copy of MASTER_DB. This prevents results from one thread polluting the results of another thread.
DB_PER_THREAD: Dict[int, Dict[str, Dict[str, List[List[Optional[str]]]]]] = {}
MASTER_DB: Dict[str, Dict[str, List[List[Optional[str]]]]] = {
# Format: 'algorithm_name': [['version_first_appeared_in'], [reason_for_failure1, reason_for_failure2, ...], [warning1, warning2, ...], [info1, info2, ...]]
'kex': { '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_74_TO_89]],
'gss-gex-sha1-toWM5Slw5Ew8Mqkay+al2g==': [[], [], [WARN_HASH_WEAK]], 'curve25519-sha256@libssh.org': [['6.4,d2013.62,l10.6.0'], [], [], [INFO_DEFAULT_OPENSSH_KEX_65_TO_73]],
'gss-gex-sha1-': [[], [], [WARN_HASH_WEAK]], 'curve448-sha512': [[]],
'gss-group1-sha1-': [[], [FAIL_1024BIT_MODULUS], [WARN_HASH_WEAK]], 'curve448-sha512@libssh.org': [[]],
'gss-group14-sha1-': [[], [], [WARN_HASH_WEAK]], 'diffie-hellman-group14-sha1': [['3.9,d0.53,l10.6.0'], [FAIL_SHA1], [WARN_2048BIT_MODULUS]],
'gss-group14-sha1-toWM5Slw5Ew8Mqkay+al2g==': [[], [], [WARN_HASH_WEAK]], 'diffie-hellman-group14-sha224@ssh.com': [[]],
'gss-group14-sha256-': [[]], 'diffie-hellman-group14-sha256': [['7.3,d2016.73'], [], [WARN_2048BIT_MODULUS]],
'gss-group14-sha256-toWM5Slw5Ew8Mqkay+al2g==': [[]], 'diffie-hellman-group14-sha256@ssh.com': [[], [], [WARN_2048BIT_MODULUS]],
'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': [[]],
@ -89,183 +100,373 @@ 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-nistp256-kyber-512r3-sha256-d00@openquantumsafe.org': [[], [FAIL_NSA_BACKDOORED_CURVE]],
'ecdh-sha2-nistb233': [[], [WARN_CURVES_WEAK]], 'ecdh-nistp384-kyber-768r3-sha384-d00@openquantumsafe.org': [[], [FAIL_NSA_BACKDOORED_CURVE]],
'ecdh-sha2-nistb409': [[], [WARN_CURVES_WEAK]], 'ecdh-nistp521-kyber-1024r3-sha512-d00@openquantumsafe.org': [[], [FAIL_NSA_BACKDOORED_CURVE]],
'ecdh-sha2-nistk163': [[], [WARN_CURVES_WEAK]], 'ecdh-sha2-1.2.840.10045.3.1.1': [[], [FAIL_SMALL_ECC_MODULUS, FAIL_NSA_BACKDOORED_CURVE]], # NIST P-192 / secp192r1
'ecdh-sha2-nistk233': [[], [WARN_CURVES_WEAK]], 'ecdh-sha2-1.2.840.10045.3.1.7': [[], [FAIL_NSA_BACKDOORED_CURVE]], # NIST P-256 / secp256r1
'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': [[], [FAIL_UNPROVEN]], # sect283k1
'curve25519-sha256': [['7.4,d2018.76']], 'ecdh-sha2-1.3.132.0.1': [[], [FAIL_UNPROVEN, FAIL_SMALL_ECC_MODULUS]], # sect163k1
'curve448-sha512': [[]], 'ecdh-sha2-1.3.132.0.26': [[], [FAIL_UNPROVEN, 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'], [], [WARN_EXPERIMENTAL]], 'ecdh-sha2-1.3.132.0.35': [[], [FAIL_NSA_BACKDOORED_CURVE]], # NIST P-521 / secp521r1
'ecdh-sha2-1.3.132.0.36': [[], [FAIL_UNPROVEN]], # sect409k1
'ecdh-sha2-1.3.132.0.37': [[], [FAIL_NSA_BACKDOORED_CURVE]], # sect409r1
'ecdh-sha2-1.3.132.0.38': [[], [FAIL_UNPROVEN]], # sect571k1
# Note: the base64 strings, according to draft 6 of RFC5656, is Base64(MD5(DER(OID))). The final RFC5656 dropped the base64 strings in favor of plain OID concatenation, but apparently some SSH servers implement them anyway. See: https://datatracker.ietf.org/doc/html/draft-green-secsh-ecc-06#section-9.2
'ecdh-sha2-4MHB+NBt3AlaSRQ7MnB4cg==': [[], [FAIL_UNPROVEN, FAIL_SMALL_ECC_MODULUS]], # sect163k1
'ecdh-sha2-5pPrSUQtIaTjUSt5VZNBjg==': [[], [FAIL_SMALL_ECC_MODULUS, FAIL_NSA_BACKDOORED_CURVE]], # NIST P-192 / secp192r1
'ecdh-sha2-9UzNcgwTlEnSCECZa7V1mw==': [[], [FAIL_NSA_BACKDOORED_CURVE]], # NIST P-256 / secp256r1
'ecdh-sha2-brainpoolp256r1@genua.de': [[], [FAIL_UNPROVEN]],
'ecdh-sha2-brainpoolp384r1@genua.de': [[], [FAIL_UNPROVEN]],
'ecdh-sha2-brainpoolp521r1@genua.de': [[], [FAIL_UNPROVEN]],
'ecdh-sha2-curve25519': [[], []],
'ecdh-sha2-D3FefCjYoJ/kfXgAyLddYA==': [[], [FAIL_NSA_BACKDOORED_CURVE]], # sect409r1
'ecdh-sha2-h/SsxnLCtRBh7I9ATyeB3A==': [[], [FAIL_NSA_BACKDOORED_CURVE]], # NIST P-521 / secp521r1
'ecdh-sha2-m/FtSAmrV4j/Wy6RVUaK7A==': [[], [FAIL_UNPROVEN]], # sect409k1
'ecdh-sha2-mNVwCXAoS1HGmHpLvBC94w==': [[], [FAIL_UNPROVEN]], # sect571k1
'ecdh-sha2-nistb233': [[], [FAIL_UNPROVEN, FAIL_SMALL_ECC_MODULUS]],
'ecdh-sha2-nistb409': [[], [FAIL_UNPROVEN]],
'ecdh-sha2-nistk163': [[], [FAIL_UNPROVEN, FAIL_SMALL_ECC_MODULUS]],
'ecdh-sha2-nistk233': [[], [FAIL_UNPROVEN, FAIL_SMALL_ECC_MODULUS]],
'ecdh-sha2-nistk283': [[], [FAIL_UNPROVEN]],
'ecdh-sha2-nistk409': [[], [FAIL_UNPROVEN]],
'ecdh-sha2-nistp192': [[], [FAIL_NSA_BACKDOORED_CURVE]],
'ecdh-sha2-nistp224': [[], [FAIL_NSA_BACKDOORED_CURVE]],
'ecdh-sha2-nistp256': [['5.7,d2013.62,l10.6.0'], [FAIL_NSA_BACKDOORED_CURVE]],
'ecdh-sha2-nistp384': [['5.7,d2013.62'], [FAIL_NSA_BACKDOORED_CURVE]],
'ecdh-sha2-nistp521': [['5.7,d2013.62'], [FAIL_NSA_BACKDOORED_CURVE]],
'ecdh-sha2-nistt571': [[], [FAIL_UNPROVEN]],
'ecdh-sha2-qCbG5Cn/jjsZ7nBeR7EnOA==': [[FAIL_SMALL_ECC_MODULUS, FAIL_NSA_BACKDOORED_CURVE]], # sect233r1
'ecdh-sha2-qcFQaMAMGhTziMT0z+Tuzw==': [[], [FAIL_NSA_BACKDOORED_CURVE]], # NIST P-384 / secp384r1
'ecdh-sha2-VqBg4QRPjxx1EXZdV0GdWQ==': [[], [FAIL_NSA_BACKDOORED_CURVE, FAIL_SMALL_ECC_MODULUS]], # NIST P-224 / secp224r1
'ecdh-sha2-wiRIU8TKjMZ418sMqlqtvQ==': [[], [FAIL_UNPROVEN]], # sect283k1
'ecdh-sha2-zD/b3hu/71952ArpUG4OjQ==': [[], [FAIL_UNPROVEN, FAIL_SMALL_ECC_MODULUS]], # sect233k1
'ecmqv-sha2': [[], [FAIL_UNPROVEN]],
'ext-info-c': [[], [], [], [INFO_EXTENSION_NEGOTIATION]], # Extension negotiation (RFC 8308)
'ext-info-s': [[], [], [], [INFO_EXTENSION_NEGOTIATION]], # Extension negotiation (RFC 8308)
'kex-strict-c-v00@openssh.com': [[], [], [], [INFO_STRICT_KEX]], # Strict KEX marker (countermeasure for CVE-2023-48795).
'kex-strict-s-v00@openssh.com': [[], [], [], [INFO_STRICT_KEX]], # Strict KEX marker (countermeasure for CVE-2023-48795).
# The GSS kex algorithms get special wildcard handling, since they include variable base64 data after their standard prefixes.
'gss-13.3.132.0.10-sha256-*': [[], [FAIL_UNKNOWN]],
'gss-curve25519-sha256-*': [[]],
'gss-curve448-sha512-*': [[]],
'gss-gex-sha1-*': [[], [FAIL_SHA1]],
'gss-gex-sha256-*': [[]],
'gss-group14-sha1-*': [[], [FAIL_SHA1], [WARN_2048BIT_MODULUS]],
'gss-group14-sha256-*': [[], [], [WARN_2048BIT_MODULUS]],
'gss-group15-sha512-*': [[]],
'gss-group16-sha512-*': [[]],
'gss-group17-sha512-*': [[]],
'gss-group18-sha512-*': [[]],
'gss-group1-sha1-*': [[], [FAIL_1024BIT_MODULUS, FAIL_LOGJAM_ATTACK, FAIL_SHA1]],
'gss-nistp256-sha256-*': [[], [FAIL_NSA_BACKDOORED_CURVE]],
'gss-nistp384-sha256-*': [[], [FAIL_NSA_BACKDOORED_CURVE]],
'gss-nistp384-sha384-*': [[], [FAIL_NSA_BACKDOORED_CURVE]],
'gss-nistp521-sha512-*': [[], [FAIL_NSA_BACKDOORED_CURVE]],
'kexAlgoCurve25519SHA256': [[]], 'kexAlgoCurve25519SHA256': [[]],
'Curve25519SHA256': [[]], 'kexAlgoDH14SHA1': [[], [FAIL_SHA1], [WARN_2048BIT_MODULUS]],
'ext-info-c': [[]], # Extension negotiation (RFC 8308) 'kexAlgoDH1SHA1': [[], [FAIL_1024BIT_MODULUS, FAIL_LOGJAM_ATTACK, FAIL_SHA1]],
'ext-info-s': [[]], # Extension negotiation (RFC 8308) 'kexAlgoECDH256': [[], [FAIL_NSA_BACKDOORED_CURVE]],
'kexAlgoECDH384': [[], [FAIL_NSA_BACKDOORED_CURVE]],
'kexAlgoECDH521': [[], [FAIL_NSA_BACKDOORED_CURVE]],
'kexguess2@matt.ucc.asn.au': [['d2013.57']],
'm383-sha384@libassh.org': [[], [FAIL_UNPROVEN]],
'm511-sha512@libassh.org': [[], [FAIL_UNPROVEN]],
'rsa1024-sha1': [[], [FAIL_1024BIT_MODULUS, FAIL_SHA1]],
'rsa2048-sha256': [[], [], [WARN_2048BIT_MODULUS]],
'sm2kep-sha2-nistp256': [[], [FAIL_NSA_BACKDOORED_CURVE, FAIL_UNTRUSTED]],
'sntrup4591761x25519-sha512@tinyssh.org': [['8.0', '8.4'], [], [WARN_EXPERIMENTAL], [INFO_WITHDRAWN_PQ_ALG]],
'sntrup761x25519-sha512@openssh.com': [['8.5'], [], [], [INFO_DEFAULT_OPENSSH_KEX_90]],
'x25519-kyber-512r3-sha256-d00@amazon.com': [[]],
'x25519-kyber512-sha512@aws.amazon.com': [[]],
}, },
'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'], [WARN_HASH_WEAK]],
'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-curve25519': [[], [], [WARN_RNDSIG_KEY]], # ECDSA with Curve25519? Bizarre...
'x509v3-sign-rsa': [[], [], [WARN_HASH_WEAK]], 'ecdsa-sha2-nistb233': [[], [FAIL_UNPROVEN, FAIL_SMALL_ECC_MODULUS], [WARN_RNDSIG_KEY]],
'x509v3-sign-rsa-sha256@ssh.com': [[]], 'ecdsa-sha2-nistb409': [[], [FAIL_UNPROVEN], [WARN_RNDSIG_KEY]],
'x509v3-ssh-dss': [[], [FAIL_1024BIT_MODULUS, FAIL_OPENSSH70_WEAK], [WARN_RNDSIG_KEY]], 'ecdsa-sha2-nistk163': [[], [FAIL_UNPROVEN, FAIL_SMALL_ECC_MODULUS], [WARN_RNDSIG_KEY]],
'x509v3-ssh-rsa': [[], [], [WARN_HASH_WEAK]], 'ecdsa-sha2-nistk233': [[], [FAIL_UNPROVEN, FAIL_SMALL_ECC_MODULUS], [WARN_RNDSIG_KEY]],
'ssh-rsa-cert-v00@openssh.com': [['5.4', '6.9'], [FAIL_OPENSSH70_LEGACY], []], 'ecdsa-sha2-nistk283': [[], [FAIL_UNPROVEN], [WARN_RNDSIG_KEY]],
'ssh-dss-cert-v00@openssh.com': [['5.4', '6.9'], [FAIL_1024BIT_MODULUS, FAIL_OPENSSH70_LEGACY], [WARN_RNDSIG_KEY]], 'ecdsa-sha2-nistk409': [[], [FAIL_UNPROVEN], [WARN_RNDSIG_KEY]],
'ssh-rsa-cert-v01@openssh.com': [['5.6'], [WARN_HASH_WEAK]], 'ecdsa-sha2-nistp224': [[], [FAIL_NSA_BACKDOORED_CURVE, FAIL_SMALL_ECC_MODULUS], [WARN_RNDSIG_KEY]],
'ssh-dss-cert-v01@openssh.com': [['5.6', '6.9'], [FAIL_1024BIT_MODULUS, FAIL_OPENSSH70_WEAK], [WARN_RNDSIG_KEY]], 'ecdsa-sha2-nistp192': [[], [FAIL_NSA_BACKDOORED_CURVE, FAIL_SMALL_ECC_MODULUS], [WARN_RNDSIG_KEY]],
'ecdsa-sha2-nistp256-cert-v01@openssh.com': [['5.7'], [WARN_CURVES_WEAK], [WARN_RNDSIG_KEY]], 'ecdsa-sha2-nistp256': [['5.7,d2013.62,l10.6.4'], [FAIL_NSA_BACKDOORED_CURVE], [WARN_RNDSIG_KEY]],
'ecdsa-sha2-nistp384-cert-v01@openssh.com': [['5.7'], [WARN_CURVES_WEAK], [WARN_RNDSIG_KEY]], 'ecdsa-sha2-nistp256-cert-v01@openssh.com': [['5.7'], [FAIL_NSA_BACKDOORED_CURVE], [WARN_RNDSIG_KEY]],
'ecdsa-sha2-nistp521-cert-v01@openssh.com': [['5.7'], [WARN_CURVES_WEAK], [WARN_RNDSIG_KEY]], 'ecdsa-sha2-nistp384': [['5.7,d2013.62,l10.6.4'], [FAIL_NSA_BACKDOORED_CURVE], [WARN_RNDSIG_KEY]],
'ecdsa-sha2-nistp384-cert-v01@openssh.com': [['5.7'], [FAIL_NSA_BACKDOORED_CURVE], [WARN_RNDSIG_KEY]],
'ecdsa-sha2-nistp521': [['5.7,d2013.62,l10.6.4'], [FAIL_NSA_BACKDOORED_CURVE], [WARN_RNDSIG_KEY]],
'ecdsa-sha2-nistp521-cert-v01@openssh.com': [['5.7'], [FAIL_NSA_BACKDOORED_CURVE], [WARN_RNDSIG_KEY]],
'ecdsa-sha2-nistt571': [[], [FAIL_UNPROVEN], [WARN_RNDSIG_KEY]],
'eddsa-e382-shake256@libassh.org': [[], [FAIL_UNPROVEN]],
'eddsa-e521-shake256@libassh.org': [[], [FAIL_UNPROVEN]],
'null': [[], [FAIL_PLAINTEXT]],
'pgp-sign-dss': [[], [FAIL_1024BIT_MODULUS]],
'pgp-sign-rsa': [[], [FAIL_1024BIT_MODULUS]],
'rsa-sha2-256': [['7.2,d2020.79']],
'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-dsa': [[], [FAIL_1024BIT_MODULUS], [WARN_RNDSIG_KEY]],
'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,d2020.79,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': [[]],
'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']],
'aes128-ocb@libassh.org': [[], [], [WARN_CIPHER_MODE]],
'aes192-cbc': [['2.3.0,l10.2', '6.6', None], [], [WARN_CIPHER_MODE]],
'aes192-ctr': [['3.7,l10.4.1']],
'aes192-gcm@openssh.com': [[], [], [], [INFO_NEVER_IMPLEMENTED_IN_OPENSSH]],
'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-12-cbc': [[], [FAIL_CAST], [WARN_CIPHER_MODE]],
'cast128-12-cfb': [[], [FAIL_CAST], [WARN_CIPHER_MODE]],
'cast128-12-ecb': [[], [FAIL_CAST], [WARN_CIPHER_MODE]],
'cast128-12-ofb': [[], [FAIL_CAST], [WARN_CIPHER_MODE]],
'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,d2020.79'], [], [], [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-cfb': [[], [FAIL_DES], [WARN_CIPHER_MODE, WARN_BLOCK_SIZE]],
'des-ecb': [[], [FAIL_DES], [WARN_CIPHER_MODE, WARN_BLOCK_SIZE]],
'des-ofb': [[], [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': [[]],
'cbcmac-3des': [[], [FAIL_UNPROVEN, FAIL_3DES]],
'cbcmac-aes': [[], [FAIL_UNPROVEN]],
'cbcmac-blowfish': [[], [FAIL_UNPROVEN, FAIL_BLOWFISH]],
'cbcmac-des': [[], [FAIL_UNPROVEN, FAIL_DES]],
'cbcmac-rijndael': [[], [FAIL_UNPROVEN, FAIL_RIJNDAEL]],
'cbcmac-twofish': [[], [FAIL_UNPROVEN]],
'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-96': [[], [], [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]], 'md5': [[], [FAIL_PLAINTEXT]],
'hmac-ripemd160': [['2.5.0', '6.6', '7.1'], [FAIL_OPENSSH67_UNSAFE], [WARN_OPENSSH72_LEGACY, WARN_ENCRYPT_AND_MAC]], 'md5-8': [[], [FAIL_PLAINTEXT]],
'hmac-ripemd160@openssh.com': [['2.1.0', '6.6', '7.1'], [FAIL_OPENSSH67_UNSAFE], [WARN_OPENSSH72_LEGACY, WARN_ENCRYPT_AND_MAC]], 'none': [['d2013.56'], [FAIL_PLAINTEXT]],
'umac-64@openssh.com': [['4.7'], [], [WARN_ENCRYPT_AND_MAC, WARN_TAG_SIZE]], 'ripemd160': [[], [FAIL_PLAINTEXT]],
'umac-128@openssh.com': [['6.2'], [], [WARN_ENCRYPT_AND_MAC]], 'ripemd160-8': [[], [FAIL_PLAINTEXT]],
'hmac-sha1-etm@openssh.com': [['6.2'], [], [WARN_HASH_WEAK]], 'sha1': [[], [FAIL_PLAINTEXT]],
'hmac-sha1-96-etm@openssh.com': [['6.2', '6.6', None], [FAIL_OPENSSH67_UNSAFE], [WARN_HASH_WEAK]], 'sha1-8': [[], [FAIL_PLAINTEXT]],
'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 (?). 'umac-128': [[], [], [WARN_ENCRYPT_AND_MAC]],
'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]],
'umac-96@openssh.com': [[], [], [WARN_ENCRYPT_AND_MAC], [INFO_NEVER_IMPLEMENTED_IN_OPENSSH]],
} }
} # type: Dict[str, Dict[str, List[List[Optional[str]]]]] }
@staticmethod
def get_db() -> Dict[str, Dict[str, List[List[Optional[str]]]]]:
'''Returns a copy of the MASTER_DB that is private to the calling thread. This prevents multiple threads from polluting the results of other threads.'''
calling_thread_id = threading.get_ident()
if calling_thread_id not in SSH2_KexDB.DB_PER_THREAD:
SSH2_KexDB.DB_PER_THREAD[calling_thread_id] = copy.deepcopy(SSH2_KexDB.MASTER_DB)
return SSH2_KexDB.DB_PER_THREAD[calling_thread_id]
@staticmethod
def thread_exit() -> None:
'''Deletes the calling thread's copy of the MASTER_DB. This is needed because, in rare circumstances, a terminated thread's ID can be re-used by new threads.'''
calling_thread_id = threading.get_ident()
if calling_thread_id in SSH2_KexDB.DB_PER_THREAD:
del SSH2_KexDB.DB_PER_THREAD[calling_thread_id]

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
""" """
The MIT License (MIT) The MIT License (MIT)
Copyright (C) 2017-2020 Joe Testa (jtesta@positronsecurity.com) Copyright (C) 2017-2021 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
@ -36,7 +36,7 @@ from typing import Callable, Optional, Union, Any # noqa: F401
from ssh_audit import exitcodes from ssh_audit import exitcodes
from ssh_audit.banner import Banner from ssh_audit.banner import Banner
from ssh_audit.globals import SSH_HEADER from ssh_audit.globals import SSH_HEADER
from ssh_audit.output import Output from ssh_audit.outputbuffer import OutputBuffer
from ssh_audit.protocol import Protocol from ssh_audit.protocol import Protocol
from ssh_audit.readbuf import ReadBuf from ssh_audit.readbuf import ReadBuf
from ssh_audit.ssh1 import SSH1 from ssh_audit.ssh1 import SSH1
@ -52,14 +52,15 @@ class SSH_Socket(ReadBuf, WriteBuf):
SM_BANNER_SENT = 1 SM_BANNER_SENT = 1
def __init__(self, host: Optional[str], port: int, ipvo: Optional[Sequence[int]] = None, timeout: Union[int, float] = 5, timeout_set: bool = False) -> None: def __init__(self, outputbuffer: 'OutputBuffer', host: Optional[str], port: int, ip_version_preference: List[int] = [], timeout: Union[int, float] = 5, timeout_set: bool = False) -> None: # pylint: disable=dangerous-default-value
super(SSH_Socket, self).__init__() super(SSH_Socket, self).__init__()
self.__sock = None # type: Optional[socket.socket] self.__outputbuffer = outputbuffer
self.__sock_map = {} # type: Dict[int, socket.socket] self.__sock: Optional[socket.socket] = None
self.__sock_map: Dict[int, socket.socket] = {}
self.__block_size = 8 self.__block_size = 8
self.__state = 0 self.__state = 0
self.__header = [] # type: List[str] self.__header: List[str] = []
self.__banner = None # type: Optional[Banner] self.__banner: Optional[Banner] = None
if host is None: if host is None:
raise ValueError('undefined host') raise ValueError('undefined host')
nport = Utils.parse_int(port) nport = Utils.parse_int(port)
@ -67,36 +68,33 @@ class SSH_Socket(ReadBuf, WriteBuf):
raise ValueError('invalid port: {}'.format(port)) raise ValueError('invalid port: {}'.format(port))
self.__host = host self.__host = host
self.__port = nport self.__port = nport
if ipvo is not None: self.__ip_version_preference = ip_version_preference # Holds only 5 possible values: [] (no preference), [4] (use IPv4 only), [6] (use IPv6 only), [46] (use both IPv4 and IPv6, but prioritize v4), and [64] (use both IPv4 and IPv6, but prioritize v6).
self.__ipvo = ipvo
else:
self.__ipvo = ()
self.__timeout = timeout self.__timeout = timeout
self.__timeout_set = timeout_set self.__timeout_set = timeout_set
self.client_host = None # type: Optional[str] self.client_host: Optional[str] = None
self.client_port = None self.client_port = None
def _resolve(self, ipvo: Sequence[int]) -> Iterable[Tuple[int, Tuple[Any, ...]]]: def _resolve(self) -> Iterable[Tuple[int, Tuple[Any, ...]]]:
ipvo = tuple([x for x in Utils.unique_seq(ipvo) if x in (4, 6)]) """Resolves a hostname into a list of IPs
ipvo_len = len(ipvo) Raises
prefer_ipvo = ipvo_len > 0 ------
prefer_ipv4 = prefer_ipvo and ipvo[0] == 4 socket.gaierror [Errno -2]
if ipvo_len == 1: If the hostname cannot be resolved.
family = socket.AF_INET if ipvo[0] == 4 else socket.AF_INET6 """
# If __ip_version_preference has only one entry, then it means that ONLY that IP version should be used.
if len(self.__ip_version_preference) == 1:
family = socket.AF_INET if self.__ip_version_preference[0] == 4 else socket.AF_INET6
else: else:
family = socket.AF_UNSPEC family = socket.AF_UNSPEC
try: stype = socket.SOCK_STREAM
stype = socket.SOCK_STREAM r = socket.getaddrinfo(self.__host, self.__port, family, stype)
r = socket.getaddrinfo(self.__host, self.__port, family, stype)
if prefer_ipvo: # 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.
r = sorted(r, key=lambda x: x[0], reverse=not prefer_ipv4) if len(self.__ip_version_preference) == 2:
check = any(stype == rline[2] for rline in r) 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 not check or socktype == socket.SOCK_STREAM: if socktype == socket.SOCK_STREAM:
yield af, addr yield af, addr
except socket.error as e:
Output().fail('[exception] {}'.format(e))
sys.exit(exitcodes.CONNECTION_ERROR)
# Listens on a server socket and accepts one connection (used for # Listens on a server socket and accepts one connection (used for
# auditing client connections). # auditing client connections).
@ -109,8 +107,8 @@ class SSH_Socket(ReadBuf, WriteBuf):
s.bind(('0.0.0.0', self.__port)) s.bind(('0.0.0.0', self.__port))
s.listen() s.listen()
self.__sock_map[s.fileno()] = s self.__sock_map[s.fileno()] = s
except Exception: except Exception as e:
print("Warning: failed to listen on any IPv4 interfaces.") print("Warning: failed to listen on any IPv4 interfaces: %s" % str(e))
try: try:
# Socket to listen on all IPv6 addresses. # Socket to listen on all IPv6 addresses.
@ -120,8 +118,8 @@ class SSH_Socket(ReadBuf, WriteBuf):
s.bind(('::', self.__port)) s.bind(('::', self.__port))
s.listen() s.listen()
self.__sock_map[s.fileno()] = s self.__sock_map[s.fileno()] = s
except Exception: except Exception as e:
print("Warning: failed to listen on any IPv6 interfaces.") print("Warning: failed to listen on any IPv6 interfaces: %s" % str(e))
# If we failed to listen on any interfaces, terminate. # If we failed to listen on any interfaces, terminate.
if len(self.__sock_map.keys()) == 0: if len(self.__sock_map.keys()) == 0:
@ -156,17 +154,18 @@ class SSH_Socket(ReadBuf, WriteBuf):
def connect(self) -> Optional[str]: def connect(self) -> Optional[str]:
'''Returns None on success, or an error string.''' '''Returns None on success, or an error string.'''
err = None err = None
for af, addr in self._resolve(self.__ipvo): s = None
s = None try:
try: for af, addr in self._resolve():
s = socket.socket(af, socket.SOCK_STREAM) s = socket.socket(af, socket.SOCK_STREAM)
s.settimeout(self.__timeout) s.settimeout(self.__timeout)
self.__outputbuffer.d(("Connecting to %s:%d..." % ('[%s]' % addr[0] if Utils.is_ipv6_address(addr[0]) else addr[0], addr[1])), write_now=True)
s.connect(addr) s.connect(addr)
self.__sock = s self.__sock = s
return None return None
except socket.error as e: except socket.error as e:
err = e err = e
self._close_socket(s) self._close_socket(s)
if err is None: if err is None:
errm = 'host {} has no DNS records'.format(self.__host) errm = 'host {} has no DNS records'.format(self.__host)
else: else:
@ -175,6 +174,8 @@ class SSH_Socket(ReadBuf, WriteBuf):
return '[exception] {}'.format(errm) return '[exception] {}'.format(errm)
def get_banner(self, sshv: int = 2) -> Tuple[Optional['Banner'], List[str], Optional[str]]: def get_banner(self, sshv: int = 2) -> Tuple[Optional['Banner'], List[str], Optional[str]]:
self.__outputbuffer.d('Getting banner...', write_now=True)
if self.__sock is None: if self.__sock is None:
return self.__banner, self.__header, 'not connected' return self.__banner, self.__header, 'not connected'
if self.__banner is not None: if self.__banner is not None:
@ -230,18 +231,14 @@ class SSH_Socket(ReadBuf, WriteBuf):
except socket.error as e: except socket.error as e:
return -1, str(e.args[-1]) return -1, str(e.args[-1])
def send_algorithms(self) -> None: # Send a KEXINIT with the lists of key exchanges, hostkeys, ciphers, MACs, compressions, and languages that we "support".
def send_kexinit(self, key_exchanges: List[str] = ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'ecdh-sha2-nistp256', 'ecdh-sha2-nistp384', 'ecdh-sha2-nistp521', 'diffie-hellman-group-exchange-sha256', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group14-sha256'], hostkeys: List[str] = ['rsa-sha2-512', 'rsa-sha2-256', 'ssh-rsa', 'ecdsa-sha2-nistp256', 'ssh-ed25519'], ciphers: List[str] = ['chacha20-poly1305@openssh.com', 'aes128-ctr', 'aes192-ctr', 'aes256-ctr', 'aes128-gcm@openssh.com', 'aes256-gcm@openssh.com'], macs: List[str] = ['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'], compressions: List[str] = ['none', 'zlib@openssh.com'], languages: List[str] = ['']) -> None: # pylint: disable=dangerous-default-value
'''Sends the list of supported host keys, key exchanges, ciphers, and MACs. Emulates OpenSSH v8.2.''' '''Sends the list of supported host keys, key exchanges, ciphers, and MACs. Emulates OpenSSH v8.2.'''
key_exchanges = ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'ecdh-sha2-nistp256', 'ecdh-sha2-nistp384', 'ecdh-sha2-nistp521', 'diffie-hellman-group-exchange-sha256', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group14-sha256'] self.__outputbuffer.d('KEX initialisation...', write_now=True)
hostkeys = ['rsa-sha2-512', 'rsa-sha2-256', 'ssh-rsa', 'ecdsa-sha2-nistp256', 'ssh-ed25519']
ciphers = ['chacha20-poly1305@openssh.com', 'aes128-ctr', 'aes192-ctr', 'aes256-ctr', 'aes128-gcm@openssh.com', 'aes256-gcm@openssh.com']
macs = ['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']
compressions = ['none', 'zlib@openssh.com']
languages = ['']
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)
@ -249,8 +246,7 @@ class SSH_Socket(ReadBuf, WriteBuf):
def send_banner(self, banner: str) -> None: def send_banner(self, banner: str) -> None:
self.send(banner.encode() + b'\r\n') self.send(banner.encode() + b'\r\n')
if self.__state < self.SM_BANNER_SENT: self.__state = max(self.__state, self.SM_BANNER_SENT)
self.__state = self.SM_BANNER_SENT
def ensure_read(self, size: int) -> None: def ensure_read(self, size: int) -> None:
while self.unread_len < size: while self.unread_len < size:
@ -279,7 +275,7 @@ class SSH_Socket(ReadBuf, WriteBuf):
payload_length = packet_length - padding_length - 1 payload_length = packet_length - padding_length - 1
check_size = 4 + 1 + payload_length + padding_length check_size = 4 + 1 + payload_length + padding_length
if check_size % self.__block_size != 0: if check_size % self.__block_size != 0:
Output().fail('[exception] invalid ssh packet (block size)') self.__outputbuffer.fail('[exception] invalid ssh packet (block size)').write()
sys.exit(exitcodes.CONNECTION_ERROR) sys.exit(exitcodes.CONNECTION_ERROR)
self.ensure_read(payload_length) self.ensure_read(payload_length)
if sshv == 1: if sshv == 1:
@ -294,7 +290,7 @@ class SSH_Socket(ReadBuf, WriteBuf):
if sshv == 1: if sshv == 1:
rcrc = SSH1.crc32(padding + payload) rcrc = SSH1.crc32(padding + payload)
if crc != rcrc: if crc != rcrc:
Output().fail('[exception] packet checksum CRC32 mismatch.') self.__outputbuffer.fail('[exception] packet checksum CRC32 mismatch.').write()
sys.exit(exitcodes.CONNECTION_ERROR) sys.exit(exitcodes.CONNECTION_ERROR)
else: else:
self.ensure_read(padding_length) self.ensure_read(padding_length)
@ -330,7 +326,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)
@ -343,6 +339,6 @@ class SSH_Socket(ReadBuf, WriteBuf):
def __cleanup(self) -> None: def __cleanup(self) -> None:
self._close_socket(self.__sock) self._close_socket(self.__sock)
for fd in self.__sock_map: for sock in self.__sock_map.values():
self._close_socket(self.__sock_map[fd]) self._close_socket(sock)
self.__sock = None self.__sock = None

View File

@ -30,12 +30,12 @@ from ssh_audit.algorithm import Algorithm
class Timeframe: class Timeframe:
def __init__(self) -> None: def __init__(self) -> None:
self.__storage = {} # type: Dict[str, List[Optional[str]]] self.__storage: Dict[str, List[Optional[str]]] = {}
def __contains__(self, product: str) -> bool: def __contains__(self, product: str) -> bool:
return product in self.__storage return product in self.__storage
def __getitem__(self, product): # type: (str) -> Sequence[Optional[str]] def __getitem__(self, product: str) -> Sequence[Optional[str]]:
return tuple(self.__storage.get(product, [None] * 4)) return tuple(self.__storage.get(product, [None] * 4))
def __str__(self) -> str: def __str__(self) -> str:
@ -51,7 +51,7 @@ class Timeframe:
return self[product][1 if bool(for_server) else 3] return self[product][1 if bool(for_server) else 3]
def _update(self, versions: Optional[str], pos: int) -> None: def _update(self, versions: Optional[str], pos: int) -> None:
ssh_versions = {} # type: Dict[str, str] ssh_versions: Dict[str, str] = {}
for_srv, for_cli = pos < 2, pos > 1 for_srv, for_cli = pos < 2, pos > 1
for v in (versions or '').split(','): for v in (versions or '').split(','):
ssh_prod, ssh_ver, is_cli = Algorithm.get_ssh_version(v) ssh_prod, ssh_ver, is_cli = Algorithm.get_ssh_version(v)

View File

@ -96,7 +96,7 @@ class Utils:
@classmethod @classmethod
def unique_seq(cls, seq: Sequence[Any]) -> Sequence[Any]: def unique_seq(cls, seq: Sequence[Any]) -> Sequence[Any]:
seen = set() # type: Set[Any] seen: Set[Any] = set()
def _seen_add(x: Any) -> bool: def _seen_add(x: Any) -> bool:
seen.add(x) seen.add(x)
@ -129,10 +129,10 @@ class Utils:
return -1.0 return -1.0
@staticmethod @staticmethod
def parse_host_and_port(host_and_port: str) -> Tuple[str, int]: def parse_host_and_port(host_and_port: str, default_port: int = 0) -> Tuple[str, int]:
'''Parses a string into a tuple of its host and port. The port is 0 if not specified.''' '''Parses a string into a tuple of its host and port. The port is 0 if not specified.'''
host = host_and_port host = host_and_port
port = 0 port = default_port
mx = re.match(r'^\[([^\]]+)\](?::(\d+))?$', host_and_port) mx = re.match(r'^\[([^\]]+)\](?::(\d+))?$', host_and_port)
if mx is not None: if mx is not None:

View File

@ -33,8 +33,9 @@ class VersionVulnerabilityDB: # pylint: disable=too-few-public-methods
# Example: if it affects servers, both remote & local, then affected # Example: if it affects servers, both remote & local, then affected
# = 1. If it affects servers, but is a local issue only, # = 1. If it affects servers, but is a local issue only,
# then affected = 1 + 4 = 5. # then affected = 1 + 4 = 5.
CVE = { 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,6 +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': [
['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)'],
@ -106,7 +122,7 @@ class VersionVulnerabilityDB: # pylint: disable=too-few-public-methods
['2.1', '4.1p1', 1, 'CVE-2005-2798', 5.0, 'leak data about authentication credentials'], ['2.1', '4.1p1', 1, 'CVE-2005-2798', 5.0, 'leak data about authentication credentials'],
['3.5', '3.5p1', 1, 'CVE-2004-2760', 6.8, 'leak data through different connection states'], ['3.5', '3.5p1', 1, 'CVE-2004-2760', 6.8, 'leak data through different connection states'],
['2.3', '3.7.1p2', 1, 'CVE-2004-2069', 5.0, 'cause DoS via large number of connections (slot exhaustion)'], ['2.3', '3.7.1p2', 1, 'CVE-2004-2069', 5.0, 'cause DoS via large number of connections (slot exhaustion)'],
['3.0', '3.4p1', 1, 'CVE-2004-0175', 4.3, 'leak data through directoy traversal'], ['3.0', '3.4p1', 1, 'CVE-2004-0175', 4.3, 'leak data through directory traversal'],
['1.2', '3.9p1', 1, 'CVE-2003-1562', 7.6, 'leak data about authentication credentials'], ['1.2', '3.9p1', 1, 'CVE-2003-1562', 7.6, 'leak data about authentication credentials'],
['3.1p1', '3.7.1p1', 1, 'CVE-2003-0787', 7.5, 'privilege escalation via modifying stack'], ['3.1p1', '3.7.1p1', 1, 'CVE-2003-0787', 7.5, 'privilege escalation via modifying stack'],
['3.1p1', '3.7.1p1', 1, 'CVE-2003-0786', 10.0, 'privilege escalation via bypassing authentication'], ['3.1p1', '3.7.1p1', 1, 'CVE-2003-0786', 10.0, 'privilege escalation via bypassing authentication'],
@ -124,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'],
@ -139,12 +159,12 @@ class VersionVulnerabilityDB: # pylint: disable=too-few-public-methods
['0.0', '0.66', 2, 'CVE-2016-2563', 7.5, 'buffer overflow in SCP command-line utility'], ['0.0', '0.66', 2, 'CVE-2016-2563', 7.5, 'buffer overflow in SCP command-line utility'],
['0.0', '0.65', 2, 'CVE-2015-5309', 4.3, 'integer overflow in terminal-handling code'], ['0.0', '0.65', 2, 'CVE-2015-5309', 4.3, 'integer overflow in terminal-handling code'],
] ]
} # type: Dict[str, List[List[Any]]] }
TXT = { TXT: Dict[str, List[List[Any]]] = {
'Dropbear SSH': [ 'Dropbear SSH': [
['0.28', '0.34', 1, 'remote root exploit', 'remote format string buffer overflow exploit (exploit-db#387)']], ['0.28', '0.34', 1, 'remote root exploit', 'remote format string buffer overflow exploit (exploit-db#387)']],
'libssh': [ 'libssh': [
['0.3.3', '0.3.3', 1, 'null pointer check', 'missing null pointer check in "crypt_set_algorithms_server"'], ['0.3.3', '0.3.3', 1, 'null pointer check', 'missing null pointer check in "crypt_set_algorithms_server"'],
['0.3.3', '0.3.3', 1, 'integer overflow', 'integer overflow in "buffer_get_data"'], ['0.3.3', '0.3.3', 1, 'integer overflow', 'integer overflow in "buffer_get_data"'],
['0.3.3', '0.3.3', 3, 'heap overflow', 'heap overflow in "packet_decrypt"']] ['0.3.3', '0.3.3', 3, 'heap overflow', 'heap overflow in "packet_decrypt"']]
} # type: Dict[str, List[List[Any]]] }

View File

@ -54,7 +54,7 @@ class WriteBuf:
return self.write(v) return self.write(v)
def write_list(self, v: List[str]) -> 'WriteBuf': def write_list(self, v: List[str]) -> 'WriteBuf':
return self.write_string(u','.join(v)) return self.write_string(','.join(v))
@classmethod @classmethod
def _bitlength(cls, n: int) -> int: def _bitlength(cls, n: int) -> int:

View File

@ -1,4 +1,4 @@
.TH SSH-AUDIT 1 "October 19, 2020" .TH SSH-AUDIT 1 "April 18, 2024"
.SH NAME .SH NAME
\fBssh-audit\fP \- SSH server & client configuration auditor \fBssh-audit\fP \- SSH server & client configuration auditor
.SH SYNOPSIS .SH SYNOPSIS
@ -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.
@ -46,10 +46,55 @@ Enables grepable output.
.br .br
Starts a server on port 2222 to audit client software configuration. Use -p/--port=<port> to change port and -t/--timeout=<secs> to change listen timeout. Starts a server on port 2222 to audit client software configuration. Use -p/--port=<port> to change port and -t/--timeout=<secs> to change listen timeout.
.TP
.B \-\-conn\-rate\-test=N[:max_rate]
.br
Performs a connection rate test (useful for collecting metrics related to susceptibility of the DHEat vulnerability [CVE-2002-20001]). A successful connection is counted when the server returns a valid SSH banner. Testing is conducted with N concurrent sockets with an optional maximum rate of connections per second.
.TP
.B -d, \-\-debug
.br
Enable debug output.
.TP
.B \-\-dheat=N[:kex[:e_len]]
.br
Run the DHEat DoS attack (CVE-2002-20001) against the target server (which will consume all available CPU resources). The number of concurrent sockets, N, needed to achieve this effect will be highly dependent on the CPU resources available on the target, as well as the latency between the source and target machines. The key exchange is automatically chosen based on which would cause maximum effect, unless explicitly chosen in the second field. Lastly, an (experimental) option allows the length in bytes of the fake e value sent to the server to be specified in the third field. Normally, the length of e is roughly the length of the modulus of the Diffie-Hellman exchange (hence, an 8192-bit / 1024-byte value of e is sent in each connection when targeting the diffie-hellman-group18-sha512 algorithm). Instead, it was observed that many SSH implementations accept small values, such as 4 bytes; this results in a much more network-efficient attack.
.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
Output results in JSON format. Output results in JSON format. Specify twice (-jj) to enable indent printing (useful for debugging).
.TP .TP
.B -l, \-\-level=<info|warn|fail> .B -l, \-\-level=<info|warn|fail>
@ -59,13 +104,18 @@ Specify the minimum output level. Default is info.
.TP .TP
.B -L, \-\-list-policies .B -L, \-\-list-policies
.br .br
List all official, built-in policies for common systems. Their full names can then be passed to -P/--policy. List all official, built-in policies for common systems. Their full names can then be passed to -P/--policy. Add \-v to \-L to view policy change logs.
.TP .TP
.B \-\-lookup=<alg1,alg2,...> .B \-\-lookup=<alg1,alg2,...>
.br .br
Look up the security information of an algorithm(s) in the internal database. Does not connect to a server. Look up the security information of an algorithm(s) in the internal database. Does not connect to a server.
.TP
.B -m, \-\-manual
.br
Print the man page (Docker, PyPI, Snap, and Windows builds only).
.TP .TP
.B -M, \-\-make-policy=<custom_policy.txt> .B -M, \-\-make-policy=<custom_policy.txt>
.br .br
@ -74,7 +124,7 @@ Creates a policy based on the target server. Useful when other servers should b
.TP .TP
.B -n, \-\-no-colors .B -n, \-\-no-colors
.br .br
Disable color output. Disable color output. Automatically set when the NO_COLOR environment variable is set.
.TP .TP
.B -p, \-\-port=<port> .B -p, \-\-port=<port>
@ -86,6 +136,11 @@ The TCP port to connect to when auditing a server, or the port to listen on when
.br .br
Runs a policy audit against a target using the specified policy (see \fBPOLICY AUDIT\fP section for detailed description of this mode of operation). Combine with -c/--client-audit to audit a client configuration instead of a server. Use -L/--list-policies to list all official, built-in policies for common systems. Runs a policy audit against a target using the specified policy (see \fBPOLICY AUDIT\fP section for detailed description of this mode of operation). Combine with -c/--client-audit to audit a client configuration instead of a server. Use -L/--list-policies to list all official, built-in policies for common systems.
.TP
.B \-\-skip\-rate\-test
.br
Skips the connection rate test during standard audits. By default, a few dozen TCP connections are created with the target host to see if connection throttling is implemented (this can safely infer whether the target is vulnerable to the DHEat attack; see CVE-2002-20001).
.TP .TP
.B -t, \-\-timeout=<secs> .B -t, \-\-timeout=<secs>
.br .br
@ -94,7 +149,12 @@ The timeout, in seconds, for creating connections and reading data from the sock
.TP .TP
.B -T, \-\-targets=<hosts.txt> .B -T, \-\-targets=<hosts.txt>
.br .br
A file containing a list of target hosts. Each line must have one host, in the format of HOST[:PORT]. A file containing a list of target hosts. Each line must have one host, in the format of HOST[:PORT]. Use --threads to control concurrent scans.
.TP
.B \-\-threads=<threads>
.br
The number of threads to use when scanning multiple targets (with -T/--targets). Default is 32.
.TP .TP
.B -v, \-\-verbose .B -v, \-\-verbose
@ -204,6 +264,70 @@ 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
.LP
To run the DHEat DoS attack (monitor the target server's CPU usage to determine the optimal number of concurrent sockets):
.RS
.nf
ssh-audit targetserver --dheat=10
.fi
.RE
.LP
To run the DHEat attack and manually target the diffie-hellman-group-exchange-sha256 algorithm:
.RS
.nf
ssh-audit targetserver --dheat=10:diffie-hellman-group-exchange-sha256
.fi
.RE
.LP
To run the DHEat attack and manually target the diffie-hellman-group-exchange-sha256 algorithm with a very small length of e (resulting in the same effect but without having to send large packets):
.RS
.nf
ssh-audit targetserver --dheat=10:diffie-hellman-group-exchange-sha256:4
.fi
.RE
.LP
To test the number of successful connections per second that can be created with the target using 8 parallel threads (useful for detecting whether connection throttling is implemented by the target):
.RS
.nf
ssh-audit targetserver --conn-rate-test=8
.fi
.RE
.LP
To use 8 parallel threads to create up to 100 connections per second with the target (useful for understanding how much CPU load is caused on the target simply from handling new connections vs excess modular exponentiation when performing the DHEat attack):
.RS
.nf
ssh-audit targetserver --conn-rate-test=8:100
.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:

View File

@ -1,6 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""src/ssh_audit/ssh_audit.py wrapper for backwards compatibility""" """src/ssh_audit/ssh_audit.py wrapper for backwards compatibility"""
import multiprocessing
import sys import sys
import traceback import traceback
from pathlib import Path from pathlib import Path
@ -10,12 +11,14 @@ sys.path.insert(0, str(Path(__file__).resolve().parent / "src"))
from ssh_audit.ssh_audit import main # noqa: E402 from ssh_audit.ssh_audit import main # noqa: E402
from ssh_audit import exitcodes # noqa: E402 from ssh_audit import exitcodes # noqa: E402
exit_code = exitcodes.GOOD if __name__ == "__main__":
multiprocessing.freeze_support() # Needed for PyInstaller (Windows) builds.
try: exit_code = exitcodes.GOOD
exit_code = main() try:
except Exception: exit_code = main()
exit_code = exitcodes.UNKNOWN_ERROR except Exception:
print(traceback.format_exc()) exit_code = exitcodes.UNKNOWN_ERROR
print(traceback.format_exc())
sys.exit(exit_code) sys.exit(exit_code)

View File

@ -73,6 +73,7 @@ class _VirtualSocket:
self.rdata = [] self.rdata = []
self.sdata = [] self.sdata = []
self.errors = {} self.errors = {}
self.blocking = False
self.gsock = _VirtualGlobalSocket(self) self.gsock = _VirtualGlobalSocket(self)
def _check_err(self, method): def _check_err(self, method):
@ -83,12 +84,18 @@ class _VirtualSocket:
def connect(self, address): def connect(self, address):
return self._connect(address, False) return self._connect(address, False)
def connect_ex(self, address):
return self.connect(address)
def _connect(self, address, ret=True): def _connect(self, address, ret=True):
self.peer_address = address self.peer_address = address
self._connected = True self._connected = True
self._check_err('connect') self._check_err('connect')
return self if ret else None return self if ret else None
def setblocking(self, r: bool):
self.blocking = r
def settimeout(self, timeout): def settimeout(self, timeout):
self.timeout = timeout self.timeout = timeout

View File

@ -1 +1,369 @@
{"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": [{"fp": "SHA256:CDfAU12pjQS7/91kg7gYacza0U/6PDbE04Ic3IpYxkM", "type": "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"]} {
"additional_notes": [],
"banner": {
"comments": null,
"protocol": "2.0",
"raw": "SSH-2.0-dropbear_2019.78",
"software": "dropbear_2019.78"
},
"compression": [
"zlib@openssh.com",
"none"
],
"cves": [],
"enc": [
{
"algorithm": "aes128-ctr",
"notes": {
"info": [
"available since OpenSSH 3.7, Dropbear SSH 0.52"
]
}
},
{
"algorithm": "aes256-ctr",
"notes": {
"info": [
"available since OpenSSH 3.7, Dropbear SSH 0.52"
]
}
},
{
"algorithm": "aes128-cbc",
"notes": {
"info": [
"available since OpenSSH 2.3.0, Dropbear SSH 0.28"
],
"warn": [
"using weak cipher mode"
]
}
},
{
"algorithm": "aes256-cbc",
"notes": {
"info": [
"available since OpenSSH 2.3.0, Dropbear SSH 0.47"
],
"warn": [
"using weak cipher mode"
]
}
},
{
"algorithm": "3des-ctr",
"notes": {
"fail": [
"using broken & deprecated 3DES cipher"
],
"info": [
"available since Dropbear SSH 0.52"
]
}
},
{
"algorithm": "3des-cbc",
"notes": {
"fail": [
"using broken & deprecated 3DES cipher"
],
"info": [
"available since OpenSSH 1.2.2, Dropbear SSH 0.28"
],
"warn": [
"using weak cipher mode",
"using small 64-bit block size"
]
}
}
],
"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",
"notes": {
"info": [
"default key exchange from OpenSSH 7.4 to 8.9",
"available since OpenSSH 7.4, Dropbear SSH 2018.76"
]
}
},
{
"algorithm": "curve25519-sha256@libssh.org",
"notes": {
"info": [
"default key exchange from OpenSSH 6.5 to 7.3",
"available since OpenSSH 6.4, Dropbear SSH 2013.62"
]
}
},
{
"algorithm": "ecdh-sha2-nistp521",
"notes": {
"fail": [
"using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency"
],
"info": [
"available since OpenSSH 5.7, Dropbear SSH 2013.62"
]
}
},
{
"algorithm": "ecdh-sha2-nistp384",
"notes": {
"fail": [
"using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency"
],
"info": [
"available since OpenSSH 5.7, Dropbear SSH 2013.62"
]
}
},
{
"algorithm": "ecdh-sha2-nistp256",
"notes": {
"fail": [
"using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency"
],
"info": [
"available since OpenSSH 5.7, Dropbear SSH 2013.62"
]
}
},
{
"algorithm": "diffie-hellman-group14-sha256",
"notes": {
"info": [
"available since OpenSSH 7.3, Dropbear SSH 2016.73"
],
"warn": [
"2048-bit modulus only provides 112-bits of symmetric strength"
]
}
},
{
"algorithm": "diffie-hellman-group14-sha1",
"notes": {
"fail": [
"using broken SHA-1 hash algorithm"
],
"info": [
"available since OpenSSH 3.9, Dropbear SSH 0.53"
],
"warn": [
"2048-bit modulus only provides 112-bits of symmetric strength"
]
}
},
{
"algorithm": "kexguess2@matt.ucc.asn.au",
"notes": {
"info": [
"available since Dropbear SSH 2013.57"
]
}
}
],
"key": [
{
"algorithm": "ecdsa-sha2-nistp256",
"notes": {
"fail": [
"using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency"
],
"info": [
"available since OpenSSH 5.7, Dropbear SSH 2013.62"
],
"warn": [
"using weak random number generator could reveal the key"
]
}
},
{
"algorithm": "ssh-rsa",
"keysize": 1024,
"notes": {
"fail": [
"using broken SHA-1 hash algorithm",
"using small 1024-bit modulus"
],
"info": [
"deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8",
"available since OpenSSH 2.5.0, Dropbear SSH 0.28"
]
}
},
{
"algorithm": "ssh-dss",
"notes": {
"fail": [
"using small 1024-bit modulus"
],
"info": [
"disabled in OpenSSH 7.0: https://www.openssh.com/txt/release-7.0",
"available since OpenSSH 2.1.0, Dropbear SSH 0.28"
],
"warn": [
"using weak random number generator could reveal the key"
]
}
}
],
"mac": [
{
"algorithm": "hmac-sha1-96",
"notes": {
"fail": [
"using broken SHA-1 hash algorithm"
],
"info": [
"available since OpenSSH 2.5.0, Dropbear SSH 0.47"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "hmac-sha1",
"notes": {
"fail": [
"using broken SHA-1 hash algorithm"
],
"info": [
"available since OpenSSH 2.1.0, Dropbear SSH 0.28"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "hmac-sha2-256",
"notes": {
"info": [
"available since OpenSSH 5.9, Dropbear SSH 2013.56"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
}
],
"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"
}

View File

@ -6,56 +6,55 @@
# key exchange algorithms # key exchange algorithms
(kex) curve25519-sha256 -- [info] available since OpenSSH 7.4, Dropbear SSH 2018.76 (kex) curve25519-sha256 -- [info] available since OpenSSH 7.4, Dropbear SSH 2018.76
(kex) curve25519-sha256@libssh.org -- [info] available since OpenSSH 6.5, Dropbear SSH 2013.62  `- [info] default key exchange from OpenSSH 7.4 to 8.9
(kex) ecdh-sha2-nistp521 -- [fail] using weak elliptic curves (kex) curve25519-sha256@libssh.org -- [info] available since OpenSSH 6.4, Dropbear SSH 2013.62
 `- [info] default key exchange from OpenSSH 6.5 to 7.3
(kex) ecdh-sha2-nistp521 -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62 `- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(kex) ecdh-sha2-nistp384 -- [fail] using weak elliptic curves (kex) ecdh-sha2-nistp384 -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62 `- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(kex) ecdh-sha2-nistp256 -- [fail] using weak elliptic curves (kex) ecdh-sha2-nistp256 -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62 `- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(kex) diffie-hellman-group14-sha256 -- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73 (kex) diffie-hellman-group14-sha256 -- [warn] 2048-bit modulus only provides 112-bits of symmetric strength
(kex) diffie-hellman-group14-sha1 -- [warn] using weak hashing algorithm `- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73
(kex) diffie-hellman-group14-sha1 -- [fail] using broken SHA-1 hash algorithm
 `- [warn] 2048-bit modulus only provides 112-bits of symmetric strength
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53 `- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
(kex) kexguess2@matt.ucc.asn.au -- [info] available since Dropbear SSH 2013.57 (kex) kexguess2@matt.ucc.asn.au -- [info] available since Dropbear SSH 2013.57
# host-key algorithms # host-key algorithms
(key) ecdsa-sha2-nistp256 -- [fail] using weak elliptic curves (key) ecdsa-sha2-nistp256 -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency
 `- [warn] using weak random number generator could reveal the key  `- [warn] using weak random number generator could reveal the key
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62 `- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(key) ssh-rsa (1024-bit) -- [fail] using weak hashing algorithm (key) ssh-rsa (1024-bit) -- [fail] using broken SHA-1 hash algorithm
 `- [warn] using small 1024-bit modulus  `- [fail] using small 1024-bit modulus
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28 `- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
`- [info] deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8
(key) ssh-dss -- [fail] using small 1024-bit modulus (key) ssh-dss -- [fail] using small 1024-bit modulus
 `- [fail] removed (in server) and disabled (in client) since OpenSSH 7.0, weak algorithm
 `- [warn] using weak random number generator could reveal the key  `- [warn] using weak random number generator could reveal the key
`- [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
# encryption algorithms (ciphers) # encryption algorithms (ciphers)
(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52 (enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52 (enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) aes128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) aes128-cbc -- [warn] using weak cipher mode
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28 `- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
(enc) aes256-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) aes256-cbc -- [warn] using weak cipher mode
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47 `- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47
(enc) 3des-ctr -- [fail] using weak cipher (enc) 3des-ctr -- [fail] using broken & deprecated 3DES cipher
`- [info] available since Dropbear SSH 0.52 `- [info] available since Dropbear SSH 0.52
(enc) 3des-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) 3des-cbc -- [fail] using broken & deprecated 3DES cipher
 `- [warn] disabled (in client) since OpenSSH 7.4, unsafe algorithm
 `- [warn] using weak cipher
 `- [warn] using weak cipher mode  `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size  `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28 `- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
# message authentication code algorithms # message authentication code algorithms
(mac) hmac-sha1-96 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (mac) hmac-sha1-96 -- [fail] using broken SHA-1 hash algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode  `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.47 `- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.47
(mac) hmac-sha1 -- [warn] using encrypt-and-MAC mode (mac) hmac-sha1 -- [fail] using broken SHA-1 hash algorithm
 `- [warn] using weak hashing algorithm  `- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28 `- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
(mac) hmac-sha2-256 -- [warn] using encrypt-and-MAC mode (mac) hmac-sha2-256 -- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56 `- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56
@ -66,20 +65,21 @@
# algorithm recommendations (for Dropbear SSH 2019.78) # algorithm recommendations (for Dropbear SSH 2019.78)
(rec) -3des-cbc -- enc algorithm to remove  (rec) -3des-cbc -- enc algorithm to remove 
(rec) -3des-ctr -- enc algorithm to remove  (rec) -3des-ctr -- enc algorithm to remove 
(rec) -aes128-cbc -- enc algorithm to remove  (rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove 
(rec) -aes256-cbc -- enc algorithm to remove 
(rec) -ecdh-sha2-nistp256 -- kex algorithm to remove  (rec) -ecdh-sha2-nistp256 -- kex algorithm to remove 
(rec) -ecdh-sha2-nistp384 -- kex algorithm to remove  (rec) -ecdh-sha2-nistp384 -- kex algorithm to remove 
(rec) -ecdh-sha2-nistp521 -- kex algorithm to remove  (rec) -ecdh-sha2-nistp521 -- kex algorithm to remove 
(rec) -ecdsa-sha2-nistp256 -- key algorithm to remove  (rec) -ecdsa-sha2-nistp256 -- key algorithm to remove 
(rec) -hmac-sha1 -- mac algorithm to remove 
(rec) -hmac-sha1-96 -- mac algorithm to remove  (rec) -hmac-sha1-96 -- mac algorithm to remove 
(rec) -ssh-dss -- key algorithm to remove  (rec) -ssh-dss -- key algorithm to remove 
(rec) -ssh-rsa -- key algorithm to remove  (rec) -ssh-rsa -- key algorithm to remove 
(rec) +diffie-hellman-group16-sha512 -- kex algorithm to append  (rec) +diffie-hellman-group16-sha512 -- kex algorithm to append 
(rec) +twofish128-ctr -- enc algorithm to append  (rec) +twofish128-ctr -- enc algorithm to append 
(rec) +twofish256-ctr -- enc algorithm to append  (rec) +twofish256-ctr -- enc algorithm to append 
(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove  (rec) -aes128-cbc -- enc algorithm to remove 
(rec) -hmac-sha1 -- mac algorithm to remove  (rec) -aes256-cbc -- enc algorithm to remove 
(rec) -diffie-hellman-group14-sha256 -- kex algorithm to remove 
(rec) -hmac-sha2-256 -- mac algorithm to remove  (rec) -hmac-sha2-256 -- mac algorithm to remove 
# additional info # additional info

View File

@ -1 +1,523 @@
{"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": [{"fp": "SHA256:YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4", "type": "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"]} {
"additional_notes": [],
"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": [
{
"algorithm": "aes128-cbc",
"notes": {
"info": [
"available since OpenSSH 2.3.0, Dropbear SSH 0.28"
],
"warn": [
"using weak cipher mode"
]
}
},
{
"algorithm": "3des-cbc",
"notes": {
"fail": [
"using broken & deprecated 3DES cipher"
],
"info": [
"available since OpenSSH 1.2.2, Dropbear SSH 0.28"
],
"warn": [
"using weak cipher mode",
"using small 64-bit block size"
]
}
},
{
"algorithm": "blowfish-cbc",
"notes": {
"fail": [
"using weak & deprecated Blowfish cipher"
],
"info": [
"available since OpenSSH 1.2.2, Dropbear SSH 0.28"
],
"warn": [
"using weak cipher mode",
"using small 64-bit block size"
]
}
},
{
"algorithm": "cast128-cbc",
"notes": {
"fail": [
"using weak & deprecated CAST cipher"
],
"info": [
"available since OpenSSH 2.1.0"
],
"warn": [
"using weak cipher mode",
"using small 64-bit block size"
]
}
},
{
"algorithm": "arcfour",
"notes": {
"fail": [
"using broken RC4 cipher"
],
"info": [
"available since OpenSSH 2.1.0"
]
}
},
{
"algorithm": "aes192-cbc",
"notes": {
"info": [
"available since OpenSSH 2.3.0"
],
"warn": [
"using weak cipher mode"
]
}
},
{
"algorithm": "aes256-cbc",
"notes": {
"info": [
"available since OpenSSH 2.3.0, Dropbear SSH 0.47"
],
"warn": [
"using weak cipher mode"
]
}
},
{
"algorithm": "rijndael-cbc@lysator.liu.se",
"notes": {
"fail": [
"using deprecated & non-standardized Rijndael cipher"
],
"info": [
"disabled in OpenSSH 7.0: https://www.openssh.com/txt/release-7.0",
"available since OpenSSH 2.3.0"
],
"warn": [
"using weak cipher mode"
]
}
},
{
"algorithm": "aes128-ctr",
"notes": {
"info": [
"available since OpenSSH 3.7, Dropbear SSH 0.52"
]
}
},
{
"algorithm": "aes192-ctr",
"notes": {
"info": [
"available since OpenSSH 3.7"
]
}
},
{
"algorithm": "aes256-ctr",
"notes": {
"info": [
"available since OpenSSH 3.7, Dropbear SSH 0.52"
]
}
}
],
"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,
"notes": {
"fail": [
"using small 1024-bit modulus"
],
"info": [
"available since OpenSSH 2.3.0"
]
}
},
{
"algorithm": "diffie-hellman-group14-sha1",
"notes": {
"fail": [
"using broken SHA-1 hash algorithm"
],
"info": [
"available since OpenSSH 3.9, Dropbear SSH 0.53"
],
"warn": [
"2048-bit modulus only provides 112-bits of symmetric strength"
]
}
},
{
"algorithm": "diffie-hellman-group1-sha1",
"notes": {
"fail": [
"using small 1024-bit modulus",
"vulnerable to the Logjam attack: https://en.wikipedia.org/wiki/Logjam_(computer_security)",
"using broken SHA-1 hash algorithm"
],
"info": [
"removed in OpenSSH 6.9: https://www.openssh.com/txt/release-6.9",
"available since OpenSSH 2.3.0, Dropbear SSH 0.28"
]
}
}
],
"key": [
{
"algorithm": "ssh-rsa",
"keysize": 1024,
"notes": {
"fail": [
"using broken SHA-1 hash algorithm",
"using small 1024-bit modulus"
],
"info": [
"deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8",
"available since OpenSSH 2.5.0, Dropbear SSH 0.28"
]
}
},
{
"algorithm": "ssh-dss",
"notes": {
"fail": [
"using small 1024-bit modulus"
],
"info": [
"disabled in OpenSSH 7.0: https://www.openssh.com/txt/release-7.0",
"available since OpenSSH 2.1.0, Dropbear SSH 0.28"
],
"warn": [
"using weak random number generator could reveal the key"
]
}
}
],
"mac": [
{
"algorithm": "hmac-md5",
"notes": {
"fail": [
"using broken MD5 hash algorithm"
],
"info": [
"available since OpenSSH 2.1.0, Dropbear SSH 0.28"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "hmac-sha1",
"notes": {
"fail": [
"using broken SHA-1 hash algorithm"
],
"info": [
"available since OpenSSH 2.1.0, Dropbear SSH 0.28"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "hmac-ripemd160",
"notes": {
"fail": [
"using deprecated RIPEMD hash algorithm"
],
"info": [
"available since OpenSSH 2.5.0"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "hmac-ripemd160@openssh.com",
"notes": {
"fail": [
"using deprecated RIPEMD hash algorithm"
],
"info": [
"available since OpenSSH 2.1.0"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "hmac-sha1-96",
"notes": {
"fail": [
"using broken SHA-1 hash algorithm"
],
"info": [
"available since OpenSSH 2.5.0, Dropbear SSH 0.47"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "hmac-md5-96",
"notes": {
"fail": [
"using broken MD5 hash algorithm"
],
"info": [
"available since OpenSSH 2.5.0"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
}
],
"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"
}

View File

@ -1,11 +1,15 @@
# general # general
(gen) banner: SSH-1.99-OpenSSH_4.0 (gen) banner: SSH-1.99-OpenSSH_4.0
(gen) protocol SSH1 enabled (gen) protocol SSH1 enabled
(gen) software: OpenSSH 4.0 (gen) software: OpenSSH 4.0
(gen) compatibility: OpenSSH 3.9-6.6, Dropbear SSH 0.53+ (some functionality from 0.52) (gen) compatibility: OpenSSH 3.9-6.6, Dropbear SSH 0.53+ (some functionality from 0.52)
(gen) compression: enabled (zlib) (gen) compression: enabled (zlib)
# security # security
(cve) CVE-2020-15778 -- (CVSSv2: 7.8) command injection via anomalous argument transfers
(cve) CVE-2018-15473 -- (CVSSv2: 5.3) enumerate usernames due to timing discrepancies
(cve) CVE-2017-15906 -- (CVSSv2: 5.3) readonly bypass via sftp
(cve) CVE-2016-20012 -- (CVSSv2: 5.3) enumerate usernames via challenge response
(cve) CVE-2016-3115 -- (CVSSv2: 5.5) bypass command restrictions via crafted X11 forwarding data (cve) CVE-2016-3115 -- (CVSSv2: 5.5) bypass command restrictions via crafted X11 forwarding data
(cve) CVE-2014-1692 -- (CVSSv2: 7.5) cause DoS via triggering error condition (memory corruption) (cve) CVE-2014-1692 -- (CVSSv2: 7.5) cause DoS via triggering error condition (memory corruption)
(cve) CVE-2012-0814 -- (CVSSv2: 3.5) leak data via debug messages (cve) CVE-2012-0814 -- (CVSSv2: 3.5) leak data via debug messages
@ -24,93 +28,77 @@
(cve) CVE-2006-4924 -- (CVSSv2: 7.8) cause DoS via crafted packet (CPU consumption) (cve) CVE-2006-4924 -- (CVSSv2: 7.8) cause DoS via crafted packet (CPU consumption)
(cve) CVE-2006-0225 -- (CVSSv2: 4.6) execute arbitrary code (cve) CVE-2006-0225 -- (CVSSv2: 4.6) execute arbitrary code
(cve) CVE-2005-2798 -- (CVSSv2: 5.0) leak data about authentication credentials (cve) CVE-2005-2798 -- (CVSSv2: 5.0) leak data about authentication credentials
(sec) SSH v1 enabled -- SSH v1 can be exploited to recover plaintext passwords
# key exchange algorithms # key exchange algorithms
(kex) diffie-hellman-group-exchange-sha1 (1024-bit) -- [fail] using small 1024-bit modulus (kex) diffie-hellman-group-exchange-sha1 (1024-bit) -- [fail] using small 1024-bit modulus
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.3.0 `- [info] available since OpenSSH 2.3.0
(kex) diffie-hellman-group14-sha1 -- [warn] using weak hashing algorithm (kex) diffie-hellman-group14-sha1 -- [fail] using broken SHA-1 hash algorithm
 `- [warn] 2048-bit modulus only provides 112-bits of symmetric strength
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53 `- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
(kex) diffie-hellman-group1-sha1 -- [fail] using small 1024-bit modulus (kex) diffie-hellman-group1-sha1 -- [fail] using small 1024-bit modulus
 `- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm  `- [fail] vulnerable to the Logjam attack: https://en.wikipedia.org/wiki/Logjam_(computer_security)
 `- [fail] disabled (in client) since OpenSSH 7.0, logjam attack  `- [fail] using broken SHA-1 hash algorithm
 `- [warn] using weak hashing algorithm
`- [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
# host-key algorithms # host-key algorithms
(key) ssh-rsa (1024-bit) -- [fail] using weak hashing algorithm (key) ssh-rsa (1024-bit) -- [fail] using broken SHA-1 hash algorithm
 `- [warn] using small 1024-bit modulus  `- [fail] using small 1024-bit modulus
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28 `- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
`- [info] deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8
(key) ssh-dss -- [fail] using small 1024-bit modulus (key) ssh-dss -- [fail] using small 1024-bit modulus
 `- [fail] removed (in server) and disabled (in client) since OpenSSH 7.0, weak algorithm
 `- [warn] using weak random number generator could reveal the key  `- [warn] using weak random number generator could reveal the key
`- [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
# encryption algorithms (ciphers) # encryption algorithms (ciphers)
(enc) aes128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) aes128-cbc -- [warn] using weak cipher mode
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28 `- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
(enc) 3des-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) 3des-cbc -- [fail] using broken & deprecated 3DES cipher
 `- [warn] disabled (in client) since OpenSSH 7.4, unsafe algorithm
 `- [warn] using weak cipher
 `- [warn] using weak cipher mode  `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size  `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28 `- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
(enc) blowfish-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) blowfish-cbc -- [fail] using weak & deprecated Blowfish cipher
 `- [fail] disabled since Dropbear SSH 0.53
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode  `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size  `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28 `- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
(enc) cast128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) cast128-cbc -- [fail] using weak & deprecated CAST cipher
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode  `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size  `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 2.1.0 `- [info] available since OpenSSH 2.1.0
(enc) arcfour -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) arcfour -- [fail] using broken RC4 cipher
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher
`- [info] available since OpenSSH 2.1.0 `- [info] available since OpenSSH 2.1.0
(enc) aes192-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) aes192-cbc -- [warn] using weak cipher mode
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0 `- [info] available since OpenSSH 2.3.0
(enc) aes256-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) aes256-cbc -- [warn] using weak cipher mode
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47 `- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47
(enc) rijndael-cbc@lysator.liu.se -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) rijndael-cbc@lysator.liu.se -- [fail] using deprecated & non-standardized Rijndael cipher
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode  `- [warn] using weak cipher mode
`- [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
(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52 (enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) aes192-ctr -- [info] available since OpenSSH 3.7 (enc) aes192-ctr -- [info] available since OpenSSH 3.7
(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52 (enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
# message authentication code algorithms # message authentication code algorithms
(mac) hmac-md5 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (mac) hmac-md5 -- [fail] using broken MD5 hash algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode  `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28 `- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
(mac) hmac-sha1 -- [warn] using encrypt-and-MAC mode (mac) hmac-sha1 -- [fail] using broken SHA-1 hash algorithm
 `- [warn] using weak hashing algorithm  `- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28 `- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
(mac) hmac-ripemd160 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (mac) hmac-ripemd160 -- [fail] using deprecated RIPEMD hash algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode  `- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 2.5.0 `- [info] available since OpenSSH 2.5.0
(mac) hmac-ripemd160@openssh.com -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (mac) hmac-ripemd160@openssh.com -- [fail] using deprecated RIPEMD hash algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode  `- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 2.1.0 `- [info] available since OpenSSH 2.1.0
(mac) hmac-sha1-96 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (mac) hmac-sha1-96 -- [fail] using broken SHA-1 hash algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode  `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.47 `- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.47
(mac) hmac-md5-96 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (mac) hmac-md5-96 -- [fail] using broken MD5 hash algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode  `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.5.0 `- [info] available since OpenSSH 2.5.0
# fingerprints # fingerprints
@ -118,24 +106,24 @@
# algorithm recommendations (for OpenSSH 4.0) # algorithm recommendations (for OpenSSH 4.0)
(rec) -3des-cbc -- enc algorithm to remove  (rec) -3des-cbc -- enc algorithm to remove 
(rec) -aes128-cbc -- enc algorithm to remove 
(rec) -aes192-cbc -- enc algorithm to remove 
(rec) -aes256-cbc -- enc algorithm to remove 
(rec) -arcfour -- enc algorithm to remove  (rec) -arcfour -- enc algorithm to remove 
(rec) -blowfish-cbc -- enc algorithm to remove  (rec) -blowfish-cbc -- enc algorithm to remove 
(rec) -cast128-cbc -- enc algorithm to remove  (rec) -cast128-cbc -- enc algorithm to remove 
(rec) -diffie-hellman-group-exchange-sha1 -- kex algorithm to remove  (rec) -diffie-hellman-group-exchange-sha1 -- kex algorithm to remove 
(rec) -diffie-hellman-group1-sha1 -- kex algorithm to remove  (rec) -diffie-hellman-group1-sha1 -- kex algorithm to remove 
(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove 
(rec) -hmac-md5 -- mac algorithm to remove  (rec) -hmac-md5 -- mac algorithm to remove 
(rec) -hmac-md5-96 -- mac algorithm to remove  (rec) -hmac-md5-96 -- mac algorithm to remove 
(rec) -hmac-ripemd160 -- mac algorithm to remove  (rec) -hmac-ripemd160 -- mac algorithm to remove 
(rec) -hmac-ripemd160@openssh.com -- mac algorithm to remove  (rec) -hmac-ripemd160@openssh.com -- mac algorithm to remove 
(rec) -hmac-sha1 -- mac algorithm to remove 
(rec) -hmac-sha1-96 -- mac algorithm to remove  (rec) -hmac-sha1-96 -- mac algorithm to remove 
(rec) -rijndael-cbc@lysator.liu.se -- enc algorithm to remove  (rec) -rijndael-cbc@lysator.liu.se -- enc algorithm to remove 
(rec) -ssh-dss -- key algorithm to remove  (rec) -ssh-dss -- key algorithm to remove 
(rec) -ssh-rsa -- key algorithm to remove  (rec) -ssh-rsa -- key algorithm to remove 
(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove  (rec) -aes128-cbc -- enc algorithm to remove 
(rec) -hmac-sha1 -- mac algorithm to remove  (rec) -aes192-cbc -- enc algorithm to remove 
(rec) -aes256-cbc -- enc algorithm to remove 
# additional info # additional info
(nfo) For hardening guides on common OSes, please see: <https://www.ssh-audit.com/hardening_guides.html> (nfo) For hardening guides on common OSes, please see: <https://www.ssh-audit.com/hardening_guides.html>

View File

@ -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)"
}

View File

@ -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)"
}

View File

@ -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: ❌ Failed! Result: ❌ Failed!
 
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
 

View File

@ -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)"
}

View File

@ -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)"
}

View File

@ -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)"
}

View File

@ -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)"
}

View File

@ -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)"
}

View File

@ -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: ✔ Passed Result: ✔ Passed

View File

@ -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)"
}

View File

@ -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: ❌ Failed! Result: ❌ Failed!
 
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
 

View File

@ -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)"
}

View File

@ -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: ❌ Failed! Result: ❌ Failed!
 
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
 

View File

@ -1 +1,556 @@
{"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": [{"fp": "SHA256:YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4", "type": "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"]} {
"additional_notes": [],
"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": [
{
"algorithm": "aes128-ctr",
"notes": {
"info": [
"available since OpenSSH 3.7, Dropbear SSH 0.52"
]
}
},
{
"algorithm": "aes192-ctr",
"notes": {
"info": [
"available since OpenSSH 3.7"
]
}
},
{
"algorithm": "aes256-ctr",
"notes": {
"info": [
"available since OpenSSH 3.7, Dropbear SSH 0.52"
]
}
},
{
"algorithm": "arcfour256",
"notes": {
"fail": [
"using broken RC4 cipher"
],
"info": [
"available since OpenSSH 4.2"
]
}
},
{
"algorithm": "arcfour128",
"notes": {
"fail": [
"using broken RC4 cipher"
],
"info": [
"available since OpenSSH 4.2"
]
}
},
{
"algorithm": "aes128-cbc",
"notes": {
"info": [
"available since OpenSSH 2.3.0, Dropbear SSH 0.28"
],
"warn": [
"using weak cipher mode"
]
}
},
{
"algorithm": "3des-cbc",
"notes": {
"fail": [
"using broken & deprecated 3DES cipher"
],
"info": [
"available since OpenSSH 1.2.2, Dropbear SSH 0.28"
],
"warn": [
"using weak cipher mode",
"using small 64-bit block size"
]
}
},
{
"algorithm": "blowfish-cbc",
"notes": {
"fail": [
"using weak & deprecated Blowfish cipher"
],
"info": [
"available since OpenSSH 1.2.2, Dropbear SSH 0.28"
],
"warn": [
"using weak cipher mode",
"using small 64-bit block size"
]
}
},
{
"algorithm": "cast128-cbc",
"notes": {
"fail": [
"using weak & deprecated CAST cipher"
],
"info": [
"available since OpenSSH 2.1.0"
],
"warn": [
"using weak cipher mode",
"using small 64-bit block size"
]
}
},
{
"algorithm": "aes192-cbc",
"notes": {
"info": [
"available since OpenSSH 2.3.0"
],
"warn": [
"using weak cipher mode"
]
}
},
{
"algorithm": "aes256-cbc",
"notes": {
"info": [
"available since OpenSSH 2.3.0, Dropbear SSH 0.47"
],
"warn": [
"using weak cipher mode"
]
}
},
{
"algorithm": "arcfour",
"notes": {
"fail": [
"using broken RC4 cipher"
],
"info": [
"available since OpenSSH 2.1.0"
]
}
},
{
"algorithm": "rijndael-cbc@lysator.liu.se",
"notes": {
"fail": [
"using deprecated & non-standardized Rijndael cipher"
],
"info": [
"disabled in OpenSSH 7.0: https://www.openssh.com/txt/release-7.0",
"available since OpenSSH 2.3.0"
],
"warn": [
"using weak cipher mode"
]
}
}
],
"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,
"notes": {
"fail": [
"using small 1024-bit modulus"
],
"info": [
"available since OpenSSH 4.4"
]
}
},
{
"algorithm": "diffie-hellman-group-exchange-sha1",
"keysize": 1024,
"notes": {
"fail": [
"using small 1024-bit modulus"
],
"info": [
"available since OpenSSH 2.3.0"
]
}
},
{
"algorithm": "diffie-hellman-group14-sha1",
"notes": {
"fail": [
"using broken SHA-1 hash algorithm"
],
"info": [
"available since OpenSSH 3.9, Dropbear SSH 0.53"
],
"warn": [
"2048-bit modulus only provides 112-bits of symmetric strength"
]
}
},
{
"algorithm": "diffie-hellman-group1-sha1",
"notes": {
"fail": [
"using small 1024-bit modulus",
"vulnerable to the Logjam attack: https://en.wikipedia.org/wiki/Logjam_(computer_security)",
"using broken SHA-1 hash algorithm"
],
"info": [
"removed in OpenSSH 6.9: https://www.openssh.com/txt/release-6.9",
"available since OpenSSH 2.3.0, Dropbear SSH 0.28"
]
}
}
],
"key": [
{
"algorithm": "ssh-rsa",
"keysize": 1024,
"notes": {
"fail": [
"using broken SHA-1 hash algorithm",
"using small 1024-bit modulus"
],
"info": [
"deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8",
"available since OpenSSH 2.5.0, Dropbear SSH 0.28"
]
}
},
{
"algorithm": "ssh-dss",
"notes": {
"fail": [
"using small 1024-bit modulus"
],
"info": [
"disabled in OpenSSH 7.0: https://www.openssh.com/txt/release-7.0",
"available since OpenSSH 2.1.0, Dropbear SSH 0.28"
],
"warn": [
"using weak random number generator could reveal the key"
]
}
}
],
"mac": [
{
"algorithm": "hmac-md5",
"notes": {
"fail": [
"using broken MD5 hash algorithm"
],
"info": [
"available since OpenSSH 2.1.0, Dropbear SSH 0.28"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "hmac-sha1",
"notes": {
"fail": [
"using broken SHA-1 hash algorithm"
],
"info": [
"available since OpenSSH 2.1.0, Dropbear SSH 0.28"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "umac-64@openssh.com",
"notes": {
"info": [
"available since OpenSSH 4.7"
],
"warn": [
"using encrypt-and-MAC mode",
"using small 64-bit tag size"
]
}
},
{
"algorithm": "hmac-ripemd160",
"notes": {
"fail": [
"using deprecated RIPEMD hash algorithm"
],
"info": [
"available since OpenSSH 2.5.0"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "hmac-ripemd160@openssh.com",
"notes": {
"fail": [
"using deprecated RIPEMD hash algorithm"
],
"info": [
"available since OpenSSH 2.1.0"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "hmac-sha1-96",
"notes": {
"fail": [
"using broken SHA-1 hash algorithm"
],
"info": [
"available since OpenSSH 2.5.0, Dropbear SSH 0.47"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "hmac-md5-96",
"notes": {
"fail": [
"using broken MD5 hash algorithm"
],
"info": [
"available since OpenSSH 2.5.0"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
}
],
"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"
}

View File

@ -5,6 +5,10 @@
(gen) compression: enabled (zlib@openssh.com) (gen) compression: enabled (zlib@openssh.com)
# security # security
(cve) CVE-2020-15778 -- (CVSSv2: 7.8) command injection via anomalous argument transfers
(cve) CVE-2018-15473 -- (CVSSv2: 5.3) enumerate usernames due to timing discrepancies
(cve) CVE-2017-15906 -- (CVSSv2: 5.3) readonly bypass via sftp
(cve) CVE-2016-20012 -- (CVSSv2: 5.3) enumerate usernames via challenge response
(cve) CVE-2016-3115 -- (CVSSv2: 5.5) bypass command restrictions via crafted X11 forwarding data (cve) CVE-2016-3115 -- (CVSSv2: 5.5) bypass command restrictions via crafted X11 forwarding data
(cve) CVE-2016-1907 -- (CVSSv2: 5.0) cause DoS via crafted network traffic (out of bounds read) (cve) CVE-2016-1907 -- (CVSSv2: 5.0) cause DoS via crafted network traffic (out of bounds read)
(cve) CVE-2015-6564 -- (CVSSv2: 6.9) privilege escalation via leveraging sshd uid (cve) CVE-2015-6564 -- (CVSSv2: 6.9) privilege escalation via leveraging sshd uid
@ -21,112 +25,88 @@
(kex) diffie-hellman-group-exchange-sha256 (1024-bit) -- [fail] using small 1024-bit modulus (kex) diffie-hellman-group-exchange-sha256 (1024-bit) -- [fail] using small 1024-bit modulus
`- [info] available since OpenSSH 4.4 `- [info] available since OpenSSH 4.4
(kex) diffie-hellman-group-exchange-sha1 (1024-bit) -- [fail] using small 1024-bit modulus (kex) diffie-hellman-group-exchange-sha1 (1024-bit) -- [fail] using small 1024-bit modulus
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.3.0 `- [info] available since OpenSSH 2.3.0
(kex) diffie-hellman-group14-sha1 -- [warn] using weak hashing algorithm (kex) diffie-hellman-group14-sha1 -- [fail] using broken SHA-1 hash algorithm
 `- [warn] 2048-bit modulus only provides 112-bits of symmetric strength
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53 `- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
(kex) diffie-hellman-group1-sha1 -- [fail] using small 1024-bit modulus (kex) diffie-hellman-group1-sha1 -- [fail] using small 1024-bit modulus
 `- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm  `- [fail] vulnerable to the Logjam attack: https://en.wikipedia.org/wiki/Logjam_(computer_security)
 `- [fail] disabled (in client) since OpenSSH 7.0, logjam attack  `- [fail] using broken SHA-1 hash algorithm
 `- [warn] using weak hashing algorithm
`- [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
# host-key algorithms # host-key algorithms
(key) ssh-rsa (1024-bit) -- [fail] using weak hashing algorithm (key) ssh-rsa (1024-bit) -- [fail] using broken SHA-1 hash algorithm
 `- [warn] using small 1024-bit modulus  `- [fail] using small 1024-bit modulus
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28 `- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
`- [info] deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8
(key) ssh-dss -- [fail] using small 1024-bit modulus (key) ssh-dss -- [fail] using small 1024-bit modulus
 `- [fail] removed (in server) and disabled (in client) since OpenSSH 7.0, weak algorithm
 `- [warn] using weak random number generator could reveal the key  `- [warn] using weak random number generator could reveal the key
`- [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
# encryption algorithms (ciphers) # encryption algorithms (ciphers)
(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52 (enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) aes192-ctr -- [info] available since OpenSSH 3.7 (enc) aes192-ctr -- [info] available since OpenSSH 3.7
(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52 (enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) arcfour256 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) arcfour256 -- [fail] using broken RC4 cipher
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher
`- [info] available since OpenSSH 4.2 `- [info] available since OpenSSH 4.2
(enc) arcfour128 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) arcfour128 -- [fail] using broken RC4 cipher
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher
`- [info] available since OpenSSH 4.2 `- [info] available since OpenSSH 4.2
(enc) aes128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) aes128-cbc -- [warn] using weak cipher mode
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28 `- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
(enc) 3des-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) 3des-cbc -- [fail] using broken & deprecated 3DES cipher
 `- [warn] disabled (in client) since OpenSSH 7.4, unsafe algorithm
 `- [warn] using weak cipher
 `- [warn] using weak cipher mode  `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size  `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28 `- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
(enc) blowfish-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) blowfish-cbc -- [fail] using weak & deprecated Blowfish cipher
 `- [fail] disabled since Dropbear SSH 0.53
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode  `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size  `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28 `- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
(enc) cast128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) cast128-cbc -- [fail] using weak & deprecated CAST cipher
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode  `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size  `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 2.1.0 `- [info] available since OpenSSH 2.1.0
(enc) aes192-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) aes192-cbc -- [warn] using weak cipher mode
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0 `- [info] available since OpenSSH 2.3.0
(enc) aes256-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) aes256-cbc -- [warn] using weak cipher mode
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47 `- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47
(enc) arcfour -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) arcfour -- [fail] using broken RC4 cipher
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher
`- [info] available since OpenSSH 2.1.0 `- [info] available since OpenSSH 2.1.0
(enc) rijndael-cbc@lysator.liu.se -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) rijndael-cbc@lysator.liu.se -- [fail] using deprecated & non-standardized Rijndael cipher
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode  `- [warn] using weak cipher mode
`- [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
# message authentication code algorithms # message authentication code algorithms
(mac) hmac-md5 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (mac) hmac-md5 -- [fail] using broken MD5 hash algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode  `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28 `- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
(mac) hmac-sha1 -- [warn] using encrypt-and-MAC mode (mac) hmac-sha1 -- [fail] using broken SHA-1 hash algorithm
 `- [warn] using weak hashing algorithm  `- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28 `- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
(mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode (mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode
 `- [warn] using small 64-bit tag size  `- [warn] using small 64-bit tag size
`- [info] available since OpenSSH 4.7 `- [info] available since OpenSSH 4.7
(mac) hmac-ripemd160 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (mac) hmac-ripemd160 -- [fail] using deprecated RIPEMD hash algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode  `- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 2.5.0 `- [info] available since OpenSSH 2.5.0
(mac) hmac-ripemd160@openssh.com -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (mac) hmac-ripemd160@openssh.com -- [fail] using deprecated RIPEMD hash algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode  `- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 2.1.0 `- [info] available since OpenSSH 2.1.0
(mac) hmac-sha1-96 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (mac) hmac-sha1-96 -- [fail] using broken SHA-1 hash algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode  `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.47 `- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.47
(mac) hmac-md5-96 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (mac) hmac-md5-96 -- [fail] using broken MD5 hash algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode  `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.5.0 `- [info] available since OpenSSH 2.5.0
# fingerprints # fingerprints
(fin) ssh-rsa: SHA256:YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4 (fin) ssh-rsa: SHA256:YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4
# algorithm recommendations (for OpenSSH 5.6) # algorithm recommendations (for OpenSSH 5.6)
(rec) !diffie-hellman-group-exchange-sha256 -- kex algorithm to change (increase modulus size to 2048 bits or larger)  (rec) !diffie-hellman-group-exchange-sha256 -- kex algorithm to change (increase modulus size to 3072 bits or larger) 
(rec) -3des-cbc -- enc algorithm to remove  (rec) -3des-cbc -- enc algorithm to remove 
(rec) -aes128-cbc -- enc algorithm to remove 
(rec) -aes192-cbc -- enc algorithm to remove 
(rec) -aes256-cbc -- enc algorithm to remove 
(rec) -arcfour -- enc algorithm to remove  (rec) -arcfour -- enc algorithm to remove 
(rec) -arcfour128 -- enc algorithm to remove  (rec) -arcfour128 -- enc algorithm to remove 
(rec) -arcfour256 -- enc algorithm to remove  (rec) -arcfour256 -- enc algorithm to remove 
@ -134,16 +114,19 @@
(rec) -cast128-cbc -- enc algorithm to remove  (rec) -cast128-cbc -- enc algorithm to remove 
(rec) -diffie-hellman-group-exchange-sha1 -- kex algorithm to remove  (rec) -diffie-hellman-group-exchange-sha1 -- kex algorithm to remove 
(rec) -diffie-hellman-group1-sha1 -- kex algorithm to remove  (rec) -diffie-hellman-group1-sha1 -- kex algorithm to remove 
(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove 
(rec) -hmac-md5 -- mac algorithm to remove  (rec) -hmac-md5 -- mac algorithm to remove 
(rec) -hmac-md5-96 -- mac algorithm to remove  (rec) -hmac-md5-96 -- mac algorithm to remove 
(rec) -hmac-ripemd160 -- mac algorithm to remove  (rec) -hmac-ripemd160 -- mac algorithm to remove 
(rec) -hmac-ripemd160@openssh.com -- mac algorithm to remove  (rec) -hmac-ripemd160@openssh.com -- mac algorithm to remove 
(rec) -hmac-sha1 -- mac algorithm to remove 
(rec) -hmac-sha1-96 -- mac algorithm to remove  (rec) -hmac-sha1-96 -- mac algorithm to remove 
(rec) -rijndael-cbc@lysator.liu.se -- enc algorithm to remove  (rec) -rijndael-cbc@lysator.liu.se -- enc algorithm to remove 
(rec) -ssh-dss -- key algorithm to remove  (rec) -ssh-dss -- key algorithm to remove 
(rec) -ssh-rsa -- key algorithm to remove  (rec) -ssh-rsa -- key algorithm to remove 
(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove  (rec) -aes128-cbc -- enc algorithm to remove 
(rec) -hmac-sha1 -- mac algorithm to remove  (rec) -aes192-cbc -- enc algorithm to remove 
(rec) -aes256-cbc -- enc algorithm to remove 
(rec) -umac-64@openssh.com -- mac algorithm to remove  (rec) -umac-64@openssh.com -- mac algorithm to remove 
# additional info # additional info

View File

@ -1 +1,558 @@
{"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": [{"fp": "SHA256:YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4", "type": "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"]} {
"additional_notes": [],
"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": [
{
"algorithm": "aes128-ctr",
"notes": {
"info": [
"available since OpenSSH 3.7, Dropbear SSH 0.52"
]
}
},
{
"algorithm": "aes192-ctr",
"notes": {
"info": [
"available since OpenSSH 3.7"
]
}
},
{
"algorithm": "aes256-ctr",
"notes": {
"info": [
"available since OpenSSH 3.7, Dropbear SSH 0.52"
]
}
},
{
"algorithm": "arcfour256",
"notes": {
"fail": [
"using broken RC4 cipher"
],
"info": [
"available since OpenSSH 4.2"
]
}
},
{
"algorithm": "arcfour128",
"notes": {
"fail": [
"using broken RC4 cipher"
],
"info": [
"available since OpenSSH 4.2"
]
}
},
{
"algorithm": "aes128-cbc",
"notes": {
"info": [
"available since OpenSSH 2.3.0, Dropbear SSH 0.28"
],
"warn": [
"using weak cipher mode"
]
}
},
{
"algorithm": "3des-cbc",
"notes": {
"fail": [
"using broken & deprecated 3DES cipher"
],
"info": [
"available since OpenSSH 1.2.2, Dropbear SSH 0.28"
],
"warn": [
"using weak cipher mode",
"using small 64-bit block size"
]
}
},
{
"algorithm": "blowfish-cbc",
"notes": {
"fail": [
"using weak & deprecated Blowfish cipher"
],
"info": [
"available since OpenSSH 1.2.2, Dropbear SSH 0.28"
],
"warn": [
"using weak cipher mode",
"using small 64-bit block size"
]
}
},
{
"algorithm": "cast128-cbc",
"notes": {
"fail": [
"using weak & deprecated CAST cipher"
],
"info": [
"available since OpenSSH 2.1.0"
],
"warn": [
"using weak cipher mode",
"using small 64-bit block size"
]
}
},
{
"algorithm": "aes192-cbc",
"notes": {
"info": [
"available since OpenSSH 2.3.0"
],
"warn": [
"using weak cipher mode"
]
}
},
{
"algorithm": "aes256-cbc",
"notes": {
"info": [
"available since OpenSSH 2.3.0, Dropbear SSH 0.47"
],
"warn": [
"using weak cipher mode"
]
}
},
{
"algorithm": "arcfour",
"notes": {
"fail": [
"using broken RC4 cipher"
],
"info": [
"available since OpenSSH 2.1.0"
]
}
},
{
"algorithm": "rijndael-cbc@lysator.liu.se",
"notes": {
"fail": [
"using deprecated & non-standardized Rijndael cipher"
],
"info": [
"disabled in OpenSSH 7.0: https://www.openssh.com/txt/release-7.0",
"available since OpenSSH 2.3.0"
],
"warn": [
"using weak cipher mode"
]
}
}
],
"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,
"notes": {
"fail": [
"using small 1024-bit modulus"
],
"info": [
"available since OpenSSH 4.4"
]
}
},
{
"algorithm": "diffie-hellman-group-exchange-sha1",
"keysize": 1024,
"notes": {
"fail": [
"using small 1024-bit modulus"
],
"info": [
"available since OpenSSH 2.3.0"
]
}
},
{
"algorithm": "diffie-hellman-group14-sha1",
"notes": {
"fail": [
"using broken SHA-1 hash algorithm"
],
"info": [
"available since OpenSSH 3.9, Dropbear SSH 0.53"
],
"warn": [
"2048-bit modulus only provides 112-bits of symmetric strength"
]
}
},
{
"algorithm": "diffie-hellman-group1-sha1",
"notes": {
"fail": [
"using small 1024-bit modulus",
"vulnerable to the Logjam attack: https://en.wikipedia.org/wiki/Logjam_(computer_security)",
"using broken SHA-1 hash algorithm"
],
"info": [
"removed in OpenSSH 6.9: https://www.openssh.com/txt/release-6.9",
"available since OpenSSH 2.3.0, Dropbear SSH 0.28"
]
}
}
],
"key": [
{
"algorithm": "ssh-rsa",
"keysize": 1024,
"notes": {
"fail": [
"using broken SHA-1 hash algorithm",
"using small 1024-bit modulus"
],
"info": [
"deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8",
"available since OpenSSH 2.5.0, Dropbear SSH 0.28"
]
}
},
{
"algorithm": "ssh-rsa-cert-v01@openssh.com",
"ca_algorithm": "ssh-rsa",
"casize": 1024,
"keysize": 1024,
"notes": {
"fail": [
"using broken SHA-1 hash algorithm",
"using small 1024-bit hostkey modulus",
"using small 1024-bit CA key modulus"
],
"info": [
"deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8",
"available since OpenSSH 5.6"
]
}
}
],
"mac": [
{
"algorithm": "hmac-md5",
"notes": {
"fail": [
"using broken MD5 hash algorithm"
],
"info": [
"available since OpenSSH 2.1.0, Dropbear SSH 0.28"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "hmac-sha1",
"notes": {
"fail": [
"using broken SHA-1 hash algorithm"
],
"info": [
"available since OpenSSH 2.1.0, Dropbear SSH 0.28"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "umac-64@openssh.com",
"notes": {
"info": [
"available since OpenSSH 4.7"
],
"warn": [
"using encrypt-and-MAC mode",
"using small 64-bit tag size"
]
}
},
{
"algorithm": "hmac-ripemd160",
"notes": {
"fail": [
"using deprecated RIPEMD hash algorithm"
],
"info": [
"available since OpenSSH 2.5.0"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "hmac-ripemd160@openssh.com",
"notes": {
"fail": [
"using deprecated RIPEMD hash algorithm"
],
"info": [
"available since OpenSSH 2.1.0"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "hmac-sha1-96",
"notes": {
"fail": [
"using broken SHA-1 hash algorithm"
],
"info": [
"available since OpenSSH 2.5.0, Dropbear SSH 0.47"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "hmac-md5-96",
"notes": {
"fail": [
"using broken MD5 hash algorithm"
],
"info": [
"available since OpenSSH 2.5.0"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
}
],
"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"
}

View File

@ -5,6 +5,10 @@
(gen) compression: enabled (zlib@openssh.com) (gen) compression: enabled (zlib@openssh.com)
# security # security
(cve) CVE-2020-15778 -- (CVSSv2: 7.8) command injection via anomalous argument transfers
(cve) CVE-2018-15473 -- (CVSSv2: 5.3) enumerate usernames due to timing discrepancies
(cve) CVE-2017-15906 -- (CVSSv2: 5.3) readonly bypass via sftp
(cve) CVE-2016-20012 -- (CVSSv2: 5.3) enumerate usernames via challenge response
(cve) CVE-2016-3115 -- (CVSSv2: 5.5) bypass command restrictions via crafted X11 forwarding data (cve) CVE-2016-3115 -- (CVSSv2: 5.5) bypass command restrictions via crafted X11 forwarding data
(cve) CVE-2016-1907 -- (CVSSv2: 5.0) cause DoS via crafted network traffic (out of bounds read) (cve) CVE-2016-1907 -- (CVSSv2: 5.0) cause DoS via crafted network traffic (out of bounds read)
(cve) CVE-2015-6564 -- (CVSSv2: 6.9) privilege escalation via leveraging sshd uid (cve) CVE-2015-6564 -- (CVSSv2: 6.9) privilege escalation via leveraging sshd uid
@ -21,111 +25,89 @@
(kex) diffie-hellman-group-exchange-sha256 (1024-bit) -- [fail] using small 1024-bit modulus (kex) diffie-hellman-group-exchange-sha256 (1024-bit) -- [fail] using small 1024-bit modulus
`- [info] available since OpenSSH 4.4 `- [info] available since OpenSSH 4.4
(kex) diffie-hellman-group-exchange-sha1 (1024-bit) -- [fail] using small 1024-bit modulus (kex) diffie-hellman-group-exchange-sha1 (1024-bit) -- [fail] using small 1024-bit modulus
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.3.0 `- [info] available since OpenSSH 2.3.0
(kex) diffie-hellman-group14-sha1 -- [warn] using weak hashing algorithm (kex) diffie-hellman-group14-sha1 -- [fail] using broken SHA-1 hash algorithm
 `- [warn] 2048-bit modulus only provides 112-bits of symmetric strength
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53 `- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
(kex) diffie-hellman-group1-sha1 -- [fail] using small 1024-bit modulus (kex) diffie-hellman-group1-sha1 -- [fail] using small 1024-bit modulus
 `- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm  `- [fail] vulnerable to the Logjam attack: https://en.wikipedia.org/wiki/Logjam_(computer_security)
 `- [fail] disabled (in client) since OpenSSH 7.0, logjam attack  `- [fail] using broken SHA-1 hash algorithm
 `- [warn] using weak hashing algorithm
`- [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
# host-key algorithms # host-key algorithms
(key) ssh-rsa (1024-bit) -- [fail] using weak hashing algorithm (key) ssh-rsa (1024-bit) -- [fail] using broken SHA-1 hash algorithm
 `- [warn] using small 1024-bit modulus  `- [fail] using small 1024-bit modulus
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28 `- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
(key) ssh-rsa-cert-v01@openssh.com (1024-bit cert/1024-bit CA) -- [fail] using weak hashing algorithm `- [info] deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8
 `- [warn] using small 1024-bit modulus (key) ssh-rsa-cert-v01@openssh.com (1024-bit cert/1024-bit RSA CA) -- [fail] using broken SHA-1 hash algorithm
`- [info] available since OpenSSH 5.6  `- [fail] using small 1024-bit hostkey modulus
 `- [fail] using small 1024-bit CA key modulus
`- [info] available since OpenSSH 5.6
`- [info] deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8
# encryption algorithms (ciphers) # encryption algorithms (ciphers)
(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52 (enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) aes192-ctr -- [info] available since OpenSSH 3.7 (enc) aes192-ctr -- [info] available since OpenSSH 3.7
(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52 (enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) arcfour256 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) arcfour256 -- [fail] using broken RC4 cipher
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher
`- [info] available since OpenSSH 4.2 `- [info] available since OpenSSH 4.2
(enc) arcfour128 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) arcfour128 -- [fail] using broken RC4 cipher
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher
`- [info] available since OpenSSH 4.2 `- [info] available since OpenSSH 4.2
(enc) aes128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) aes128-cbc -- [warn] using weak cipher mode
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28 `- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
(enc) 3des-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) 3des-cbc -- [fail] using broken & deprecated 3DES cipher
 `- [warn] disabled (in client) since OpenSSH 7.4, unsafe algorithm
 `- [warn] using weak cipher
 `- [warn] using weak cipher mode  `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size  `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28 `- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
(enc) blowfish-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) blowfish-cbc -- [fail] using weak & deprecated Blowfish cipher
 `- [fail] disabled since Dropbear SSH 0.53
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode  `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size  `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28 `- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
(enc) cast128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) cast128-cbc -- [fail] using weak & deprecated CAST cipher
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode  `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size  `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 2.1.0 `- [info] available since OpenSSH 2.1.0
(enc) aes192-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) aes192-cbc -- [warn] using weak cipher mode
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0 `- [info] available since OpenSSH 2.3.0
(enc) aes256-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) aes256-cbc -- [warn] using weak cipher mode
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47 `- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47
(enc) arcfour -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) arcfour -- [fail] using broken RC4 cipher
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher
`- [info] available since OpenSSH 2.1.0 `- [info] available since OpenSSH 2.1.0
(enc) rijndael-cbc@lysator.liu.se -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) rijndael-cbc@lysator.liu.se -- [fail] using deprecated & non-standardized Rijndael cipher
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode  `- [warn] using weak cipher mode
`- [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
# message authentication code algorithms # message authentication code algorithms
(mac) hmac-md5 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (mac) hmac-md5 -- [fail] using broken MD5 hash algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode  `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28 `- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
(mac) hmac-sha1 -- [warn] using encrypt-and-MAC mode (mac) hmac-sha1 -- [fail] using broken SHA-1 hash algorithm
 `- [warn] using weak hashing algorithm  `- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28 `- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
(mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode (mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode
 `- [warn] using small 64-bit tag size  `- [warn] using small 64-bit tag size
`- [info] available since OpenSSH 4.7 `- [info] available since OpenSSH 4.7
(mac) hmac-ripemd160 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (mac) hmac-ripemd160 -- [fail] using deprecated RIPEMD hash algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode  `- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 2.5.0 `- [info] available since OpenSSH 2.5.0
(mac) hmac-ripemd160@openssh.com -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (mac) hmac-ripemd160@openssh.com -- [fail] using deprecated RIPEMD hash algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode  `- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 2.1.0 `- [info] available since OpenSSH 2.1.0
(mac) hmac-sha1-96 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (mac) hmac-sha1-96 -- [fail] using broken SHA-1 hash algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode  `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.47 `- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.47
(mac) hmac-md5-96 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (mac) hmac-md5-96 -- [fail] using broken MD5 hash algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode  `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.5.0 `- [info] available since OpenSSH 2.5.0
# fingerprints # fingerprints
(fin) ssh-rsa: SHA256:YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4 (fin) ssh-rsa: SHA256:YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4
# algorithm recommendations (for OpenSSH 5.6) # algorithm recommendations (for OpenSSH 5.6)
(rec) !diffie-hellman-group-exchange-sha256 -- kex algorithm to change (increase modulus size to 2048 bits or larger)  (rec) !diffie-hellman-group-exchange-sha256 -- kex algorithm to change (increase modulus size to 3072 bits or larger) 
(rec) -3des-cbc -- enc algorithm to remove  (rec) -3des-cbc -- enc algorithm to remove 
(rec) -aes128-cbc -- enc algorithm to remove 
(rec) -aes192-cbc -- enc algorithm to remove 
(rec) -aes256-cbc -- enc algorithm to remove 
(rec) -arcfour -- enc algorithm to remove  (rec) -arcfour -- enc algorithm to remove 
(rec) -arcfour128 -- enc algorithm to remove  (rec) -arcfour128 -- enc algorithm to remove 
(rec) -arcfour256 -- enc algorithm to remove  (rec) -arcfour256 -- enc algorithm to remove 
@ -133,16 +115,19 @@
(rec) -cast128-cbc -- enc algorithm to remove  (rec) -cast128-cbc -- enc algorithm to remove 
(rec) -diffie-hellman-group-exchange-sha1 -- kex algorithm to remove  (rec) -diffie-hellman-group-exchange-sha1 -- kex algorithm to remove 
(rec) -diffie-hellman-group1-sha1 -- kex algorithm to remove  (rec) -diffie-hellman-group1-sha1 -- kex algorithm to remove 
(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove 
(rec) -hmac-md5 -- mac algorithm to remove  (rec) -hmac-md5 -- mac algorithm to remove 
(rec) -hmac-md5-96 -- mac algorithm to remove  (rec) -hmac-md5-96 -- mac algorithm to remove 
(rec) -hmac-ripemd160 -- mac algorithm to remove  (rec) -hmac-ripemd160 -- mac algorithm to remove 
(rec) -hmac-ripemd160@openssh.com -- mac algorithm to remove  (rec) -hmac-ripemd160@openssh.com -- mac algorithm to remove 
(rec) -hmac-sha1 -- mac algorithm to remove 
(rec) -hmac-sha1-96 -- mac algorithm to remove  (rec) -hmac-sha1-96 -- mac algorithm to remove 
(rec) -rijndael-cbc@lysator.liu.se -- enc algorithm to remove  (rec) -rijndael-cbc@lysator.liu.se -- enc algorithm to remove 
(rec) -ssh-rsa -- key algorithm to remove  (rec) -ssh-rsa -- key algorithm to remove 
(rec) -ssh-rsa-cert-v01@openssh.com -- key algorithm to remove  (rec) -ssh-rsa-cert-v01@openssh.com -- key algorithm to remove 
(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove  (rec) -aes128-cbc -- enc algorithm to remove 
(rec) -hmac-sha1 -- mac algorithm to remove  (rec) -aes192-cbc -- enc algorithm to remove 
(rec) -aes256-cbc -- enc algorithm to remove 
(rec) -umac-64@openssh.com -- mac algorithm to remove  (rec) -umac-64@openssh.com -- mac algorithm to remove 
# additional info # additional info

View File

@ -1 +1,557 @@
{"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": [{"fp": "SHA256:YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4", "type": "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"]} {
"additional_notes": [],
"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": [
{
"algorithm": "aes128-ctr",
"notes": {
"info": [
"available since OpenSSH 3.7, Dropbear SSH 0.52"
]
}
},
{
"algorithm": "aes192-ctr",
"notes": {
"info": [
"available since OpenSSH 3.7"
]
}
},
{
"algorithm": "aes256-ctr",
"notes": {
"info": [
"available since OpenSSH 3.7, Dropbear SSH 0.52"
]
}
},
{
"algorithm": "arcfour256",
"notes": {
"fail": [
"using broken RC4 cipher"
],
"info": [
"available since OpenSSH 4.2"
]
}
},
{
"algorithm": "arcfour128",
"notes": {
"fail": [
"using broken RC4 cipher"
],
"info": [
"available since OpenSSH 4.2"
]
}
},
{
"algorithm": "aes128-cbc",
"notes": {
"info": [
"available since OpenSSH 2.3.0, Dropbear SSH 0.28"
],
"warn": [
"using weak cipher mode"
]
}
},
{
"algorithm": "3des-cbc",
"notes": {
"fail": [
"using broken & deprecated 3DES cipher"
],
"info": [
"available since OpenSSH 1.2.2, Dropbear SSH 0.28"
],
"warn": [
"using weak cipher mode",
"using small 64-bit block size"
]
}
},
{
"algorithm": "blowfish-cbc",
"notes": {
"fail": [
"using weak & deprecated Blowfish cipher"
],
"info": [
"available since OpenSSH 1.2.2, Dropbear SSH 0.28"
],
"warn": [
"using weak cipher mode",
"using small 64-bit block size"
]
}
},
{
"algorithm": "cast128-cbc",
"notes": {
"fail": [
"using weak & deprecated CAST cipher"
],
"info": [
"available since OpenSSH 2.1.0"
],
"warn": [
"using weak cipher mode",
"using small 64-bit block size"
]
}
},
{
"algorithm": "aes192-cbc",
"notes": {
"info": [
"available since OpenSSH 2.3.0"
],
"warn": [
"using weak cipher mode"
]
}
},
{
"algorithm": "aes256-cbc",
"notes": {
"info": [
"available since OpenSSH 2.3.0, Dropbear SSH 0.47"
],
"warn": [
"using weak cipher mode"
]
}
},
{
"algorithm": "arcfour",
"notes": {
"fail": [
"using broken RC4 cipher"
],
"info": [
"available since OpenSSH 2.1.0"
]
}
},
{
"algorithm": "rijndael-cbc@lysator.liu.se",
"notes": {
"fail": [
"using deprecated & non-standardized Rijndael cipher"
],
"info": [
"disabled in OpenSSH 7.0: https://www.openssh.com/txt/release-7.0",
"available since OpenSSH 2.3.0"
],
"warn": [
"using weak cipher mode"
]
}
}
],
"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,
"notes": {
"fail": [
"using small 1024-bit modulus"
],
"info": [
"available since OpenSSH 4.4"
]
}
},
{
"algorithm": "diffie-hellman-group-exchange-sha1",
"keysize": 1024,
"notes": {
"fail": [
"using small 1024-bit modulus"
],
"info": [
"available since OpenSSH 2.3.0"
]
}
},
{
"algorithm": "diffie-hellman-group14-sha1",
"notes": {
"fail": [
"using broken SHA-1 hash algorithm"
],
"info": [
"available since OpenSSH 3.9, Dropbear SSH 0.53"
],
"warn": [
"2048-bit modulus only provides 112-bits of symmetric strength"
]
}
},
{
"algorithm": "diffie-hellman-group1-sha1",
"notes": {
"fail": [
"using small 1024-bit modulus",
"vulnerable to the Logjam attack: https://en.wikipedia.org/wiki/Logjam_(computer_security)",
"using broken SHA-1 hash algorithm"
],
"info": [
"removed in OpenSSH 6.9: https://www.openssh.com/txt/release-6.9",
"available since OpenSSH 2.3.0, Dropbear SSH 0.28"
]
}
}
],
"key": [
{
"algorithm": "ssh-rsa",
"keysize": 1024,
"notes": {
"fail": [
"using broken SHA-1 hash algorithm",
"using small 1024-bit modulus"
],
"info": [
"deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8",
"available since OpenSSH 2.5.0, Dropbear SSH 0.28"
]
}
},
{
"algorithm": "ssh-rsa-cert-v01@openssh.com",
"ca_algorithm": "ssh-rsa",
"casize": 3072,
"keysize": 1024,
"notes": {
"fail": [
"using broken SHA-1 hash algorithm",
"using small 1024-bit hostkey modulus"
],
"info": [
"deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8",
"available since OpenSSH 5.6"
]
}
}
],
"mac": [
{
"algorithm": "hmac-md5",
"notes": {
"fail": [
"using broken MD5 hash algorithm"
],
"info": [
"available since OpenSSH 2.1.0, Dropbear SSH 0.28"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "hmac-sha1",
"notes": {
"fail": [
"using broken SHA-1 hash algorithm"
],
"info": [
"available since OpenSSH 2.1.0, Dropbear SSH 0.28"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "umac-64@openssh.com",
"notes": {
"info": [
"available since OpenSSH 4.7"
],
"warn": [
"using encrypt-and-MAC mode",
"using small 64-bit tag size"
]
}
},
{
"algorithm": "hmac-ripemd160",
"notes": {
"fail": [
"using deprecated RIPEMD hash algorithm"
],
"info": [
"available since OpenSSH 2.5.0"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "hmac-ripemd160@openssh.com",
"notes": {
"fail": [
"using deprecated RIPEMD hash algorithm"
],
"info": [
"available since OpenSSH 2.1.0"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "hmac-sha1-96",
"notes": {
"fail": [
"using broken SHA-1 hash algorithm"
],
"info": [
"available since OpenSSH 2.5.0, Dropbear SSH 0.47"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "hmac-md5-96",
"notes": {
"fail": [
"using broken MD5 hash algorithm"
],
"info": [
"available since OpenSSH 2.5.0"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
}
],
"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"
}

View File

@ -5,6 +5,10 @@
(gen) compression: enabled (zlib@openssh.com) (gen) compression: enabled (zlib@openssh.com)
# security # security
(cve) CVE-2020-15778 -- (CVSSv2: 7.8) command injection via anomalous argument transfers
(cve) CVE-2018-15473 -- (CVSSv2: 5.3) enumerate usernames due to timing discrepancies
(cve) CVE-2017-15906 -- (CVSSv2: 5.3) readonly bypass via sftp
(cve) CVE-2016-20012 -- (CVSSv2: 5.3) enumerate usernames via challenge response
(cve) CVE-2016-3115 -- (CVSSv2: 5.5) bypass command restrictions via crafted X11 forwarding data (cve) CVE-2016-3115 -- (CVSSv2: 5.5) bypass command restrictions via crafted X11 forwarding data
(cve) CVE-2016-1907 -- (CVSSv2: 5.0) cause DoS via crafted network traffic (out of bounds read) (cve) CVE-2016-1907 -- (CVSSv2: 5.0) cause DoS via crafted network traffic (out of bounds read)
(cve) CVE-2015-6564 -- (CVSSv2: 6.9) privilege escalation via leveraging sshd uid (cve) CVE-2015-6564 -- (CVSSv2: 6.9) privilege escalation via leveraging sshd uid
@ -21,111 +25,88 @@
(kex) diffie-hellman-group-exchange-sha256 (1024-bit) -- [fail] using small 1024-bit modulus (kex) diffie-hellman-group-exchange-sha256 (1024-bit) -- [fail] using small 1024-bit modulus
`- [info] available since OpenSSH 4.4 `- [info] available since OpenSSH 4.4
(kex) diffie-hellman-group-exchange-sha1 (1024-bit) -- [fail] using small 1024-bit modulus (kex) diffie-hellman-group-exchange-sha1 (1024-bit) -- [fail] using small 1024-bit modulus
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.3.0 `- [info] available since OpenSSH 2.3.0
(kex) diffie-hellman-group14-sha1 -- [warn] using weak hashing algorithm (kex) diffie-hellman-group14-sha1 -- [fail] using broken SHA-1 hash algorithm
 `- [warn] 2048-bit modulus only provides 112-bits of symmetric strength
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53 `- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
(kex) diffie-hellman-group1-sha1 -- [fail] using small 1024-bit modulus (kex) diffie-hellman-group1-sha1 -- [fail] using small 1024-bit modulus
 `- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm  `- [fail] vulnerable to the Logjam attack: https://en.wikipedia.org/wiki/Logjam_(computer_security)
 `- [fail] disabled (in client) since OpenSSH 7.0, logjam attack  `- [fail] using broken SHA-1 hash algorithm
 `- [warn] using weak hashing algorithm
`- [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
# host-key algorithms # host-key algorithms
(key) ssh-rsa (1024-bit) -- [fail] using weak hashing algorithm (key) ssh-rsa (1024-bit) -- [fail] using broken SHA-1 hash algorithm
 `- [warn] using small 1024-bit modulus  `- [fail] using small 1024-bit modulus
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28 `- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
(key) ssh-rsa-cert-v01@openssh.com (1024-bit cert/3072-bit CA) -- [fail] using weak hashing algorithm `- [info] deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8
 `- [warn] using small 1024-bit modulus (key) ssh-rsa-cert-v01@openssh.com (1024-bit cert/3072-bit RSA CA) -- [fail] using broken SHA-1 hash algorithm
`- [info] available since OpenSSH 5.6  `- [fail] using small 1024-bit hostkey modulus
`- [info] available since OpenSSH 5.6
`- [info] deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8
# encryption algorithms (ciphers) # encryption algorithms (ciphers)
(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52 (enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) aes192-ctr -- [info] available since OpenSSH 3.7 (enc) aes192-ctr -- [info] available since OpenSSH 3.7
(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52 (enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) arcfour256 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) arcfour256 -- [fail] using broken RC4 cipher
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher
`- [info] available since OpenSSH 4.2 `- [info] available since OpenSSH 4.2
(enc) arcfour128 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) arcfour128 -- [fail] using broken RC4 cipher
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher
`- [info] available since OpenSSH 4.2 `- [info] available since OpenSSH 4.2
(enc) aes128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) aes128-cbc -- [warn] using weak cipher mode
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28 `- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
(enc) 3des-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) 3des-cbc -- [fail] using broken & deprecated 3DES cipher
 `- [warn] disabled (in client) since OpenSSH 7.4, unsafe algorithm
 `- [warn] using weak cipher
 `- [warn] using weak cipher mode  `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size  `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28 `- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
(enc) blowfish-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) blowfish-cbc -- [fail] using weak & deprecated Blowfish cipher
 `- [fail] disabled since Dropbear SSH 0.53
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode  `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size  `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28 `- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
(enc) cast128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) cast128-cbc -- [fail] using weak & deprecated CAST cipher
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode  `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size  `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 2.1.0 `- [info] available since OpenSSH 2.1.0
(enc) aes192-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) aes192-cbc -- [warn] using weak cipher mode
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0 `- [info] available since OpenSSH 2.3.0
(enc) aes256-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) aes256-cbc -- [warn] using weak cipher mode
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47 `- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47
(enc) arcfour -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) arcfour -- [fail] using broken RC4 cipher
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher
`- [info] available since OpenSSH 2.1.0 `- [info] available since OpenSSH 2.1.0
(enc) rijndael-cbc@lysator.liu.se -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) rijndael-cbc@lysator.liu.se -- [fail] using deprecated & non-standardized Rijndael cipher
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode  `- [warn] using weak cipher mode
`- [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
# message authentication code algorithms # message authentication code algorithms
(mac) hmac-md5 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (mac) hmac-md5 -- [fail] using broken MD5 hash algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode  `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28 `- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
(mac) hmac-sha1 -- [warn] using encrypt-and-MAC mode (mac) hmac-sha1 -- [fail] using broken SHA-1 hash algorithm
 `- [warn] using weak hashing algorithm  `- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28 `- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
(mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode (mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode
 `- [warn] using small 64-bit tag size  `- [warn] using small 64-bit tag size
`- [info] available since OpenSSH 4.7 `- [info] available since OpenSSH 4.7
(mac) hmac-ripemd160 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (mac) hmac-ripemd160 -- [fail] using deprecated RIPEMD hash algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode  `- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 2.5.0 `- [info] available since OpenSSH 2.5.0
(mac) hmac-ripemd160@openssh.com -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (mac) hmac-ripemd160@openssh.com -- [fail] using deprecated RIPEMD hash algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode  `- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 2.1.0 `- [info] available since OpenSSH 2.1.0
(mac) hmac-sha1-96 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (mac) hmac-sha1-96 -- [fail] using broken SHA-1 hash algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode  `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.47 `- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.47
(mac) hmac-md5-96 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (mac) hmac-md5-96 -- [fail] using broken MD5 hash algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode  `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.5.0 `- [info] available since OpenSSH 2.5.0
# fingerprints # fingerprints
(fin) ssh-rsa: SHA256:YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4 (fin) ssh-rsa: SHA256:YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4
# algorithm recommendations (for OpenSSH 5.6) # algorithm recommendations (for OpenSSH 5.6)
(rec) !diffie-hellman-group-exchange-sha256 -- kex algorithm to change (increase modulus size to 2048 bits or larger)  (rec) !diffie-hellman-group-exchange-sha256 -- kex algorithm to change (increase modulus size to 3072 bits or larger) 
(rec) -3des-cbc -- enc algorithm to remove  (rec) -3des-cbc -- enc algorithm to remove 
(rec) -aes128-cbc -- enc algorithm to remove 
(rec) -aes192-cbc -- enc algorithm to remove 
(rec) -aes256-cbc -- enc algorithm to remove 
(rec) -arcfour -- enc algorithm to remove  (rec) -arcfour -- enc algorithm to remove 
(rec) -arcfour128 -- enc algorithm to remove  (rec) -arcfour128 -- enc algorithm to remove 
(rec) -arcfour256 -- enc algorithm to remove  (rec) -arcfour256 -- enc algorithm to remove 
@ -133,16 +114,19 @@
(rec) -cast128-cbc -- enc algorithm to remove  (rec) -cast128-cbc -- enc algorithm to remove 
(rec) -diffie-hellman-group-exchange-sha1 -- kex algorithm to remove  (rec) -diffie-hellman-group-exchange-sha1 -- kex algorithm to remove 
(rec) -diffie-hellman-group1-sha1 -- kex algorithm to remove  (rec) -diffie-hellman-group1-sha1 -- kex algorithm to remove 
(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove 
(rec) -hmac-md5 -- mac algorithm to remove  (rec) -hmac-md5 -- mac algorithm to remove 
(rec) -hmac-md5-96 -- mac algorithm to remove  (rec) -hmac-md5-96 -- mac algorithm to remove 
(rec) -hmac-ripemd160 -- mac algorithm to remove  (rec) -hmac-ripemd160 -- mac algorithm to remove 
(rec) -hmac-ripemd160@openssh.com -- mac algorithm to remove  (rec) -hmac-ripemd160@openssh.com -- mac algorithm to remove 
(rec) -hmac-sha1 -- mac algorithm to remove 
(rec) -hmac-sha1-96 -- mac algorithm to remove  (rec) -hmac-sha1-96 -- mac algorithm to remove 
(rec) -rijndael-cbc@lysator.liu.se -- enc algorithm to remove  (rec) -rijndael-cbc@lysator.liu.se -- enc algorithm to remove 
(rec) -ssh-rsa -- key algorithm to remove  (rec) -ssh-rsa -- key algorithm to remove 
(rec) -ssh-rsa-cert-v01@openssh.com -- key algorithm to remove  (rec) -ssh-rsa-cert-v01@openssh.com -- key algorithm to remove 
(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove  (rec) -aes128-cbc -- enc algorithm to remove 
(rec) -hmac-sha1 -- mac algorithm to remove  (rec) -aes192-cbc -- enc algorithm to remove 
(rec) -aes256-cbc -- enc algorithm to remove 
(rec) -umac-64@openssh.com -- mac algorithm to remove  (rec) -umac-64@openssh.com -- mac algorithm to remove 
# additional info # additional info

View File

@ -1 +1,556 @@
{"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": [{"fp": "SHA256:nsWtdJ9Z67Vrf7OsUzQov7esXhsWAfVppArGh25u244", "type": "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"]} {
"additional_notes": [],
"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": [
{
"algorithm": "aes128-ctr",
"notes": {
"info": [
"available since OpenSSH 3.7, Dropbear SSH 0.52"
]
}
},
{
"algorithm": "aes192-ctr",
"notes": {
"info": [
"available since OpenSSH 3.7"
]
}
},
{
"algorithm": "aes256-ctr",
"notes": {
"info": [
"available since OpenSSH 3.7, Dropbear SSH 0.52"
]
}
},
{
"algorithm": "arcfour256",
"notes": {
"fail": [
"using broken RC4 cipher"
],
"info": [
"available since OpenSSH 4.2"
]
}
},
{
"algorithm": "arcfour128",
"notes": {
"fail": [
"using broken RC4 cipher"
],
"info": [
"available since OpenSSH 4.2"
]
}
},
{
"algorithm": "aes128-cbc",
"notes": {
"info": [
"available since OpenSSH 2.3.0, Dropbear SSH 0.28"
],
"warn": [
"using weak cipher mode"
]
}
},
{
"algorithm": "3des-cbc",
"notes": {
"fail": [
"using broken & deprecated 3DES cipher"
],
"info": [
"available since OpenSSH 1.2.2, Dropbear SSH 0.28"
],
"warn": [
"using weak cipher mode",
"using small 64-bit block size"
]
}
},
{
"algorithm": "blowfish-cbc",
"notes": {
"fail": [
"using weak & deprecated Blowfish cipher"
],
"info": [
"available since OpenSSH 1.2.2, Dropbear SSH 0.28"
],
"warn": [
"using weak cipher mode",
"using small 64-bit block size"
]
}
},
{
"algorithm": "cast128-cbc",
"notes": {
"fail": [
"using weak & deprecated CAST cipher"
],
"info": [
"available since OpenSSH 2.1.0"
],
"warn": [
"using weak cipher mode",
"using small 64-bit block size"
]
}
},
{
"algorithm": "aes192-cbc",
"notes": {
"info": [
"available since OpenSSH 2.3.0"
],
"warn": [
"using weak cipher mode"
]
}
},
{
"algorithm": "aes256-cbc",
"notes": {
"info": [
"available since OpenSSH 2.3.0, Dropbear SSH 0.47"
],
"warn": [
"using weak cipher mode"
]
}
},
{
"algorithm": "arcfour",
"notes": {
"fail": [
"using broken RC4 cipher"
],
"info": [
"available since OpenSSH 2.1.0"
]
}
},
{
"algorithm": "rijndael-cbc@lysator.liu.se",
"notes": {
"fail": [
"using deprecated & non-standardized Rijndael cipher"
],
"info": [
"disabled in OpenSSH 7.0: https://www.openssh.com/txt/release-7.0",
"available since OpenSSH 2.3.0"
],
"warn": [
"using weak cipher mode"
]
}
}
],
"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,
"notes": {
"fail": [
"using small 1024-bit modulus"
],
"info": [
"available since OpenSSH 4.4"
]
}
},
{
"algorithm": "diffie-hellman-group-exchange-sha1",
"keysize": 1024,
"notes": {
"fail": [
"using small 1024-bit modulus"
],
"info": [
"available since OpenSSH 2.3.0"
]
}
},
{
"algorithm": "diffie-hellman-group14-sha1",
"notes": {
"fail": [
"using broken SHA-1 hash algorithm"
],
"info": [
"available since OpenSSH 3.9, Dropbear SSH 0.53"
],
"warn": [
"2048-bit modulus only provides 112-bits of symmetric strength"
]
}
},
{
"algorithm": "diffie-hellman-group1-sha1",
"notes": {
"fail": [
"using small 1024-bit modulus",
"vulnerable to the Logjam attack: https://en.wikipedia.org/wiki/Logjam_(computer_security)",
"using broken SHA-1 hash algorithm"
],
"info": [
"removed in OpenSSH 6.9: https://www.openssh.com/txt/release-6.9",
"available since OpenSSH 2.3.0, Dropbear SSH 0.28"
]
}
}
],
"key": [
{
"algorithm": "ssh-rsa",
"keysize": 3072,
"notes": {
"fail": [
"using broken SHA-1 hash algorithm"
],
"info": [
"deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8",
"available since OpenSSH 2.5.0, Dropbear SSH 0.28"
]
}
},
{
"algorithm": "ssh-rsa-cert-v01@openssh.com",
"ca_algorithm": "ssh-rsa",
"casize": 1024,
"keysize": 3072,
"notes": {
"fail": [
"using broken SHA-1 hash algorithm",
"using small 1024-bit CA key modulus"
],
"info": [
"deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8",
"available since OpenSSH 5.6"
]
}
}
],
"mac": [
{
"algorithm": "hmac-md5",
"notes": {
"fail": [
"using broken MD5 hash algorithm"
],
"info": [
"available since OpenSSH 2.1.0, Dropbear SSH 0.28"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "hmac-sha1",
"notes": {
"fail": [
"using broken SHA-1 hash algorithm"
],
"info": [
"available since OpenSSH 2.1.0, Dropbear SSH 0.28"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "umac-64@openssh.com",
"notes": {
"info": [
"available since OpenSSH 4.7"
],
"warn": [
"using encrypt-and-MAC mode",
"using small 64-bit tag size"
]
}
},
{
"algorithm": "hmac-ripemd160",
"notes": {
"fail": [
"using deprecated RIPEMD hash algorithm"
],
"info": [
"available since OpenSSH 2.5.0"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "hmac-ripemd160@openssh.com",
"notes": {
"fail": [
"using deprecated RIPEMD hash algorithm"
],
"info": [
"available since OpenSSH 2.1.0"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "hmac-sha1-96",
"notes": {
"fail": [
"using broken SHA-1 hash algorithm"
],
"info": [
"available since OpenSSH 2.5.0, Dropbear SSH 0.47"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "hmac-md5-96",
"notes": {
"fail": [
"using broken MD5 hash algorithm"
],
"info": [
"available since OpenSSH 2.5.0"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
}
],
"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"
}

View File

@ -5,6 +5,10 @@
(gen) compression: enabled (zlib@openssh.com) (gen) compression: enabled (zlib@openssh.com)
# security # security
(cve) CVE-2020-15778 -- (CVSSv2: 7.8) command injection via anomalous argument transfers
(cve) CVE-2018-15473 -- (CVSSv2: 5.3) enumerate usernames due to timing discrepancies
(cve) CVE-2017-15906 -- (CVSSv2: 5.3) readonly bypass via sftp
(cve) CVE-2016-20012 -- (CVSSv2: 5.3) enumerate usernames via challenge response
(cve) CVE-2016-3115 -- (CVSSv2: 5.5) bypass command restrictions via crafted X11 forwarding data (cve) CVE-2016-3115 -- (CVSSv2: 5.5) bypass command restrictions via crafted X11 forwarding data
(cve) CVE-2016-1907 -- (CVSSv2: 5.0) cause DoS via crafted network traffic (out of bounds read) (cve) CVE-2016-1907 -- (CVSSv2: 5.0) cause DoS via crafted network traffic (out of bounds read)
(cve) CVE-2015-6564 -- (CVSSv2: 6.9) privilege escalation via leveraging sshd uid (cve) CVE-2015-6564 -- (CVSSv2: 6.9) privilege escalation via leveraging sshd uid
@ -21,110 +25,87 @@
(kex) diffie-hellman-group-exchange-sha256 (1024-bit) -- [fail] using small 1024-bit modulus (kex) diffie-hellman-group-exchange-sha256 (1024-bit) -- [fail] using small 1024-bit modulus
`- [info] available since OpenSSH 4.4 `- [info] available since OpenSSH 4.4
(kex) diffie-hellman-group-exchange-sha1 (1024-bit) -- [fail] using small 1024-bit modulus (kex) diffie-hellman-group-exchange-sha1 (1024-bit) -- [fail] using small 1024-bit modulus
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.3.0 `- [info] available since OpenSSH 2.3.0
(kex) diffie-hellman-group14-sha1 -- [warn] using weak hashing algorithm (kex) diffie-hellman-group14-sha1 -- [fail] using broken SHA-1 hash algorithm
 `- [warn] 2048-bit modulus only provides 112-bits of symmetric strength
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53 `- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
(kex) diffie-hellman-group1-sha1 -- [fail] using small 1024-bit modulus (kex) diffie-hellman-group1-sha1 -- [fail] using small 1024-bit modulus
 `- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm  `- [fail] vulnerable to the Logjam attack: https://en.wikipedia.org/wiki/Logjam_(computer_security)
 `- [fail] disabled (in client) since OpenSSH 7.0, logjam attack  `- [fail] using broken SHA-1 hash algorithm
 `- [warn] using weak hashing algorithm
`- [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
# host-key algorithms # host-key algorithms
(key) ssh-rsa (3072-bit) -- [fail] using weak hashing algorithm (key) ssh-rsa (3072-bit) -- [fail] using broken SHA-1 hash algorithm
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28 `- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
(key) ssh-rsa-cert-v01@openssh.com (3072-bit cert/1024-bit CA) -- [fail] using weak hashing algorithm `- [info] deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8
 `- [warn] using small 1024-bit modulus (key) ssh-rsa-cert-v01@openssh.com (3072-bit cert/1024-bit RSA CA) -- [fail] using broken SHA-1 hash algorithm
`- [info] available since OpenSSH 5.6  `- [fail] using small 1024-bit CA key modulus
`- [info] available since OpenSSH 5.6
`- [info] deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8
# encryption algorithms (ciphers) # encryption algorithms (ciphers)
(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52 (enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) aes192-ctr -- [info] available since OpenSSH 3.7 (enc) aes192-ctr -- [info] available since OpenSSH 3.7
(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52 (enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) arcfour256 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) arcfour256 -- [fail] using broken RC4 cipher
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher
`- [info] available since OpenSSH 4.2 `- [info] available since OpenSSH 4.2
(enc) arcfour128 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) arcfour128 -- [fail] using broken RC4 cipher
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher
`- [info] available since OpenSSH 4.2 `- [info] available since OpenSSH 4.2
(enc) aes128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) aes128-cbc -- [warn] using weak cipher mode
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28 `- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
(enc) 3des-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) 3des-cbc -- [fail] using broken & deprecated 3DES cipher
 `- [warn] disabled (in client) since OpenSSH 7.4, unsafe algorithm
 `- [warn] using weak cipher
 `- [warn] using weak cipher mode  `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size  `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28 `- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
(enc) blowfish-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) blowfish-cbc -- [fail] using weak & deprecated Blowfish cipher
 `- [fail] disabled since Dropbear SSH 0.53
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode  `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size  `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28 `- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
(enc) cast128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) cast128-cbc -- [fail] using weak & deprecated CAST cipher
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode  `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size  `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 2.1.0 `- [info] available since OpenSSH 2.1.0
(enc) aes192-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) aes192-cbc -- [warn] using weak cipher mode
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0 `- [info] available since OpenSSH 2.3.0
(enc) aes256-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) aes256-cbc -- [warn] using weak cipher mode
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47 `- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47
(enc) arcfour -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) arcfour -- [fail] using broken RC4 cipher
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher
`- [info] available since OpenSSH 2.1.0 `- [info] available since OpenSSH 2.1.0
(enc) rijndael-cbc@lysator.liu.se -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) rijndael-cbc@lysator.liu.se -- [fail] using deprecated & non-standardized Rijndael cipher
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode  `- [warn] using weak cipher mode
`- [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
# message authentication code algorithms # message authentication code algorithms
(mac) hmac-md5 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (mac) hmac-md5 -- [fail] using broken MD5 hash algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode  `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28 `- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
(mac) hmac-sha1 -- [warn] using encrypt-and-MAC mode (mac) hmac-sha1 -- [fail] using broken SHA-1 hash algorithm
 `- [warn] using weak hashing algorithm  `- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28 `- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
(mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode (mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode
 `- [warn] using small 64-bit tag size  `- [warn] using small 64-bit tag size
`- [info] available since OpenSSH 4.7 `- [info] available since OpenSSH 4.7
(mac) hmac-ripemd160 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (mac) hmac-ripemd160 -- [fail] using deprecated RIPEMD hash algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode  `- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 2.5.0 `- [info] available since OpenSSH 2.5.0
(mac) hmac-ripemd160@openssh.com -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (mac) hmac-ripemd160@openssh.com -- [fail] using deprecated RIPEMD hash algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode  `- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 2.1.0 `- [info] available since OpenSSH 2.1.0
(mac) hmac-sha1-96 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (mac) hmac-sha1-96 -- [fail] using broken SHA-1 hash algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode  `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.47 `- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.47
(mac) hmac-md5-96 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (mac) hmac-md5-96 -- [fail] using broken MD5 hash algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode  `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.5.0 `- [info] available since OpenSSH 2.5.0
# fingerprints # fingerprints
(fin) ssh-rsa: SHA256:nsWtdJ9Z67Vrf7OsUzQov7esXhsWAfVppArGh25u244 (fin) ssh-rsa: SHA256:nsWtdJ9Z67Vrf7OsUzQov7esXhsWAfVppArGh25u244
# algorithm recommendations (for OpenSSH 5.6) # algorithm recommendations (for OpenSSH 5.6)
(rec) !diffie-hellman-group-exchange-sha256 -- kex algorithm to change (increase modulus size to 2048 bits or larger)  (rec) !diffie-hellman-group-exchange-sha256 -- kex algorithm to change (increase modulus size to 3072 bits or larger) 
(rec) -3des-cbc -- enc algorithm to remove  (rec) -3des-cbc -- enc algorithm to remove 
(rec) -aes128-cbc -- enc algorithm to remove 
(rec) -aes192-cbc -- enc algorithm to remove 
(rec) -aes256-cbc -- enc algorithm to remove 
(rec) -arcfour -- enc algorithm to remove  (rec) -arcfour -- enc algorithm to remove 
(rec) -arcfour128 -- enc algorithm to remove  (rec) -arcfour128 -- enc algorithm to remove 
(rec) -arcfour256 -- enc algorithm to remove  (rec) -arcfour256 -- enc algorithm to remove 
@ -132,16 +113,19 @@
(rec) -cast128-cbc -- enc algorithm to remove  (rec) -cast128-cbc -- enc algorithm to remove 
(rec) -diffie-hellman-group-exchange-sha1 -- kex algorithm to remove  (rec) -diffie-hellman-group-exchange-sha1 -- kex algorithm to remove 
(rec) -diffie-hellman-group1-sha1 -- kex algorithm to remove  (rec) -diffie-hellman-group1-sha1 -- kex algorithm to remove 
(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove 
(rec) -hmac-md5 -- mac algorithm to remove  (rec) -hmac-md5 -- mac algorithm to remove 
(rec) -hmac-md5-96 -- mac algorithm to remove  (rec) -hmac-md5-96 -- mac algorithm to remove 
(rec) -hmac-ripemd160 -- mac algorithm to remove  (rec) -hmac-ripemd160 -- mac algorithm to remove 
(rec) -hmac-ripemd160@openssh.com -- mac algorithm to remove  (rec) -hmac-ripemd160@openssh.com -- mac algorithm to remove 
(rec) -hmac-sha1 -- mac algorithm to remove 
(rec) -hmac-sha1-96 -- mac algorithm to remove  (rec) -hmac-sha1-96 -- mac algorithm to remove 
(rec) -rijndael-cbc@lysator.liu.se -- enc algorithm to remove  (rec) -rijndael-cbc@lysator.liu.se -- enc algorithm to remove 
(rec) -ssh-rsa -- key algorithm to remove  (rec) -ssh-rsa -- key algorithm to remove 
(rec) -ssh-rsa-cert-v01@openssh.com -- key algorithm to remove  (rec) -ssh-rsa-cert-v01@openssh.com -- key algorithm to remove 
(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove  (rec) -aes128-cbc -- enc algorithm to remove 
(rec) -hmac-sha1 -- mac algorithm to remove  (rec) -aes192-cbc -- enc algorithm to remove 
(rec) -aes256-cbc -- enc algorithm to remove 
(rec) -umac-64@openssh.com -- mac algorithm to remove  (rec) -umac-64@openssh.com -- mac algorithm to remove 
# additional info # additional info

View File

@ -1 +1,555 @@
{"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": [{"fp": "SHA256:nsWtdJ9Z67Vrf7OsUzQov7esXhsWAfVppArGh25u244", "type": "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"]} {
"additional_notes": [],
"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": [
{
"algorithm": "aes128-ctr",
"notes": {
"info": [
"available since OpenSSH 3.7, Dropbear SSH 0.52"
]
}
},
{
"algorithm": "aes192-ctr",
"notes": {
"info": [
"available since OpenSSH 3.7"
]
}
},
{
"algorithm": "aes256-ctr",
"notes": {
"info": [
"available since OpenSSH 3.7, Dropbear SSH 0.52"
]
}
},
{
"algorithm": "arcfour256",
"notes": {
"fail": [
"using broken RC4 cipher"
],
"info": [
"available since OpenSSH 4.2"
]
}
},
{
"algorithm": "arcfour128",
"notes": {
"fail": [
"using broken RC4 cipher"
],
"info": [
"available since OpenSSH 4.2"
]
}
},
{
"algorithm": "aes128-cbc",
"notes": {
"info": [
"available since OpenSSH 2.3.0, Dropbear SSH 0.28"
],
"warn": [
"using weak cipher mode"
]
}
},
{
"algorithm": "3des-cbc",
"notes": {
"fail": [
"using broken & deprecated 3DES cipher"
],
"info": [
"available since OpenSSH 1.2.2, Dropbear SSH 0.28"
],
"warn": [
"using weak cipher mode",
"using small 64-bit block size"
]
}
},
{
"algorithm": "blowfish-cbc",
"notes": {
"fail": [
"using weak & deprecated Blowfish cipher"
],
"info": [
"available since OpenSSH 1.2.2, Dropbear SSH 0.28"
],
"warn": [
"using weak cipher mode",
"using small 64-bit block size"
]
}
},
{
"algorithm": "cast128-cbc",
"notes": {
"fail": [
"using weak & deprecated CAST cipher"
],
"info": [
"available since OpenSSH 2.1.0"
],
"warn": [
"using weak cipher mode",
"using small 64-bit block size"
]
}
},
{
"algorithm": "aes192-cbc",
"notes": {
"info": [
"available since OpenSSH 2.3.0"
],
"warn": [
"using weak cipher mode"
]
}
},
{
"algorithm": "aes256-cbc",
"notes": {
"info": [
"available since OpenSSH 2.3.0, Dropbear SSH 0.47"
],
"warn": [
"using weak cipher mode"
]
}
},
{
"algorithm": "arcfour",
"notes": {
"fail": [
"using broken RC4 cipher"
],
"info": [
"available since OpenSSH 2.1.0"
]
}
},
{
"algorithm": "rijndael-cbc@lysator.liu.se",
"notes": {
"fail": [
"using deprecated & non-standardized Rijndael cipher"
],
"info": [
"disabled in OpenSSH 7.0: https://www.openssh.com/txt/release-7.0",
"available since OpenSSH 2.3.0"
],
"warn": [
"using weak cipher mode"
]
}
}
],
"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,
"notes": {
"fail": [
"using small 1024-bit modulus"
],
"info": [
"available since OpenSSH 4.4"
]
}
},
{
"algorithm": "diffie-hellman-group-exchange-sha1",
"keysize": 1024,
"notes": {
"fail": [
"using small 1024-bit modulus"
],
"info": [
"available since OpenSSH 2.3.0"
]
}
},
{
"algorithm": "diffie-hellman-group14-sha1",
"notes": {
"fail": [
"using broken SHA-1 hash algorithm"
],
"info": [
"available since OpenSSH 3.9, Dropbear SSH 0.53"
],
"warn": [
"2048-bit modulus only provides 112-bits of symmetric strength"
]
}
},
{
"algorithm": "diffie-hellman-group1-sha1",
"notes": {
"fail": [
"using small 1024-bit modulus",
"vulnerable to the Logjam attack: https://en.wikipedia.org/wiki/Logjam_(computer_security)",
"using broken SHA-1 hash algorithm"
],
"info": [
"removed in OpenSSH 6.9: https://www.openssh.com/txt/release-6.9",
"available since OpenSSH 2.3.0, Dropbear SSH 0.28"
]
}
}
],
"key": [
{
"algorithm": "ssh-rsa",
"keysize": 3072,
"notes": {
"fail": [
"using broken SHA-1 hash algorithm"
],
"info": [
"deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8",
"available since OpenSSH 2.5.0, Dropbear SSH 0.28"
]
}
},
{
"algorithm": "ssh-rsa-cert-v01@openssh.com",
"ca_algorithm": "ssh-rsa",
"casize": 3072,
"keysize": 3072,
"notes": {
"fail": [
"using broken SHA-1 hash algorithm"
],
"info": [
"deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8",
"available since OpenSSH 5.6"
]
}
}
],
"mac": [
{
"algorithm": "hmac-md5",
"notes": {
"fail": [
"using broken MD5 hash algorithm"
],
"info": [
"available since OpenSSH 2.1.0, Dropbear SSH 0.28"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "hmac-sha1",
"notes": {
"fail": [
"using broken SHA-1 hash algorithm"
],
"info": [
"available since OpenSSH 2.1.0, Dropbear SSH 0.28"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "umac-64@openssh.com",
"notes": {
"info": [
"available since OpenSSH 4.7"
],
"warn": [
"using encrypt-and-MAC mode",
"using small 64-bit tag size"
]
}
},
{
"algorithm": "hmac-ripemd160",
"notes": {
"fail": [
"using deprecated RIPEMD hash algorithm"
],
"info": [
"available since OpenSSH 2.5.0"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "hmac-ripemd160@openssh.com",
"notes": {
"fail": [
"using deprecated RIPEMD hash algorithm"
],
"info": [
"available since OpenSSH 2.1.0"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "hmac-sha1-96",
"notes": {
"fail": [
"using broken SHA-1 hash algorithm"
],
"info": [
"available since OpenSSH 2.5.0, Dropbear SSH 0.47"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "hmac-md5-96",
"notes": {
"fail": [
"using broken MD5 hash algorithm"
],
"info": [
"available since OpenSSH 2.5.0"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
}
],
"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"
}

View File

@ -5,6 +5,10 @@
(gen) compression: enabled (zlib@openssh.com) (gen) compression: enabled (zlib@openssh.com)
# security # security
(cve) CVE-2020-15778 -- (CVSSv2: 7.8) command injection via anomalous argument transfers
(cve) CVE-2018-15473 -- (CVSSv2: 5.3) enumerate usernames due to timing discrepancies
(cve) CVE-2017-15906 -- (CVSSv2: 5.3) readonly bypass via sftp
(cve) CVE-2016-20012 -- (CVSSv2: 5.3) enumerate usernames via challenge response
(cve) CVE-2016-3115 -- (CVSSv2: 5.5) bypass command restrictions via crafted X11 forwarding data (cve) CVE-2016-3115 -- (CVSSv2: 5.5) bypass command restrictions via crafted X11 forwarding data
(cve) CVE-2016-1907 -- (CVSSv2: 5.0) cause DoS via crafted network traffic (out of bounds read) (cve) CVE-2016-1907 -- (CVSSv2: 5.0) cause DoS via crafted network traffic (out of bounds read)
(cve) CVE-2015-6564 -- (CVSSv2: 6.9) privilege escalation via leveraging sshd uid (cve) CVE-2015-6564 -- (CVSSv2: 6.9) privilege escalation via leveraging sshd uid
@ -21,109 +25,86 @@
(kex) diffie-hellman-group-exchange-sha256 (1024-bit) -- [fail] using small 1024-bit modulus (kex) diffie-hellman-group-exchange-sha256 (1024-bit) -- [fail] using small 1024-bit modulus
`- [info] available since OpenSSH 4.4 `- [info] available since OpenSSH 4.4
(kex) diffie-hellman-group-exchange-sha1 (1024-bit) -- [fail] using small 1024-bit modulus (kex) diffie-hellman-group-exchange-sha1 (1024-bit) -- [fail] using small 1024-bit modulus
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.3.0 `- [info] available since OpenSSH 2.3.0
(kex) diffie-hellman-group14-sha1 -- [warn] using weak hashing algorithm (kex) diffie-hellman-group14-sha1 -- [fail] using broken SHA-1 hash algorithm
 `- [warn] 2048-bit modulus only provides 112-bits of symmetric strength
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53 `- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
(kex) diffie-hellman-group1-sha1 -- [fail] using small 1024-bit modulus (kex) diffie-hellman-group1-sha1 -- [fail] using small 1024-bit modulus
 `- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm  `- [fail] vulnerable to the Logjam attack: https://en.wikipedia.org/wiki/Logjam_(computer_security)
 `- [fail] disabled (in client) since OpenSSH 7.0, logjam attack  `- [fail] using broken SHA-1 hash algorithm
 `- [warn] using weak hashing algorithm
`- [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
# host-key algorithms # host-key algorithms
(key) ssh-rsa (3072-bit) -- [fail] using weak hashing algorithm (key) ssh-rsa (3072-bit) -- [fail] using broken SHA-1 hash algorithm
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28 `- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
(key) ssh-rsa-cert-v01@openssh.com (3072-bit cert/3072-bit CA) -- [fail] using weak hashing algorithm `- [info] deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8
`- [info] available since OpenSSH 5.6 (key) ssh-rsa-cert-v01@openssh.com (3072-bit cert/3072-bit RSA CA) -- [fail] using broken SHA-1 hash algorithm
`- [info] available since OpenSSH 5.6
`- [info] deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8
# encryption algorithms (ciphers) # encryption algorithms (ciphers)
(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52 (enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) aes192-ctr -- [info] available since OpenSSH 3.7 (enc) aes192-ctr -- [info] available since OpenSSH 3.7
(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52 (enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) arcfour256 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) arcfour256 -- [fail] using broken RC4 cipher
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher
`- [info] available since OpenSSH 4.2 `- [info] available since OpenSSH 4.2
(enc) arcfour128 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) arcfour128 -- [fail] using broken RC4 cipher
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher
`- [info] available since OpenSSH 4.2 `- [info] available since OpenSSH 4.2
(enc) aes128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) aes128-cbc -- [warn] using weak cipher mode
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28 `- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
(enc) 3des-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) 3des-cbc -- [fail] using broken & deprecated 3DES cipher
 `- [warn] disabled (in client) since OpenSSH 7.4, unsafe algorithm
 `- [warn] using weak cipher
 `- [warn] using weak cipher mode  `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size  `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28 `- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
(enc) blowfish-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) blowfish-cbc -- [fail] using weak & deprecated Blowfish cipher
 `- [fail] disabled since Dropbear SSH 0.53
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode  `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size  `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28 `- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
(enc) cast128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) cast128-cbc -- [fail] using weak & deprecated CAST cipher
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode  `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size  `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 2.1.0 `- [info] available since OpenSSH 2.1.0
(enc) aes192-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) aes192-cbc -- [warn] using weak cipher mode
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0 `- [info] available since OpenSSH 2.3.0
(enc) aes256-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) aes256-cbc -- [warn] using weak cipher mode
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47 `- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47
(enc) arcfour -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) arcfour -- [fail] using broken RC4 cipher
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher
`- [info] available since OpenSSH 2.1.0 `- [info] available since OpenSSH 2.1.0
(enc) rijndael-cbc@lysator.liu.se -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (enc) rijndael-cbc@lysator.liu.se -- [fail] using deprecated & non-standardized Rijndael cipher
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode  `- [warn] using weak cipher mode
`- [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
# message authentication code algorithms # message authentication code algorithms
(mac) hmac-md5 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (mac) hmac-md5 -- [fail] using broken MD5 hash algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode  `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28 `- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
(mac) hmac-sha1 -- [warn] using encrypt-and-MAC mode (mac) hmac-sha1 -- [fail] using broken SHA-1 hash algorithm
 `- [warn] using weak hashing algorithm  `- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28 `- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
(mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode (mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode
 `- [warn] using small 64-bit tag size  `- [warn] using small 64-bit tag size
`- [info] available since OpenSSH 4.7 `- [info] available since OpenSSH 4.7
(mac) hmac-ripemd160 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (mac) hmac-ripemd160 -- [fail] using deprecated RIPEMD hash algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode  `- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 2.5.0 `- [info] available since OpenSSH 2.5.0
(mac) hmac-ripemd160@openssh.com -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (mac) hmac-ripemd160@openssh.com -- [fail] using deprecated RIPEMD hash algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode  `- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 2.1.0 `- [info] available since OpenSSH 2.1.0
(mac) hmac-sha1-96 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (mac) hmac-sha1-96 -- [fail] using broken SHA-1 hash algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode  `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.47 `- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.47
(mac) hmac-md5-96 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm (mac) hmac-md5-96 -- [fail] using broken MD5 hash algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode  `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.5.0 `- [info] available since OpenSSH 2.5.0
# fingerprints # fingerprints
(fin) ssh-rsa: SHA256:nsWtdJ9Z67Vrf7OsUzQov7esXhsWAfVppArGh25u244 (fin) ssh-rsa: SHA256:nsWtdJ9Z67Vrf7OsUzQov7esXhsWAfVppArGh25u244
# algorithm recommendations (for OpenSSH 5.6) # algorithm recommendations (for OpenSSH 5.6)
(rec) !diffie-hellman-group-exchange-sha256 -- kex algorithm to change (increase modulus size to 2048 bits or larger)  (rec) !diffie-hellman-group-exchange-sha256 -- kex algorithm to change (increase modulus size to 3072 bits or larger) 
(rec) -3des-cbc -- enc algorithm to remove  (rec) -3des-cbc -- enc algorithm to remove 
(rec) -aes128-cbc -- enc algorithm to remove 
(rec) -aes192-cbc -- enc algorithm to remove 
(rec) -aes256-cbc -- enc algorithm to remove 
(rec) -arcfour -- enc algorithm to remove  (rec) -arcfour -- enc algorithm to remove 
(rec) -arcfour128 -- enc algorithm to remove  (rec) -arcfour128 -- enc algorithm to remove 
(rec) -arcfour256 -- enc algorithm to remove  (rec) -arcfour256 -- enc algorithm to remove 
@ -131,16 +112,19 @@
(rec) -cast128-cbc -- enc algorithm to remove  (rec) -cast128-cbc -- enc algorithm to remove 
(rec) -diffie-hellman-group-exchange-sha1 -- kex algorithm to remove  (rec) -diffie-hellman-group-exchange-sha1 -- kex algorithm to remove 
(rec) -diffie-hellman-group1-sha1 -- kex algorithm to remove  (rec) -diffie-hellman-group1-sha1 -- kex algorithm to remove 
(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove 
(rec) -hmac-md5 -- mac algorithm to remove  (rec) -hmac-md5 -- mac algorithm to remove 
(rec) -hmac-md5-96 -- mac algorithm to remove  (rec) -hmac-md5-96 -- mac algorithm to remove 
(rec) -hmac-ripemd160 -- mac algorithm to remove  (rec) -hmac-ripemd160 -- mac algorithm to remove 
(rec) -hmac-ripemd160@openssh.com -- mac algorithm to remove  (rec) -hmac-ripemd160@openssh.com -- mac algorithm to remove 
(rec) -hmac-sha1 -- mac algorithm to remove 
(rec) -hmac-sha1-96 -- mac algorithm to remove  (rec) -hmac-sha1-96 -- mac algorithm to remove 
(rec) -rijndael-cbc@lysator.liu.se -- enc algorithm to remove  (rec) -rijndael-cbc@lysator.liu.se -- enc algorithm to remove 
(rec) -ssh-rsa -- key algorithm to remove  (rec) -ssh-rsa -- key algorithm to remove 
(rec) -ssh-rsa-cert-v01@openssh.com -- key algorithm to remove  (rec) -ssh-rsa-cert-v01@openssh.com -- key algorithm to remove 
(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove  (rec) -aes128-cbc -- enc algorithm to remove 
(rec) -hmac-sha1 -- mac algorithm to remove  (rec) -aes192-cbc -- enc algorithm to remove 
(rec) -aes256-cbc -- enc algorithm to remove 
(rec) -umac-64@openssh.com -- mac algorithm to remove  (rec) -umac-64@openssh.com -- mac algorithm to remove 
# additional info # additional info

View File

@ -1 +1,43 @@
{"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"
},
{
"actual": [
"4096"
],
"expected_optional": [
""
],
"expected_required": [
"3072"
],
"mismatched_field": "Group exchange (diffie-hellman-group-exchange-sha256) modulus sizes"
}
],
"host": "localhost",
"passed": false,
"policy": "Hardened OpenSSH Server v8.0 (version 4)"
}

View File

@ -1,3 +1,17 @@
Host: localhost:2222 Host: localhost:2222
Policy: Hardened OpenSSH Server v8.0 (version 1) Policy: Hardened OpenSSH Server v8.0 (version 4)
Result: ✔ Passed Result: ❌ Failed!

Errors:
* Group exchange (diffie-hellman-group-exchange-sha256) modulus sizes did not match.
- Expected: 3072
- Actual: 4096
* 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


View File

@ -1 +1,66 @@
{"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"
},
{
"actual": [
"4096"
],
"expected_optional": [
""
],
"expected_required": [
"3072"
],
"mismatched_field": "Group exchange (diffie-hellman-group-exchange-sha256) modulus sizes"
}
],
"host": "localhost",
"passed": false,
"policy": "Hardened OpenSSH Server v8.0 (version 4)"
}

View File

@ -1,8 +1,20 @@
Host: localhost:2222 Host: localhost:2222
Policy: Hardened OpenSSH Server v8.0 (version 1) Policy: Hardened OpenSSH Server v8.0 (version 4)
Result: ❌ Failed! Result: ❌ Failed!
 
Errors: Errors:
* Group exchange (diffie-hellman-group-exchange-sha256) modulus sizes did not match.
- Expected: 3072
- Actual: 4096
* 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

View File

@ -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)"
}

View File

@ -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: ✔ Passed Result: ✔ Passed

View File

@ -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)"
}

View File

@ -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: ❌ Failed! Result: ❌ Failed!
 
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
 

View File

@ -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)"
}

View File

@ -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: ✔ Passed Result: ✔ Passed

View File

@ -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": [
"4096"
],
"expected_optional": [
""
],
"expected_required": [
"8192"
],
"mismatched_field": "Group exchange (diffie-hellman-group-exchange-sha256) modulus sizes"
}
],
"host": "localhost",
"passed": false,
"policy": "Docker policy: test14 (version 1)"
}

View File

@ -1,9 +1,21 @@
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: ❌ Failed! Result: ❌ Failed!
 
Errors: Errors:
* Group exchange (diffie-hellman-group-exchange-sha256) modulus sizes did not match. * Group exchange (diffie-hellman-group-exchange-sha256) modulus sizes did not match.
- Expected: 4096 - Expected: 8192
- Actual: 2048 - Actual: 4096
 

View File

@ -0,0 +1,6 @@
{
"errors": [],
"host": "localhost",
"passed": true,
"policy": "Docker policy: test15 (version 1)"
}

View File

@ -0,0 +1,3 @@
Host: localhost:2222
Policy: Docker policy: test15 (version 1)
Result: ✔ Passed

View File

@ -0,0 +1,86 @@
{
"errors": [
{
"actual": [
"rsa-sha2-512",
"rsa-sha2-256",
"ssh-rsa",
"ecdsa-sha2-nistp256",
"ssh-ed25519"
],
"expected_optional": [
""
],
"expected_required": [
"rsa-sha2-512",
"extra_hostkey_alg"
],
"mismatched_field": "Host keys"
},
{
"actual": [
"curve25519-sha256",
"curve25519-sha256@libssh.org",
"ecdh-sha2-nistp256",
"ecdh-sha2-nistp384",
"ecdh-sha2-nistp521",
"diffie-hellman-group-exchange-sha256",
"diffie-hellman-group16-sha512",
"diffie-hellman-group18-sha512",
"diffie-hellman-group14-sha256",
"diffie-hellman-group14-sha1"
],
"expected_optional": [
""
],
"expected_required": [
"curve25519-sha256",
"extra_kex_alg"
],
"mismatched_field": "Key exchanges"
},
{
"actual": [
"chacha20-poly1305@openssh.com",
"aes128-ctr",
"aes192-ctr",
"aes256-ctr",
"aes128-gcm@openssh.com",
"aes256-gcm@openssh.com"
],
"expected_optional": [
""
],
"expected_required": [
"chacha20-poly1305@openssh.com",
"extra_cipher_alg"
],
"mismatched_field": "Ciphers"
},
{
"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": [
"umac-64-etm@openssh.com",
"extra_mac_alg"
],
"mismatched_field": "MACs"
}
],
"host": "localhost",
"passed": false,
"policy": "Docker policy: test16 (version 1)"
}

View File

@ -0,0 +1,21 @@
Host: localhost:2222
Policy: Docker policy: test16 (version 1)
Result: ❌ Failed!

Errors:
* Ciphers did not match.
- Expected (subset and/or reordering allowed): chacha20-poly1305@openssh.com, extra_cipher_alg
- Actual: chacha20-poly1305@openssh.com, aes128-ctr, aes192-ctr, aes256-ctr, aes128-gcm@openssh.com, aes256-gcm@openssh.com
* Host keys did not match.
- Expected (subset and/or reordering allowed): rsa-sha2-512, extra_hostkey_alg
- Actual: rsa-sha2-512, rsa-sha2-256, ssh-rsa, ecdsa-sha2-nistp256, ssh-ed25519
* Key exchanges did not match.
- Expected (subset and/or reordering allowed): curve25519-sha256, extra_kex_alg
- Actual: curve25519-sha256, curve25519-sha256@libssh.org, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, diffie-hellman-group-exchange-sha256, diffie-hellman-group16-sha512, diffie-hellman-group18-sha512, diffie-hellman-group14-sha256, diffie-hellman-group14-sha1
* MACs did not match.
- Expected (subset and/or reordering allowed): umac-64-etm@openssh.com, extra_mac_alg
- 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


View File

@ -0,0 +1,6 @@
{
"errors": [],
"host": "localhost",
"passed": true,
"policy": "Docker policy: test17 (version 1)"
}

View File

@ -0,0 +1,3 @@
Host: localhost:2222
Policy: Docker policy: test17 (version 1)
Result: ✔ Passed

View File

@ -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)"
}

View File

@ -1 +1,460 @@
{"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": [{"fp": "SHA256:UrnXIVH+7dlw8UqYocl48yUEcKrthGDQG2CPCgp7MxU", "type": "ssh-ed25519"}, {"fp": "SHA256:nsWtdJ9Z67Vrf7OsUzQov7esXhsWAfVppArGh25u244", "type": "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"]} {
"additional_notes": [],
"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": [
{
"algorithm": "chacha20-poly1305@openssh.com",
"notes": {
"info": [
"default cipher since OpenSSH 6.9",
"available since OpenSSH 6.5, Dropbear SSH 2020.79"
],
"warn": [
"vulnerable to the Terrapin attack (CVE-2023-48795), allowing message prefix truncation"
]
}
},
{
"algorithm": "aes128-ctr",
"notes": {
"info": [
"available since OpenSSH 3.7, Dropbear SSH 0.52"
]
}
},
{
"algorithm": "aes192-ctr",
"notes": {
"info": [
"available since OpenSSH 3.7"
]
}
},
{
"algorithm": "aes256-ctr",
"notes": {
"info": [
"available since OpenSSH 3.7, Dropbear SSH 0.52"
]
}
},
{
"algorithm": "aes128-gcm@openssh.com",
"notes": {
"info": [
"available since OpenSSH 6.2"
]
}
},
{
"algorithm": "aes256-gcm@openssh.com",
"notes": {
"info": [
"available since OpenSSH 6.2"
]
}
}
],
"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",
"notes": {
"info": [
"default key exchange from OpenSSH 7.4 to 8.9",
"available since OpenSSH 7.4, Dropbear SSH 2018.76"
]
}
},
{
"algorithm": "curve25519-sha256@libssh.org",
"notes": {
"info": [
"default key exchange from OpenSSH 6.5 to 7.3",
"available since OpenSSH 6.4, Dropbear SSH 2013.62"
]
}
},
{
"algorithm": "ecdh-sha2-nistp256",
"notes": {
"fail": [
"using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency"
],
"info": [
"available since OpenSSH 5.7, Dropbear SSH 2013.62"
]
}
},
{
"algorithm": "ecdh-sha2-nistp384",
"notes": {
"fail": [
"using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency"
],
"info": [
"available since OpenSSH 5.7, Dropbear SSH 2013.62"
]
}
},
{
"algorithm": "ecdh-sha2-nistp521",
"notes": {
"fail": [
"using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency"
],
"info": [
"available since OpenSSH 5.7, Dropbear SSH 2013.62"
]
}
},
{
"algorithm": "diffie-hellman-group-exchange-sha256",
"keysize": 4096,
"notes": {
"info": [
"OpenSSH's GEX fallback mechanism was triggered during testing. Very old SSH clients will still be able to create connections using a 2048-bit modulus, though modern clients will use 4096. This can only be disabled by recompiling the code (see https://github.com/openssh/openssh-portable/blob/V_9_4/dh.c#L477).",
"available since OpenSSH 4.4"
]
}
},
{
"algorithm": "diffie-hellman-group16-sha512",
"notes": {
"info": [
"available since OpenSSH 7.3, Dropbear SSH 2016.73"
]
}
},
{
"algorithm": "diffie-hellman-group18-sha512",
"notes": {
"info": [
"available since OpenSSH 7.3"
]
}
},
{
"algorithm": "diffie-hellman-group14-sha256",
"notes": {
"info": [
"available since OpenSSH 7.3, Dropbear SSH 2016.73"
],
"warn": [
"2048-bit modulus only provides 112-bits of symmetric strength"
]
}
},
{
"algorithm": "diffie-hellman-group14-sha1",
"notes": {
"fail": [
"using broken SHA-1 hash algorithm"
],
"info": [
"available since OpenSSH 3.9, Dropbear SSH 0.53"
],
"warn": [
"2048-bit modulus only provides 112-bits of symmetric strength"
]
}
}
],
"key": [
{
"algorithm": "rsa-sha2-512",
"keysize": 3072,
"notes": {
"info": [
"available since OpenSSH 7.2"
]
}
},
{
"algorithm": "rsa-sha2-256",
"keysize": 3072,
"notes": {
"info": [
"available since OpenSSH 7.2, Dropbear SSH 2020.79"
]
}
},
{
"algorithm": "ssh-rsa",
"keysize": 3072,
"notes": {
"fail": [
"using broken SHA-1 hash algorithm"
],
"info": [
"deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8",
"available since OpenSSH 2.5.0, Dropbear SSH 0.28"
]
}
},
{
"algorithm": "ecdsa-sha2-nistp256",
"notes": {
"fail": [
"using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency"
],
"info": [
"available since OpenSSH 5.7, Dropbear SSH 2013.62"
],
"warn": [
"using weak random number generator could reveal the key"
]
}
},
{
"algorithm": "ssh-ed25519",
"notes": {
"info": [
"available since OpenSSH 6.5, Dropbear SSH 2020.79"
]
}
}
],
"mac": [
{
"algorithm": "umac-64-etm@openssh.com",
"notes": {
"info": [
"available since OpenSSH 6.2"
],
"warn": [
"using small 64-bit tag size"
]
}
},
{
"algorithm": "umac-128-etm@openssh.com",
"notes": {
"info": [
"available since OpenSSH 6.2"
]
}
},
{
"algorithm": "hmac-sha2-256-etm@openssh.com",
"notes": {
"info": [
"available since OpenSSH 6.2"
]
}
},
{
"algorithm": "hmac-sha2-512-etm@openssh.com",
"notes": {
"info": [
"available since OpenSSH 6.2"
]
}
},
{
"algorithm": "hmac-sha1-etm@openssh.com",
"notes": {
"fail": [
"using broken SHA-1 hash algorithm"
],
"info": [
"available since OpenSSH 6.2"
]
}
},
{
"algorithm": "umac-64@openssh.com",
"notes": {
"info": [
"available since OpenSSH 4.7"
],
"warn": [
"using encrypt-and-MAC mode",
"using small 64-bit tag size"
]
}
},
{
"algorithm": "umac-128@openssh.com",
"notes": {
"info": [
"available since OpenSSH 6.2"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "hmac-sha2-256",
"notes": {
"info": [
"available since OpenSSH 5.9, Dropbear SSH 2013.56"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "hmac-sha2-512",
"notes": {
"info": [
"available since OpenSSH 5.9, Dropbear SSH 2013.56"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "hmac-sha1",
"notes": {
"fail": [
"using broken SHA-1 hash algorithm"
],
"info": [
"available since OpenSSH 2.1.0, Dropbear SSH 0.28"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
}
],
"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": {
"enc": [
{
"name": "chacha20-poly1305@openssh.com",
"notes": ""
}
],
"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"
}

View File

@ -1,38 +1,51 @@
# general # general
(gen) banner: SSH-2.0-OpenSSH_8.0 (gen) banner: SSH-2.0-OpenSSH_8.0
(gen) software: OpenSSH 8.0 (gen) software: OpenSSH 8.0
(gen) compatibility: OpenSSH 7.4+, Dropbear SSH 2018.76+ (gen) compatibility: OpenSSH 7.4+, Dropbear SSH 2020.79+
(gen) compression: enabled (zlib@openssh.com) (gen) compression: enabled (zlib@openssh.com)
# security
(cve) CVE-2021-41617 -- (CVSSv2: 7.0) privilege escalation via supplemental groups
(cve) CVE-2020-15778 -- (CVSSv2: 7.8) command injection via anomalous argument transfers
(cve) CVE-2019-16905 -- (CVSSv2: 7.8) memory corruption and local code execution via pre-authentication integer overflow
(cve) CVE-2016-20012 -- (CVSSv2: 5.3) enumerate usernames via challenge response
# key exchange algorithms # key exchange algorithms
(kex) curve25519-sha256 -- [info] available since OpenSSH 7.4, Dropbear SSH 2018.76 (kex) curve25519-sha256 -- [info] available since OpenSSH 7.4, Dropbear SSH 2018.76
(kex) curve25519-sha256@libssh.org -- [info] available since OpenSSH 6.5, Dropbear SSH 2013.62  `- [info] default key exchange from OpenSSH 7.4 to 8.9
(kex) ecdh-sha2-nistp256 -- [fail] using weak elliptic curves (kex) curve25519-sha256@libssh.org -- [info] available since OpenSSH 6.4, Dropbear SSH 2013.62
 `- [info] default key exchange from OpenSSH 6.5 to 7.3
(kex) ecdh-sha2-nistp256 -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62 `- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(kex) ecdh-sha2-nistp384 -- [fail] using weak elliptic curves (kex) ecdh-sha2-nistp384 -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62 `- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(kex) ecdh-sha2-nistp521 -- [fail] using weak elliptic curves (kex) ecdh-sha2-nistp521 -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62 `- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(kex) diffie-hellman-group-exchange-sha256 (2048-bit) -- [info] available since OpenSSH 4.4 (kex) diffie-hellman-group-exchange-sha256 (4096-bit) -- [info] available since OpenSSH 4.4
 `- [info] OpenSSH's GEX fallback mechanism was triggered during testing. Very old SSH clients will still be able to create connections using a 2048-bit modulus, though modern clients will use 4096. This can only be disabled by recompiling the code (see https://github.com/openssh/openssh-portable/blob/V_9_4/dh.c#L477).
(kex) diffie-hellman-group16-sha512 -- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73 (kex) diffie-hellman-group16-sha512 -- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73
(kex) diffie-hellman-group18-sha512 -- [info] available since OpenSSH 7.3 (kex) diffie-hellman-group18-sha512 -- [info] available since OpenSSH 7.3
(kex) diffie-hellman-group14-sha256 -- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73 (kex) diffie-hellman-group14-sha256 -- [warn] 2048-bit modulus only provides 112-bits of symmetric strength
(kex) diffie-hellman-group14-sha1 -- [warn] using weak hashing algorithm `- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73
(kex) diffie-hellman-group14-sha1 -- [fail] using broken SHA-1 hash algorithm
 `- [warn] 2048-bit modulus only provides 112-bits of symmetric strength
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53 `- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
# host-key algorithms # host-key algorithms
(key) rsa-sha2-512 (3072-bit) -- [info] available since OpenSSH 7.2 (key) rsa-sha2-512 (3072-bit) -- [info] available since OpenSSH 7.2
(key) rsa-sha2-256 (3072-bit) -- [info] available since OpenSSH 7.2 (key) rsa-sha2-256 (3072-bit) -- [info] available since OpenSSH 7.2, Dropbear SSH 2020.79
(key) ssh-rsa (3072-bit) -- [fail] using weak hashing algorithm (key) ssh-rsa (3072-bit) -- [fail] using broken SHA-1 hash algorithm
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28 `- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
(key) ecdsa-sha2-nistp256 -- [fail] using weak elliptic curves `- [info] deprecated in OpenSSH 8.8: https://www.openssh.com/txt/release-8.8
(key) ecdsa-sha2-nistp256 -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency
 `- [warn] using weak random number generator could reveal the key  `- [warn] using weak random number generator could reveal the key
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62 `- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(key) ssh-ed25519 -- [info] available since OpenSSH 6.5 (key) ssh-ed25519 -- [info] available since OpenSSH 6.5, Dropbear SSH 2020.79
# encryption algorithms (ciphers) # encryption algorithms (ciphers)
(enc) chacha20-poly1305@openssh.com -- [info] available since OpenSSH 6.5 (enc) chacha20-poly1305@openssh.com -- [warn] vulnerable to the Terrapin attack (CVE-2023-48795), allowing message prefix truncation
`- [info] default cipher since OpenSSH 6.9. `- [info] available since OpenSSH 6.5, Dropbear SSH 2020.79
`- [info] default cipher since OpenSSH 6.9
(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52 (enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) aes192-ctr -- [info] available since OpenSSH 3.7 (enc) aes192-ctr -- [info] available since OpenSSH 3.7
(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52 (enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
@ -45,7 +58,7 @@
(mac) umac-128-etm@openssh.com -- [info] available since OpenSSH 6.2 (mac) umac-128-etm@openssh.com -- [info] available since OpenSSH 6.2
(mac) hmac-sha2-256-etm@openssh.com -- [info] available since OpenSSH 6.2 (mac) hmac-sha2-256-etm@openssh.com -- [info] available since OpenSSH 6.2
(mac) hmac-sha2-512-etm@openssh.com -- [info] available since OpenSSH 6.2 (mac) hmac-sha2-512-etm@openssh.com -- [info] available since OpenSSH 6.2
(mac) hmac-sha1-etm@openssh.com -- [warn] using weak hashing algorithm (mac) hmac-sha1-etm@openssh.com -- [fail] using broken SHA-1 hash algorithm
`- [info] available since OpenSSH 6.2 `- [info] available since OpenSSH 6.2
(mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode (mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode
 `- [warn] using small 64-bit tag size  `- [warn] using small 64-bit tag size
@ -56,8 +69,8 @@
`- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56 `- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56
(mac) hmac-sha2-512 -- [warn] using encrypt-and-MAC mode (mac) hmac-sha2-512 -- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56 `- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56
(mac) hmac-sha1 -- [warn] using encrypt-and-MAC mode (mac) hmac-sha1 -- [fail] using broken SHA-1 hash algorithm
 `- [warn] using weak hashing algorithm  `- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28 `- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
# fingerprints # fingerprints
@ -65,14 +78,16 @@
(fin) ssh-rsa: SHA256:nsWtdJ9Z67Vrf7OsUzQov7esXhsWAfVppArGh25u244 (fin) ssh-rsa: SHA256:nsWtdJ9Z67Vrf7OsUzQov7esXhsWAfVppArGh25u244
# algorithm recommendations (for OpenSSH 8.0) # algorithm recommendations (for OpenSSH 8.0)
(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove 
(rec) -ecdh-sha2-nistp256 -- kex algorithm to remove  (rec) -ecdh-sha2-nistp256 -- kex algorithm to remove 
(rec) -ecdh-sha2-nistp384 -- kex algorithm to remove  (rec) -ecdh-sha2-nistp384 -- kex algorithm to remove 
(rec) -ecdh-sha2-nistp521 -- kex algorithm to remove  (rec) -ecdh-sha2-nistp521 -- kex algorithm to remove 
(rec) -ecdsa-sha2-nistp256 -- key algorithm to remove  (rec) -ecdsa-sha2-nistp256 -- key algorithm to remove 
(rec) -hmac-sha1 -- mac algorithm to remove 
(rec) -hmac-sha1-etm@openssh.com -- mac algorithm to remove 
(rec) -ssh-rsa -- key algorithm to remove  (rec) -ssh-rsa -- key algorithm to remove 
(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove  (rec) -chacha20-poly1305@openssh.com -- enc algorithm to remove 
(rec) -hmac-sha1 -- mac algorithm to remove  (rec) -diffie-hellman-group14-sha256 -- kex algorithm to remove 
(rec) -hmac-sha1-etm@openssh.com -- mac algorithm to remove 
(rec) -hmac-sha2-256 -- mac algorithm to remove  (rec) -hmac-sha2-256 -- mac algorithm to remove 
(rec) -hmac-sha2-512 -- mac algorithm to remove  (rec) -hmac-sha2-512 -- mac algorithm to remove 
(rec) -umac-128@openssh.com -- mac algorithm to remove  (rec) -umac-128@openssh.com -- mac algorithm to remove 

View File

@ -1 +1,419 @@
{"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": [{"fp": "SHA256:UrnXIVH+7dlw8UqYocl48yUEcKrthGDQG2CPCgp7MxU", "type": "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"]} {
"additional_notes": [],
"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": [
{
"algorithm": "chacha20-poly1305@openssh.com",
"notes": {
"info": [
"default cipher since OpenSSH 6.9",
"available since OpenSSH 6.5, Dropbear SSH 2020.79"
],
"warn": [
"vulnerable to the Terrapin attack (CVE-2023-48795), allowing message prefix truncation"
]
}
},
{
"algorithm": "aes128-ctr",
"notes": {
"info": [
"available since OpenSSH 3.7, Dropbear SSH 0.52"
]
}
},
{
"algorithm": "aes192-ctr",
"notes": {
"info": [
"available since OpenSSH 3.7"
]
}
},
{
"algorithm": "aes256-ctr",
"notes": {
"info": [
"available since OpenSSH 3.7, Dropbear SSH 0.52"
]
}
},
{
"algorithm": "aes128-gcm@openssh.com",
"notes": {
"info": [
"available since OpenSSH 6.2"
]
}
},
{
"algorithm": "aes256-gcm@openssh.com",
"notes": {
"info": [
"available since OpenSSH 6.2"
]
}
}
],
"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",
"notes": {
"info": [
"default key exchange from OpenSSH 7.4 to 8.9",
"available since OpenSSH 7.4, Dropbear SSH 2018.76"
]
}
},
{
"algorithm": "curve25519-sha256@libssh.org",
"notes": {
"info": [
"default key exchange from OpenSSH 6.5 to 7.3",
"available since OpenSSH 6.4, Dropbear SSH 2013.62"
]
}
},
{
"algorithm": "ecdh-sha2-nistp256",
"notes": {
"fail": [
"using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency"
],
"info": [
"available since OpenSSH 5.7, Dropbear SSH 2013.62"
]
}
},
{
"algorithm": "ecdh-sha2-nistp384",
"notes": {
"fail": [
"using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency"
],
"info": [
"available since OpenSSH 5.7, Dropbear SSH 2013.62"
]
}
},
{
"algorithm": "ecdh-sha2-nistp521",
"notes": {
"fail": [
"using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency"
],
"info": [
"available since OpenSSH 5.7, Dropbear SSH 2013.62"
]
}
},
{
"algorithm": "diffie-hellman-group-exchange-sha256",
"keysize": 4096,
"notes": {
"info": [
"OpenSSH's GEX fallback mechanism was triggered during testing. Very old SSH clients will still be able to create connections using a 2048-bit modulus, though modern clients will use 4096. This can only be disabled by recompiling the code (see https://github.com/openssh/openssh-portable/blob/V_9_4/dh.c#L477).",
"available since OpenSSH 4.4"
]
}
},
{
"algorithm": "diffie-hellman-group16-sha512",
"notes": {
"info": [
"available since OpenSSH 7.3, Dropbear SSH 2016.73"
]
}
},
{
"algorithm": "diffie-hellman-group18-sha512",
"notes": {
"info": [
"available since OpenSSH 7.3"
]
}
},
{
"algorithm": "diffie-hellman-group14-sha256",
"notes": {
"info": [
"available since OpenSSH 7.3, Dropbear SSH 2016.73"
],
"warn": [
"2048-bit modulus only provides 112-bits of symmetric strength"
]
}
},
{
"algorithm": "diffie-hellman-group14-sha1",
"notes": {
"fail": [
"using broken SHA-1 hash algorithm"
],
"info": [
"available since OpenSSH 3.9, Dropbear SSH 0.53"
],
"warn": [
"2048-bit modulus only provides 112-bits of symmetric strength"
]
}
}
],
"key": [
{
"algorithm": "ssh-ed25519",
"notes": {
"info": [
"available since OpenSSH 6.5, Dropbear SSH 2020.79"
]
}
},
{
"algorithm": "ssh-ed25519-cert-v01@openssh.com",
"ca_algorithm": "ssh-ed25519",
"casize": 256,
"notes": {
"info": [
"available since OpenSSH 6.5"
]
}
}
],
"mac": [
{
"algorithm": "umac-64-etm@openssh.com",
"notes": {
"info": [
"available since OpenSSH 6.2"
],
"warn": [
"using small 64-bit tag size"
]
}
},
{
"algorithm": "umac-128-etm@openssh.com",
"notes": {
"info": [
"available since OpenSSH 6.2"
]
}
},
{
"algorithm": "hmac-sha2-256-etm@openssh.com",
"notes": {
"info": [
"available since OpenSSH 6.2"
]
}
},
{
"algorithm": "hmac-sha2-512-etm@openssh.com",
"notes": {
"info": [
"available since OpenSSH 6.2"
]
}
},
{
"algorithm": "hmac-sha1-etm@openssh.com",
"notes": {
"fail": [
"using broken SHA-1 hash algorithm"
],
"info": [
"available since OpenSSH 6.2"
]
}
},
{
"algorithm": "umac-64@openssh.com",
"notes": {
"info": [
"available since OpenSSH 4.7"
],
"warn": [
"using encrypt-and-MAC mode",
"using small 64-bit tag size"
]
}
},
{
"algorithm": "umac-128@openssh.com",
"notes": {
"info": [
"available since OpenSSH 6.2"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "hmac-sha2-256",
"notes": {
"info": [
"available since OpenSSH 5.9, Dropbear SSH 2013.56"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "hmac-sha2-512",
"notes": {
"info": [
"available since OpenSSH 5.9, Dropbear SSH 2013.56"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
},
{
"algorithm": "hmac-sha1",
"notes": {
"fail": [
"using broken SHA-1 hash algorithm"
],
"info": [
"available since OpenSSH 2.1.0, Dropbear SSH 0.28"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
}
],
"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": {
"enc": [
{
"name": "chacha20-poly1305@openssh.com",
"notes": ""
}
],
"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"
}

View File

@ -1,32 +1,44 @@
# general # general
(gen) banner: SSH-2.0-OpenSSH_8.0 (gen) banner: SSH-2.0-OpenSSH_8.0
(gen) software: OpenSSH 8.0 (gen) software: OpenSSH 8.0
(gen) compatibility: OpenSSH 7.4+, Dropbear SSH 2018.76+ (gen) compatibility: OpenSSH 7.4+, Dropbear SSH 2020.79+
(gen) compression: enabled (zlib@openssh.com) (gen) compression: enabled (zlib@openssh.com)
# security
(cve) CVE-2021-41617 -- (CVSSv2: 7.0) privilege escalation via supplemental groups
(cve) CVE-2020-15778 -- (CVSSv2: 7.8) command injection via anomalous argument transfers
(cve) CVE-2019-16905 -- (CVSSv2: 7.8) memory corruption and local code execution via pre-authentication integer overflow
(cve) CVE-2016-20012 -- (CVSSv2: 5.3) enumerate usernames via challenge response
# key exchange algorithms # key exchange algorithms
(kex) curve25519-sha256 -- [info] available since OpenSSH 7.4, Dropbear SSH 2018.76 (kex) curve25519-sha256 -- [info] available since OpenSSH 7.4, Dropbear SSH 2018.76
(kex) curve25519-sha256@libssh.org -- [info] available since OpenSSH 6.5, Dropbear SSH 2013.62  `- [info] default key exchange from OpenSSH 7.4 to 8.9
(kex) ecdh-sha2-nistp256 -- [fail] using weak elliptic curves (kex) curve25519-sha256@libssh.org -- [info] available since OpenSSH 6.4, Dropbear SSH 2013.62
 `- [info] default key exchange from OpenSSH 6.5 to 7.3
(kex) ecdh-sha2-nistp256 -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62 `- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(kex) ecdh-sha2-nistp384 -- [fail] using weak elliptic curves (kex) ecdh-sha2-nistp384 -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62 `- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(kex) ecdh-sha2-nistp521 -- [fail] using weak elliptic curves (kex) ecdh-sha2-nistp521 -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62 `- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(kex) diffie-hellman-group-exchange-sha256 (2048-bit) -- [info] available since OpenSSH 4.4 (kex) diffie-hellman-group-exchange-sha256 (4096-bit) -- [info] available since OpenSSH 4.4
 `- [info] OpenSSH's GEX fallback mechanism was triggered during testing. Very old SSH clients will still be able to create connections using a 2048-bit modulus, though modern clients will use 4096. This can only be disabled by recompiling the code (see https://github.com/openssh/openssh-portable/blob/V_9_4/dh.c#L477).
(kex) diffie-hellman-group16-sha512 -- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73 (kex) diffie-hellman-group16-sha512 -- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73
(kex) diffie-hellman-group18-sha512 -- [info] available since OpenSSH 7.3 (kex) diffie-hellman-group18-sha512 -- [info] available since OpenSSH 7.3
(kex) diffie-hellman-group14-sha256 -- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73 (kex) diffie-hellman-group14-sha256 -- [warn] 2048-bit modulus only provides 112-bits of symmetric strength
(kex) diffie-hellman-group14-sha1 -- [warn] using weak hashing algorithm `- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73
(kex) diffie-hellman-group14-sha1 -- [fail] using broken SHA-1 hash algorithm
 `- [warn] 2048-bit modulus only provides 112-bits of symmetric strength
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53 `- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
# host-key algorithms # host-key algorithms
(key) ssh-ed25519 -- [info] available since OpenSSH 6.5 (key) ssh-ed25519 -- [info] available since OpenSSH 6.5, Dropbear SSH 2020.79
(key) ssh-ed25519-cert-v01@openssh.com -- [info] available since OpenSSH 6.5 (key) ssh-ed25519-cert-v01@openssh.com (256-bit cert/256-bit ssh-ed25519 CA) -- [info] available since OpenSSH 6.5
# encryption algorithms (ciphers) # encryption algorithms (ciphers)
(enc) chacha20-poly1305@openssh.com -- [info] available since OpenSSH 6.5 (enc) chacha20-poly1305@openssh.com -- [warn] vulnerable to the Terrapin attack (CVE-2023-48795), allowing message prefix truncation
`- [info] default cipher since OpenSSH 6.9. `- [info] available since OpenSSH 6.5, Dropbear SSH 2020.79
`- [info] default cipher since OpenSSH 6.9
(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52 (enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) aes192-ctr -- [info] available since OpenSSH 3.7 (enc) aes192-ctr -- [info] available since OpenSSH 3.7
(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52 (enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
@ -39,7 +51,7 @@
(mac) umac-128-etm@openssh.com -- [info] available since OpenSSH 6.2 (mac) umac-128-etm@openssh.com -- [info] available since OpenSSH 6.2
(mac) hmac-sha2-256-etm@openssh.com -- [info] available since OpenSSH 6.2 (mac) hmac-sha2-256-etm@openssh.com -- [info] available since OpenSSH 6.2
(mac) hmac-sha2-512-etm@openssh.com -- [info] available since OpenSSH 6.2 (mac) hmac-sha2-512-etm@openssh.com -- [info] available since OpenSSH 6.2
(mac) hmac-sha1-etm@openssh.com -- [warn] using weak hashing algorithm (mac) hmac-sha1-etm@openssh.com -- [fail] using broken SHA-1 hash algorithm
`- [info] available since OpenSSH 6.2 `- [info] available since OpenSSH 6.2
(mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode (mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode
 `- [warn] using small 64-bit tag size  `- [warn] using small 64-bit tag size
@ -50,22 +62,24 @@
`- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56 `- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56
(mac) hmac-sha2-512 -- [warn] using encrypt-and-MAC mode (mac) hmac-sha2-512 -- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56 `- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56
(mac) hmac-sha1 -- [warn] using encrypt-and-MAC mode (mac) hmac-sha1 -- [fail] using broken SHA-1 hash algorithm
 `- [warn] using weak hashing algorithm  `- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28 `- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
# fingerprints # fingerprints
(fin) ssh-ed25519: SHA256:UrnXIVH+7dlw8UqYocl48yUEcKrthGDQG2CPCgp7MxU (fin) ssh-ed25519: SHA256:UrnXIVH+7dlw8UqYocl48yUEcKrthGDQG2CPCgp7MxU
# algorithm recommendations (for OpenSSH 8.0) # algorithm recommendations (for OpenSSH 8.0)
(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove 
(rec) -ecdh-sha2-nistp256 -- kex algorithm to remove  (rec) -ecdh-sha2-nistp256 -- kex algorithm to remove 
(rec) -ecdh-sha2-nistp384 -- kex algorithm to remove  (rec) -ecdh-sha2-nistp384 -- kex algorithm to remove 
(rec) -ecdh-sha2-nistp521 -- kex algorithm to remove  (rec) -ecdh-sha2-nistp521 -- kex algorithm to remove 
(rec) -hmac-sha1 -- mac algorithm to remove 
(rec) -hmac-sha1-etm@openssh.com -- mac algorithm to remove 
(rec) +rsa-sha2-256 -- key algorithm to append  (rec) +rsa-sha2-256 -- key algorithm to append 
(rec) +rsa-sha2-512 -- key algorithm to append  (rec) +rsa-sha2-512 -- key algorithm to append 
(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove  (rec) -chacha20-poly1305@openssh.com -- enc algorithm to remove 
(rec) -hmac-sha1 -- mac algorithm to remove  (rec) -diffie-hellman-group14-sha256 -- kex algorithm to remove 
(rec) -hmac-sha1-etm@openssh.com -- mac algorithm to remove 
(rec) -hmac-sha2-256 -- mac algorithm to remove  (rec) -hmac-sha2-256 -- mac algorithm to remove 
(rec) -hmac-sha2-512 -- mac algorithm to remove  (rec) -hmac-sha2-512 -- mac algorithm to remove 
(rec) -umac-128@openssh.com -- mac algorithm to remove  (rec) -umac-128@openssh.com -- mac algorithm to remove 

View File

@ -1 +1,204 @@
{"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": [{"fp": "SHA256:UrnXIVH+7dlw8UqYocl48yUEcKrthGDQG2CPCgp7MxU", "type": "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"]} {
"additional_notes": [],
"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": [
{
"algorithm": "chacha20-poly1305@openssh.com",
"notes": {
"info": [
"default cipher since OpenSSH 6.9",
"available since OpenSSH 6.5, Dropbear SSH 2020.79"
],
"warn": [
"vulnerable to the Terrapin attack (CVE-2023-48795), allowing message prefix truncation"
]
}
},
{
"algorithm": "aes256-gcm@openssh.com",
"notes": {
"info": [
"available since OpenSSH 6.2"
]
}
},
{
"algorithm": "aes128-gcm@openssh.com",
"notes": {
"info": [
"available since OpenSSH 6.2"
]
}
},
{
"algorithm": "aes256-ctr",
"notes": {
"info": [
"available since OpenSSH 3.7, Dropbear SSH 0.52"
]
}
},
{
"algorithm": "aes192-ctr",
"notes": {
"info": [
"available since OpenSSH 3.7"
]
}
},
{
"algorithm": "aes128-ctr",
"notes": {
"info": [
"available since OpenSSH 3.7, Dropbear SSH 0.52"
]
}
}
],
"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",
"notes": {
"info": [
"default key exchange from OpenSSH 7.4 to 8.9",
"available since OpenSSH 7.4, Dropbear SSH 2018.76"
]
}
},
{
"algorithm": "curve25519-sha256@libssh.org",
"notes": {
"info": [
"default key exchange from OpenSSH 6.5 to 7.3",
"available since OpenSSH 6.4, Dropbear SSH 2013.62"
]
}
},
{
"algorithm": "diffie-hellman-group-exchange-sha256",
"keysize": 4096,
"notes": {
"info": [
"OpenSSH's GEX fallback mechanism was triggered during testing. Very old SSH clients will still be able to create connections using a 2048-bit modulus, though modern clients will use 4096. This can only be disabled by recompiling the code (see https://github.com/openssh/openssh-portable/blob/V_9_4/dh.c#L477).",
"available since OpenSSH 4.4"
]
}
}
],
"key": [
{
"algorithm": "ssh-ed25519",
"notes": {
"info": [
"available since OpenSSH 6.5, Dropbear SSH 2020.79"
]
}
}
],
"mac": [
{
"algorithm": "hmac-sha2-256-etm@openssh.com",
"notes": {
"info": [
"available since OpenSSH 6.2"
]
}
},
{
"algorithm": "hmac-sha2-512-etm@openssh.com",
"notes": {
"info": [
"available since OpenSSH 6.2"
]
}
},
{
"algorithm": "umac-128-etm@openssh.com",
"notes": {
"info": [
"available since OpenSSH 6.2"
]
}
}
],
"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": ""
}
]
}
},
"warning": {
"del": {
"enc": [
{
"name": "chacha20-poly1305@openssh.com",
"notes": ""
}
]
}
}
},
"target": "localhost:2222"
}

View File

@ -1,20 +1,30 @@
# general # general
(gen) banner: SSH-2.0-OpenSSH_8.0 (gen) banner: SSH-2.0-OpenSSH_8.0
(gen) software: OpenSSH 8.0 (gen) software: OpenSSH 8.0
(gen) compatibility: OpenSSH 7.4+, Dropbear SSH 2018.76+ (gen) compatibility: OpenSSH 7.4+, Dropbear SSH 2020.79+
(gen) compression: enabled (zlib@openssh.com) (gen) compression: enabled (zlib@openssh.com)
# security
(cve) CVE-2021-41617 -- (CVSSv2: 7.0) privilege escalation via supplemental groups
(cve) CVE-2020-15778 -- (CVSSv2: 7.8) command injection via anomalous argument transfers
(cve) CVE-2019-16905 -- (CVSSv2: 7.8) memory corruption and local code execution via pre-authentication integer overflow
(cve) CVE-2016-20012 -- (CVSSv2: 5.3) enumerate usernames via challenge response
# key exchange algorithms # key exchange algorithms
(kex) curve25519-sha256 -- [info] available since OpenSSH 7.4, Dropbear SSH 2018.76 (kex) curve25519-sha256 -- [info] available since OpenSSH 7.4, Dropbear SSH 2018.76
(kex) curve25519-sha256@libssh.org -- [info] available since OpenSSH 6.5, Dropbear SSH 2013.62  `- [info] default key exchange from OpenSSH 7.4 to 8.9
(kex) diffie-hellman-group-exchange-sha256 (2048-bit) -- [info] available since OpenSSH 4.4 (kex) curve25519-sha256@libssh.org -- [info] available since OpenSSH 6.4, Dropbear SSH 2013.62
 `- [info] default key exchange from OpenSSH 6.5 to 7.3
(kex) diffie-hellman-group-exchange-sha256 (4096-bit) -- [info] available since OpenSSH 4.4
 `- [info] OpenSSH's GEX fallback mechanism was triggered during testing. Very old SSH clients will still be able to create connections using a 2048-bit modulus, though modern clients will use 4096. This can only be disabled by recompiling the code (see https://github.com/openssh/openssh-portable/blob/V_9_4/dh.c#L477).
# host-key algorithms # host-key algorithms
(key) ssh-ed25519 -- [info] available since OpenSSH 6.5 (key) ssh-ed25519 -- [info] available since OpenSSH 6.5, Dropbear SSH 2020.79
# encryption algorithms (ciphers) # encryption algorithms (ciphers)
(enc) chacha20-poly1305@openssh.com -- [info] available since OpenSSH 6.5 (enc) chacha20-poly1305@openssh.com -- [warn] vulnerable to the Terrapin attack (CVE-2023-48795), allowing message prefix truncation
`- [info] default cipher since OpenSSH 6.9. `- [info] available since OpenSSH 6.5, Dropbear SSH 2020.79
`- [info] default cipher since OpenSSH 6.9
(enc) aes256-gcm@openssh.com -- [info] available since OpenSSH 6.2 (enc) aes256-gcm@openssh.com -- [info] available since OpenSSH 6.2
(enc) aes128-gcm@openssh.com -- [info] available since OpenSSH 6.2 (enc) aes128-gcm@openssh.com -- [info] available since OpenSSH 6.2
(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52 (enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
@ -30,9 +40,12 @@
(fin) ssh-ed25519: SHA256:UrnXIVH+7dlw8UqYocl48yUEcKrthGDQG2CPCgp7MxU (fin) ssh-ed25519: SHA256:UrnXIVH+7dlw8UqYocl48yUEcKrthGDQG2CPCgp7MxU
# algorithm recommendations (for OpenSSH 8.0) # algorithm recommendations (for OpenSSH 8.0)
(rec) +diffie-hellman-group14-sha256 -- kex algorithm to append 
(rec) +diffie-hellman-group16-sha512 -- kex algorithm to append  (rec) +diffie-hellman-group16-sha512 -- kex algorithm to append 
(rec) +diffie-hellman-group18-sha512 -- kex algorithm to append  (rec) +diffie-hellman-group18-sha512 -- kex algorithm to append 
(rec) +rsa-sha2-256 -- key algorithm to append  (rec) +rsa-sha2-256 -- key algorithm to append 
(rec) +rsa-sha2-512 -- key algorithm to append  (rec) +rsa-sha2-512 -- key algorithm to append 
(rec) -chacha20-poly1305@openssh.com -- enc algorithm to remove 
# additional info
(nfo) For hardening guides on common OSes, please see: <https://www.ssh-audit.com/hardening_guides.html>

View File

@ -1 +1,96 @@
{"banner": {"comments": "", "protocol": [2, 0], "raw": "", "software": "tinyssh_noversion"}, "compression": ["none"], "enc": ["chacha20-poly1305@openssh.com"], "fingerprints": [{"fp": "SHA256:89ocln1x7KNqnMgWffGoYtD70ksJ4FrH7BMJHa7SrwU", "type": "ssh-ed25519"}], "kex": [{"algorithm": "curve25519-sha256"}, {"algorithm": "curve25519-sha256@libssh.org"}, {"algorithm": "sntrup4591761x25519-sha512@tinyssh.org"}], "key": [{"algorithm": "ssh-ed25519"}], "mac": ["hmac-sha2-256"]} {
"additional_notes": [],
"banner": {
"comments": "",
"protocol": "2.0",
"raw": "",
"software": "tinyssh_noversion"
},
"compression": [
"none"
],
"cves": [],
"enc": [
{
"algorithm": "chacha20-poly1305@openssh.com",
"notes": {
"info": [
"default cipher since OpenSSH 6.9",
"available since OpenSSH 6.5, Dropbear SSH 2020.79"
],
"warn": [
"vulnerable to the Terrapin attack (CVE-2023-48795), allowing message prefix truncation"
]
}
}
],
"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",
"notes": {
"info": [
"default key exchange from OpenSSH 7.4 to 8.9",
"available since OpenSSH 7.4, Dropbear SSH 2018.76"
]
}
},
{
"algorithm": "curve25519-sha256@libssh.org",
"notes": {
"info": [
"default key exchange from OpenSSH 6.5 to 7.3",
"available since OpenSSH 6.4, Dropbear SSH 2013.62"
]
}
},
{
"algorithm": "sntrup4591761x25519-sha512@tinyssh.org",
"notes": {
"info": [
"the sntrup4591761 algorithm was withdrawn, as it may not provide strong post-quantum security",
"available since OpenSSH 8.0"
],
"warn": [
"using experimental algorithm"
]
}
}
],
"key": [
{
"algorithm": "ssh-ed25519",
"notes": {
"info": [
"available since OpenSSH 6.5, Dropbear SSH 2020.79"
]
}
}
],
"mac": [
{
"algorithm": "hmac-sha2-256",
"notes": {
"info": [
"available since OpenSSH 5.9, Dropbear SSH 2013.56"
],
"warn": [
"using encrypt-and-MAC mode"
]
}
}
],
"recommendations": {},
"target": "localhost:2222"
}

Some files were not shown because too many files have changed in this diff Show More