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

158 Commits

Author SHA1 Message Date
dc36622b50 Bumped version to v2.1.1. 2019-11-26 11:48:18 -05:00
8e0b83176a Updated ChangeLog. Added link to hardening guide. 2019-11-26 11:47:35 -05:00
a16eb2d6cb Added three new PuTTY vulns. 2019-11-18 22:08:17 -05:00
2848c1fb16 Added two new ciphers: 'des', and '3des'. 2019-11-18 20:22:12 -05:00
2cff202b32 Added two new host key types: 'rsa-sha2-256-cert-v01@openssh.com' and 'rsa-sha2-512-cert-v01@openssh.com'. 2019-11-14 16:45:40 -05:00
dae92513fd During client tests, client IP is now listed in output. 2019-11-14 13:52:36 -05:00
e101e22720 Bumped version number. 2019-11-14 11:07:16 -05:00
b3a46e8318 Added pypi notes. 2019-11-14 11:06:05 -05:00
3606863ebf Updated client auditing screen shot. 2019-11-14 10:15:30 -05:00
cf1e069db4 Updated version to 2.1.0. 2019-11-14 08:56:43 -05:00
1e1220807f Updated README with client auditing screen shot and credit for JSON output code. 2019-11-14 08:56:14 -05:00
0263769243 Added JSON output tests to docker testing suite. 2019-11-08 18:40:32 -05:00
e6c31ee4f5 Added JSON output to ChangeLog. 2019-11-08 11:10:41 -05:00
14e0ed0e00 Fixed minor whitespace issue. 2019-11-08 11:09:00 -05:00
0f21f2131c Merge pull request #12 from x-way/json_output
RFC: JSON output
2019-11-08 11:06:09 -05:00
b6c64d296b Add --json output option 2019-11-07 22:08:09 +01:00
1ec13c653e A timeout can now be specified when auditing client connections. 2019-11-06 20:40:25 -05:00
a401afd099 Merged arthepsy/ssh-audit#47 2019-10-25 11:48:02 -04:00
8a3ae321f1 Added five kex algorithms: gss-gex-sha1-toWM5Slw5Ew8Mqkay+al2g==, gss-group14-sha1-, gss-group14-sha1-toWM5Slw5Ew8Mqkay+al2g==, gss-group14-sha256-toWM5Slw5Ew8Mqkay+al2g==, gss-group15-sha512-toWM5Slw5Ew8Mqkay+al2g==; added four ciphers: idea-cbc, serpent128-cbc, serpent192-cbc, serpent256-cbc; added four MACs: hmac-ripemd, hmac-sha256-96@ssh.com, umac-32@openssh.com, umac-96@openssh.com. 2019-10-25 11:27:22 -04:00
e62b548677 Updated info on curve25519-sha256 kex. 2019-10-21 11:50:23 -04:00
fd85e247e7 Improved IPv4/IPv6 error handling during client testing. 2019-10-10 23:09:45 -04:00
e3a59a3e21 Client auditing feature now supports IPv6. 2019-10-09 22:29:56 -04:00
4ebefdf894 Updated usage message. 2019-10-09 21:12:09 -04:00
83544836c9 Fixed client parsing crash. 2019-10-09 20:57:31 -04:00
4c9b871f5c Removed duplicate MAC. 2019-10-07 11:00:11 -04:00
1d707276d7 Updated README. 2019-10-07 10:59:52 -04:00
166c93ace4 Updated project description to mention client auditing ability. 2019-09-27 18:19:49 -04:00
9759480ae4 Updated ChangeLog. 2019-09-27 18:16:50 -04:00
fd3a1f7d41 Added client audit functionality. (#3) 2019-09-27 18:14:36 -04:00
08677d65b1 Added potential fix for additional crash against Sun_SSH. 2019-09-19 22:25:30 -04:00
8c5493ae3e Added 2 key exchanges (ecdh-sha2-1.3.132.0.10, curve448-sha512), 1 host key type (ecdsa-sha2-1.3.132.0.10), and 2 MACs (hmac-sha2-256-96-etm@openssh.com, hmac-sha2-512-96-etm@openssh.com). 2019-09-19 22:19:26 -04:00
14af53cf04 Updated ChangeLog for v2.1.0. 2019-09-19 20:10:37 -04:00
bbf6204ce1 Add support for Sun_SSH (on Solaris). Add 'gss-group1-sha1-toWM5Slw5Ew8Mqkay+al2g==' key exchange. 2019-09-19 20:08:10 -04:00
0df63c20ac Updated screen shot. 2019-09-05 18:52:32 -04:00
209bcab427 Added entries to .gitignore. 2019-09-04 15:06:49 -04:00
eac81455a9 Added PyPI package support. 2019-09-04 15:05:07 -04:00
bce9e2b152 Added new KEX: diffie-hellman-group15-sha256. 2019-09-03 20:41:53 -04:00
f5431559ff Bumped version number. 2019-08-29 16:52:38 -04:00
6f60722455 Fixed version number. 2019-08-29 15:53:35 -04:00
f7cbe71aba Updated for v2.0.0 release. 2019-08-29 15:34:19 -04:00
c185a25af1 For unrecognized servers, only recommend algorithm changes & removals, not additions (since they can be very inaccurate). 2019-08-28 00:37:55 -04:00
7221413567 Added TinySSH test. 2019-08-27 22:28:24 -04:00
747177c1c7 Added TinySSH support. Fixes #7. 2019-08-27 17:02:03 -04:00
6846b1bf29 Added two KEX algorithms: diffie-hellman-group16-sha256 and diffie-hellman-group-exchange-sha512@ssh.com. 2019-08-26 15:28:37 -04:00
af7e2a088c Added hmac-sha512 and hmac-sha512@ssh.com MACs. Added diffie-hellman-group17-sha512 key exchange. 2019-08-26 15:19:49 -04:00
120f898539 Added Dropbear test. 2019-08-26 14:45:31 -04:00
0b034b8226 Marked 3des-ctr as a weak cipher. 2019-08-26 14:44:35 -04:00
4ebccb8068 Added OpenSSH v4.0 test. 2019-08-22 16:48:23 -04:00
4f138d7f82 Added docker testing framework. 2019-08-22 16:04:46 -04:00
7a06b872f9 Fixed automatic links in changelog. 2019-08-22 15:54:14 -04:00
6baff0f8fe Updated changelog for v2.0.0. 2019-08-22 15:49:10 -04:00
af663da838 Now SHA256 fingerprints are displayed for RSA and ED25519 host keys. Fixes #2. 2019-08-22 15:47:37 -04:00
ed11fc135b When unknown algorithms are encountered, ask the user to report them. 2019-08-18 15:20:16 -04:00
afa73d2dd2 Added 1 kex (diffie-hellman-group-exchange-sha256@ssh.com), 3 encryption algs (des-cbc-ssh1, blowfish-ctr, twofish-ctr), and 8 macs (hmac-sha2-56, hmac-sha2-224, hmac-sha2-384, hmac-sha3-256, hmac-sha3-384, hmac-sha3-512, hmac-sha256, hmac-sha256@ssh.com). 2019-08-18 14:38:39 -04:00
64656b5228 Added timeout option to usage message. 2019-08-18 10:03:44 -04:00
99ac875542 Added timeout argument. 2019-08-18 10:03:03 -04:00
f9a51d4108 Default interpreter changed to python3. 2019-08-18 00:34:03 -04:00
8527d13343 Added documentation on ALGORITHMS structure. 2019-08-18 00:32:59 -04:00
f8fcd119e2 Tagged sntrup4591761x25519-sha512@tinyssh.org as experimental, just as the OpenSSH 8.0 release notes say. 2019-08-18 00:16:42 -04:00
76a4750934 Added support for kex sntrup4591761x25519-sha512@tinyssh.org, introduced in OpenSSH 8.0. 2019-08-18 00:09:40 -04:00
7155efeb4a Added CVEs for Dropbear & libssh. Fixed libssh CVE parsing. Now prints CVEs in red when score is >= 8.0, otherwise they are printed in orange. 2019-08-17 23:11:03 -04:00
41d396f551 Updated version, copyright header, URL, and added Python 2 warning. 2019-08-17 20:59:23 -04:00
a9933f9211 Added myself to copyright header in license. 2019-08-16 08:56:50 -04:00
b35ca6c6f3 Merged all_my_patches branch to master, since a new project maintainer is needed. 2019-08-16 08:30:45 -04:00
f2e6f1a71c Replace getopt.getopt with getopt.gnu_getopt
Addresses Issue #41, gnu_getopt allows non-option arguments to be intermingled with option arguments whereas getopt stops processing arguments when a non option is found.
2019-06-05 16:19:33 -04:00
f44663bfc4 Fixed Socket.connect() method arguments. 2017-10-31 16:49:19 -04:00
95ca0bb243 Fixed merge collision in connect() method. 2017-10-31 16:40:02 -04:00
a9f6b93391 Merge branch 'timeout_arg' into all_my_patches 2017-10-31 16:36:20 -04:00
04973df2af Added command-line option to modify connection/read timeout. 2017-10-29 17:48:04 -04:00
a3f126a1dd Added missing algorithms from RFC4250 and RFC4432. 2017-10-11 15:47:01 -04:00
1bb5490e01 Added new algorithms (some as per RFC4344). 2017-10-11 15:13:58 -04:00
c1d0540d1e Fixed one more warning. 2017-09-27 22:42:49 -04:00
cd80917c62 Fixed more warnings. 2017-09-27 22:36:23 -04:00
b7bf8ab38a Suppressed more unused variables warnings. 2017-09-27 22:22:42 -04:00
a3c6d16500 Suppressing pylint warnings on unused variables. 2017-09-27 22:14:48 -04:00
4f6e23e568 Fixed send_init() inheritance problems. Now kex failures will try to continue on instead of terminating the program. 2017-09-27 21:27:08 -04:00
b2775c9cf9 Python3 fixes. 2017-09-26 20:51:10 -04:00
ee5dde1cde Added RSA certificate auditing. 2017-09-26 20:46:00 -04:00
33ae2946ea Syntax fix for Python2. 2017-09-22 15:01:51 -04:00
7c919b093b Added RSA & DH modulus size auditing. 2017-09-21 22:44:34 -04:00
d8eb46d766 Correct IPv6 parsing in command-line. Fixes #26. 2017-05-05 14:12:45 +03:00
96d442ec62 Test Timeframe repr(). 2017-04-11 13:32:38 +03:00
9c463b4e06 Fix lint tox environment. 2017-04-10 19:32:40 +03:00
1d1f842bed Refactor output level/colors, fix python:S1845. 2017-04-10 19:20:31 +03:00
72a6b9eeaf Refactor and test SSH.Algorithm. 2017-04-10 13:20:32 +03:00
774d1c1fe4 Ignore linting long assertion lines. 2017-04-10 13:20:02 +03:00
6c8173d409 Fix to_ntext test. 2017-04-06 05:27:40 +03:00
21a93cbd66 Condition must be a boolean fixes. 2017-04-06 05:27:29 +03:00
0d555d43b3 Condition must be a boolean fixes. 2017-04-05 18:12:26 +03:00
e4bdabb891 Fix method type and naming. 2017-04-05 17:34:19 +03:00
c132c62b96 Remove useless parentheses. 2017-04-05 16:13:35 +03:00
bb122ffe13 Replace assertions with exceptions. 2017-04-05 16:02:40 +03:00
09c2e7b2d5 Fix SonarQube python:S1871. 2017-04-05 04:27:39 +03:00
464bb154f3 Use git commit as dev version suffix. Add badge. 2017-04-05 04:25:01 +03:00
9fe69841eb Integrate SonarQube analysis. 2017-04-05 03:22:13 +03:00
f330608278 Test with pypy and pypy3 environments. 2017-04-01 10:21:50 +03:00
cab83f837a Update to Xcode 8.3. 2017-03-31 02:48:51 +03:00
041805f608 Test with AppVeyor environment. 2017-03-30 16:31:12 +03:00
2f7c64d896 Report python version in CI. 2017-03-28 10:25:55 +03:00
e91bbb5e30 Better testing environment. 2017-03-28 07:49:52 +03:00
95ba7d11ce Test on Ubuntu 12.04/14.04 and Mac OS X 10.10-10.12. 2017-03-26 17:47:13 +03:00
0ffb15dd54 Pylint and flake8 is not supported on Python 2.6. 2017-03-26 06:48:44 +03:00
76849540be It's 2017 already. 2017-03-26 06:31:06 +03:00
57a8744d03 Fix some unused variable warnings. 2017-03-26 06:24:07 +03:00
3ebb59108b Ignore pylint's else-if-used in validly used places. 2017-03-26 05:58:39 +03:00
74d1b5c7b5 Fix pylint's bad-builtin and deprecated-lambda with list comprehension. 2017-03-26 05:54:14 +03:00
6d9f5e6f2a Refactor tox.ini to be more versatile. 2017-03-26 05:42:20 +03:00
29d9e4270d Fix flake8 reported issues. 2017-03-25 08:44:37 +02:00
cfae0d020a Fix vulture output for Python 3. 2017-03-25 08:33:16 +02:00
8b7659c4d3 Remove unnecessary files, now that everything is in tox. Add codecov badge. 2017-03-25 08:02:49 +02:00
d3ba5a4e6f Use tox, use codecov, work around pypy3 issues. 2017-03-25 07:44:27 +02:00
65ef250aae Upgrade to Mypy 0.501 and fix issues. Add requirements.txt. 2017-03-23 23:17:35 +02:00
94a74e9cfd Reviewed libssh-0.7.4 changes. 2017-02-13 13:33:50 +02:00
9ac03d368a Add OpenSSH 7.4 changes and use as default banner. 2017-01-24 12:45:53 +02:00
54b0960502 Upgrade to Mypy 0.470. Add colorama stub. Fix identation. 2017-01-23 19:34:06 +02:00
c9443e6e06 Fix pyp3 version for Travis-CI (https://github.com/travis-ci/travis-ci/issues/6277). 2017-01-23 19:20:42 +02:00
bs
ff500ba84b Add OpenSSH CVE list (#25) 2017-01-23 17:45:25 +02:00
9a409e835e Refactor outer functions within classes.
Use mypy strict optional checks and fix them.
Use better comparison for compatiblity output.
Add initial socket tests.
2016-11-03 19:10:49 +02:00
6fde896d77 Add resolve tests. 2016-11-02 19:29:21 +02:00
6c4b9fcadf Banner should be in printable ASCII, not the whole ASCII space. 2016-11-02 18:25:13 +02:00
5bb0ae0ceb Rework is/to ASCII and implement printable ASCII is/to functions.
Add Utils tests.
2016-11-02 18:23:55 +02:00
11b6155c64 Use Python defined error numbers. 2016-11-02 13:18:03 +02:00
b3ed4c7715 Add LICENSE file (#22)
Create LICENSE
2016-11-02 13:03:30 +02:00
44c1d4827c Specify error when couldn't get banner. Test for timeout and retry cases. 2016-11-02 13:00:24 +02:00
22b671e15f Add LICENSE file (#22)
Create LICENSE
2016-11-02 12:45:56 +02:00
dd3ca9688e Back to development version. 2016-10-26 19:14:03 +03:00
e42064b9b9 Release 1.7.0. 2016-10-26 19:02:13 +03:00
8c24fc01e8 Merge branch 'develop' 2016-10-26 19:00:44 +03:00
4fbd339c54 Document changes and add coverage badge. 2016-10-26 18:56:38 +03:00
66b9e079a8 Implement new options (-4/--ipv4, -6/--ipv6, -p/--port <port>).
By default both IPv4 and IPv6 is supported and order of precedence depends on OS.
By using -46, IPv4 is prefered, but by using -64, IPv6 is preferd.
For now the old way how to specify port (host:port) has been kept intact.
2016-10-26 18:33:00 +03:00
8018209dd1 Fixed typos 2016-10-26 12:17:31 +03:00
7314d780e7 Merge pull request #20 from radarhere/master
Fixed typo
2016-10-26 12:11:04 +03:00
6a1f5d2d75 Fixed typos 2016-10-26 05:52:58 +11:00
4684ff0113 Add linter fixes for tests. 2016-10-25 17:19:08 +03:00
84dfdcaf5e Invalid CRC32 checksum test. 2016-10-25 16:59:43 +03:00
318aab79bc Add simple server tests for SSH1 and SSH2. 2016-10-25 16:57:30 +03:00
aa4eabda66 Do not count coverage for missing import. 2016-10-25 14:04:54 +03:00
4bbb1f4d11 Use safer UTF-8 decoding (with replace) and add related tests. 2016-10-25 13:53:51 +03:00
66bd6c3ef0 Test colors only if they are supported. 2016-10-25 11:57:13 +03:00
182467e0e8 Fix typo, which slipped in while adding type system. 2016-10-25 11:52:55 +03:00
385c230376 Add colors support for Microsoft Windows via optional colorama dependency. 2016-10-25 11:50:12 +03:00
855d64f5b1 Ignore virtualenv and cache. 2016-10-25 03:13:42 +03:00
5b3b630623 Fix pylint reported issues and disable unnecessary ones. 2016-10-20 20:00:51 +03:00
a5f1cd9197 Tune prospector and pylint settings. 2016-10-20 20:00:29 +03:00
cdfe06e75d Fix type after argument removal. 2016-10-20 17:19:37 +03:00
cbe7ad4ac3 Fix pylint reported no-self-use and disable checks in py2/3 compatibility code. 2016-10-20 17:06:23 +03:00
dfb8c302bf Fix pylint reported attribute-defined-outside-init. 2016-10-20 16:46:53 +03:00
4120377c0b Remove unnecessary argument. 2016-10-20 16:41:44 +03:00
5be64a8ad2 Fix pylint reported dangerous-default-value. 2016-10-20 16:31:48 +03:00
67087fb920 Fix pylint reported anomalous-backslash-in-string. 2016-10-20 16:27:11 +03:00
42be99a2c7 Test for non-ASCII banner. 2016-10-19 20:53:47 +03:00
ca6cfb81a2 Import mypy configuration script and run scripts (for Python 2.7 and 3.5).
Import pytest coverage script.
2016-10-19 20:51:57 +03:00
fabb4b5bb2 Add static typing and refactor code to pass all mypy checks.
Move Python compatibility types to first lines of code.
Add Python (text/byte) compatibility helper functions.
Check for SSH banner ASCII validity.
2016-10-19 20:47:13 +03:00
8ca6ec591d Handle the case when received data is in wrong encoding (not utf-8). 2016-10-18 09:45:03 +03:00
6b76e68d0d Fix wrongly introduced Python 3 incompatibility. Fixes #14 and #15.
Add static type checks via mypy (optional static type checker),
Add relevant tests, which could trigger the issue.
2016-10-17 20:31:13 +03:00
f065118959 Create virtual socket fixture (socket mocking). 2016-10-17 20:27:35 +03:00
63a9c479a7 Test kex payload generation. 2016-10-14 16:17:38 +03:00
c9d58bb827 Switch to new development version. 2016-10-14 09:14:07 +03:00
87 changed files with 6360 additions and 761 deletions

37
.appveyor.yml Normal file
View File

@ -0,0 +1,37 @@
version: '1.7.1.dev.{build}'
build: off
branches:
only:
- master
- develop
environment:
matrix:
- PYTHON: "C:\\Python26"
- PYTHON: "C:\\Python26-x64"
- PYTHON: "C:\\Python27"
- PYTHON: "C:\\Python27-x64"
- PYTHON: "C:\\Python33"
- PYTHON: "C:\\Python33-x64"
- PYTHON: "C:\\Python34"
- PYTHON: "C:\\Python34-x64"
- PYTHON: "C:\\Python35"
- PYTHON: "C:\\Python35-x64"
- PYTHON: "C:\\Python36"
- PYTHON: "C:\\Python36-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\*

9
.gitignore vendored
View File

@ -1,2 +1,11 @@
*~
*.pyc
venv*/
.cache/
.tox
.coverage*
reports/
.scannerwork/
pypi/sshaudit/LICENSE
pypi/sshaudit/README.md
pypi/sshaudit/sshaudit.py

View File

@ -1,18 +1,80 @@
language: python
python:
- 2.6
- 2.7
- 3.3
- 3.4
- 3.5
- pypy
- pypy3
install:
- pip install --upgrade pytest
- pip install --upgrade pytest-cov
- pip install --upgrade coveralls
script:
- py.test --cov-report= --cov=ssh-audit -v test
after_success:
- coveralls
sudo: false
matrix:
include:
# (default)
- os: linux
python: 2.6
- os: linux
python: 2.7
env: SQ=1
- os: linux
python: 3.3
- os: linux
python: 3.4
- os: linux
python: 3.5
- os: linux
python: 3.6
- os: linux
python: pypy
- os: linux
python: pypy3
- os: linux
python: 3.7-dev
# Ubuntu 12.04
- os: linux
dist: precise
language: generic
env: PY_VER=py26,py27,py33,py34,py35,py36,pypy,pypy3 PY_ORIGIN=pyenv
# Ubuntu 14.04
- os: linux
dist: trusty
language: generic
env: PY_VER=py26,py27,py33,py34,py35,py36,pypy,pypy3 PY_ORIGIN=pyenv
# macOS 10.12 Sierra
- os: osx
osx_image: xcode8.3
language: generic
env: PY_VER=py26,py27,py33,py34,py35,py36,pypy,pypy3
# Mac OS X 10.11 El Capitan
- os: osx
osx_image: xcode7.3
language: generic
env: PY_VER=py26,py27,py33,py34,py35,py36,pypy,pypy3
# Mac OS X 10.10 Yosemite
- os: osx
osx_image: xcode6.4
language: generic
env: PY_VER=py26,py27,py33,py34,py35,py36,pypy,pypy3
allow_failures:
# PyPy3 on Travis CI is out of date
- python: pypy3
# Python nightly could fail
- python: 3.7-dev
- env: PY_VER=py37
- env: PY_VER=py37/pyenv
- env: PY_VER=py37 PY_ORIGIN=pyenv
fast_finish: true
cache:
- pip
- directories:
- $HOME/.pyenv.cache
- $HOME/.bin
before_install:
- source test/tools/ci-linux.sh
- ci_step_before_install
install:
- ci_step_install
script:
- ci_step_script
after_success:
- ci_step_success
after_failure:
- ci_step_failure

23
LICENSE Normal file
View File

@ -0,0 +1,23 @@
The MIT License (MIT)
Copyright (C) 2017 Andris Raugulis (moo@arthepsy.eu)
Copyright (C) 2017-2019 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.

View File

@ -1,9 +1,15 @@
# ssh-audit
[![build status](https://api.travis-ci.org/arthepsy/ssh-audit.svg)](https://travis-ci.org/arthepsy/ssh-audit)
**ssh-audit** is a tool for ssh server auditing.
<!--
[![travis build status](https://api.travis-ci.org/arthepsy/ssh-audit.svg?branch=develop)](https://travis-ci.org/arthepsy/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)
[![codecov](https://codecov.io/gh/arthepsy/ssh-audit/branch/develop/graph/badge.svg)](https://codecov.io/gh/arthepsy/ssh-audit)
[![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)
-->
**ssh-audit** is a tool for ssh server & client configuration auditing.
## Features
- SSH1 and SSH2 protocol server support;
- analyze SSH client configuration;
- grab banner, recognize device or software and operating system, detect compression;
- gather key-exchange, host-key, encryption and message authentication code algorithms;
- output algorithm information (available since, removed/disabled, unsafe/weak/legacy, etc);
@ -11,27 +17,78 @@
- output security information (related issues, assigned CVE list, etc);
- analyze SSH version compatibility based on algorithm information;
- historical information from OpenSSH, Dropbear SSH and libssh;
- no dependencies, compatible with Python 2.6+, Python 3.x and PyPy;
- no dependencies
## Usage
```
usage: ssh-audit.py [-bnv] [-l <level>] <host[:port]>
usage: ssh-audit.py [-1246pbcnjvlt] <host>
-1, --ssh1 force ssh version 1 only
-2, --ssh2 force ssh version 2 only
-4, --ipv4 enable IPv4 (order of precedence)
-6, --ipv6 enable IPv6 (order of precedence)
-p, --port=<port> port to connect
-b, --batch batch output
-c, --client-audit starts a server on port 2222 to audit client
software config (use -p to change port;
use -t to change timeout)
-n, --no-colors disable colors
-j, --json JSON output
-v, --verbose verbose output
-l, --level=<level> minimum output level (info|warn|fail)
-t, --timeout=<secs> timeout (in seconds) for connection and reading
(default: 5)
```
* 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).
* verbose flag `-v` will prefix each line with section type and algorithm name.
### example
![screenshot](https://cloud.githubusercontent.com/assets/7356025/19233757/3e09b168-8ef0-11e6-91b4-e880bacd0b8a.png)
### Server Audit Example
Below is a screen shot of the 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)
### Client Audit Example
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)
### 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)
## ChangeLog
### v2.1.1 (2019-11-26)
- Added 2 new host key types: `rsa-sha2-256-cert-v01@openssh.com`, `rsa-sha2-512-cert-v01@openssh.com`.
- Added 2 new ciphers: `des`, `3des`.
- Added 3 new PuTTY vulnerabilities.
- During client testing, client IP address is now listed in output.
### v2.1.0 (2019-11-14)
- Added client software auditing functionality (see `-c` / `--client-audit` option).
- Added JSON output option (see `-j` / `--json` option; credit [Andreas Jaggi](https://github.com/x-way)).
- Fixed crash while scanning Solaris Sun_SSH.
- Added 9 new key exchanges: `gss-group1-sha1-toWM5Slw5Ew8Mqkay+al2g==`, `gss-gex-sha1-toWM5Slw5Ew8Mqkay+al2g==`, `gss-group14-sha1-`, `gss-group14-sha1-toWM5Slw5Ew8Mqkay+al2g==`, `gss-group14-sha256-toWM5Slw5Ew8Mqkay+al2g==`, `gss-group15-sha512-toWM5Slw5Ew8Mqkay+al2g==`, `diffie-hellman-group15-sha256`, `ecdh-sha2-1.3.132.0.10`, `curve448-sha512`.
- Added 1 new host key type: `ecdsa-sha2-1.3.132.0.10`.
- Added 4 new ciphers: `idea-cbc`, `serpent128-cbc`, `serpent192-cbc`, `serpent256-cbc`.
- Added 6 new MACs: `hmac-sha2-256-96-etm@openssh.com`, `hmac-sha2-512-96-etm@openssh.com`, `hmac-ripemd`, `hmac-sha256-96@ssh.com`, `umac-32@openssh.com`, `umac-96@openssh.com`.
### v2.0.0 (2019-08-29)
- Forked from https://github.com/arthepsy/ssh-audit (development was stalled, and developer went MIA).
- Added RSA host key length test.
- Added RSA certificate key length test.
- Added Diffie-Hellman modulus size test.
- Now outputs host key fingerprints for RSA and ED25519.
- Added 5 new key exchanges: `sntrup4591761x25519-sha512@tinyssh.org`, `diffie-hellman-group-exchange-sha256@ssh.com`, `diffie-hellman-group-exchange-sha512@ssh.com`, `diffie-hellman-group16-sha256`, `diffie-hellman-group17-sha512`.
- Added 3 new encryption algorithms: `des-cbc-ssh1`, `blowfish-ctr`, `twofish-ctr`.
- Added 10 new MACs: `hmac-sha2-56`, `hmac-sha2-224`, `hmac-sha2-384`, `hmac-sha3-256`, `hmac-sha3-384`, `hmac-sha3-512`, `hmac-sha256`, `hmac-sha256@ssh.com`, `hmac-sha512`, `hmac-512@ssh.com`.
- Added command line argument (`-t` / `--timeout`) for connection & reading timeouts.
- Updated CVEs for libssh & Dropbear.
### v1.7.0 (2016-10-26)
- implement options to allow specify IPv4/IPv6 usage and order of precedence
- implement option to specify remote port (old behavior kept for compatibility)
- add colors support for Microsoft Windows via optional colorama dependency
- fix encoding and decoding issues, add tests, do not crash on encoding errors
- use mypy-lang for static type checking and verify all code
### v1.6.0 (2016-10-14)
- implement algorithm recommendations section (based on recognized software)
- implement full libssh support (version history, algorithms, security, etc)
@ -47,7 +104,7 @@ usage: ssh-audit.py [-bnv] [-l <level>] <host[:port]>
- implement full SSH1 support with fingerprint information
- automatically fallback to SSH1 on protocol mismatch
- add new options to force SSH1 or SSH2 (both allowed by default)
- parse banner information and convert it to specific sofware and OS version
- parse banner information and convert it to specific software and OS version
- do not use padding in batch mode
- several fixes (Cisco sshd, rare hangs, error handling, etc)

511
docker_test.sh Executable file
View File

@ -0,0 +1,511 @@
#!/bin/bash
#
# This script will set up a docker image with multiple versions of OpenSSH, then
# use it to run tests.
#
# For debugging purposes, here is a cheat sheet for manually running the docker image:
#
# docker run -p 2222:22 -it ssh-audit-test:X /bin/bash
# docker run -p 2222:22 --security-opt seccomp:unconfined -it ssh-audit-test /debug.sh
# docker run -d -p 2222:22 ssh-audit-test:X /openssh/sshd-5.6p1 -D -f /etc/ssh/sshd_config-5.6p1_test1
# docker run -d -p 2222:22 ssh-audit-test:X /openssh/sshd-8.0p1 -D -f /etc/ssh/sshd_config-8.0p1_test1
#
# This is the docker tag for the image. If this tag doesn't exist, then we assume the
# image is out of date, and generate a new one with this tag.
IMAGE_VERSION=3
# This is the name of our docker image.
IMAGE_NAME=ssh-audit-test
# Terminal colors.
CLR="\033[0m"
RED="\033[0;31m"
GREEN="\033[0;32m"
REDB="\033[1;31m" # Red + bold
GREENB="\033[1;32m" # Green + bold
# Returns 0 if current docker image exists.
function check_if_docker_image_exists {
images=`docker image ls | egrep "$IMAGE_NAME[[:space:]]+$IMAGE_VERSION"`
}
# Uncompresses and compiles the specified version of Dropbear.
function compile_dropbear {
version=$1
compile 'Dropbear' $version
}
# Uncompresses and compiles the specified version of OpenSSH.
function compile_openssh {
version=$1
compile 'OpenSSH' $version
}
# Uncompresses and compiles the specified version of TinySSH.
function compile_tinyssh {
version=$1
compile 'TinySSH' $version
}
function compile {
project=$1
version=$2
tarball=
uncompress_options=
source_dir=
server_executable=
if [[ $project == 'OpenSSH' ]]; then
tarball="openssh-${version}.tar.gz"
uncompress_options="xzf"
source_dir="openssh-${version}"
server_executable=sshd
elif [[ $project == 'Dropbear' ]]; then
tarball="dropbear-${version}.tar.bz2"
uncompress_options="xjf"
source_dir="dropbear-${version}"
server_executable=dropbear
elif [[ $project == 'TinySSH' ]]; then
tarball="${version}.tar.gz"
uncompress_options="xzf"
source_dir="tinyssh-${version}"
server_executable='build/bin/tinysshd'
fi
echo "Uncompressing ${project} ${version}..."
tar $uncompress_options $tarball
echo "Compiling ${project} ${version}..."
pushd $source_dir > /dev/null
# TinySSH has no configure script... only a Makefile.
if [[ $project == 'TinySSH' ]]; then
make -j 10
else
./configure && make -j 10
fi
if [[ ! -f $server_executable ]]; then
echo -e "${REDB}Error: ${server_executable} not built!${CLR}"
exit 1
fi
echo -e "\n${GREEN}Successfully built ${project} ${version}${CLR}\n"
popd > /dev/null
}
# Creates a new docker image.
function create_docker_image {
# Create a new temporary directory.
TMP_DIR=`mktemp -d /tmp/sshaudit-docker-XXXXXXXXXX`
# Copy the Dockerfile and all files in the test/docker/ dir to our new temp directory.
find test/docker/ -maxdepth 1 -type f | xargs cp -t $TMP_DIR
# Make the temp directory our working directory for the duration of the build
# process.
pushd $TMP_DIR > /dev/null
# Get the release keys.
get_dropbear_release_key
get_openssh_release_key
get_tinyssh_release_key
# Aside from checking the GPG signatures, we also compare against this known-good
# SHA-256 hash just in case.
get_openssh '4.0p1' '5adb9b2c2002650e15216bf94ed9db9541d9a17c96fcd876784861a8890bc92b'
get_openssh '5.6p1' '538af53b2b8162c21a293bb004ae2bdb141abd250f61b4cea55244749f3c6c2b'
get_openssh '8.0p1' 'bd943879e69498e8031eb6b7f44d08cdc37d59a7ab689aa0b437320c3481fd68'
get_dropbear '2019.78' '525965971272270995364a0eb01f35180d793182e63dd0b0c3eb0292291644a4'
get_tinyssh '20190101' '554a9a94e53b370f0cd0c5fbbd322c34d1f695cbcea6a6a32dcb8c9f595b3fea'
# Compile the versions of OpenSSH.
compile_openssh '4.0p1'
compile_openssh '5.6p1'
compile_openssh '8.0p1'
# Compile the versions of Dropbear.
compile_dropbear '2019.78'
# Compile the versions of TinySSH.
compile_tinyssh '20190101'
# Rename the default config files so we know they are our originals.
mv openssh-4.0p1/sshd_config sshd_config-4.0p1_orig
mv openssh-5.6p1/sshd_config sshd_config-5.6p1_orig
mv openssh-8.0p1/sshd_config sshd_config-8.0p1_orig
# Create the configurations for each test.
#
# OpenSSH v4.0p1
#
# Test 1: Basic test.
create_openssh_config '4.0p1' 'test1' "HostKey /etc/ssh/ssh1_host_key\nHostKey /etc/ssh/ssh_host_rsa_key_1024\nHostKey /etc/ssh/ssh_host_dsa_key"
#
# OpenSSH v5.6p1
#
# Test 1: Basic test.
create_openssh_config '5.6p1' 'test1' "HostKey /etc/ssh/ssh_host_rsa_key_1024\nHostKey /etc/ssh/ssh_host_dsa_key"
# Test 2: RSA 1024 host key with RSA 1024 certificate.
create_openssh_config '5.6p1' 'test2' "HostKey /etc/ssh/ssh_host_rsa_key_1024\nHostCertificate /etc/ssh/ssh_host_rsa_key_1024-cert_1024.pub"
# Test 3: RSA 1024 host key with RSA 3072 certificate.
create_openssh_config '5.6p1' 'test3' "HostKey /etc/ssh/ssh_host_rsa_key_1024\nHostCertificate /etc/ssh/ssh_host_rsa_key_1024-cert_3072.pub"
# Test 4: RSA 3072 host key with RSA 1024 certificate.
create_openssh_config '5.6p1' 'test4' "HostKey /etc/ssh/ssh_host_rsa_key_3072\nHostCertificate /etc/ssh/ssh_host_rsa_key_3072-cert_1024.pub"
# Test 5: RSA 3072 host key with RSA 3072 certificate.
create_openssh_config '5.6p1' 'test5' "HostKey /etc/ssh/ssh_host_rsa_key_3072\nHostCertificate /etc/ssh/ssh_host_rsa_key_3072-cert_3072.pub"
#
# OpenSSH v8.0p1
#
# Test 1: Basic test.
create_openssh_config '8.0p1' 'test1' "HostKey /etc/ssh/ssh_host_rsa_key_3072\nHostKey /etc/ssh/ssh_host_ecdsa_key\nHostKey /etc/ssh/ssh_host_ed25519_key"
# Test 2: ED25519 certificate test.
create_openssh_config '8.0p1' 'test2' "HostKey /etc/ssh/ssh_host_ed25519_key\nHostCertificate /etc/ssh/ssh_host_ed25519_key-cert.pub"
# Test 3: Hardened installation test.
create_openssh_config '8.0p1' 'test3' "HostKey /etc/ssh/ssh_host_ed25519_key\nKexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256\nCiphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr\nMACs hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,umac-128-etm@openssh.com"
# Now build the docker image!
docker build --tag $IMAGE_NAME:$IMAGE_VERSION .
popd > /dev/null
rm -rf $TMP_DIR
}
# Creates an OpenSSH configuration file for a specific test.
function create_openssh_config {
openssh_version=$1
test_number=$2
config_text=$3
cp sshd_config-${openssh_version}_orig sshd_config-${openssh_version}_${test_number}
echo -e "${config_text}" >> sshd_config-${openssh_version}_${test_number}
}
# Downloads the Dropbear release key and adds it to the local keyring.
function get_dropbear_release_key {
get_release_key 'Dropbear' 'https://matt.ucc.asn.au/dropbear/releases/dropbear-key-2015.asc' 'F29C6773' 'F734 7EF2 EE2E 07A2 6762 8CA9 4493 1494 F29C 6773'
}
# Downloads the OpenSSH release key and adds it to the local keyring.
function get_openssh_release_key {
get_release_key 'OpenSSH' 'https://ftp.openbsd.org/pub/OpenBSD/OpenSSH/RELEASE_KEY.asc' '6D920D30' '59C2 118E D206 D927 E667 EBE3 D3E5 F56B 6D92 0D30'
}
# Downloads the TinySSH release key and adds it to the local keyring.
function get_tinyssh_release_key {
get_release_key 'TinySSH' '' '96939FF9' 'AADF 2EDF 5529 F170 2772 C8A2 DEC4 D246 931E F49B'
}
function get_release_key {
project=$1
key_url=$2
key_id=$3
release_key_fingerprint_expected=$4
# The TinySSH release key isn't on any website, apparently.
if [[ $project == 'TinySSH' ]]; then
gpg --recv-key $key_id
else
echo -e "\nGetting ${project} release key...\n"
wget -O key.asc $2
echo -e "\nImporting ${project} release key...\n"
gpg --import key.asc
rm key.asc
fi
local release_key_fingerprint_actual=`gpg --fingerprint ${key_id}`
if [[ $release_key_fingerprint_actual != *"$release_key_fingerprint_expected"* ]]; then
echo -e "\n${REDB}Error: ${project} release key fingerprint does not match expected value!\n\tExpected: $release_key_fingerprint_expected\n\tActual: $release_key_fingerprint_actual\n\nTerminating.${CLR}"
exit -1
fi
echo -e "\n\n${GREEN}${project} release key matches expected value.${CLR}\n"
}
# Downloads the specified version of Dropbear.
function get_dropbear {
version=$1
tarball_checksum_expected=$2
get_source 'Dropbear' $version $tarball_checksum_expected
}
# Downloads the specified version of OpenSSH.
function get_openssh {
version=$1
tarball_checksum_expected=$2
get_source 'OpenSSH' $version $tarball_checksum_expected
}
# Downloads the specified version of TinySSH.
function get_tinyssh {
version=$1
tarball_checksum_expected=$2
get_source 'TinySSH' $version $tarball_checksum_expected
}
function get_source {
project=$1
version=$2
tarball_checksum_expected=$3
base_url_source=
base_url_sig=
tarball=
sig=
signer=
if [[ $project == 'OpenSSH' ]]; then
base_url_source='https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/'
base_url_sig=$base_url_source
tarball="openssh-${version}.tar.gz"
sig="${tarball}.asc"
signer="Damien Miller "
elif [[ $project == 'Dropbear' ]]; then
base_url_source='https://matt.ucc.asn.au/dropbear/releases/'
base_url_sig=$base_url_source
tarball="dropbear-${version}.tar.bz2"
sig="${tarball}.asc"
signer="Dropbear SSH Release Signing <matt@ucc.asn.au>"
elif [[ $project == 'TinySSH' ]]; then
base_url_source='https://github.com/janmojzis/tinyssh/archive/'
base_url_sig="https://github.com/janmojzis/tinyssh/releases/download/${version}/"
tarball="${version}.tar.gz"
sig="${tarball}.asc"
signer="Jan Mojžíš <jan.mojzis@gmail.com>"
fi
echo -e "\nGetting ${project} ${version} sources...\n"
wget "${base_url_source}${tarball}"
echo -e "\nGetting ${project} ${version} signature...\n"
wget "${base_url_sig}${sig}"
# Older OpenSSH releases were .sigs.
if [[ ($project == 'OpenSSH') && (! -f $sig) ]]; then
wget ${base_url_sig}openssh-${version}.tar.gz.sig
sig=openssh-${version}.tar.gz.sig
fi
local gpg_verify=`gpg --verify ${sig} ${tarball} 2>&1`
if [[ $gpg_verify != *"Good signature from \"${signer}"* ]]; then
echo -e "\n\n${REDB}Error: ${project} signature invalid!\n$gpg_verify\n\nTerminating.${CLR}"
exit -1
fi
# Check GPG's return value. 0 denotes a valid signature, and 1 is returned
# on invalid signatures.
if [[ $? != 0 ]]; then
echo -e "\n\n${REDB}Error: ${project} signature invalid! Verification returned code: $?\n\nTerminating.${CLR}"
exit -1
fi
echo -e "${GREEN}Signature on ${project} sources verified.${CLR}\n"
local checksum_actual=`sha256sum ${tarball} | cut -f1 -d" "`
if [[ $checksum_actual != $tarball_checksum_expected ]]; then
echo -e "${REDB}Error: ${project} checksum is invalid!\n Expected: ${tarball_checksum_expected}\n Actual: ${checksum_actual}\n\n Terminating.${CLR}"
exit -1
fi
}
# Runs a Dropbear test. Upon failure, a diff between the expected and actual results
# is shown, then the script immediately terminates.
function run_dropbear_test {
dropbear_version=$1
test_number=$2
options=$3
run_test 'Dropbear' $dropbear_version $test_number "$options"
}
# Runs an OpenSSH test. Upon failure, a diff between the expected and actual results
# is shown, then the script immediately terminates.
function run_openssh_test {
openssh_version=$1
test_number=$2
run_test 'OpenSSH' $openssh_version $test_number ''
}
# Runs a TinySSH test. Upon failure, a diff between the expected and actual results
# is shown, then the script immediately terminates.
function run_tinyssh_test {
tinyssh_version=$1
test_number=$2
run_test 'TinySSH' $tinyssh_version $test_number ''
}
function run_test {
server_type=$1
version=$2
test_number=$3
options=$4
server_exec=
test_result_stdout=
test_result_json=
expected_result_stdout=
expected_result_json=
test_name=
if [[ $server_type == 'OpenSSH' ]]; then
server_exec="/openssh/sshd-${version} -D -f /etc/ssh/sshd_config-${version}_${test_number}"
test_result_stdout="${TEST_RESULT_DIR}/openssh_${version}_${test_number}.txt"
test_result_json="${TEST_RESULT_DIR}/openssh_${version}_${test_number}.json"
expected_result_stdout="test/docker/expected_results/openssh_${version}_${test_number}.txt"
expected_result_json="test/docker/expected_results/openssh_${version}_${test_number}.json"
test_name="OpenSSH ${version} ${test_number}"
options=
elif [[ $server_type == 'Dropbear' ]]; then
server_exec="/dropbear/dropbear-${version} -F ${options}"
test_result_stdout="${TEST_RESULT_DIR}/dropbear_${version}_${test_number}.txt"
test_result_json="${TEST_RESULT_DIR}/dropbear_${version}_${test_number}.json"
expected_result_stdout="test/docker/expected_results/dropbear_${version}_${test_number}.txt"
expected_result_json="test/docker/expected_results/dropbear_${version}_${test_number}.json"
test_name="Dropbear ${version} ${test_number}"
elif [[ $server_type == 'TinySSH' ]]; then
server_exec="/usr/bin/tcpserver -HRDl0 0.0.0.0 22 /tinysshd/tinyssh-20190101 -v /etc/tinyssh/"
test_result_stdout="${TEST_RESULT_DIR}/tinyssh_${version}_${test_number}.txt"
test_result_json="${TEST_RESULT_DIR}/tinyssh_${version}_${test_number}.json"
expected_result_stdout="test/docker/expected_results/tinyssh_${version}_${test_number}.txt"
expected_result_json="test/docker/expected_results/tinyssh_${version}_${test_number}.json"
test_name="TinySSH ${version} ${test_number}"
fi
cid=`docker run -d -p 2222:22 ${IMAGE_NAME}:${IMAGE_VERSION} ${server_exec}`
if [[ $? != 0 ]]; then
echo -e "${REDB}Failed to run docker image! (exit code: $?)${CLR}"
exit 1
fi
./ssh-audit.py localhost:2222 > $test_result_stdout
if [[ $? != 0 ]]; then
echo -e "${REDB}Failed to run ssh-audit.py! (exit code: $?)${CLR}"
docker container stop $cid > /dev/null
exit 1
fi
./ssh-audit.py -j localhost:2222 > $test_result_json
if [[ $? != 0 ]]; then
echo -e "${REDB}Failed to run ssh-audit.py! (exit code: $?)${CLR}"
docker container stop $cid > /dev/null
exit 1
fi
docker container stop $cid > /dev/null
if [[ $? != 0 ]]; then
echo -e "${REDB}Failed to stop docker container ${cid}! (exit code: $?)${CLR}"
exit 1
fi
# TinySSH outputs a random string in each banner, which breaks our test. So
# we need to filter out the banner part of the output so we get stable, repeatable
# results.
if [[ $server_type == 'TinySSH' ]]; then
grep -v "(gen) banner: " ${test_result_stdout} > "${test_result_stdout}.tmp"
mv "${test_result_stdout}.tmp" ${test_result_stdout}
cat "${test_result_json}" | perl -pe 's/"comments": ".*?"/"comments": ""/' | perl -pe 's/"raw": ".+?"/"raw": ""/' > "${test_result_json}.tmp"
mv "${test_result_json}.tmp" ${test_result_json}
fi
diff=`diff -u ${expected_result_stdout} ${test_result_stdout}`
if [[ $? != 0 ]]; then
echo -e "${test_name} ${REDB}FAILED${CLR}.\n\n${diff}\n"
exit 1
fi
diff=`diff -u ${expected_result_json} ${test_result_json}`
if [[ $? != 0 ]]; then
echo -e "${test_name} ${REDB}FAILED${CLR}.\n\n${diff}\n"
exit 1
fi
echo -e "${test_name} ${GREEN}passed${CLR}."
}
# First check if docker is functional.
docker version > /dev/null
if [[ $? != 0 ]]; then
echo -e "${REDB}Error: 'docker version' command failed (error code: $?). Is docker installed and functioning?${CLR}"
exit 1
fi
# Check if the docker image is the most up-to-date version. If not, create it.
check_if_docker_image_exists
if [[ $? == 0 ]]; then
echo -e "\n${GREEN}Docker image $IMAGE_NAME:$IMAGE_VERSION already exists.${CLR}"
else
echo -e "\nCreating docker image $IMAGE_NAME:$IMAGE_VERSION..."
create_docker_image
echo -e "\n${GREEN}Done creating docker image!${CLR}"
fi
# Create a temporary directory to write test results to.
TEST_RESULT_DIR=`mktemp -d /tmp/ssh-audit_test-results_XXXXXXXXXX`
# Now run all the tests.
echo -e "\nRunning tests..."
run_openssh_test '4.0p1' 'test1'
echo
run_openssh_test '5.6p1' 'test1'
run_openssh_test '5.6p1' 'test2'
run_openssh_test '5.6p1' 'test3'
run_openssh_test '5.6p1' 'test4'
run_openssh_test '5.6p1' 'test5'
echo
run_openssh_test '8.0p1' 'test1'
run_openssh_test '8.0p1' 'test2'
run_openssh_test '8.0p1' 'test3'
echo
run_dropbear_test '2019.78' 'test1' '-r /etc/dropbear/dropbear_rsa_host_key_1024 -r /etc/dropbear/dropbear_dss_host_key -r /etc/dropbear/dropbear_ecdsa_host_key'
echo
run_tinyssh_test '20190101' 'test1'
# The test functions above will terminate the script on failure, so if we reached here,
# all tests are successful.
echo -e "\n${GREENB}ALL TESTS PASS!${CLR}\n"
rm -rf $TEST_RESULT_DIR
exit 0

1
pypi/MANIFEST.in Normal file
View File

@ -0,0 +1 @@
include sshaudit/LICENSE

14
pypi/Makefile Normal file
View File

@ -0,0 +1,14 @@
all:
cp ../ssh-audit.py sshaudit/sshaudit.py
cp ../LICENSE sshaudit/LICENSE
cp ../README.md sshaudit/README.md
python3 setup.py sdist bdist_wheel
uploadtest:
twine upload --repository-url https://test.pypi.org/legacy/ dist/*
uploadprod:
twine upload dist/*
clean:
rm -rf build/ dist/ *.egg-info/ sshaudit/sshaudit.py sshaudit/LICENSE sshaudit/README.md

17
pypi/notes.txt Normal file
View File

@ -0,0 +1,17 @@
To create package and upload to test server:
# apt install virtualenv
$ virtualenv -p /usr/bin/python3 pypi_upload
$ cd pypi_upload; source bin/activate
$ pip3 install twine
$ cp -R path/to/ssh-audit .
$ cd ssh-audit/pypi
$ make
$ make uploadtest
To download from test server and verify:
$ virtualenv -p /usr/bin/python3 pypi_test
$ cd pypi_test; source bin/activate
$ pip3 install --index-url https://test.pypi.org/simple ssh-audit

38
pypi/setup.py Normal file
View File

@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
import re
from setuptools import setup
version = re.search('^VERSION\s*=\s*\'v(\d\.\d\.\d)\'', open('sshaudit/sshaudit.py').read(), re.M).group(1)
print("\n\nPackaging ssh-audit v%s...\n\n" % version)
with open("sshaudit/README.md", "rb") as f:
long_descr = f.read().decode("utf-8")
setup(
name = "ssh-audit",
packages = ["sshaudit"],
license = 'MIT',
entry_points = {
"console_scripts": ['ssh-audit = sshaudit.sshaudit:main']
},
version = version,
description = "An SSH server configuration security auditing tool",
long_description = long_descr,
long_description_content_type = "text/markdown",
author = "Joe Testa",
author_email = "jtesta@positronsecurity.com",
url = "https://github.com/jtesta/ssh-audit",
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Information Technology",
"Intended Audience :: System Administrators",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Topic :: Security",
"Topic :: Security :: Cryptography"
])

View File

View File

@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
from .sshaudit import main
main()

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,14 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pytest, os, sys, io
import os
import io
import sys
import socket
import pytest
if sys.version_info[0] == 2:
import StringIO
import StringIO # pylint: disable=import-error
StringIO = StringIO.StringIO
else:
StringIO = io.StringIO
@ -17,6 +21,7 @@ def ssh_audit():
return __import__('ssh-audit')
# pylint: disable=attribute-defined-outside-init
class _OutputSpy(list):
def begin(self):
self.__out = StringIO()
@ -33,3 +38,119 @@ class _OutputSpy(list):
@pytest.fixture(scope='module')
def output_spy():
return _OutputSpy()
class _VirtualGlobalSocket(object):
def __init__(self, vsocket):
self.vsocket = vsocket
self.addrinfodata = {}
# pylint: disable=unused-argument
def create_connection(self, address, timeout=0, source_address=None):
# pylint: disable=protected-access
return self.vsocket._connect(address, True)
# pylint: disable=unused-argument
def socket(self,
family=socket.AF_INET,
socktype=socket.SOCK_STREAM,
proto=0,
fileno=None):
return self.vsocket
def getaddrinfo(self, host, port, family=0, socktype=0, proto=0, flags=0):
key = '{0}#{1}'.format(host, port)
if key in self.addrinfodata:
data = self.addrinfodata[key]
if isinstance(data, Exception):
raise data
return data
if host == 'localhost':
r = []
if family in (0, socket.AF_INET):
r.append((socket.AF_INET, 1, 6, '', ('127.0.0.1', port)))
if family in (0, socket.AF_INET6):
r.append((socket.AF_INET6, 1, 6, '', ('::1', port)))
return r
return []
class _VirtualSocket(object):
def __init__(self):
self.sock_address = ('127.0.0.1', 0)
self.peer_address = None
self._connected = False
self.timeout = -1.0
self.rdata = []
self.sdata = []
self.errors = {}
self.gsock = _VirtualGlobalSocket(self)
def _check_err(self, method):
method_error = self.errors.get(method)
if method_error:
raise method_error
def connect(self, address):
return self._connect(address, False)
def _connect(self, address, ret=True):
self.peer_address = address
self._connected = True
self._check_err('connect')
return self if ret else None
def settimeout(self, timeout):
self.timeout = timeout
def gettimeout(self):
return self.timeout
def getpeername(self):
if self.peer_address is None or not self._connected:
raise socket.error(57, 'Socket is not connected')
return self.peer_address
def getsockname(self):
return self.sock_address
def bind(self, address):
self.sock_address = address
def listen(self, backlog):
pass
def accept(self):
# pylint: disable=protected-access
conn = _VirtualSocket()
conn.sock_address = self.sock_address
conn.peer_address = ('127.0.0.1', 0)
conn._connected = True
return conn, conn.peer_address
def recv(self, bufsize, flags=0):
# pylint: disable=unused-argument
if not self._connected:
raise socket.error(54, 'Connection reset by peer')
if not len(self.rdata) > 0:
return b''
data = self.rdata.pop(0)
if isinstance(data, Exception):
raise data
return data
def send(self, data):
if self.peer_address is None or not self._connected:
raise socket.error(32, 'Broken pipe')
self._check_err('send')
self.sdata.append(data)
@pytest.fixture()
def virtual_socket(monkeypatch):
vsocket = _VirtualSocket()
gsock = vsocket.gsock
monkeypatch.setattr(socket, 'create_connection', gsock.create_connection)
monkeypatch.setattr(socket, 'socket', gsock.socket)
monkeypatch.setattr(socket, 'getaddrinfo', gsock.getaddrinfo)
return vsocket

1
test/docker/.ed25519.sk Normal file
View File

@ -0,0 +1 @@
<EFBFBD><EFBFBD><EFBFBD><1C><><EFBFBD>V<EFBFBD><EFBFBD>Z/D<><<3C><>|S<>z<EFBFBD>=<3D>:<3A>1vu}<7D><><11>J<EFBFBD>ݷ<EFBFBD><DDB7>"<22>^Bb&U<><03>P<EFBFBD><50>

32
test/docker/Dockerfile Normal file
View File

@ -0,0 +1,32 @@
FROM ubuntu:16.04
COPY openssh-4.0p1/sshd /openssh/sshd-4.0p1
COPY openssh-5.6p1/sshd /openssh/sshd-5.6p1
COPY openssh-8.0p1/sshd /openssh/sshd-8.0p1
COPY dropbear-2019.78/dropbear /dropbear/dropbear-2019.78
COPY tinyssh-20190101/build/bin/tinysshd /tinysshd/tinyssh-20190101
# Dropbear host keys.
COPY dropbear_*_host_key* /etc/dropbear/
# OpenSSH configs.
COPY sshd_config* /etc/ssh/
# OpenSSH host keys & moduli file.
COPY ssh_host_* /etc/ssh/
COPY ssh1_host_* /etc/ssh/
COPY moduli_1024 /usr/local/etc/moduli
# TinySSH host keys.
COPY ed25519.pk /etc/tinyssh/
COPY .ed25519.sk /etc/tinyssh/
COPY debug.sh /debug.sh
RUN apt update 2> /dev/null
RUN apt install -y libssl-dev strace rsyslog ucspi-tcp 2> /dev/null
RUN apt clean 2> /dev/null
RUN useradd -s /bin/false sshd
RUN mkdir /var/empty
EXPOSE 22

9
test/docker/debug.sh Executable file
View File

@ -0,0 +1,9 @@
#!/bin/bash
# This script is run on in docker container. It will enable logging for sshd in
# /var/log/auth.log.
/etc/init.d/rsyslog start
sleep 1
/openssh/sshd-5.6p1 -o LogLevel=DEBUG3 -f /etc/ssh/sshd_config-5.6p1_test1
/bin/bash

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

1
test/docker/ed25519.pk Normal file
View File

@ -0,0 +1 @@
1vu}<7D><><11>J<EFBFBD>ݷ<EFBFBD><DDB7>"<22>^Bb&U<><03>P<EFBFBD><50>

View File

@ -0,0 +1 @@
{"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"]}

View File

@ -0,0 +1,85 @@
# general
(gen) banner: SSH-2.0-dropbear_2019.78
(gen) software: Dropbear SSH 2019.78
(gen) compatibility: OpenSSH 7.4+ (some functionality from 6.6), Dropbear SSH 2018.76+
(gen) compression: enabled (zlib@openssh.com)
# key exchange algorithms
(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
(kex) ecdh-sha2-nistp521 -- [fail] using weak elliptic curves
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(kex) ecdh-sha2-nistp384 -- [fail] using weak elliptic curves
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(kex) ecdh-sha2-nistp256 -- [fail] using weak elliptic curves
`- [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-sha1 -- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
(kex) kexguess2@matt.ucc.asn.au -- [info] available since Dropbear SSH 2013.57
# host-key algorithms
(key) ecdsa-sha2-nistp256 -- [fail] using weak elliptic curves
 `- [warn] using weak random number generator could reveal the key
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(key) ssh-rsa (1024-bit) -- [fail] using small 1024-bit modulus
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
(key) ssh-dss -- [fail] removed (in server) and disabled (in client) since OpenSSH 7.0, weak algorithm
 `- [warn] using small 1024-bit modulus
 `- [warn] using weak random number generator could reveal the key
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
# encryption algorithms (ciphers)
(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) aes128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
(enc) aes256-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47
(enc) 3des-ctr -- [fail] using weak cipher
`- [info] available since Dropbear SSH 0.52
(enc) 3des-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.4, unsafe algorithm
 `- [warn] using weak cipher
 `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
# message authentication code algorithms
(mac) hmac-sha1-96 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.47
(mac) hmac-sha1 -- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
(mac) hmac-sha2-256 -- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56
# fingerprints
(fin) ssh-rsa: SHA256:CDfAU12pjQS7/91kg7gYacza0U/6PDbE04Ic3IpYxkM
# algorithm recommendations (for Dropbear SSH 2019.78)
(rec) !ssh-rsa -- key algorithm to change (increase modulus size to 2048 bits or larger) 
(rec) -3des-cbc -- enc algorithm to remove 
(rec) -3des-ctr -- enc algorithm to remove 
(rec) -aes128-cbc -- enc algorithm to remove 
(rec) -aes256-cbc -- enc algorithm to remove 
(rec) -ecdh-sha2-nistp256 -- kex algorithm to remove 
(rec) -ecdh-sha2-nistp384 -- kex algorithm to remove 
(rec) -ecdh-sha2-nistp521 -- kex algorithm to remove 
(rec) -ecdsa-sha2-nistp256 -- key algorithm to remove 
(rec) -hmac-sha1-96 -- mac algorithm to remove 
(rec) -ssh-dss -- key algorithm to remove 
(rec) +diffie-hellman-group16-sha512 -- kex algorithm to append 
(rec) +twofish128-ctr -- enc algorithm to append 
(rec) +twofish256-ctr -- enc algorithm to append 
(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove 
(rec) -hmac-sha1 -- mac algorithm to remove 
# additional info
(nfo) For hardening guides on common OSes, please see: <https://www.ssh-audit.com/hardening_guides.html>

View File

@ -0,0 +1 @@
{"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"]}

View File

@ -0,0 +1,139 @@
# general
(gen) banner: SSH-1.99-OpenSSH_4.0
(gen) protocol SSH1 enabled
(gen) software: OpenSSH 4.0
(gen) compatibility: OpenSSH 3.9-6.6, Dropbear SSH 0.53+ (some functionality from 0.52)
(gen) compression: enabled (zlib)
# security
(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-2012-0814 -- (CVSSv2: 3.5) leak data via debug messages
(cve) CVE-2011-5000 -- (CVSSv2: 3.5) cause DoS via large value in certain length field (memory consumption)
(cve) CVE-2010-5107 -- (CVSSv2: 5.0) cause DoS via large number of connections (slot exhaustion)
(cve) CVE-2010-4755 -- (CVSSv2: 4.0) cause DoS via crafted glob expression (CPU and memory consumption)
(cve) CVE-2010-4478 -- (CVSSv2: 7.5) bypass authentication check via crafted values
(cve) CVE-2008-5161 -- (CVSSv2: 2.6) recover plaintext data from ciphertext
(cve) CVE-2008-4109 -- (CVSSv2: 5.0) cause DoS via multiple login attempts (slot exhaustion)
(cve) CVE-2008-1657 -- (CVSSv2: 6.5) bypass command restrictions via modifying session file
(cve) CVE-2008-1483 -- (CVSSv2: 6.9) hijack forwarded X11 connections
(cve) CVE-2007-4752 -- (CVSSv2: 7.5) privilege escalation via causing an X client to be trusted
(cve) CVE-2007-2243 -- (CVSSv2: 5.0) discover valid usernames through different responses
(cve) CVE-2006-5052 -- (CVSSv2: 5.0) discover valid usernames through different responses
(cve) CVE-2006-5051 -- (CVSSv2: 9.3) cause DoS or execute arbitrary code (double free)
(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-2005-2798 -- (CVSSv2: 5.0) leak data about authentication credentials
# key exchange algorithms
(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
(kex) diffie-hellman-group14-sha1 -- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
(kex) diffie-hellman-group1-sha1 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [fail] disabled (in client) since OpenSSH 7.0, logjam attack
 `- [warn] using small 1024-bit modulus
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
# host-key algorithms
(key) ssh-rsa (1024-bit) -- [fail] using small 1024-bit modulus
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
(key) ssh-dss -- [fail] removed (in server) and disabled (in client) since OpenSSH 7.0, weak algorithm
 `- [warn] using small 1024-bit modulus
 `- [warn] using weak random number generator could reveal the key
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
# encryption algorithms (ciphers)
(enc) aes128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
(enc) 3des-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.4, unsafe algorithm
 `- [warn] using weak cipher
 `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
(enc) blowfish-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [fail] disabled since Dropbear SSH 0.53
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
(enc) cast128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 2.1.0
(enc) arcfour -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher
`- [info] available since OpenSSH 2.1.0
(enc) aes192-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0
(enc) aes256-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] using weak cipher mode
`- [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
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0
(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) aes192-ctr -- [info] available since OpenSSH 3.7
(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
# message authentication code algorithms
(mac) hmac-md5 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
(mac) hmac-sha1 -- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
(mac) hmac-ripemd160 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 2.5.0
(mac) hmac-ripemd160@openssh.com -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 2.1.0
(mac) hmac-sha1-96 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [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
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.5.0
# fingerprints
(fin) ssh-rsa: SHA256:YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4
# algorithm recommendations (for OpenSSH 4.0)
(rec) !ssh-rsa -- key algorithm to change (increase modulus size to 2048 bits or larger) 
(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) -blowfish-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-group1-sha1 -- kex algorithm to remove 
(rec) -hmac-md5 -- mac algorithm to remove 
(rec) -hmac-md5-96 -- mac algorithm to remove 
(rec) -hmac-ripemd160 -- mac algorithm to remove 
(rec) -hmac-ripemd160@openssh.com -- mac algorithm to remove 
(rec) -hmac-sha1-96 -- mac algorithm to remove 
(rec) -rijndael-cbc@lysator.liu.se -- enc algorithm to remove 
(rec) -ssh-dss -- key algorithm to remove 
# additional info
(nfo) For hardening guides on common OSes, please see: <https://www.ssh-audit.com/hardening_guides.html>

View File

@ -0,0 +1 @@
{"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"]}

View File

@ -0,0 +1,148 @@
# general
(gen) banner: SSH-2.0-OpenSSH_5.6
(gen) software: OpenSSH 5.6
(gen) compatibility: OpenSSH 4.7-6.6, Dropbear SSH 0.53+ (some functionality from 0.52)
(gen) compression: enabled (zlib@openssh.com)
# security
(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-2015-6564 -- (CVSSv2: 6.9) privilege escalation via leveraging sshd uid
(cve) CVE-2015-6563 -- (CVSSv2: 1.9) conduct impersonation attack
(cve) CVE-2014-2532 -- (CVSSv2: 5.8) bypass environment restrictions via specific string before wildcard
(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-2011-5000 -- (CVSSv2: 3.5) cause DoS via large value in certain length field (memory consumption)
(cve) CVE-2010-5107 -- (CVSSv2: 5.0) cause DoS via large number of connections (slot exhaustion)
(cve) CVE-2010-4755 -- (CVSSv2: 4.0) cause DoS via crafted glob expression (CPU and memory consumption)
(cve) CVE-2010-4478 -- (CVSSv2: 7.5) bypass authentication check via crafted values
# key exchange algorithms
(kex) diffie-hellman-group-exchange-sha256 (1024-bit) -- [fail] using small 1024-bit modulus
`- [info] available since OpenSSH 4.4
(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
(kex) diffie-hellman-group14-sha1 -- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
(kex) diffie-hellman-group1-sha1 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [fail] disabled (in client) since OpenSSH 7.0, logjam attack
 `- [warn] using small 1024-bit modulus
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
# host-key algorithms
(key) ssh-rsa (1024-bit) -- [fail] using small 1024-bit modulus
`- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
(key) ssh-dss -- [fail] removed (in server) and disabled (in client) since OpenSSH 7.0, weak algorithm
 `- [warn] using small 1024-bit modulus
 `- [warn] using weak random number generator could reveal the key
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
# encryption algorithms (ciphers)
(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) aes192-ctr -- [info] available since OpenSSH 3.7
(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
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher
`- [info] available since OpenSSH 4.2
(enc) arcfour128 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher
`- [info] available since OpenSSH 4.2
(enc) aes128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
(enc) 3des-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.4, unsafe algorithm
 `- [warn] using weak cipher
 `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
(enc) blowfish-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [fail] disabled since Dropbear SSH 0.53
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
(enc) cast128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 2.1.0
(enc) aes192-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0
(enc) aes256-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47
(enc) arcfour -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher
`- [info] available since OpenSSH 2.1.0
(enc) rijndael-cbc@lysator.liu.se -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0
# message authentication code algorithms
(mac) hmac-md5 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
(mac) hmac-sha1 -- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
(mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode
 `- [warn] using small 64-bit tag size
`- [info] available since OpenSSH 4.7
(mac) hmac-ripemd160 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 2.5.0
(mac) hmac-ripemd160@openssh.com -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 2.1.0
(mac) hmac-sha1-96 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [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
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.5.0
# fingerprints
(fin) ssh-rsa: SHA256:YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4
# 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) !ssh-rsa -- key algorithm to change (increase modulus size to 2048 bits or larger) 
(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) -arcfour128 -- enc algorithm to remove 
(rec) -arcfour256 -- enc algorithm to remove 
(rec) -blowfish-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-group1-sha1 -- kex algorithm to remove 
(rec) -hmac-md5 -- mac algorithm to remove 
(rec) -hmac-md5-96 -- mac algorithm to remove 
(rec) -hmac-ripemd160 -- mac algorithm to remove 
(rec) -hmac-ripemd160@openssh.com -- mac algorithm to remove 
(rec) -hmac-sha1-96 -- mac algorithm to remove 
(rec) -rijndael-cbc@lysator.liu.se -- enc algorithm to remove 
(rec) -ssh-dss -- key algorithm to remove 
(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove 
# additional info
(nfo) For hardening guides on common OSes, please see: <https://www.ssh-audit.com/hardening_guides.html>

View File

@ -0,0 +1 @@
{"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"]}

View File

@ -0,0 +1,146 @@
# general
(gen) banner: SSH-2.0-OpenSSH_5.6
(gen) software: OpenSSH 5.6
(gen) compatibility: OpenSSH 5.6-6.6, Dropbear SSH 0.53+ (some functionality from 0.52)
(gen) compression: enabled (zlib@openssh.com)
# security
(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-2015-6564 -- (CVSSv2: 6.9) privilege escalation via leveraging sshd uid
(cve) CVE-2015-6563 -- (CVSSv2: 1.9) conduct impersonation attack
(cve) CVE-2014-2532 -- (CVSSv2: 5.8) bypass environment restrictions via specific string before wildcard
(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-2011-5000 -- (CVSSv2: 3.5) cause DoS via large value in certain length field (memory consumption)
(cve) CVE-2010-5107 -- (CVSSv2: 5.0) cause DoS via large number of connections (slot exhaustion)
(cve) CVE-2010-4755 -- (CVSSv2: 4.0) cause DoS via crafted glob expression (CPU and memory consumption)
(cve) CVE-2010-4478 -- (CVSSv2: 7.5) bypass authentication check via crafted values
# key exchange algorithms
(kex) diffie-hellman-group-exchange-sha256 (1024-bit) -- [fail] using small 1024-bit modulus
`- [info] available since OpenSSH 4.4
(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
(kex) diffie-hellman-group14-sha1 -- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
(kex) diffie-hellman-group1-sha1 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [fail] disabled (in client) since OpenSSH 7.0, logjam attack
 `- [warn] using small 1024-bit modulus
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
# host-key algorithms
(key) ssh-rsa (1024-bit) -- [fail] using small 1024-bit modulus
`- [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 small 1024-bit modulus
`- [info] available since OpenSSH 5.6
# encryption algorithms (ciphers)
(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) aes192-ctr -- [info] available since OpenSSH 3.7
(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
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher
`- [info] available since OpenSSH 4.2
(enc) arcfour128 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher
`- [info] available since OpenSSH 4.2
(enc) aes128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
(enc) 3des-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.4, unsafe algorithm
 `- [warn] using weak cipher
 `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
(enc) blowfish-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [fail] disabled since Dropbear SSH 0.53
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
(enc) cast128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 2.1.0
(enc) aes192-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0
(enc) aes256-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47
(enc) arcfour -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher
`- [info] available since OpenSSH 2.1.0
(enc) rijndael-cbc@lysator.liu.se -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0
# message authentication code algorithms
(mac) hmac-md5 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
(mac) hmac-sha1 -- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
(mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode
 `- [warn] using small 64-bit tag size
`- [info] available since OpenSSH 4.7
(mac) hmac-ripemd160 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 2.5.0
(mac) hmac-ripemd160@openssh.com -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 2.1.0
(mac) hmac-sha1-96 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [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
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.5.0
# fingerprints
(fin) ssh-rsa: SHA256:YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4
# 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) !ssh-rsa -- key algorithm to change (increase modulus size to 2048 bits or larger) 
(rec) !ssh-rsa-cert-v01@openssh.com -- key algorithm to change (increase modulus size to 2048 bits or larger) 
(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) -arcfour128 -- enc algorithm to remove 
(rec) -arcfour256 -- enc algorithm to remove 
(rec) -blowfish-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-group1-sha1 -- kex algorithm to remove 
(rec) -hmac-md5 -- mac algorithm to remove 
(rec) -hmac-md5-96 -- mac algorithm to remove 
(rec) -hmac-ripemd160 -- mac algorithm to remove 
(rec) -hmac-ripemd160@openssh.com -- mac algorithm to remove 
(rec) -hmac-sha1-96 -- mac algorithm to remove 
(rec) -rijndael-cbc@lysator.liu.se -- enc algorithm to remove 
(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove 
# additional info
(nfo) For hardening guides on common OSes, please see: <https://www.ssh-audit.com/hardening_guides.html>

View File

@ -0,0 +1 @@
{"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"]}

View File

@ -0,0 +1,146 @@
# general
(gen) banner: SSH-2.0-OpenSSH_5.6
(gen) software: OpenSSH 5.6
(gen) compatibility: OpenSSH 5.6-6.6, Dropbear SSH 0.53+ (some functionality from 0.52)
(gen) compression: enabled (zlib@openssh.com)
# security
(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-2015-6564 -- (CVSSv2: 6.9) privilege escalation via leveraging sshd uid
(cve) CVE-2015-6563 -- (CVSSv2: 1.9) conduct impersonation attack
(cve) CVE-2014-2532 -- (CVSSv2: 5.8) bypass environment restrictions via specific string before wildcard
(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-2011-5000 -- (CVSSv2: 3.5) cause DoS via large value in certain length field (memory consumption)
(cve) CVE-2010-5107 -- (CVSSv2: 5.0) cause DoS via large number of connections (slot exhaustion)
(cve) CVE-2010-4755 -- (CVSSv2: 4.0) cause DoS via crafted glob expression (CPU and memory consumption)
(cve) CVE-2010-4478 -- (CVSSv2: 7.5) bypass authentication check via crafted values
# key exchange algorithms
(kex) diffie-hellman-group-exchange-sha256 (1024-bit) -- [fail] using small 1024-bit modulus
`- [info] available since OpenSSH 4.4
(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
(kex) diffie-hellman-group14-sha1 -- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
(kex) diffie-hellman-group1-sha1 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [fail] disabled (in client) since OpenSSH 7.0, logjam attack
 `- [warn] using small 1024-bit modulus
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
# host-key algorithms
(key) ssh-rsa (1024-bit) -- [fail] using small 1024-bit modulus
`- [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 small 1024-bit modulus
`- [info] available since OpenSSH 5.6
# encryption algorithms (ciphers)
(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) aes192-ctr -- [info] available since OpenSSH 3.7
(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
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher
`- [info] available since OpenSSH 4.2
(enc) arcfour128 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher
`- [info] available since OpenSSH 4.2
(enc) aes128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
(enc) 3des-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.4, unsafe algorithm
 `- [warn] using weak cipher
 `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
(enc) blowfish-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [fail] disabled since Dropbear SSH 0.53
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
(enc) cast128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 2.1.0
(enc) aes192-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0
(enc) aes256-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47
(enc) arcfour -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher
`- [info] available since OpenSSH 2.1.0
(enc) rijndael-cbc@lysator.liu.se -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0
# message authentication code algorithms
(mac) hmac-md5 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
(mac) hmac-sha1 -- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
(mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode
 `- [warn] using small 64-bit tag size
`- [info] available since OpenSSH 4.7
(mac) hmac-ripemd160 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 2.5.0
(mac) hmac-ripemd160@openssh.com -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 2.1.0
(mac) hmac-sha1-96 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [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
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.5.0
# fingerprints
(fin) ssh-rsa: SHA256:YZ457EBcJTSxRKI3yXRgtAj3PBf5B9/F36b1SVooml4
# 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) !ssh-rsa -- key algorithm to change (increase modulus size to 2048 bits or larger) 
(rec) !ssh-rsa-cert-v01@openssh.com -- key algorithm to change (increase modulus size to 2048 bits or larger) 
(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) -arcfour128 -- enc algorithm to remove 
(rec) -arcfour256 -- enc algorithm to remove 
(rec) -blowfish-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-group1-sha1 -- kex algorithm to remove 
(rec) -hmac-md5 -- mac algorithm to remove 
(rec) -hmac-md5-96 -- mac algorithm to remove 
(rec) -hmac-ripemd160 -- mac algorithm to remove 
(rec) -hmac-ripemd160@openssh.com -- mac algorithm to remove 
(rec) -hmac-sha1-96 -- mac algorithm to remove 
(rec) -rijndael-cbc@lysator.liu.se -- enc algorithm to remove 
(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove 
# additional info
(nfo) For hardening guides on common OSes, please see: <https://www.ssh-audit.com/hardening_guides.html>

View File

@ -0,0 +1 @@
{"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"]}

View File

@ -0,0 +1,144 @@
# general
(gen) banner: SSH-2.0-OpenSSH_5.6
(gen) software: OpenSSH 5.6
(gen) compatibility: OpenSSH 5.6-6.6, Dropbear SSH 0.53+ (some functionality from 0.52)
(gen) compression: enabled (zlib@openssh.com)
# security
(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-2015-6564 -- (CVSSv2: 6.9) privilege escalation via leveraging sshd uid
(cve) CVE-2015-6563 -- (CVSSv2: 1.9) conduct impersonation attack
(cve) CVE-2014-2532 -- (CVSSv2: 5.8) bypass environment restrictions via specific string before wildcard
(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-2011-5000 -- (CVSSv2: 3.5) cause DoS via large value in certain length field (memory consumption)
(cve) CVE-2010-5107 -- (CVSSv2: 5.0) cause DoS via large number of connections (slot exhaustion)
(cve) CVE-2010-4755 -- (CVSSv2: 4.0) cause DoS via crafted glob expression (CPU and memory consumption)
(cve) CVE-2010-4478 -- (CVSSv2: 7.5) bypass authentication check via crafted values
# key exchange algorithms
(kex) diffie-hellman-group-exchange-sha256 (1024-bit) -- [fail] using small 1024-bit modulus
`- [info] available since OpenSSH 4.4
(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
(kex) diffie-hellman-group14-sha1 -- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
(kex) diffie-hellman-group1-sha1 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [fail] disabled (in client) since OpenSSH 7.0, logjam attack
 `- [warn] using small 1024-bit modulus
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
# host-key algorithms
(key) ssh-rsa (3072-bit) -- [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 small 1024-bit modulus
`- [info] available since OpenSSH 5.6
# encryption algorithms (ciphers)
(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) aes192-ctr -- [info] available since OpenSSH 3.7
(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
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher
`- [info] available since OpenSSH 4.2
(enc) arcfour128 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher
`- [info] available since OpenSSH 4.2
(enc) aes128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
(enc) 3des-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.4, unsafe algorithm
 `- [warn] using weak cipher
 `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
(enc) blowfish-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [fail] disabled since Dropbear SSH 0.53
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
(enc) cast128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 2.1.0
(enc) aes192-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0
(enc) aes256-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47
(enc) arcfour -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher
`- [info] available since OpenSSH 2.1.0
(enc) rijndael-cbc@lysator.liu.se -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0
# message authentication code algorithms
(mac) hmac-md5 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
(mac) hmac-sha1 -- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
(mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode
 `- [warn] using small 64-bit tag size
`- [info] available since OpenSSH 4.7
(mac) hmac-ripemd160 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 2.5.0
(mac) hmac-ripemd160@openssh.com -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 2.1.0
(mac) hmac-sha1-96 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [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
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.5.0
# fingerprints
(fin) ssh-rsa: SHA256:nsWtdJ9Z67Vrf7OsUzQov7esXhsWAfVppArGh25u244
# 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) !ssh-rsa-cert-v01@openssh.com -- key algorithm to change (increase modulus size to 2048 bits or larger) 
(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) -arcfour128 -- enc algorithm to remove 
(rec) -arcfour256 -- enc algorithm to remove 
(rec) -blowfish-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-group1-sha1 -- kex algorithm to remove 
(rec) -hmac-md5 -- mac algorithm to remove 
(rec) -hmac-md5-96 -- mac algorithm to remove 
(rec) -hmac-ripemd160 -- mac algorithm to remove 
(rec) -hmac-ripemd160@openssh.com -- mac algorithm to remove 
(rec) -hmac-sha1-96 -- mac algorithm to remove 
(rec) -rijndael-cbc@lysator.liu.se -- enc algorithm to remove 
(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove 
# additional info
(nfo) For hardening guides on common OSes, please see: <https://www.ssh-audit.com/hardening_guides.html>

View File

@ -0,0 +1 @@
{"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"]}

View File

@ -0,0 +1,142 @@
# general
(gen) banner: SSH-2.0-OpenSSH_5.6
(gen) software: OpenSSH 5.6
(gen) compatibility: OpenSSH 5.6-6.6, Dropbear SSH 0.53+ (some functionality from 0.52)
(gen) compression: enabled (zlib@openssh.com)
# security
(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-2015-6564 -- (CVSSv2: 6.9) privilege escalation via leveraging sshd uid
(cve) CVE-2015-6563 -- (CVSSv2: 1.9) conduct impersonation attack
(cve) CVE-2014-2532 -- (CVSSv2: 5.8) bypass environment restrictions via specific string before wildcard
(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-2011-5000 -- (CVSSv2: 3.5) cause DoS via large value in certain length field (memory consumption)
(cve) CVE-2010-5107 -- (CVSSv2: 5.0) cause DoS via large number of connections (slot exhaustion)
(cve) CVE-2010-4755 -- (CVSSv2: 4.0) cause DoS via crafted glob expression (CPU and memory consumption)
(cve) CVE-2010-4478 -- (CVSSv2: 7.5) bypass authentication check via crafted values
# key exchange algorithms
(kex) diffie-hellman-group-exchange-sha256 (1024-bit) -- [fail] using small 1024-bit modulus
`- [info] available since OpenSSH 4.4
(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
(kex) diffie-hellman-group14-sha1 -- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
(kex) diffie-hellman-group1-sha1 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [fail] disabled (in client) since OpenSSH 7.0, logjam attack
 `- [warn] using small 1024-bit modulus
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
# host-key algorithms
(key) ssh-rsa (3072-bit) -- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
(key) ssh-rsa-cert-v01@openssh.com (3072-bit cert/3072-bit CA) -- [info] available since OpenSSH 5.6
# encryption algorithms (ciphers)
(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) aes192-ctr -- [info] available since OpenSSH 3.7
(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
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher
`- [info] available since OpenSSH 4.2
(enc) arcfour128 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher
`- [info] available since OpenSSH 4.2
(enc) aes128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.28
(enc) 3des-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.4, unsafe algorithm
 `- [warn] using weak cipher
 `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
(enc) blowfish-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [fail] disabled since Dropbear SSH 0.53
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 1.2.2, Dropbear SSH 0.28
(enc) cast128-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode
 `- [warn] using small 64-bit block size
`- [info] available since OpenSSH 2.1.0
(enc) aes192-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0
(enc) aes256-cbc -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0, Dropbear SSH 0.47
(enc) arcfour -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher
`- [info] available since OpenSSH 2.1.0
(enc) rijndael-cbc@lysator.liu.se -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using weak cipher mode
`- [info] available since OpenSSH 2.3.0
# message authentication code algorithms
(mac) hmac-md5 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
(mac) hmac-sha1 -- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
(mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode
 `- [warn] using small 64-bit tag size
`- [info] available since OpenSSH 4.7
(mac) hmac-ripemd160 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 2.5.0
(mac) hmac-ripemd160@openssh.com -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 2.1.0
(mac) hmac-sha1-96 -- [fail] removed (in server) since OpenSSH 6.7, unsafe algorithm
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [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
 `- [warn] disabled (in client) since OpenSSH 7.2, legacy algorithm
 `- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.5.0
# fingerprints
(fin) ssh-rsa: SHA256:nsWtdJ9Z67Vrf7OsUzQov7esXhsWAfVppArGh25u244
# 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) -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) -arcfour128 -- enc algorithm to remove 
(rec) -arcfour256 -- enc algorithm to remove 
(rec) -blowfish-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-group1-sha1 -- kex algorithm to remove 
(rec) -hmac-md5 -- mac algorithm to remove 
(rec) -hmac-md5-96 -- mac algorithm to remove 
(rec) -hmac-ripemd160 -- mac algorithm to remove 
(rec) -hmac-ripemd160@openssh.com -- mac algorithm to remove 
(rec) -hmac-sha1-96 -- mac algorithm to remove 
(rec) -rijndael-cbc@lysator.liu.se -- enc algorithm to remove 
(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove 
# additional info
(nfo) For hardening guides on common OSes, please see: <https://www.ssh-audit.com/hardening_guides.html>

View File

@ -0,0 +1 @@
{"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"]}

View File

@ -0,0 +1,82 @@
# general
(gen) banner: SSH-2.0-OpenSSH_8.0
(gen) software: OpenSSH 8.0
(gen) compatibility: OpenSSH 7.4+, Dropbear SSH 2018.76+
(gen) compression: enabled (zlib@openssh.com)
# key exchange algorithms
(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
(kex) ecdh-sha2-nistp256 -- [fail] using weak elliptic curves
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(kex) ecdh-sha2-nistp384 -- [fail] using weak elliptic curves
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(kex) ecdh-sha2-nistp521 -- [fail] using weak elliptic curves
`- [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-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-group14-sha256 -- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73
(kex) diffie-hellman-group14-sha1 -- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
# host-key algorithms
(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) ssh-rsa (3072-bit) -- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
(key) ecdsa-sha2-nistp256 -- [fail] using weak elliptic curves
 `- [warn] using weak random number generator could reveal the key
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(key) ssh-ed25519 -- [info] available since OpenSSH 6.5
# encryption algorithms (ciphers)
(enc) chacha20-poly1305@openssh.com -- [info] available since OpenSSH 6.5
`- [info] default cipher since OpenSSH 6.9.
(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) aes192-ctr -- [info] available since OpenSSH 3.7
(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) aes128-gcm@openssh.com -- [info] available since OpenSSH 6.2
(enc) aes256-gcm@openssh.com -- [info] available since OpenSSH 6.2
# message authentication code algorithms
(mac) umac-64-etm@openssh.com -- [warn] using small 64-bit tag size
`- [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-512-etm@openssh.com -- [info] available since OpenSSH 6.2
(mac) hmac-sha1-etm@openssh.com -- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 6.2
(mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode
 `- [warn] using small 64-bit tag size
`- [info] available since OpenSSH 4.7
(mac) umac-128@openssh.com -- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 6.2
(mac) hmac-sha2-256 -- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56
(mac) hmac-sha2-512 -- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56
(mac) hmac-sha1 -- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
# fingerprints
(fin) ssh-ed25519: SHA256:UrnXIVH+7dlw8UqYocl48yUEcKrthGDQG2CPCgp7MxU
(fin) ssh-rsa: SHA256:nsWtdJ9Z67Vrf7OsUzQov7esXhsWAfVppArGh25u244
# algorithm recommendations (for OpenSSH 8.0)
(rec) -ecdh-sha2-nistp256 -- kex algorithm to remove 
(rec) -ecdh-sha2-nistp384 -- kex algorithm to remove 
(rec) -ecdh-sha2-nistp521 -- kex algorithm to remove 
(rec) -ecdsa-sha2-nistp256 -- key algorithm to remove 
(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove 
(rec) -hmac-sha1 -- mac algorithm to remove 
(rec) -hmac-sha1-etm@openssh.com -- mac algorithm to remove 
(rec) -hmac-sha2-256 -- mac algorithm to remove 
(rec) -hmac-sha2-512 -- mac algorithm to remove 
(rec) -umac-128@openssh.com -- mac algorithm to remove 
(rec) -umac-64-etm@openssh.com -- mac algorithm to remove 
(rec) -umac-64@openssh.com -- mac algorithm to remove 
# additional info
(nfo) For hardening guides on common OSes, please see: <https://www.ssh-audit.com/hardening_guides.html>

View File

@ -0,0 +1 @@
{"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"]}

View File

@ -0,0 +1,78 @@
# general
(gen) banner: SSH-2.0-OpenSSH_8.0
(gen) software: OpenSSH 8.0
(gen) compatibility: OpenSSH 7.4+, Dropbear SSH 2018.76+
(gen) compression: enabled (zlib@openssh.com)
# key exchange algorithms
(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
(kex) ecdh-sha2-nistp256 -- [fail] using weak elliptic curves
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(kex) ecdh-sha2-nistp384 -- [fail] using weak elliptic curves
`- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(kex) ecdh-sha2-nistp521 -- [fail] using weak elliptic curves
`- [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-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-group14-sha256 -- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73
(kex) diffie-hellman-group14-sha1 -- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 3.9, Dropbear SSH 0.53
# host-key algorithms
(key) ssh-ed25519 -- [info] available since OpenSSH 6.5
(key) ssh-ed25519-cert-v01@openssh.com -- [info] available since OpenSSH 6.5
# encryption algorithms (ciphers)
(enc) chacha20-poly1305@openssh.com -- [info] available since OpenSSH 6.5
`- [info] default cipher since OpenSSH 6.9.
(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) aes192-ctr -- [info] available since OpenSSH 3.7
(enc) aes256-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) aes128-gcm@openssh.com -- [info] available since OpenSSH 6.2
(enc) aes256-gcm@openssh.com -- [info] available since OpenSSH 6.2
# message authentication code algorithms
(mac) umac-64-etm@openssh.com -- [warn] using small 64-bit tag size
`- [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-512-etm@openssh.com -- [info] available since OpenSSH 6.2
(mac) hmac-sha1-etm@openssh.com -- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 6.2
(mac) umac-64@openssh.com -- [warn] using encrypt-and-MAC mode
 `- [warn] using small 64-bit tag size
`- [info] available since OpenSSH 4.7
(mac) umac-128@openssh.com -- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 6.2
(mac) hmac-sha2-256 -- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56
(mac) hmac-sha2-512 -- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56
(mac) hmac-sha1 -- [warn] using encrypt-and-MAC mode
 `- [warn] using weak hashing algorithm
`- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28
# fingerprints
(fin) ssh-ed25519: SHA256:UrnXIVH+7dlw8UqYocl48yUEcKrthGDQG2CPCgp7MxU
# algorithm recommendations (for OpenSSH 8.0)
(rec) -ecdh-sha2-nistp256 -- kex algorithm to remove 
(rec) -ecdh-sha2-nistp384 -- kex algorithm to remove 
(rec) -ecdh-sha2-nistp521 -- kex algorithm to remove 
(rec) +rsa-sha2-256 -- key algorithm to append 
(rec) +rsa-sha2-512 -- key algorithm to append 
(rec) +ssh-rsa -- key algorithm to append 
(rec) -diffie-hellman-group14-sha1 -- kex algorithm to remove 
(rec) -hmac-sha1 -- mac algorithm to remove 
(rec) -hmac-sha1-etm@openssh.com -- mac algorithm to remove 
(rec) -hmac-sha2-256 -- mac algorithm to remove 
(rec) -hmac-sha2-512 -- mac algorithm to remove 
(rec) -umac-128@openssh.com -- mac algorithm to remove 
(rec) -umac-64-etm@openssh.com -- mac algorithm to remove 
(rec) -umac-64@openssh.com -- mac algorithm to remove 
# additional info
(nfo) For hardening guides on common OSes, please see: <https://www.ssh-audit.com/hardening_guides.html>

View File

@ -0,0 +1 @@
{"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"]}

View File

@ -0,0 +1,39 @@
# general
(gen) banner: SSH-2.0-OpenSSH_8.0
(gen) software: OpenSSH 8.0
(gen) compatibility: OpenSSH 7.4+, Dropbear SSH 2018.76+
(gen) compression: enabled (zlib@openssh.com)
# key exchange algorithms
(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
(kex) diffie-hellman-group-exchange-sha256 (2048-bit) -- [info] available since OpenSSH 4.4
# host-key algorithms
(key) ssh-ed25519 -- [info] available since OpenSSH 6.5
# encryption algorithms (ciphers)
(enc) chacha20-poly1305@openssh.com -- [info] available since OpenSSH 6.5
`- [info] default cipher since OpenSSH 6.9.
(enc) aes256-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) aes192-ctr -- [info] available since OpenSSH 3.7
(enc) aes128-ctr -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
# message authentication code algorithms
(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) umac-128-etm@openssh.com -- [info] available since OpenSSH 6.2
# fingerprints
(fin) ssh-ed25519: SHA256:UrnXIVH+7dlw8UqYocl48yUEcKrthGDQG2CPCgp7MxU
# 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-group18-sha512 -- kex algorithm to append 
(rec) +rsa-sha2-256 -- key algorithm to append 
(rec) +rsa-sha2-512 -- key algorithm to append 
(rec) +ssh-rsa -- key algorithm to append 

View File

@ -0,0 +1 @@
{"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"]}

View File

@ -0,0 +1,25 @@
# general
(gen) software: TinySSH noversion
(gen) compatibility: OpenSSH 8.0+, Dropbear SSH 2018.76+
(gen) compression: disabled
# key exchange algorithms
(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
(kex) sntrup4591761x25519-sha512@tinyssh.org -- [warn] using experimental algorithm
`- [info] available since OpenSSH 8.0
# host-key algorithms
(key) ssh-ed25519 -- [info] available since OpenSSH 6.5
# encryption algorithms (ciphers)
(enc) chacha20-poly1305@openssh.com -- [info] available since OpenSSH 6.5
`- [info] default cipher since OpenSSH 6.9.
# message authentication code algorithms
(mac) hmac-sha2-256 -- [warn] using encrypt-and-MAC mode
`- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56
# fingerprints
(fin) ssh-ed25519: SHA256:89ocln1x7KNqnMgWffGoYtD70ksJ4FrH7BMJHa7SrwU

View File

@ -0,0 +1,7 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACAbM9Wp3ZPcC8Ifhu6GjNDJaoMg7KxO0el2+r9J35TltQAAAKAa0zr8GtM6
/AAAAAtzc2gtZWQyNTUxOQAAACAbM9Wp3ZPcC8Ifhu6GjNDJaoMg7KxO0el2+r9J35TltQ
AAAEC/j/BpfmgaZqNMTkJXO4cKZBr31N5z33IRFjh5m6IDDhsz1andk9wLwh+G7oaM0Mlq
gyDsrE7R6Xb6v0nflOW1AAAAHWpkb2dAbG9jYWxob3N0LndvbmRlcmxhbmQubG9s
-----END OPENSSH PRIVATE KEY-----

View File

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBsz1andk9wLwh+G7oaM0MlqgyDsrE7R6Xb6v0nflOW1 jdog@localhost.wonderland.lol

View File

@ -0,0 +1,15 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQDnRlN3AFnUe2lFf5XG9UhXLr/9POruNTFbMt0zrjOUSjmAS7hS
6pDv5VEToT6DaR1EQUYaqSMpHYzZhuCK52vrydOm5XFbJ7712r9MyZQUhoVZx8Su
dBHzVDIVO3jcMMWIlrfWBMnUaUHEqpmy88Y7gKDa2TWxJg1+hg51KqHrUQIDAQAB
AoGBANALOUXRcP1tTtOP4+In/709dsONKyDBhPavGMFGsWtyIavBcbxU+bBzrq1j
3WJFCmi99xxAjjqMNInxhMgvSaoJtsiY0/FFxqRy6l/ZnRjI6hrVKR8whrPKVgBF
pvbjeQIn9txeCYA8kwl/Si762u7byq+qvupE53xMP94J02KBAkEA/Q4+Hn1Rjblw
VXynF+oXIq6iZy+8PW+Y/FIL8d31ehzfcssCMdFV6S3/wBoQkWby30oGC/xGmHGR
6ffXGilByQJBAOn3NMrBPXNkaPeQtgV3tk4s1dRDQYhbqGNz6tcgThyyPdhJCmCy
jgUEhLwAetsDI8/+3avWbo6/csOV+BvpYUkCQQDQyEp6L1z0+FV1QqY99dZmt/yn
89t0OLnZG/xc7osU1/OHq3TBE3y1KU2D+j1HKdAiZ9l7VAYOykzf46qmG/n5AkEA
2kWjfcjcIIw7lULvXZh6fuI7NwTr3V/Nb8MUA1EDLqhnJCG4SdAqyKmXf6Fe/HYo
cgKPIaIykIAxfCCsULXg6QJAOxB0CKYJlopVBdjGMlGqOEneWTmb1A2INQDE2Una
LkSd0Rr8OiEzDeemV7j3Ec4BH0HxGMnHDxMybZwoZRnRPw==
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDnRlN3AFnUe2lFf5XG9UhXLr/9POruNTFbMt0zrjOUSjmAS7hS6pDv5VEToT6DaR1EQUYaqSMpHYzZhuCK52vrydOm5XFbJ7712r9MyZQUhoVZx8SudBHzVDIVO3jcMMWIlrfWBMnUaUHEqpmy88Y7gKDa2TWxJg1+hg51KqHrUQ== jdog@localhost.wonderland.lol

View File

@ -0,0 +1,39 @@
-----BEGIN RSA PRIVATE KEY-----
MIIG4wIBAAKCAYEAqxQEIbj8w0TrBY1fDO81curijQrdLOUr8Vl8XECWc5QGd1Lk
AG80NgdcCBPvjWxZSmYrKeqA78GUdN+KgycE0ztpxYSXKHZMaIM5Xe94BB+BocH9
1vd/2iBzGeed1nV/zfAdq2AEHQj1TpII+a+z25yxv2PuwVTTwwo9I/6JgNq3evH4
Hbwgr3SRfEEYZQ+YL8cOpBuNg1YZOR0k1yk23ZqAd92JybxZ4iCtOt7rcj2sFHzN
u1U544wWBwIL5yZZKTgBhY4dqfT2Ep7IzR5HdsdrvQV9qC92GM1zDE+U3AwrVKjH
s0YZq3jzcq/yvFDCcMMRz4/0pGFFU26oWma+n3vbAxKJoL+rhG8QM9+l2qFlLGsn
M0kUXAJXsPKbygpaP8Z3U4eKgTuJ2GuS9eLIFnB7mrwD75V6GgN9q5mY89DfkVSk
HaoqpY8pPdRkz9QAmMEuLtHmv29CVOpfX5v/rsm7wASAZqtUlmFu4rFGBLwvZbUl
Wu02HmgBT47g6EIfAgMBAAECggGAKVCdKtO03yd+pomcodAHFWiaK7uq7FOwCAo3
WUQT0Xe3FAwFmgFBF6cxV5YQ7RN0gN4poGbMmpoiUxNFLSU4KhcYFSZPJutiyn6e
VQwm7L/7G2hw+AAvdSsPAPuJh6g6pC5Py/pVI/ns2/uyhTIkem3eEz18BF6LAXgw
icfHx0GKu/tBk1TCg/zfwaUq0gUxGKC27XTl+QjK8JsUMY33fQ755Xiv9PMytcR0
cVoyfBVewFffi1UqtMQ48ZpR65G743RxrP4/wcwsfD7n5LJLdyxQkh3gIMTJ8dd/
R5V4FlueorRgjTbLTjGDxNrCAJ+locezhEEPXsPh2q0KiIXGyz2AMxaOqFmhU8oK
aVVt8pWJ+YsrKIgc/A3s18ezO8uO5ZdtjQ+CWguduUGY7YgWezGLO1LPxhJC4d7b
Q/xpeKveTRlcScAqOUzKgSuEhcvPgj8paUcRUoiXm4qiJBY5sXJks+YGp8BGksH0
O94no+Ns2G58MlL+RyXk3JWrc6zRAoHBANdPplY2sIuIiiEBu95f1Qar1nCBHhB2
i+HpnsUOdSlbxwMxoF8ffeN9N+DQqaqPu1RhFa5xbB2EUSujvOnL7b/RWqe1X9Po
UIt5UjXctNP/HYcQDyjXY+rV5SZhHDyv6TBYurNZlvlBivliDz82THPRtqVxed3B
w2MeaSkKAQ8rA7PE+0j3TG+YtIij0mHOhNPJgEZ/XZ9MIQOGMycRJhwOlclBI5NP
Ak6p30ArnU2fX4qMkU3i+wqUfXS1hhDihwKBwQDLaHWPIWPVbWdcCbYQTcUmFC3i
xkxd0UuLcfS9csk61nvdFj7m8tMExX+3fIo/fHEtzDd98Alc1i6/f6ePl0CX6NDu
QIWLryI1QQRQidHCdw0wQ3N3VD4ZXJHDeqBxogVAkA7A/1QeXwcXE/Xj2ZgyDwhL
3+myjmvWtw9zJsXL0F3tpPzn+Mrf0KRkWOaluOw7hMMjVjrgu6g24HMWbHHVLRTx
dlAI7tgxCAPe2SEi+1mzaVUZ8cfgqYqC3X66UakCgcEAopxtK7+yJi/A4pzEnnYS
FS/CjMV3R0fA7aXbW0hIBCxkaW0Zib3m/eCcSxZMjZxwBpIsJctTtBcylprbGlgB
/1TF+tNoxEo4Sp4eEL/XciTC0Da4vEewFrPklM/S26KfovvgRYPsGeP+aco9aahA
pVhFcT36pBiq0DkvgucjValO6n5iqgDboYzbDDdttKCcgLc2Qgf/VUfRxy+bgm3Z
MmdxiMXBcIfDXlW9XmGSNAWhyqnPM9uxbZQoC/Tsg+QRAoHANHMcFSsz9f2+8DGk
27FiC76aUmZ1nJ9yTmO1CwDFOMHDsK+iyqSEmy9eDm8zqsko2flVuciicWjdJw4A
o/sJceJbtYO3q9weAwNf3HCdQPq30OEjrfpwBNQk1fYR1xtDJXHADC4Kf8ZbKq0/
81/Rad8McZwsQ5mL3xLXDgdKa5KwFa48dIhnr6y6JxHxb3wule5W7w62Ierhpjzc
EEUoWSLFyrmKS7Ni1cnOTbFJZR7Q831Or2Dz/E9bYwFAQ0T5AoHAM4/zU+8rsbdD
FvvhWsj7Ivfh6pxx1Tl1Wccaauea9AJayHht0FOzkycpJrH1E+6F5MzhkFFU1SUY
60NZxzSZgbU0HBrJRcRFyo510iMcnctdTdyh8p7nweGoD0oqXzf6cHqrUep8Y8rQ
gkSVhPE31+NGlPbwz+NOflcaaAWYiDC6wjVt1asaZq292SJD4DF1fAUkbQ2hxgyQ
+G/6y5ovrcGnh7q63RLhW1TRf8dD2D2Av9UgXDmWZAZ5n838FS+X
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCrFAQhuPzDROsFjV8M7zVy6uKNCt0s5SvxWXxcQJZzlAZ3UuQAbzQ2B1wIE++NbFlKZisp6oDvwZR034qDJwTTO2nFhJcodkxogzld73gEH4Ghwf3W93/aIHMZ553WdX/N8B2rYAQdCPVOkgj5r7PbnLG/Y+7BVNPDCj0j/omA2rd68fgdvCCvdJF8QRhlD5gvxw6kG42DVhk5HSTXKTbdmoB33YnJvFniIK063utyPawUfM27VTnjjBYHAgvnJlkpOAGFjh2p9PYSnsjNHkd2x2u9BX2oL3YYzXMMT5TcDCtUqMezRhmrePNyr/K8UMJwwxHPj/SkYUVTbqhaZr6fe9sDEomgv6uEbxAz36XaoWUsayczSRRcAlew8pvKClo/xndTh4qBO4nYa5L14sgWcHuavAPvlXoaA32rmZjz0N+RVKQdqiqljyk91GTP1ACYwS4u0ea/b0JU6l9fm/+uybvABIBmq1SWYW7isUYEvC9ltSVa7TYeaAFPjuDoQh8= jdog@localhost.wonderland.lol

44
test/docker/moduli_1024 Normal file
View File

@ -0,0 +1,44 @@
20190821035337 2 6 100 1023 2 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC08BE313B
20190821035338 2 6 100 1023 2 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC08C0B443
20190821035338 2 6 100 1023 2 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC08D1AF8B
20190821035338 2 6 100 1023 2 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC08E76DDB
20190821035338 2 6 100 1023 2 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC08E8F5D3
20190821035338 2 6 100 1023 2 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC08EE3F1B
20190821035338 2 6 100 1023 5 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC08F28387
20190821035339 2 6 100 1023 5 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC08F69A57
20190821035339 2 6 100 1023 5 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC0903B157
20190821035339 2 6 100 1023 2 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC0905C973
20190821035339 2 6 100 1023 2 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC0909BCD3
20190821035339 2 6 100 1023 2 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC090F4A2B
20190821035340 2 6 100 1023 2 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC0933BC13
20190821035340 2 6 100 1023 5 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC09395757
20190821035340 2 6 100 1023 5 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC093F40D7
20190821035340 2 6 100 1023 5 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC09478D4F
20190821035340 2 6 100 1023 5 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC0953A4D7
20190821035340 2 6 100 1023 2 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC095B5C7B
20190821035341 2 6 100 1023 2 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC09696573
20190821035341 2 6 100 1023 2 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC096BA243
20190821035341 2 6 100 1023 2 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC096F3903
20190821035341 2 6 100 1023 2 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC09850E4B
20190821035341 2 6 100 1023 2 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC098A1C23
20190821035341 2 6 100 1023 5 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC098E08E7
20190821035342 2 6 100 1023 5 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC09A4FF7F
20190821035342 2 6 100 1023 5 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC09AE4707
20190821035342 2 6 100 1023 2 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC09B4CE73
20190821035342 2 6 100 1023 5 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC09C60C6F
20190821035342 2 6 100 1023 5 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC09D2588F
20190821035343 2 6 100 1023 5 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC0A025067
20190821035343 2 6 100 1023 2 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC0A0E38EB
20190821035343 2 6 100 1023 2 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC0A213923
20190821035344 2 6 100 1023 5 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC0A390CA7
20190821035344 2 6 100 1023 2 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC0A3C7ADB
20190821035344 2 6 100 1023 5 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC0A44D497
20190821035344 2 6 100 1023 2 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC0A479B13
20190821035345 2 6 100 1023 5 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC0A5EF01F
20190821035345 2 6 100 1023 2 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC0A615D43
20190821035345 2 6 100 1023 2 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC0A6BEADB
20190821035345 2 6 100 1023 5 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC0A86309F
20190821035345 2 6 100 1023 5 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC0A991E8F
20190821035346 2 6 100 1023 2 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC0AA32C53
20190821035346 2 6 100 1023 2 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC0AA9FAAB
20190821035346 2 6 100 1023 2 F0B5E9E385A451D4F46BD2E354B5FCAAC21CA960E5D3D11F877DD50541ED125161E4A5055D528D67E525115BBFAB0B2A4AB8CF5BA98A8BBA41803ED5D4CF766E9ECD39A8D8D914B6F346E0EB2BA6936082751676DCE5C4817EFC7A8105C2A094B22C25245BE13CA4085F2985D3B7A2636FF4018A7E4EA9840BF5FFBC0AAC42BB

BIN
test/docker/ssh1_host_key Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
1024 35 150823875409720459951648542224727752099073441604930026287525797402159071426070997897033651155038337251362080634963146983947007228274330777134724953282680928153520263171933106732090266742784258910450489054624715996015082463159338507115031336180486071622718809324273851629938883104520608180885444242395900180011 root@ubuntu1604server

View File

@ -0,0 +1,12 @@
-----BEGIN DSA PRIVATE KEY-----
MIIBugIBAAKBgQDth1eV+A8j191R0ey0dVXL2LGNGYM+a+PomSa7suK8xNCeVLKC
YpQ6VSWpAf6FbRWev1UVo8IpbglwFZPcyFPK2G1H7p45ows2SN4CleszDD56e6W0
3Plc+qMqSJ6LTjr4M5+HqTDOM3CS72d7MXUkfHQiagyrWQhXyc0kFsNJLwIVAKg7
b5+NiIZzpg5IEH0tlYFQpuhBAoGAGcbq79QqNNZRuPCE/F05sCoTRGCmFnDjCuCg
WN7wNRotjMz/S3pHtCCeuTT1jT6Hy0ZFHftv0t/GF8GBRgeokUbS4ytHpOkFWcTz
8oFguDL44nq8eNfSY6bzEl84qsgEe4HP93mB4FR1ZUUgI4b7gCBOYEFl3yPiH7H1
p7Z9E1oCgYAl1UPQkeRhElz+AgEbNsnMKu1+6O3/z95D1Wvv4OEwAImbytlBaC7p
kwJElJNsMMfGqCC8OHdJ0e4VQQUwk/GOhD0MFhVQHBtVZYbiWmVkpfHf1ouUQg3f
1IZmz2SSt6cPPEu+BEQ/Sn3mFRJ5XSTHLtnI0HJeDND5u1+6p1nXawIURv3Maige
oxmfqC24VoROJEq+sew=
-----END DSA PRIVATE KEY-----

View File

@ -0,0 +1 @@
ssh-dss AAAAB3NzaC1kc3MAAACBAO2HV5X4DyPX3VHR7LR1VcvYsY0Zgz5r4+iZJruy4rzE0J5UsoJilDpVJakB/oVtFZ6/VRWjwiluCXAVk9zIU8rYbUfunjmjCzZI3gKV6zMMPnp7pbTc+Vz6oypInotOOvgzn4epMM4zcJLvZ3sxdSR8dCJqDKtZCFfJzSQWw0kvAAAAFQCoO2+fjYiGc6YOSBB9LZWBUKboQQAAAIAZxurv1Co01lG48IT8XTmwKhNEYKYWcOMK4KBY3vA1Gi2MzP9Leke0IJ65NPWNPofLRkUd+2/S38YXwYFGB6iRRtLjK0ek6QVZxPPygWC4Mvjierx419JjpvMSXziqyAR7gc/3eYHgVHVlRSAjhvuAIE5gQWXfI+IfsfWntn0TWgAAAIAl1UPQkeRhElz+AgEbNsnMKu1+6O3/z95D1Wvv4OEwAImbytlBaC7pkwJElJNsMMfGqCC8OHdJ0e4VQQUwk/GOhD0MFhVQHBtVZYbiWmVkpfHf1ouUQg3f1IZmz2SSt6cPPEu+BEQ/Sn3mFRJ5XSTHLtnI0HJeDND5u1+6p1nXaw==

View File

@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEICq/YV5QenL0uW5g5tCjY3EWs+UBFmskY+Jjt2vd2aEmoAoGCCqGSM49
AwEHoUQDQgAEdYSxDVUjOpW479L/nRDiAdxRB5Kuy2bgkP/LA2pnWPcGIWmFa4QU
YN2U3JsFKcLIcx5cvTehQfgrHDnaSKVdKA==
-----END EC PRIVATE KEY-----

View File

@ -0,0 +1 @@
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHWEsQ1VIzqVuO/S/50Q4gHcUQeSrstm4JD/ywNqZ1j3BiFphWuEFGDdlNybBSnCyHMeXL03oUH4Kxw52kilXSg=

View File

@ -0,0 +1,7 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACC/9RD2Ao95ODDIH8i11ekTALut8AUNqWoQx0jHlP4xygAAAKDiqVOs4qlT
rAAAAAtzc2gtZWQyNTUxOQAAACC/9RD2Ao95ODDIH8i11ekTALut8AUNqWoQx0jHlP4xyg
AAAECTmHGkq0Qea0QqTJYMXL0bpxVU7mhgwYninfVWxrA017/1EPYCj3k4MMgfyLXV6RMA
u63wBQ2pahDHSMeU/jHKAAAAHWpkb2dAbG9jYWxob3N0LndvbmRlcmxhbmQubG9s
-----END OPENSSH PRIVATE KEY-----

View File

@ -0,0 +1 @@
ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIO1W0I8tD0c4LypvHY1XNch3BQCw9Yy28/4KmAYql80DAAAAIL/1EPYCj3k4MMgfyLXV6RMAu63wBQ2pahDHSMeU/jHKAAAAAAAAAAAAAAACAAAABHRlc3QAAAAIAAAABHRlc3QAAAAAXV7hvAAAAACBa2YhAAAAAAAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACAbM9Wp3ZPcC8Ifhu6GjNDJaoMg7KxO0el2+r9J35TltQAAAFMAAAALc3NoLWVkMjU1MTkAAABAW60bCSeIG4Ta+57zgkSbW4LIGCxtOuJJ+pP3i3S0xJJfHGnOtXbg0NQm7pulNl/wd01kgJO9A7RjbhTh7TV1AA== ssh_host_ed25519_key.pub

View File

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL/1EPYCj3k4MMgfyLXV6RMAu63wBQ2pahDHSMeU/jHK

View File

@ -0,0 +1,15 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQDeCC1U7VqVg9AfrfWrXACiW6pzYOuP8tim68z+YN/dUU7JhFZ4
0toteQkLcJBAD2miQ6ZJYkjVfhQ4FRFeOW5vcN0UYHn8ttb2mKdGJdt24ZYY5Z6J
WHQhPOpSgtWyUv6RnxU2ligEeaoPaiepUUOhoyLf4WcF7voVCAKZNqeTtQIDAQAB
AoGATGZ16s5NqDsWJ4B9k3xx/2wZZ+BGzl6a7D0habq97XLn8HGoK6UqTBFk6lnO
WSy0hZBPrNq0AzqCDJY7RrfuZqgVAu/+HEFuXencgt8Z//ueYBaGK8yAC+OrMnDG
LbSoIGRq8saaFtCzt47c+uSVsrhJ4TvK5gbceZuD/2uw10ECQQD79T0j+YWsLISK
PKvYHqEXSMPN6b+lK9hRPLoF9NMksNLSjuxxhkYHz+hJPVNT+wPtRMAYmMdPXfKa
FjuErXVFAkEA4ZgJIOeJ7OHfqGEgd29m36yFy0UaUJ+cmYuJzHAYWgW3TOanqpZm
A8EENuXvH0DtYRVytv4m/cIRVVPxWtXzsQJBALXlQUOEc0VuSi1GScVXr3KQ3JL+
ipWixqM3VRDRw9D8Ouc5uWbnygz/wrGFLXA2ioozlP7s5Q7eQzOMk2FgnIUCQQCz
j5QUgLcjuVWQbF6vMhisCGImPUaIzcKT5KE1/DMl1E7mAuGJwlRIwKVeHP6L3d4T
3EKGrRzT9lhdlocRSiLBAkEAi3xI0MOZp4xGviPc1C1TKuqdJSr8fHwbtLozwNQO
nnF6m5S72JzZEThDBZS9zcdBp9EFpTvUGzx/O0GI454eoA==
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1 @@
ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgFqxXSa9HTqCw5YW3DdIwVREPGxI+i56w32RnHWRg0NoAAAADAQABAAAAgQDeCC1U7VqVg9AfrfWrXACiW6pzYOuP8tim68z+YN/dUU7JhFZ40toteQkLcJBAD2miQ6ZJYkjVfhQ4FRFeOW5vcN0UYHn8ttb2mKdGJdt24ZYY5Z6JWHQhPOpSgtWyUv6RnxU2ligEeaoPaiepUUOhoyLf4WcF7voVCAKZNqeTtQAAAAAAAAAAAAAAAgAAAAR0ZXN0AAAACAAAAAR0ZXN0AAAAAF1evHgAAAAAgWtAtQAAAAAAAAAAAAAAAAAAAJcAAAAHc3NoLXJzYQAAAAMBAAEAAACBAOdGU3cAWdR7aUV/lcb1SFcuv/086u41MVsy3TOuM5RKOYBLuFLqkO/lUROhPoNpHURBRhqpIykdjNmG4Irna+vJ06blcVsnvvXav0zJlBSGhVnHxK50EfNUMhU7eNwwxYiWt9YEydRpQcSqmbLzxjuAoNrZNbEmDX6GDnUqoetRAAAAjwAAAAdzc2gtcnNhAAAAgFRc2g0eWXGmqSa6Z8rcMPHf4rNMornEHSnTzZ8Rdh4YBhDa9xMRRy6puaWPDzXxOfZh7eSjCwrzUMEXTgCIO4oX62xm/6kUnAmKhXle0+inR/hdPg03daE0SBJ4spBT49lJ4WIW38RKFNzjmYg70rTPAnP8oM/F3CC1GV117/Vv ssh_host_rsa_key_1024.pub

View File

@ -0,0 +1 @@
ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgrJGcfyW8V6VWGT7lD1ardj2RtTP8TOjmLRNbuoGkyZQAAAADAQABAAAAgQDeCC1U7VqVg9AfrfWrXACiW6pzYOuP8tim68z+YN/dUU7JhFZ40toteQkLcJBAD2miQ6ZJYkjVfhQ4FRFeOW5vcN0UYHn8ttb2mKdGJdt24ZYY5Z6JWHQhPOpSgtWyUv6RnxU2ligEeaoPaiepUUOhoyLf4WcF7voVCAKZNqeTtQAAAAAAAAAAAAAAAgAAAAR0ZXN0AAAACAAAAAR0ZXN0AAAAAF1evHgAAAAAgWtA7gAAAAAAAAAAAAAAAAAAAZcAAAAHc3NoLXJzYQAAAAMBAAEAAAGBAKsUBCG4/MNE6wWNXwzvNXLq4o0K3SzlK/FZfFxAlnOUBndS5ABvNDYHXAgT741sWUpmKynqgO/BlHTfioMnBNM7acWElyh2TGiDOV3veAQfgaHB/db3f9ogcxnnndZ1f83wHatgBB0I9U6SCPmvs9ucsb9j7sFU08MKPSP+iYDat3rx+B28IK90kXxBGGUPmC/HDqQbjYNWGTkdJNcpNt2agHfdicm8WeIgrTre63I9rBR8zbtVOeOMFgcCC+cmWSk4AYWOHan09hKeyM0eR3bHa70FfagvdhjNcwxPlNwMK1Sox7NGGat483Kv8rxQwnDDEc+P9KRhRVNuqFpmvp972wMSiaC/q4RvEDPfpdqhZSxrJzNJFFwCV7Dym8oKWj/Gd1OHioE7idhrkvXiyBZwe5q8A++VehoDfauZmPPQ35FUpB2qKqWPKT3UZM/UAJjBLi7R5r9vQlTqX1+b/67Ju8AEgGarVJZhbuKxRgS8L2W1JVrtNh5oAU+O4OhCHwAAAY8AAAAHc3NoLXJzYQAAAYCO78ONpHp+EGWDqDLb/GPFDH32o6oaRRrIH/Bhvg1FOi5XngnHTdU7xWdnJqNE2Sl6VOrg0sTCMYcX9fZ8tVREnCo3aF7Iwow5Br67QYKayRzHANQqHaVK46lpI1gz81V00u54tX1F8oEUqm6sRmFKFuklt6CjfbR+tnpj7DrfeOTKEBOGJP2uU0jMsJr2DrBeXrzONjIJtIJ1AxWjXd2LeIWO2C6yTkcN5ggThMMaeu6QuuBPpC2PN2COfu+Mgto9g103+/SS4Wa8CzinZZn2Xe1isUxI8QRNrShy4Hl/bIZQL7mi/0rxkfw+fA7IzMk462V99gPVSp+/jK0sbUJoC3QeeglS5hWodjW+VGZfgweGQ+AE/OxkNSv+kDPMYEkjfOf4qhxS5QFvButLt6zp2UNbE5+OWvYpdjO9/DOa0ro+wCw07+dVKIcDpU2csiCcJvQ/HmKAmhch7jOHa0WaxSX0tt0xTPJWTvr6E4WZOgEnk9AvWmrKjF5tEzGYwTU= ssh_host_rsa_key_1024.pub

View File

@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDeCC1U7VqVg9AfrfWrXACiW6pzYOuP8tim68z+YN/dUU7JhFZ40toteQkLcJBAD2miQ6ZJYkjVfhQ4FRFeOW5vcN0UYHn8ttb2mKdGJdt24ZYY5Z6JWHQhPOpSgtWyUv6RnxU2ligEeaoPaiepUUOhoyLf4WcF7voVCAKZNqeTtQ==

View File

@ -0,0 +1,39 @@
-----BEGIN RSA PRIVATE KEY-----
MIIG5AIBAAKCAYEAzhHp7eFnrQAJqOd7aihyQyIDKgxCF7H51Q3Ft3+8af+lX3Ol
Ie77Gi5GNNM+eRB4OzG+CBslxN5I3pM//sZ+gyylA1VuWZZkOlgtbOHutIkO2ldk
XtoGidla0VAxLcUcUK6cCmqwBTT31Hp4Qimp2zyeg/l5q0DhWKguY13lrm5b3YZY
rj7CW3Ktzxf8SbYz6du8KF0dHCWilzq+FLeGzXr7Yul5njVF5njkGvZ9duQ0qiVR
zqZkrkLEWgQlCM0T+PyUbvedL1MfDZPHGh7ZhU0snOvJRsxAr31tlknq+WwauZYd
DzJf1g1URcM65UwEsPlfgOW3ZoZogR1v57Im+KdsKhq2B3snEtJgdQh06JyO0ur4
uUXo1mMtvBFhiptUtwP4g9v/IN4neeK+wBRom46m2Q1bMUBPneBOa8r2SY/3ynrz
XuVIWFOQtF60aJ+BNqvgUVCKOmz1KzoJwTqGm+EFaKM5z+UQWjIbSE3Ge4X5hXtk
Ou52v+tyDUk6boZLAgMBAAECggGAdrhxWmA7N7tG1W2Pd6iXs7+brRTk2vvpYGqP
11kbNsJXBzf8EiG5vuqb/gEaA+uOKSRORCNHzjT2LG0POHwpFO+aneIRMkHnuolk
mk9ME+zGhtpEdDUOAUsc/GxD+QePeZgvQ/0VLdrHUT3BnPSd7DXvaT9IbnZxnX8/
QnYtRiJEgMrOuoxjswXNxvsdmWYEYJ38uBB1Hes80f3A1vSpECbjP6gdLh2pCM/r
MvGBdQaipMfdar4IUTEcKHQs1fY3mlAxnWRjYCqJPmq10d3NrdUrHb2zBE1HCC4h
aj2ycTxFhDJqGV6Y2AboHqh2c7lPJ+R2UjI9mIpALZSviHB1POcpWCAGA3NKjri9
8jgxl3bj03ikJNfCuvlqRTa8at63W2zZTMRsxamoiO023uUOEMNBPwWXP/rVhQ8g
ufih0SY44j0EMPIuu2PoQV4ZSOtDw8xdPrchVCa078/pP5cRa4uV0bl2K4as+cYC
BhjEq2Org3ulDW2n6Mz5ZS7NbAkxAoHBAP/bgPGKX7rfrHa5MRHIgbLSmZtUoF51
YGelc8ytRx6UT6wriJ1jQRXiI5mZlIXyVxMpIz9s4+h59kF+LpZuNLc3vTYpPOQn
RUDBVY6+SPC5MancL7bfBoHahpWEJuJB/WUE7eWvQM03/LsBtU6Nq+R632t5KdqF
A4y86qgD1vIjcBWvySLFJZGOCoNbj7ZinoBUO3ueYK6SUj8xH6TAqOJsTPvquRT3
AFBpFBmrVc24wW7wTiLkQOhkIQs1J/ZhYwKBwQDOL07qF8wsoQBBTTXkZ59BCauz
R8kfqe5oUBwsmGJdiIHX6gutBA07sSwzVekIvCCkJFXk3TxLoBSMHEZEIdnS+HVt
gMIacYuhbh+XztdY0kadH/SMbVQD/2LZcL99vcZPq1QF3cHb0Buip5+fyAYjoEc7
oVgvewD/TwdNcMjos/kMNh6l04kLi6vQG3WhoSBPWaoB669ppBNXSrWKe43nXVi6
EvjGEiL+HCCnmD6LiD6p797Owu9AChP6fXInD/kCgcEAiLP3SRbt3yLzOtvn4+CF
q83qVJv6s31zbO1x2cIbZbNIfm0kKTOG6vJQoxjzyj2ZWJt6QcEkZGoFsSiCK83m
TJ5zciTGbACvd9HUrNfukO/iISeMNuEi0O65Sdm6DNnFUdw4X6grr3pihmh7PuVj
GkisZvft7Nt08hVeKzch+W4FzRCHHxTG5eZGp7icKI64sUhQH9SXQ67aUvkkNxrZ
IWFMIK1hBlqSyGPcYXqx9aDpeSTcGrhqFcCqBxr3pySRAoHAfJNO3delEC3yxoHN
FwSYzyX1rOuplE0K89G7RCKKBDNPKFKL3Wx+Rluk9htpIlLwcdxWXWJiZNsCrykC
N3YwcuyVnqTWIj4KfG3Z/tIFgPADpDnDevkvcv7iDbi2qlV4NXix2p2C3LnfiKY4
psSnGO1lPJ0eeAmcr6VjJyIG8bqTthIY8F5gBi7Mj3+X0iFVMTxeoKxzHqP435wP
Fe3S7kCTNFH0J1Cb/eamwDwXRhz6p5h7iXd0MMAmFAmpZ/qZAoHBAPDSIvk2ocf1
FVW8pKtKOJFIs8iQVIaOLKwPJVP8/JsB1+7mQx5KMoROb5pNpX2edN4vvG0CgqpJ
KekleqpH6nQCqYGFZ1BDhORElNILxeJHcNl0eAG++IJ2PfIpTZV30edDqMm0x7EI
8POZWAx809VzcYbE2jsgpN/EuiaG30EAI5yNvyzmZRCyQykH+eltHlCx17MWBxRQ
bb2UUfpdInTMS2vyrvkeUACkC1DGYdBVVBqqPTkHZg+Kcbs8ntQqEQ==
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1 @@
ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgGHz1JwF/1IcxW3pdQtpqbUjIHaFuk0cR/+l50vG+9hIAAAADAQABAAABgQDOEent4WetAAmo53tqKHJDIgMqDEIXsfnVDcW3f7xp/6Vfc6Uh7vsaLkY00z55EHg7Mb4IGyXE3kjekz/+xn6DLKUDVW5ZlmQ6WC1s4e60iQ7aV2Re2gaJ2VrRUDEtxRxQrpwKarAFNPfUenhCKanbPJ6D+XmrQOFYqC5jXeWublvdhliuPsJbcq3PF/xJtjPp27woXR0cJaKXOr4Ut4bNevti6XmeNUXmeOQa9n125DSqJVHOpmSuQsRaBCUIzRP4/JRu950vUx8Nk8caHtmFTSyc68lGzECvfW2WSer5bBq5lh0PMl/WDVRFwzrlTASw+V+A5bdmhmiBHW/nsib4p2wqGrYHeycS0mB1CHTonI7S6vi5RejWYy28EWGKm1S3A/iD2/8g3id54r7AFGibjqbZDVsxQE+d4E5ryvZJj/fKevNe5UhYU5C0XrRon4E2q+BRUIo6bPUrOgnBOoab4QVooznP5RBaMhtITcZ7hfmFe2Q67na/63INSTpuhksAAAAAAAAAAAAAAAIAAAAEdGVzdAAAAAgAAAAEdGVzdAAAAABdXry0AAAAAIFrQR8AAAAAAAAAAAAAAAAAAACXAAAAB3NzaC1yc2EAAAADAQABAAAAgQDnRlN3AFnUe2lFf5XG9UhXLr/9POruNTFbMt0zrjOUSjmAS7hS6pDv5VEToT6DaR1EQUYaqSMpHYzZhuCK52vrydOm5XFbJ7712r9MyZQUhoVZx8SudBHzVDIVO3jcMMWIlrfWBMnUaUHEqpmy88Y7gKDa2TWxJg1+hg51KqHrUQAAAI8AAAAHc3NoLXJzYQAAAIB4HaEexgQ9T6rScEbiHZx+suCaYXI7ywLYyoSEO48K8o+MmO83UTLtpPa3DXlT8hSYL8Aq6Bb5AMkDawsgsC484owPqObT/5ndLG/fctNBFcCTSL0ftte+A8xH0pZaGRoKbdxxgMqX4ubrCXpbMLGF9aAeh7MRa756XzqGlsCiSA== ssh_host_rsa_key_3072.pub

View File

@ -0,0 +1 @@
ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAg9MVX4OlkEy3p9eC+JJp8h7j76EmI46EY/RXxCGSWTC0AAAADAQABAAABgQDOEent4WetAAmo53tqKHJDIgMqDEIXsfnVDcW3f7xp/6Vfc6Uh7vsaLkY00z55EHg7Mb4IGyXE3kjekz/+xn6DLKUDVW5ZlmQ6WC1s4e60iQ7aV2Re2gaJ2VrRUDEtxRxQrpwKarAFNPfUenhCKanbPJ6D+XmrQOFYqC5jXeWublvdhliuPsJbcq3PF/xJtjPp27woXR0cJaKXOr4Ut4bNevti6XmeNUXmeOQa9n125DSqJVHOpmSuQsRaBCUIzRP4/JRu950vUx8Nk8caHtmFTSyc68lGzECvfW2WSer5bBq5lh0PMl/WDVRFwzrlTASw+V+A5bdmhmiBHW/nsib4p2wqGrYHeycS0mB1CHTonI7S6vi5RejWYy28EWGKm1S3A/iD2/8g3id54r7AFGibjqbZDVsxQE+d4E5ryvZJj/fKevNe5UhYU5C0XrRon4E2q+BRUIo6bPUrOgnBOoab4QVooznP5RBaMhtITcZ7hfmFe2Q67na/63INSTpuhksAAAAAAAAAAAAAAAIAAAAEdGVzdAAAAAgAAAAEdGVzdAAAAABdXr0sAAAAAIFrQWwAAAAAAAAAAAAAAAAAAAGXAAAAB3NzaC1yc2EAAAADAQABAAABgQCrFAQhuPzDROsFjV8M7zVy6uKNCt0s5SvxWXxcQJZzlAZ3UuQAbzQ2B1wIE++NbFlKZisp6oDvwZR034qDJwTTO2nFhJcodkxogzld73gEH4Ghwf3W93/aIHMZ553WdX/N8B2rYAQdCPVOkgj5r7PbnLG/Y+7BVNPDCj0j/omA2rd68fgdvCCvdJF8QRhlD5gvxw6kG42DVhk5HSTXKTbdmoB33YnJvFniIK063utyPawUfM27VTnjjBYHAgvnJlkpOAGFjh2p9PYSnsjNHkd2x2u9BX2oL3YYzXMMT5TcDCtUqMezRhmrePNyr/K8UMJwwxHPj/SkYUVTbqhaZr6fe9sDEomgv6uEbxAz36XaoWUsayczSRRcAlew8pvKClo/xndTh4qBO4nYa5L14sgWcHuavAPvlXoaA32rmZjz0N+RVKQdqiqljyk91GTP1ACYwS4u0ea/b0JU6l9fm/+uybvABIBmq1SWYW7isUYEvC9ltSVa7TYeaAFPjuDoQh8AAAGPAAAAB3NzaC1yc2EAAAGAG8tCiBMSq3Of3Gmcrid2IfPmaaemYivgEEuK8ubq1rznF0vtR07/NUQ7WVzfJhUSeG0gtJ3A1ey60NjcBn0DHao4Q3ATIXnkSOIKjNolZ2urqYv9fT1LAC4I5XWGzK2aKK0NEqAYr06YPtcGOBQk5+3GPAWSJ4eQycKRz5BSuMYbKaVxU0kGSvbavG07ZntMQhia/lILyq84PjXh/JlRVpIqY+LAS0qwqkUR3gWMTmvYvYI7fXU84ReVB1ut75bY7Xx0DXHPl1Zc2MNDLGcKsByZtoO9ueZRyOlZMUJcVP5fK+OUuZKjMbCaaJnV55BQ78/rftIPYsTEEO2Sf9WT86ADa3k4S0pyWqlTxBzZcDWNt+fZFNm9wcqcYS32nDKtfixcDN8E/IJIWY7aoabPqoYnKUVQBOcIEnZf1HqsKUVmF44Dp9mKhefUs3BtcdK63j/lNXzzMrPwZQAreJqH/uV3TgYBLjMPl++ctX6tCe6Hv5zFKNhnOCSBSzcsCgIU ssh_host_rsa_key_3072.pub

View File

@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDOEent4WetAAmo53tqKHJDIgMqDEIXsfnVDcW3f7xp/6Vfc6Uh7vsaLkY00z55EHg7Mb4IGyXE3kjekz/+xn6DLKUDVW5ZlmQ6WC1s4e60iQ7aV2Re2gaJ2VrRUDEtxRxQrpwKarAFNPfUenhCKanbPJ6D+XmrQOFYqC5jXeWublvdhliuPsJbcq3PF/xJtjPp27woXR0cJaKXOr4Ut4bNevti6XmeNUXmeOQa9n125DSqJVHOpmSuQsRaBCUIzRP4/JRu950vUx8Nk8caHtmFTSyc68lGzECvfW2WSer5bBq5lh0PMl/WDVRFwzrlTASw+V+A5bdmhmiBHW/nsib4p2wqGrYHeycS0mB1CHTonI7S6vi5RejWYy28EWGKm1S3A/iD2/8g3id54r7AFGibjqbZDVsxQE+d4E5ryvZJj/fKevNe5UhYU5C0XrRon4E2q+BRUIo6bPUrOgnBOoab4QVooznP5RBaMhtITcZ7hfmFe2Q67na/63INSTpuhks=

View File

@ -1,8 +0,0 @@
#!/bin/sh
_cdir=$(cd -- "$(dirname "$0")" && pwd)
type prospector > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo "err: prospector (Python Static Analysis) not found."
exit 1
fi
prospector --profile-path "${_cdir}" -P prospector "${_cdir}/../ssh-audit.py"

View File

@ -1,9 +0,0 @@
inherits:
- strictness_veryhigh
pep8:
disable:
- W191
- W293
- E501
- E221

6
test/stubs/colorama.pyi Normal file
View File

@ -0,0 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from typing import Optional
def init(autoreset: bool = False, convert: Optional[bool] = None, strip: Optional[bool] = None, wrap: bool = True) -> None: ...

View File

@ -3,13 +3,15 @@
import pytest
# pylint: disable=attribute-defined-outside-init
class TestAuditConf(object):
@pytest.fixture(autouse=True)
def init(self, ssh_audit):
self.AuditConf = ssh_audit.AuditConf
self.usage = ssh_audit.usage
def _test_conf(self, conf, **kwargs):
@staticmethod
def _test_conf(conf, **kwargs):
options = {
'host': None,
'port': 22,
@ -18,7 +20,10 @@ class TestAuditConf(object):
'batch': False,
'colors': True,
'verbose': False,
'minlevel': 'info'
'level': 'info',
'ipv4': True,
'ipv6': True,
'ipvo': ()
}
for k, v in kwargs.items():
options[k] = v
@ -29,7 +34,10 @@ class TestAuditConf(object):
assert conf.batch is options['batch']
assert conf.colors is options['colors']
assert conf.verbose is options['verbose']
assert conf.minlevel == options['minlevel']
assert conf.level == options['level']
assert conf.ipv4 == options['ipv4']
assert conf.ipv6 == options['ipv6']
assert conf.ipvo == options['ipvo']
def test_audit_conf_defaults(self):
conf = self.AuditConf()
@ -55,18 +63,71 @@ class TestAuditConf(object):
conf.port = port
excinfo.match(r'.*invalid port.*')
def test_audit_conf_minlevel(self):
def test_audit_conf_ipvo(self):
# ipv4-only
conf = self.AuditConf()
conf.ipv4 = True
assert conf.ipv4 is True
assert conf.ipv6 is False
assert conf.ipvo == (4,)
# ipv6-only
conf = self.AuditConf()
conf.ipv6 = True
assert conf.ipv4 is False
assert conf.ipv6 is True
assert conf.ipvo == (6,)
# ipv4-only (by removing ipv6)
conf = self.AuditConf()
conf.ipv6 = False
assert conf.ipv4 is True
assert conf.ipv6 is False
assert conf.ipvo == (4, )
# ipv6-only (by removing ipv4)
conf = self.AuditConf()
conf.ipv4 = False
assert conf.ipv4 is False
assert conf.ipv6 is True
assert conf.ipvo == (6, )
# ipv4-preferred
conf = self.AuditConf()
conf.ipv4 = True
conf.ipv6 = True
assert conf.ipv4 is True
assert conf.ipv6 is True
assert conf.ipvo == (4, 6)
# ipv6-preferred
conf = self.AuditConf()
conf.ipv6 = True
conf.ipv4 = True
assert conf.ipv4 is True
assert conf.ipv6 is True
assert conf.ipvo == (6, 4)
# ipvo empty
conf = self.AuditConf()
conf.ipvo = ()
assert conf.ipv4 is True
assert conf.ipv6 is True
assert conf.ipvo == ()
# ipvo validation
conf = self.AuditConf()
conf.ipvo = (1, 2, 3, 4, 5, 6)
assert conf.ipvo == (4, 6)
conf.ipvo = (4, 4, 4, 6, 6)
assert conf.ipvo == (4, 6)
def test_audit_conf_level(self):
conf = self.AuditConf()
for level in ['info', 'warn', 'fail']:
conf.minlevel = level
assert conf.minlevel == level
conf.level = level
assert conf.level == level
for level in ['head', 'good', 'unknown', None]:
with pytest.raises(ValueError) as excinfo:
conf.minlevel = level
conf.level = level
excinfo.match(r'.*invalid level.*')
def test_audit_conf_cmdline(self):
c = lambda x: self.AuditConf.from_cmdline(x.split(), self.usage)
# pylint: disable=too-many-statements
c = lambda x: self.AuditConf.from_cmdline(x.split(), self.usage) # noqa
with pytest.raises(SystemExit):
conf = c('')
with pytest.raises(SystemExit):
@ -85,20 +146,44 @@ class TestAuditConf(object):
self._test_conf(conf, host='github.com')
conf = c('localhost:2222')
self._test_conf(conf, host='localhost', port=2222)
conf = c('-p 2222 localhost')
self._test_conf(conf, host='localhost', port=2222)
conf = c('2001:4860:4860::8888')
self._test_conf(conf, host='2001:4860:4860::8888')
conf = c('[2001:4860:4860::8888]:22')
self._test_conf(conf, host='2001:4860:4860::8888')
conf = c('[2001:4860:4860::8888]:2222')
self._test_conf(conf, host='2001:4860:4860::8888', port=2222)
conf = c('-p 2222 2001:4860:4860::8888')
self._test_conf(conf, host='2001:4860:4860::8888', port=2222)
with pytest.raises(SystemExit):
conf = c('localhost:')
with pytest.raises(SystemExit):
conf = c('localhost:abc')
with pytest.raises(SystemExit):
conf = c('-p abc localhost')
with pytest.raises(SystemExit):
conf = c('localhost:-22')
with pytest.raises(SystemExit):
conf = c('-p -22 localhost')
with pytest.raises(SystemExit):
conf = c('localhost:99999')
with pytest.raises(SystemExit):
conf = c('-p 99999 localhost')
conf = c('-1 localhost')
self._test_conf(conf, host='localhost', ssh1=True, ssh2=False)
conf = c('-2 localhost')
self._test_conf(conf, host='localhost', ssh1=False, ssh2=True)
conf = c('-12 localhost')
self._test_conf(conf, host='localhost', ssh1=True, ssh2=True)
conf = c('-4 localhost')
self._test_conf(conf, host='localhost', ipv4=True, ipv6=False, ipvo=(4,))
conf = c('-6 localhost')
self._test_conf(conf, host='localhost', ipv4=False, ipv6=True, ipvo=(6,))
conf = c('-46 localhost')
self._test_conf(conf, host='localhost', ipv4=True, ipv6=True, ipvo=(4, 6))
conf = c('-64 localhost')
self._test_conf(conf, host='localhost', ipv4=True, ipv6=True, ipvo=(6, 4))
conf = c('-b localhost')
self._test_conf(conf, host='localhost', batch=True, verbose=True)
conf = c('-n localhost')
@ -106,10 +191,10 @@ class TestAuditConf(object):
conf = c('-v localhost')
self._test_conf(conf, host='localhost', verbose=True)
conf = c('-l info localhost')
self._test_conf(conf, host='localhost', minlevel='info')
self._test_conf(conf, host='localhost', level='info')
conf = c('-l warn localhost')
self._test_conf(conf, host='localhost', minlevel='warn')
self._test_conf(conf, host='localhost', level='warn')
conf = c('-l fail localhost')
self._test_conf(conf, host='localhost', minlevel='fail')
self._test_conf(conf, host='localhost', level='fail')
with pytest.raises(SystemExit):
conf = c('-l something localhost')

View File

@ -3,13 +3,14 @@
import pytest
# pylint: disable=line-too-long,attribute-defined-outside-init
class TestBanner(object):
@pytest.fixture(autouse=True)
def init(self, ssh_audit):
self.ssh = ssh_audit.SSH
def test_simple_banners(self):
banner = lambda x: self.ssh.Banner.parse(x)
banner = lambda x: self.ssh.Banner.parse(x) # noqa
b = banner('SSH-2.0-OpenSSH_7.3')
assert b.protocol == (2, 0)
assert b.software == 'OpenSSH_7.3'
@ -27,12 +28,12 @@ class TestBanner(object):
assert str(b) == 'SSH-1.5-Cisco-1.25'
def test_invalid_banners(self):
b = lambda x: self.ssh.Banner.parse(x)
b = lambda x: self.ssh.Banner.parse(x) # noqa
assert b('Something') is None
assert b('SSH-XXX-OpenSSH_7.3') is None
def test_banners_with_spaces(self):
b = lambda x: self.ssh.Banner.parse(x)
b = lambda x: self.ssh.Banner.parse(x) # noqa
s = 'SSH-2.0-OpenSSH_4.3p2'
assert str(b('SSH-2.0-OpenSSH_4.3p2 ')) == s
assert str(b('SSH-2.0- OpenSSH_4.3p2')) == s
@ -43,7 +44,7 @@ class TestBanner(object):
assert str(b('SSH-2.0- OpenSSH_4.3p2 Debian-9etch3 on i686-pc-linux-gnu ')) == s
def test_banners_without_software(self):
b = lambda x: self.ssh.Banner.parse(x)
b = lambda x: self.ssh.Banner.parse(x) # noqa
assert b('SSH-2.0').protocol == (2, 0)
assert b('SSH-2.0').software is None
assert b('SSH-2.0').comments is None
@ -54,13 +55,13 @@ class TestBanner(object):
assert str(b('SSH-2.0-')) == 'SSH-2.0-'
def test_banners_with_comments(self):
b = lambda x: self.ssh.Banner.parse(x)
b = lambda x: self.ssh.Banner.parse(x) # noqa
assert repr(b('SSH-2.0-OpenSSH_7.2p2 Ubuntu-1')) == '<Banner(protocol=2.0, software=OpenSSH_7.2p2, comments=Ubuntu-1)>'
assert repr(b('SSH-1.99-OpenSSH_3.4p1 Debian 1:3.4p1-1.woody.3')) == '<Banner(protocol=1.99, software=OpenSSH_3.4p1, comments=Debian 1:3.4p1-1.woody.3)>'
assert repr(b('SSH-1.5-1.3.7 F-SECURE SSH')) == '<Banner(protocol=1.5, software=1.3.7, comments=F-SECURE SSH)>'
def test_banners_with_multiple_protocols(self):
b = lambda x: self.ssh.Banner.parse(x)
b = lambda x: self.ssh.Banner.parse(x) # noqa
assert str(b('SSH-1.99-SSH-1.99-OpenSSH_3.6.1p2')) == 'SSH-1.99-OpenSSH_3.6.1p2'
assert str(b('SSH-2.0-SSH-2.0-OpenSSH_4.3p2 Debian-9')) == 'SSH-2.0-OpenSSH_4.3p2 Debian-9'
assert str(b('SSH-1.99-SSH-2.0-dropbear_0.5')) == 'SSH-1.99-dropbear_0.5'

View File

@ -1,16 +1,19 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pytest
import re
import pytest
# pylint: disable=attribute-defined-outside-init,bad-whitespace
class TestBuffer(object):
@pytest.fixture(autouse=True)
def init(self, ssh_audit):
self.rbuf = ssh_audit.ReadBuf
self.wbuf = ssh_audit.WriteBuf
self.utf8rchar = b'\xef\xbf\xbd'
def _b(self, v):
@classmethod
def _b(cls, v):
v = re.sub(r'\s', '', v)
data = [int(v[i * 2:i * 2 + 2], 16) for i in range(len(v) // 2)]
return bytes(bytearray(data))
@ -25,8 +28,8 @@ class TestBuffer(object):
assert r.unread_len == 0
def test_byte(self):
w = lambda x: self.wbuf().write_byte(x).write_flush()
r = lambda x: self.rbuf(x).read_byte()
w = lambda x: self.wbuf().write_byte(x).write_flush() # noqa
r = lambda x: self.rbuf(x).read_byte() # noqa
tc = [(0x00, '00'),
(0x01, '01'),
(0x10, '10'),
@ -36,8 +39,8 @@ class TestBuffer(object):
assert r(self._b(p[1])) == p[0]
def test_bool(self):
w = lambda x: self.wbuf().write_bool(x).write_flush()
r = lambda x: self.rbuf(x).read_bool()
w = lambda x: self.wbuf().write_bool(x).write_flush() # noqa
r = lambda x: self.rbuf(x).read_bool() # noqa
tc = [(True, '01'),
(False, '00')]
for p in tc:
@ -45,8 +48,8 @@ class TestBuffer(object):
assert r(self._b(p[1])) == p[0]
def test_int(self):
w = lambda x: self.wbuf().write_int(x).write_flush()
r = lambda x: self.rbuf(x).read_int()
w = lambda x: self.wbuf().write_int(x).write_flush() # noqa
r = lambda x: self.rbuf(x).read_int() # noqa
tc = [(0x00, '00 00 00 00'),
(0x01, '00 00 00 01'),
(0xabcd, '00 00 ab cd'),
@ -56,8 +59,8 @@ class TestBuffer(object):
assert r(self._b(p[1])) == p[0]
def test_string(self):
w = lambda x: self.wbuf().write_string(x).write_flush()
r = lambda x: self.rbuf(x).read_string()
w = lambda x: self.wbuf().write_string(x).write_flush() # noqa
r = lambda x: self.rbuf(x).read_string() # noqa
tc = [(u'abc1', '00 00 00 04 61 62 63 31'),
(b'abc2', '00 00 00 04 61 62 63 32')]
for p in tc:
@ -68,22 +71,35 @@ class TestBuffer(object):
assert r(self._b(p[1])) == v
def test_list(self):
w = lambda x: self.wbuf().write_list(x).write_flush()
r = lambda x: self.rbuf(x).read_list()
w = lambda x: self.wbuf().write_list(x).write_flush() # noqa
r = lambda x: self.rbuf(x).read_list() # noqa
tc = [(['d', 'ef', 'ault'], '00 00 00 09 64 2c 65 66 2c 61 75 6c 74')]
for p in tc:
assert w(p[0]) == self._b(p[1])
assert r(self._b(p[1])) == p[0]
def test_list_nonutf8(self):
r = lambda x: self.rbuf(x).read_list() # noqa
src = self._b('00 00 00 04 de ad be ef')
dst = [(b'\xde\xad' + self.utf8rchar + self.utf8rchar).decode('utf-8')]
assert r(src) == dst
def test_line(self):
w = lambda x: self.wbuf().write_line(x).write_flush()
r = lambda x: self.rbuf(x).read_line()
w = lambda x: self.wbuf().write_line(x).write_flush() # noqa
r = lambda x: self.rbuf(x).read_line() # noqa
tc = [(u'example line', '65 78 61 6d 70 6c 65 20 6c 69 6e 65 0d 0a')]
for p in tc:
assert w(p[0]) == self._b(p[1])
assert r(self._b(p[1])) == p[0]
def test_line_nonutf8(self):
r = lambda x: self.rbuf(x).read_line() # noqa
src = self._b('de ad be af')
dst = (b'\xde\xad' + self.utf8rchar + self.utf8rchar).decode('utf-8')
assert r(src) == dst
def test_bitlen(self):
# pylint: disable=protected-access
class Py26Int(int):
def bit_length(self):
raise AttributeError
@ -91,8 +107,8 @@ class TestBuffer(object):
assert self.wbuf._bitlength(Py26Int(42)) == 6
def test_mpint1(self):
mpint1w = lambda x: self.wbuf().write_mpint1(x).write_flush()
mpint1r = lambda x: self.rbuf(x).read_mpint1()
mpint1w = lambda x: self.wbuf().write_mpint1(x).write_flush() # noqa
mpint1r = lambda x: self.rbuf(x).read_mpint1() # noqa
tc = [(0x0, '00 00'),
(0x1234, '00 0d 12 34'),
(0x12345, '00 11 01 23 45'),
@ -102,8 +118,8 @@ class TestBuffer(object):
assert mpint1r(self._b(p[1])) == p[0]
def test_mpint2(self):
mpint2w = lambda x: self.wbuf().write_mpint2(x).write_flush()
mpint2r = lambda x: self.rbuf(x).read_mpint2()
mpint2w = lambda x: self.wbuf().write_mpint2(x).write_flush() # noqa
mpint2r = lambda x: self.rbuf(x).read_mpint2() # noqa
tc = [(0x0, '00 00 00 00'),
(0x80, '00 00 00 02 00 80'),
(0x9a378f9b2e332a7, '00 00 00 08 09 a3 78 f9 b2 e3 32 a7'),

162
test/test_errors.py Normal file
View File

@ -0,0 +1,162 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socket
import errno
import pytest
# pylint: disable=attribute-defined-outside-init
class TestErrors(object):
@pytest.fixture(autouse=True)
def init(self, ssh_audit):
self.AuditConf = ssh_audit.AuditConf
self.audit = ssh_audit.audit
def _conf(self):
conf = self.AuditConf('localhost', 22)
conf.colors = False
conf.batch = True
return conf
def _audit(self, spy, conf=None, sysexit=True):
if conf is None:
conf = self._conf()
spy.begin()
if sysexit:
with pytest.raises(SystemExit):
self.audit(conf)
else:
self.audit(conf)
lines = spy.flush()
return lines
def test_connection_unresolved(self, output_spy, virtual_socket):
vsocket = virtual_socket
vsocket.gsock.addrinfodata['localhost#22'] = []
lines = self._audit(output_spy)
assert len(lines) == 1
assert 'has no DNS records' in lines[-1]
def test_connection_refused(self, output_spy, virtual_socket):
vsocket = virtual_socket
vsocket.errors['connect'] = socket.error(errno.ECONNREFUSED, 'Connection refused')
lines = self._audit(output_spy)
assert len(lines) == 1
assert 'Connection refused' in lines[-1]
def test_connection_timeout(self, output_spy, virtual_socket):
vsocket = virtual_socket
vsocket.errors['connect'] = socket.timeout('timed out')
lines = self._audit(output_spy)
assert len(lines) == 1
assert 'timed out' in lines[-1]
def test_recv_empty(self, output_spy, virtual_socket):
vsocket = virtual_socket
lines = self._audit(output_spy)
assert len(lines) == 1
assert 'did not receive banner' in lines[-1]
def test_recv_timeout(self, output_spy, virtual_socket):
vsocket = virtual_socket
vsocket.rdata.append(socket.timeout('timed out'))
lines = self._audit(output_spy)
assert len(lines) == 1
assert 'did not receive banner' in lines[-1]
assert 'timed out' in lines[-1]
def test_recv_retry_till_timeout(self, output_spy, virtual_socket):
vsocket = virtual_socket
vsocket.rdata.append(socket.error(errno.EAGAIN, 'Resource temporarily unavailable'))
vsocket.rdata.append(socket.error(errno.EWOULDBLOCK, 'Resource temporarily unavailable'))
vsocket.rdata.append(socket.error(errno.EAGAIN, 'Resource temporarily unavailable'))
vsocket.rdata.append(socket.timeout('timed out'))
lines = self._audit(output_spy)
assert len(lines) == 1
assert 'did not receive banner' in lines[-1]
assert 'timed out' in lines[-1]
def test_recv_retry_till_reset(self, output_spy, virtual_socket):
vsocket = virtual_socket
vsocket.rdata.append(socket.error(errno.EAGAIN, 'Resource temporarily unavailable'))
vsocket.rdata.append(socket.error(errno.EWOULDBLOCK, 'Resource temporarily unavailable'))
vsocket.rdata.append(socket.error(errno.EAGAIN, 'Resource temporarily unavailable'))
vsocket.rdata.append(socket.error(errno.ECONNRESET, 'Connection reset by peer'))
lines = self._audit(output_spy)
assert len(lines) == 1
assert 'did not receive banner' in lines[-1]
assert 'reset by peer' in lines[-1]
def test_connection_closed_before_banner(self, output_spy, virtual_socket):
vsocket = virtual_socket
vsocket.rdata.append(socket.error(errno.ECONNRESET, 'Connection reset by peer'))
lines = self._audit(output_spy)
assert len(lines) == 1
assert 'did not receive banner' in lines[-1]
assert 'reset by peer' in lines[-1]
def test_connection_closed_after_header(self, output_spy, virtual_socket):
vsocket = virtual_socket
vsocket.rdata.append(b'header line 1\n')
vsocket.rdata.append(b'\n')
vsocket.rdata.append(b'header line 2\n')
vsocket.rdata.append(socket.error(errno.ECONNRESET, 'Connection reset by peer'))
lines = self._audit(output_spy)
assert len(lines) == 3
assert 'did not receive banner' in lines[-1]
assert 'reset by peer' in lines[-1]
def test_connection_closed_after_banner(self, output_spy, virtual_socket):
vsocket = virtual_socket
vsocket.rdata.append(b'SSH-2.0-ssh-audit-test\r\n')
vsocket.rdata.append(socket.error(54, 'Connection reset by peer'))
lines = self._audit(output_spy)
assert len(lines) == 2
assert 'error reading packet' in lines[-1]
assert 'reset by peer' in lines[-1]
def test_empty_data_after_banner(self, output_spy, virtual_socket):
vsocket = virtual_socket
vsocket.rdata.append(b'SSH-2.0-ssh-audit-test\r\n')
lines = self._audit(output_spy)
assert len(lines) == 2
assert 'error reading packet' in lines[-1]
assert 'empty' in lines[-1]
def test_wrong_data_after_banner(self, output_spy, virtual_socket):
vsocket = virtual_socket
vsocket.rdata.append(b'SSH-2.0-ssh-audit-test\r\n')
vsocket.rdata.append(b'xxx\n')
lines = self._audit(output_spy)
assert len(lines) == 2
assert 'error reading packet' in lines[-1]
assert 'xxx' in lines[-1]
def test_non_ascii_banner(self, output_spy, virtual_socket):
vsocket = virtual_socket
vsocket.rdata.append(b'SSH-2.0-ssh-audit-test\xc3\xbc\r\n')
lines = self._audit(output_spy)
assert len(lines) == 3
assert 'error reading packet' in lines[-1]
assert 'ASCII' in lines[-2]
assert lines[-3].endswith('SSH-2.0-ssh-audit-test?')
def test_nonutf8_data_after_banner(self, output_spy, virtual_socket):
vsocket = virtual_socket
vsocket.rdata.append(b'SSH-2.0-ssh-audit-test\r\n')
vsocket.rdata.append(b'\x81\xff\n')
lines = self._audit(output_spy)
assert len(lines) == 2
assert 'error reading packet' in lines[-1]
assert '\\x81\\xff' in lines[-1]
def test_protocol_mismatch_by_conf(self, output_spy, virtual_socket):
vsocket = virtual_socket
vsocket.rdata.append(b'SSH-1.3-ssh-audit-test\r\n')
vsocket.rdata.append(b'Protocol major versions differ.\n')
conf = self._conf()
conf.ssh1, conf.ssh2 = True, False
lines = self._audit(output_spy, conf)
assert len(lines) == 3
assert 'error reading packet' in lines[-1]
assert 'major versions differ' in lines[-1]

View File

@ -1,9 +1,10 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
import pytest, io, sys
import pytest
# pylint: disable=attribute-defined-outside-init
class TestOutput(object):
@pytest.fixture(autouse=True)
def init(self, ssh_audit):
@ -23,7 +24,7 @@ class TestOutput(object):
def test_output_buffer_no_flush(self, output_spy):
output_spy.begin()
with self.OutputBuffer() as obuf:
with self.OutputBuffer():
print(u'abc')
assert output_spy.flush() == []
@ -40,13 +41,13 @@ class TestOutput(object):
out = self.Output()
# default: on
assert out.batch is False
assert out.colors is True
assert out.minlevel == 'info'
assert out.use_colors is True
assert out.level == 'info'
def test_output_colors(self, output_spy):
out = self.Output()
# test without colors
out.colors = False
out.use_colors = False
output_spy.begin()
out.info('info color')
assert output_spy.flush() == [u'info color']
@ -62,8 +63,10 @@ class TestOutput(object):
output_spy.begin()
out.fail('fail color')
assert output_spy.flush() == [u'fail color']
if not out.colors_supported:
return
# test with colors
out.colors = True
out.use_colors = True
output_spy.begin()
out.info('info color')
assert output_spy.flush() == [u'info color']
@ -90,29 +93,29 @@ class TestOutput(object):
def test_output_levels(self):
out = self.Output()
assert out.getlevel('info') == 0
assert out.getlevel('good') == 0
assert out.getlevel('warn') == 1
assert out.getlevel('fail') == 2
assert out.getlevel('unknown') > 2
assert out.get_level('info') == 0
assert out.get_level('good') == 0
assert out.get_level('warn') == 1
assert out.get_level('fail') == 2
assert out.get_level('unknown') > 2
def test_output_minlevel_property(self):
def test_output_level_property(self):
out = self.Output()
out.minlevel = 'info'
assert out.minlevel == 'info'
out.minlevel = 'good'
assert out.minlevel == 'info'
out.minlevel = 'warn'
assert out.minlevel == 'warn'
out.minlevel = 'fail'
assert out.minlevel == 'fail'
out.minlevel = 'invalid level'
assert out.minlevel == 'unknown'
out.level = 'info'
assert out.level == 'info'
out.level = 'good'
assert out.level == 'info'
out.level = 'warn'
assert out.level == 'warn'
out.level = 'fail'
assert out.level == 'fail'
out.level = 'invalid level'
assert out.level == 'unknown'
def test_output_minlevel(self, output_spy):
def test_output_level(self, output_spy):
out = self.Output()
# visible: all
out.minlevel = 'info'
out.level = 'info'
output_spy.begin()
out.info('info color')
out.head('head color')
@ -121,7 +124,7 @@ class TestOutput(object):
out.fail('fail color')
assert len(output_spy.flush()) == 5
# visible: head, warn, fail
out.minlevel = 'warn'
out.level = 'warn'
output_spy.begin()
out.info('info color')
out.head('head color')
@ -130,7 +133,7 @@ class TestOutput(object):
out.fail('fail color')
assert len(output_spy.flush()) == 3
# visible: head, fail
out.minlevel = 'fail'
out.level = 'fail'
output_spy.begin()
out.info('info color')
out.head('head color')
@ -139,7 +142,7 @@ class TestOutput(object):
out.fail('fail color')
assert len(output_spy.flush()) == 2
# visible: head
out.minlevel = 'invalid level'
out.level = 'invalid level'
output_spy.begin()
out.info('info color')
out.head('head color')
@ -152,7 +155,7 @@ class TestOutput(object):
out = self.Output()
# visible: all
output_spy.begin()
out.minlevel = 'info'
out.level = 'info'
out.batch = False
out.info('info color')
out.head('head color')
@ -162,7 +165,7 @@ class TestOutput(object):
assert len(output_spy.flush()) == 5
# visible: all except head
output_spy.begin()
out.minlevel = 'info'
out.level = 'info'
out.batch = True
out.info('info color')
out.head('head color')

85
test/test_resolve.py Normal file
View File

@ -0,0 +1,85 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socket
import pytest
# pylint: disable=attribute-defined-outside-init,protected-access
class TestResolve(object):
@pytest.fixture(autouse=True)
def init(self, ssh_audit):
self.AuditConf = ssh_audit.AuditConf
self.audit = ssh_audit.audit
self.ssh = ssh_audit.SSH
def _conf(self):
conf = self.AuditConf('localhost', 22)
conf.colors = False
conf.batch = True
return conf
def test_resolve_error(self, output_spy, virtual_socket):
vsocket = virtual_socket
vsocket.gsock.addrinfodata['localhost#22'] = socket.gaierror(8, 'hostname nor servname provided, or not known')
s = self.ssh.Socket('localhost', 22)
conf = self._conf()
output_spy.begin()
with pytest.raises(SystemExit):
r = list(s._resolve(conf.ipvo))
lines = output_spy.flush()
assert len(lines) == 1
assert 'hostname nor servname provided' in lines[-1]
def test_resolve_hostname_without_records(self, output_spy, virtual_socket):
vsocket = virtual_socket
vsocket.gsock.addrinfodata['localhost#22'] = []
s = self.ssh.Socket('localhost', 22)
conf = self._conf()
output_spy.begin()
r = list(s._resolve(conf.ipvo))
assert len(r) == 0
def test_resolve_ipv4(self, virtual_socket):
vsocket = virtual_socket
conf = self._conf()
conf.ipv4 = True
s = self.ssh.Socket('localhost', 22)
r = list(s._resolve(conf.ipvo))
assert len(r) == 1
assert r[0] == (socket.AF_INET, ('127.0.0.1', 22))
def test_resolve_ipv6(self, virtual_socket):
vsocket = virtual_socket
s = self.ssh.Socket('localhost', 22)
conf = self._conf()
conf.ipv6 = True
r = list(s._resolve(conf.ipvo))
assert len(r) == 1
assert r[0] == (socket.AF_INET6, ('::1', 22))
def test_resolve_ipv46_both(self, virtual_socket):
vsocket = virtual_socket
s = self.ssh.Socket('localhost', 22)
conf = self._conf()
r = list(s._resolve(conf.ipvo))
assert len(r) == 2
assert r[0] == (socket.AF_INET, ('127.0.0.1', 22))
assert r[1] == (socket.AF_INET6, ('::1', 22))
def test_resolve_ipv46_order(self, virtual_socket):
vsocket = virtual_socket
s = self.ssh.Socket('localhost', 22)
conf = self._conf()
conf.ipv4 = True
conf.ipv6 = True
r = list(s._resolve(conf.ipvo))
assert len(r) == 2
assert r[0] == (socket.AF_INET, ('127.0.0.1', 22))
assert r[1] == (socket.AF_INET6, ('::1', 22))
conf = self._conf()
conf.ipv6 = True
conf.ipv4 = True
r = list(s._resolve(conf.ipvo))
assert len(r) == 2
assert r[0] == (socket.AF_INET6, ('::1', 22))
assert r[1] == (socket.AF_INET, ('127.0.0.1', 22))

41
test/test_socket.py Normal file
View File

@ -0,0 +1,41 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socket
import pytest
# pylint: disable=attribute-defined-outside-init
class TestSocket(object):
@pytest.fixture(autouse=True)
def init(self, ssh_audit):
self.ssh = ssh_audit.SSH
def test_invalid_host(self, virtual_socket):
with pytest.raises(ValueError):
s = self.ssh.Socket(None, 22)
def test_invalid_port(self, virtual_socket):
with pytest.raises(ValueError):
s = self.ssh.Socket('localhost', 'abc')
with pytest.raises(ValueError):
s = self.ssh.Socket('localhost', -1)
with pytest.raises(ValueError):
s = self.ssh.Socket('localhost', 0)
with pytest.raises(ValueError):
s = self.ssh.Socket('localhost', 65536)
def test_not_connected_socket(self, virtual_socket):
sock = self.ssh.Socket('localhost', 22)
banner, header, err = sock.get_banner()
assert banner is None
assert len(header) == 0
assert err == 'not connected'
s, e = sock.recv()
assert s == -1
assert e == 'not connected'
s, e = sock.send('nothing')
assert s == -1
assert e == 'not connected'
s, e = sock.send_packet()
assert s == -1
assert e == 'not connected'

View File

@ -3,19 +3,21 @@
import pytest
# pylint: disable=line-too-long,attribute-defined-outside-init
class TestSoftware(object):
@pytest.fixture(autouse=True)
def init(self, ssh_audit):
self.ssh = ssh_audit.SSH
def test_unknown_software(self):
ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x))
ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x)) # noqa
assert ps('SSH-1.5') is None
assert ps('SSH-1.99-AlfaMegaServer') is None
assert ps('SSH-2.0-BetaMegaServer 0.0.1') is None
def test_openssh_software(self):
ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x))
# pylint: disable=too-many-statements
ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x)) # noqa
# common
s = ps('SSH-2.0-OpenSSH_7.3')
assert s.vendor is None
@ -102,7 +104,7 @@ class TestSoftware(object):
assert repr(s) == '<Software(product=OpenSSH, version=5.9, patch=CASPUR)>'
def test_dropbear_software(self):
ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x))
ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x)) # noqa
# common
s = ps('SSH-2.0-dropbear_2016.74')
assert s.vendor is None
@ -153,7 +155,7 @@ class TestSoftware(object):
assert repr(s) == '<Software(product=Dropbear SSH, version=2014.66, patch=agbn_1)>'
def test_libssh_software(self):
ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x))
ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x)) # noqa
# common
s = ps('SSH-2.0-libssh-0.2')
assert s.vendor is None
@ -166,20 +168,20 @@ class TestSoftware(object):
assert s.display(True) == str(s)
assert s.display(False) == str(s)
assert repr(s) == '<Software(product=libssh, version=0.2)>'
s = ps('SSH-2.0-libssh-0.7.3')
s = ps('SSH-2.0-libssh-0.7.4')
assert s.vendor is None
assert s.product == 'libssh'
assert s.version == '0.7.3'
assert s.version == '0.7.4'
assert s.patch is None
assert s.os is None
assert str(s) == 'libssh 0.7.3'
assert str(s) == 'libssh 0.7.4'
assert str(s) == s.display()
assert s.display(True) == str(s)
assert s.display(False) == str(s)
assert repr(s) == '<Software(product=libssh, version=0.7.3)>'
assert repr(s) == '<Software(product=libssh, version=0.7.4)>'
def test_romsshell_software(self):
ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x))
ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x)) # noqa
# common
s = ps('SSH-2.0-RomSShell_5.40')
assert s.vendor == 'Allegro Software'
@ -194,7 +196,7 @@ class TestSoftware(object):
assert repr(s) == '<Software(vendor=Allegro Software, product=RomSShell, version=5.40)>'
def test_hp_ilo_software(self):
ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x))
ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x)) # noqa
# common
s = ps('SSH-2.0-mpSSH_0.2.1')
assert s.vendor == 'HP'
@ -209,7 +211,7 @@ class TestSoftware(object):
assert repr(s) == '<Software(vendor=HP, product=iLO (Integrated Lights-Out) sshd, version=0.2.1)>'
def test_cisco_software(self):
ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x))
ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x)) # noqa
# common
s = ps('SSH-1.5-Cisco-1.25')
assert s.vendor == 'Cisco'
@ -223,8 +225,8 @@ class TestSoftware(object):
assert s.display(False) == str(s)
assert repr(s) == '<Software(vendor=Cisco, product=IOS/PIX sshd, version=1.25)>'
def test_sofware_os(self):
ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x))
def test_software_os(self):
ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x)) # noqa
# unknown
s = ps('SSH-2.0-OpenSSH_3.7.1 MegaOperatingSystem 123')
assert s.os is None

View File

@ -1,8 +1,10 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import struct
import pytest
# pylint: disable=line-too-long,attribute-defined-outside-init
class TestSSH1(object):
@pytest.fixture(autouse=True)
def init(self, ssh_audit):
@ -10,15 +12,32 @@ class TestSSH1(object):
self.ssh1 = ssh_audit.SSH1
self.rbuf = ssh_audit.ReadBuf
self.wbuf = ssh_audit.WriteBuf
self.audit = ssh_audit.audit
self.AuditConf = ssh_audit.AuditConf
def test_crc32(self):
assert self.ssh1.crc32(b'') == 0x00
assert self.ssh1.crc32(b'The quick brown fox jumps over the lazy dog') == 0xb9c60808
def _conf(self):
conf = self.AuditConf('localhost', 22)
conf.colors = False
conf.batch = True
conf.verbose = True
conf.ssh1 = True
conf.ssh2 = False
return conf
def _server_key(self):
def _create_ssh1_packet(self, payload, valid_crc=True):
padding = -(len(payload) + 4) % 8
plen = len(payload) + 4
pad_bytes = b'\x00' * padding
cksum = self.ssh1.crc32(pad_bytes + payload) if valid_crc else 0
data = struct.pack('>I', plen) + pad_bytes + payload + struct.pack('>I', cksum)
return data
@classmethod
def _server_key(cls):
return (1024, 0x10001, 0xee6552da432e0ac2c422df1a51287507748bfe3b5e3e4fa989a8f49fdc163a17754939ef18ef8a667ea3b71036a151fcd7f5e01ceef1e4439864baf3ac569047582c69d6c128212e0980dcb3168f00d371004039983f6033cd785b8b8f85096c7d9405cbfdc664e27c966356a6b4eb6ee20ad43414b50de18b22829c1880b551)
def _host_key(self):
@classmethod
def _host_key(cls):
return (2048, 0x10001, 0xdfa20cd2a530ccc8c870aa60d9feb3b35deeab81c3215a96557abbd683d21f4600f38e475d87100da9a4404220eeb3bb5584e5a2b5b48ffda58530ea19104a32577d7459d91e76aa711b241050f4cc6d5327ccce254f371acad3be56d46eb5919b73f20dbdb1177b700f00891c5bf4ed128bb90ed541b778288285bcfa28432ab5cbcb8321b6e24760e998e0daa519f093a631e44276d7dd252ce0c08c75e2ab28a7349ead779f97d0f20a6d413bf3623cd216dc35375f6366690bcc41e3b2d5465840ec7ee0dc7e3f1c101d674a0c7dbccbc3942788b111396add2f8153b46a0e4b50d66e57ee92958f1c860dd97cc0e40e32febff915343ed53573142bdf4b)
def _pkm_payload(self):
@ -33,42 +52,105 @@ class TestSSH1(object):
w.write_int(36)
return w.write_flush()
def test_crc32(self):
assert self.ssh1.crc32(b'') == 0x00
assert self.ssh1.crc32(b'The quick brown fox jumps over the lazy dog') == 0xb9c60808
def test_fingerprint(self):
# pylint: disable=protected-access
b, e, m = self._host_key()
fpd = self.wbuf._create_mpint(m, False)
fpd += self.wbuf._create_mpint(e, False)
fp = self.ssh.Fingerprint(fpd)
assert b == 2048
assert fp.md5 == 'MD5:9d:26:f8:39:fc:20:9d:9b:ca:cc:4a:0f:e1:93:f5:96'
assert fp.sha256 == 'SHA256:vZdx3mhzbvVJmn08t/ruv8WDhJ9jfKYsCTuSzot+QIs'
def test_pkm_read(self):
pkm = self.ssh1.PublicKeyMessage.parse(self._pkm_payload())
assert pkm is not None
assert pkm.cookie == b'\x88\x99\xaa\xbb\xcc\xdd\xee\xff'
b, e, m = self._server_key()
def _assert_pkm_keys(self, pkm, skey, hkey):
b, e, m = skey
assert pkm.server_key_bits == b
assert pkm.server_key_public_exponent == e
assert pkm.server_key_public_modulus == m
b, e, m = self._host_key()
b, e, m = hkey
assert pkm.host_key_bits == b
assert pkm.host_key_public_exponent == e
assert pkm.host_key_public_modulus == m
fp = self.ssh.Fingerprint(pkm.host_key_fingerprint_data)
def _assert_pkm_fields(self, pkm, skey, hkey):
assert pkm is not None
assert pkm.cookie == b'\x88\x99\xaa\xbb\xcc\xdd\xee\xff'
self._assert_pkm_keys(pkm, skey, hkey)
assert pkm.protocol_flags == 2
assert pkm.supported_ciphers_mask == 72
assert pkm.supported_ciphers == ['3des', 'blowfish']
assert pkm.supported_authentications_mask == 36
assert pkm.supported_authentications == ['rsa', 'tis']
fp = self.ssh.Fingerprint(pkm.host_key_fingerprint_data)
assert fp.md5 == 'MD5:9d:26:f8:39:fc:20:9d:9b:ca:cc:4a:0f:e1:93:f5:96'
assert fp.sha256 == 'SHA256:vZdx3mhzbvVJmn08t/ruv8WDhJ9jfKYsCTuSzot+QIs'
def test_pkm_init(self):
cookie = b'\x88\x99\xaa\xbb\xcc\xdd\xee\xff'
pflags, cmask, amask = 2, 72, 36
skey, hkey = self._server_key(), self._host_key()
pkm = self.ssh1.PublicKeyMessage(cookie, skey, hkey, pflags, cmask, amask)
self._assert_pkm_fields(pkm, skey, hkey)
for skey2 in ([], [0], [0,1], [0,1,2,3]):
with pytest.raises(ValueError):
pkm = self.ssh1.PublicKeyMessage(cookie, skey2, hkey, pflags, cmask, amask)
for hkey2 in ([], [0], [0,1], [0,1,2,3]):
with pytest.raises(ValueError):
print(hkey2)
pkm = self.ssh1.PublicKeyMessage(cookie, skey, hkey2, pflags, cmask, amask)
def test_pkm_read(self):
pkm = self.ssh1.PublicKeyMessage.parse(self._pkm_payload())
self._assert_pkm_fields(pkm, self._server_key(), self._host_key())
def test_pkm_payload(self):
cookie = b'\x88\x99\xaa\xbb\xcc\xdd\xee\xff'
skey = self._server_key()
hkey = self._host_key()
pflags = 2
cmask = 72
amask = 36
skey, hkey = self._server_key(), self._host_key()
pflags, cmask, amask = 2, 72, 36
pkm1 = self.ssh1.PublicKeyMessage(cookie, skey, hkey, pflags, cmask, amask)
pkm2 = self.ssh1.PublicKeyMessage.parse(self._pkm_payload())
assert pkm1.payload == pkm2.payload
def test_ssh1_server_simple(self, output_spy, virtual_socket):
vsocket = virtual_socket
w = self.wbuf()
w.write_byte(self.ssh.Protocol.SMSG_PUBLIC_KEY)
w.write(self._pkm_payload())
vsocket.rdata.append(b'SSH-1.5-OpenSSH_7.2 ssh-audit-test\r\n')
vsocket.rdata.append(self._create_ssh1_packet(w.write_flush()))
output_spy.begin()
self.audit(self._conf())
lines = output_spy.flush()
assert len(lines) == 13
def test_ssh1_server_invalid_first_packet(self, output_spy, virtual_socket):
vsocket = virtual_socket
w = self.wbuf()
w.write_byte(self.ssh.Protocol.SMSG_PUBLIC_KEY + 1)
w.write(self._pkm_payload())
vsocket.rdata.append(b'SSH-1.5-OpenSSH_7.2 ssh-audit-test\r\n')
vsocket.rdata.append(self._create_ssh1_packet(w.write_flush()))
output_spy.begin()
with pytest.raises(SystemExit):
self.audit(self._conf())
lines = output_spy.flush()
assert len(lines) == 7
assert 'unknown message' in lines[-1]
def test_ssh1_server_invalid_checksum(self, output_spy, virtual_socket):
vsocket = virtual_socket
w = self.wbuf()
w.write_byte(self.ssh.Protocol.SMSG_PUBLIC_KEY + 1)
w.write(self._pkm_payload())
vsocket.rdata.append(b'SSH-1.5-OpenSSH_7.2 ssh-audit-test\r\n')
vsocket.rdata.append(self._create_ssh1_packet(w.write_flush(), False))
output_spy.begin()
with pytest.raises(SystemExit):
self.audit(self._conf())
lines = output_spy.flush()
assert len(lines) == 1
assert 'checksum' in lines[-1]

View File

@ -1,8 +1,10 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import struct, os
import pytest
# pylint: disable=line-too-long,attribute-defined-outside-init
class TestSSH2(object):
@pytest.fixture(autouse=True)
def init(self, ssh_audit):
@ -10,6 +12,27 @@ class TestSSH2(object):
self.ssh2 = ssh_audit.SSH2
self.rbuf = ssh_audit.ReadBuf
self.wbuf = ssh_audit.WriteBuf
self.audit = ssh_audit.audit
self.AuditConf = ssh_audit.AuditConf
def _conf(self):
conf = self.AuditConf('localhost', 22)
conf.colors = False
conf.batch = True
conf.verbose = True
conf.ssh1 = False
conf.ssh2 = True
return conf
@classmethod
def _create_ssh2_packet(cls, payload):
padding = -(len(payload) + 5) % 8
if padding < 4:
padding += 8
plen = len(payload) + padding + 1
pad_bytes = b'\x00' * padding
data = struct.pack('>Ib', plen, padding) + payload + pad_bytes
return data
def _kex_payload(self):
w = self.wbuf()
@ -46,3 +69,87 @@ class TestSSH2(object):
assert kex.server.languages == [u'']
assert kex.follows is False
assert kex.unused == 0
def _get_empty_kex(self, cookie=None):
kex_algs, key_algs = [], []
enc, mac, compression, languages = [], [], ['none'], []
cli = self.ssh2.KexParty(enc, mac, compression, languages)
enc, mac, compression, languages = [], [], ['none'], []
srv = self.ssh2.KexParty(enc, mac, compression, languages)
if cookie is None:
cookie = os.urandom(16)
kex = self.ssh2.Kex(cookie, kex_algs, key_algs, cli, srv, 0)
return kex
def _get_kex_variat1(self):
cookie = b'\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff'
kex = self._get_empty_kex(cookie)
kex.kex_algorithms.append('curve25519-sha256@libssh.org')
kex.kex_algorithms.append('ecdh-sha2-nistp256')
kex.kex_algorithms.append('ecdh-sha2-nistp384')
kex.kex_algorithms.append('ecdh-sha2-nistp521')
kex.kex_algorithms.append('diffie-hellman-group-exchange-sha256')
kex.kex_algorithms.append('diffie-hellman-group14-sha1')
kex.key_algorithms.append('ssh-rsa')
kex.key_algorithms.append('rsa-sha2-512')
kex.key_algorithms.append('rsa-sha2-256')
kex.key_algorithms.append('ssh-ed25519')
kex.server.encryption.append('chacha20-poly1305@openssh.com')
kex.server.encryption.append('aes128-ctr')
kex.server.encryption.append('aes192-ctr')
kex.server.encryption.append('aes256-ctr')
kex.server.encryption.append('aes128-gcm@openssh.com')
kex.server.encryption.append('aes256-gcm@openssh.com')
kex.server.encryption.append('aes128-cbc')
kex.server.encryption.append('aes192-cbc')
kex.server.encryption.append('aes256-cbc')
kex.server.mac.append('umac-64-etm@openssh.com')
kex.server.mac.append('umac-128-etm@openssh.com')
kex.server.mac.append('hmac-sha2-256-etm@openssh.com')
kex.server.mac.append('hmac-sha2-512-etm@openssh.com')
kex.server.mac.append('hmac-sha1-etm@openssh.com')
kex.server.mac.append('umac-64@openssh.com')
kex.server.mac.append('umac-128@openssh.com')
kex.server.mac.append('hmac-sha2-256')
kex.server.mac.append('hmac-sha2-512')
kex.server.mac.append('hmac-sha1')
kex.server.compression.append('zlib@openssh.com')
for a in kex.server.encryption:
kex.client.encryption.append(a)
for a in kex.server.mac:
kex.client.mac.append(a)
for a in kex.server.compression:
if a == 'none':
continue
kex.client.compression.append(a)
return kex
def test_key_payload(self):
kex1 = self._get_kex_variat1()
kex2 = self.ssh2.Kex.parse(self._kex_payload())
assert kex1.payload == kex2.payload
def test_ssh2_server_simple(self, output_spy, virtual_socket):
vsocket = virtual_socket
w = self.wbuf()
w.write_byte(self.ssh.Protocol.MSG_KEXINIT)
w.write(self._kex_payload())
vsocket.rdata.append(b'SSH-2.0-OpenSSH_7.3 ssh-audit-test\r\n')
vsocket.rdata.append(self._create_ssh2_packet(w.write_flush()))
output_spy.begin()
self.audit(self._conf())
lines = output_spy.flush()
assert len(lines) == 72
def test_ssh2_server_invalid_first_packet(self, output_spy, virtual_socket):
vsocket = virtual_socket
w = self.wbuf()
w.write_byte(self.ssh.Protocol.MSG_KEXINIT + 1)
vsocket.rdata.append(b'SSH-2.0-OpenSSH_7.3 ssh-audit-test\r\n')
vsocket.rdata.append(self._create_ssh2_packet(w.write_flush()))
output_spy.begin()
with pytest.raises(SystemExit):
self.audit(self._conf())
lines = output_spy.flush()
assert len(lines) == 3
assert 'unknown message' in lines[-1]

164
test/test_ssh_algorithm.py Normal file
View File

@ -0,0 +1,164 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pytest
# pylint: disable=attribute-defined-outside-init
class TestSSHAlgorithm(object):
@pytest.fixture(autouse=True)
def init(self, ssh_audit):
self.ssh = ssh_audit.SSH
def _tf(self, v, s=None):
return self.ssh.Algorithm.Timeframe().update(v, s)
def test_get_ssh_version(self):
def ver(v):
return self.ssh.Algorithm.get_ssh_version(v)
assert ver('7.5') == ('OpenSSH', '7.5', False)
assert ver('7.5C') == ('OpenSSH', '7.5', True)
assert ver('d2016.74') == ('Dropbear SSH', '2016.74', False)
assert ver('l10.7.4') == ('libssh', '0.7.4', False)
assert ver('')[1] == ''
def test_get_since_text(self):
def gst(v):
return self.ssh.Algorithm.get_since_text(v)
assert gst(['7.5']) == 'available since OpenSSH 7.5'
assert gst(['7.5C']) == 'available since OpenSSH 7.5 (client only)'
assert gst(['7.5,']) == 'available since OpenSSH 7.5'
assert gst(['d2016.73']) == 'available since Dropbear SSH 2016.73'
assert gst(['7.5,d2016.73']) == 'available since OpenSSH 7.5, Dropbear SSH 2016.73'
assert gst(['l10.7.4']) is None
assert gst([]) is None
def test_timeframe_creation(self):
# pylint: disable=line-too-long,too-many-statements
def cmp_tf(v, s, r):
assert str(self._tf(v, s)) == str(r)
cmp_tf(['6.2'], None, {'OpenSSH': ['6.2', None, '6.2', None]})
cmp_tf(['6.2'], True, {'OpenSSH': ['6.2', None, None, None]})
cmp_tf(['6.2'], False, {'OpenSSH': [None, None, '6.2', None]})
cmp_tf(['6.2C'], None, {'OpenSSH': [None, None, '6.2', None]})
cmp_tf(['6.2C'], True, {})
cmp_tf(['6.2C'], False, {'OpenSSH': [None, None, '6.2', None]})
cmp_tf(['6.1,6.2C'], None, {'OpenSSH': ['6.1', None, '6.2', None]})
cmp_tf(['6.1,6.2C'], True, {'OpenSSH': ['6.1', None, None, None]})
cmp_tf(['6.1,6.2C'], False, {'OpenSSH': [None, None, '6.2', None]})
cmp_tf(['6.2C,6.1'], None, {'OpenSSH': ['6.1', None, '6.2', None]})
cmp_tf(['6.2C,6.1'], True, {'OpenSSH': ['6.1', None, None, None]})
cmp_tf(['6.2C,6.1'], False, {'OpenSSH': [None, None, '6.2', None]})
cmp_tf(['6.3,6.2C'], None, {'OpenSSH': ['6.3', None, '6.2', None]})
cmp_tf(['6.3,6.2C'], True, {'OpenSSH': ['6.3', None, None, None]})
cmp_tf(['6.3,6.2C'], False, {'OpenSSH': [None, None, '6.2', None]})
cmp_tf(['6.2C,6.3'], None, {'OpenSSH': ['6.3', None, '6.2', None]})
cmp_tf(['6.2C,6.3'], True, {'OpenSSH': ['6.3', None, None, None]})
cmp_tf(['6.2C,6.3'], False, {'OpenSSH': [None, None, '6.2', None]})
cmp_tf(['6.2', '6.6'], None, {'OpenSSH': ['6.2', '6.6', '6.2', '6.6']})
cmp_tf(['6.2', '6.6'], True, {'OpenSSH': ['6.2', '6.6', None, None]})
cmp_tf(['6.2', '6.6'], False, {'OpenSSH': [None, None, '6.2', '6.6']})
cmp_tf(['6.2C', '6.6'], None, {'OpenSSH': [None, '6.6', '6.2', '6.6']})
cmp_tf(['6.2C', '6.6'], True, {'OpenSSH': [None, '6.6', None, None]})
cmp_tf(['6.2C', '6.6'], False, {'OpenSSH': [None, None, '6.2', '6.6']})
cmp_tf(['6.1,6.2C', '6.6'], None, {'OpenSSH': ['6.1', '6.6', '6.2', '6.6']})
cmp_tf(['6.1,6.2C', '6.6'], True, {'OpenSSH': ['6.1', '6.6', None, None]})
cmp_tf(['6.1,6.2C', '6.6'], False, {'OpenSSH': [None, None, '6.2', '6.6']})
cmp_tf(['6.2C,6.1', '6.6'], None, {'OpenSSH': ['6.1', '6.6', '6.2', '6.6']})
cmp_tf(['6.2C,6.1', '6.6'], True, {'OpenSSH': ['6.1', '6.6', None, None]})
cmp_tf(['6.2C,6.1', '6.6'], False, {'OpenSSH': [None, None, '6.2', '6.6']})
cmp_tf(['6.3,6.2C', '6.6'], None, {'OpenSSH': ['6.3', '6.6', '6.2', '6.6']})
cmp_tf(['6.3,6.2C', '6.6'], True, {'OpenSSH': ['6.3', '6.6', None, None]})
cmp_tf(['6.3,6.2C', '6.6'], False, {'OpenSSH': [None, None, '6.2', '6.6']})
cmp_tf(['6.2C,6.3', '6.6'], None, {'OpenSSH': ['6.3', '6.6', '6.2', '6.6']})
cmp_tf(['6.2C,6.3', '6.6'], True, {'OpenSSH': ['6.3', '6.6', None, None]})
cmp_tf(['6.2C,6.3', '6.6'], False, {'OpenSSH': [None, None, '6.2', '6.6']})
cmp_tf(['6.2', '6.6', None], None, {'OpenSSH': ['6.2', '6.6', '6.2', None]})
cmp_tf(['6.2', '6.6', None], True, {'OpenSSH': ['6.2', '6.6', None, None]})
cmp_tf(['6.2', '6.6', None], False, {'OpenSSH': [None, None, '6.2', None]})
cmp_tf(['6.2C', '6.6', None], None, {'OpenSSH': [None, '6.6', '6.2', None]})
cmp_tf(['6.2C', '6.6', None], True, {'OpenSSH': [None, '6.6', None, None]})
cmp_tf(['6.2C', '6.6', None], False, {'OpenSSH': [None, None, '6.2', None]})
cmp_tf(['6.1,6.2C', '6.6', None], None, {'OpenSSH': ['6.1', '6.6', '6.2', None]})
cmp_tf(['6.1,6.2C', '6.6', None], True, {'OpenSSH': ['6.1', '6.6', None, None]})
cmp_tf(['6.1,6.2C', '6.6', None], False, {'OpenSSH': [None, None, '6.2', None]})
cmp_tf(['6.2C,6.1', '6.6', None], None, {'OpenSSH': ['6.1', '6.6', '6.2', None]})
cmp_tf(['6.2C,6.1', '6.6', None], True, {'OpenSSH': ['6.1', '6.6', None, None]})
cmp_tf(['6.2C,6.1', '6.6', None], False, {'OpenSSH': [None, None, '6.2', None]})
cmp_tf(['6.2,6.3C', '6.6', None], None, {'OpenSSH': ['6.2', '6.6', '6.3', None]})
cmp_tf(['6.2,6.3C', '6.6', None], True, {'OpenSSH': ['6.2', '6.6', None, None]})
cmp_tf(['6.2,6.3C', '6.6', None], False, {'OpenSSH': [None, None, '6.3', None]})
cmp_tf(['6.3C,6.2', '6.6', None], None, {'OpenSSH': ['6.2', '6.6', '6.3', None]})
cmp_tf(['6.3C,6.2', '6.6', None], True, {'OpenSSH': ['6.2', '6.6', None, None]})
cmp_tf(['6.3C,6.2', '6.6', None], False, {'OpenSSH': [None, None, '6.3', None]})
cmp_tf(['6.2', '6.6', '7.1'], None, {'OpenSSH': ['6.2', '6.6', '6.2', '7.1']})
cmp_tf(['6.2', '6.6', '7.1'], True, {'OpenSSH': ['6.2', '6.6', None, None]})
cmp_tf(['6.2', '6.6', '7.1'], False, {'OpenSSH': [None, None, '6.2', '7.1']})
cmp_tf(['6.1,6.2C', '6.6', '7.1'], None, {'OpenSSH': ['6.1', '6.6', '6.2', '7.1']})
cmp_tf(['6.1,6.2C', '6.6', '7.1'], True, {'OpenSSH': ['6.1', '6.6', None, None]})
cmp_tf(['6.1,6.2C', '6.6', '7.1'], False, {'OpenSSH': [None, None, '6.2', '7.1']})
cmp_tf(['6.2C,6.1', '6.6', '7.1'], None, {'OpenSSH': ['6.1', '6.6', '6.2', '7.1']})
cmp_tf(['6.2C,6.1', '6.6', '7.1'], True, {'OpenSSH': ['6.1', '6.6', None, None]})
cmp_tf(['6.2C,6.1', '6.6', '7.1'], False, {'OpenSSH': [None, None, '6.2', '7.1']})
cmp_tf(['6.2,6.3C', '6.6', '7.1'], None, {'OpenSSH': ['6.2', '6.6', '6.3', '7.1']})
cmp_tf(['6.2,6.3C', '6.6', '7.1'], True, {'OpenSSH': ['6.2', '6.6', None, None]})
cmp_tf(['6.2,6.3C', '6.6', '7.1'], False, {'OpenSSH': [None, None, '6.3', '7.1']})
cmp_tf(['6.3C,6.2', '6.6', '7.1'], None, {'OpenSSH': ['6.2', '6.6', '6.3', '7.1']})
cmp_tf(['6.3C,6.2', '6.6', '7.1'], True, {'OpenSSH': ['6.2', '6.6', None, None]})
cmp_tf(['6.3C,6.2', '6.6', '7.1'], False, {'OpenSSH': [None, None, '6.3', '7.1']})
tf1 = self._tf(['6.1,d2016.72,6.2C', '6.6,d2016.73', '7.1,d2016.74'])
tf2 = self._tf(['d2016.72,6.2C,6.1', 'd2016.73,6.6', 'd2016.74,7.1'])
tf3 = self._tf(['d2016.72,6.2C,6.1', '6.6,d2016.73', '7.1,d2016.74'])
# check without caring for output order
ov = "'OpenSSH': ['6.1', '6.6', '6.2', '7.1']"
dv = "'Dropbear SSH': ['2016.72', '2016.73', '2016.72', '2016.74']"
assert len(str(tf1)) == len(str(tf2)) == len(str(tf3))
assert ov in str(tf1) and ov in str(tf2) and ov in str(tf3)
assert dv in str(tf1) and dv in str(tf2) and dv in str(tf3)
assert ov in repr(tf1) and ov in repr(tf2) and ov in repr(tf3)
assert dv in repr(tf1) and dv in repr(tf2) and dv in repr(tf3)
def test_timeframe_object(self):
tf = self._tf(['6.1,6.2C', '6.6', '7.1'])
assert 'OpenSSH' in tf
assert 'Dropbear SSH' not in tf
assert 'libssh' not in tf
assert 'unknown' not in tf
assert tf['OpenSSH'] == ('6.1', '6.6', '6.2', '7.1')
assert tf['Dropbear SSH'] == (None, None, None, None)
assert tf['libssh'] == (None, None, None, None)
assert tf['unknown'] == (None, None, None, None)
assert tf.get_from('OpenSSH', True) == '6.1'
assert tf.get_till('OpenSSH', True) == '6.6'
assert tf.get_from('OpenSSH', False) == '6.2'
assert tf.get_till('OpenSSH', False) == '7.1'
tf = self._tf(['6.1,d2016.72,6.2C', '6.6,d2016.73', '7.1,d2016.74'])
assert 'OpenSSH' in tf
assert 'Dropbear SSH' in tf
assert 'libssh' not in tf
assert 'unknown' not in tf
assert tf['OpenSSH'] == ('6.1', '6.6', '6.2', '7.1')
assert tf['Dropbear SSH'] == ('2016.72', '2016.73', '2016.72', '2016.74')
assert tf['libssh'] == (None, None, None, None)
assert tf['unknown'] == (None, None, None, None)
assert tf.get_from('OpenSSH', True) == '6.1'
assert tf.get_till('OpenSSH', True) == '6.6'
assert tf.get_from('OpenSSH', False) == '6.2'
assert tf.get_till('OpenSSH', False) == '7.1'
assert tf.get_from('Dropbear SSH', True) == '2016.72'
assert tf.get_till('Dropbear SSH', True) == '2016.73'
assert tf.get_from('Dropbear SSH', False) == '2016.72'
assert tf.get_till('Dropbear SSH', False) == '2016.74'
ov = "'OpenSSH': ['6.1', '6.6', '6.2', '7.1']"
dv = "'Dropbear SSH': ['2016.72', '2016.73', '2016.72', '2016.74']"
assert ov in str(tf)
assert dv in str(tf)
assert ov in repr(tf)
assert dv in repr(tf)

218
test/test_utils.py Normal file
View File

@ -0,0 +1,218 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import pytest
# pylint: disable=attribute-defined-outside-init
class TestUtils(object):
@pytest.fixture(autouse=True)
def init(self, ssh_audit):
self.utils = ssh_audit.Utils
self.PY3 = sys.version_info >= (3,)
def test_to_bytes_py2(self):
if self.PY3:
return
# binary_type (native str, bytes as str)
assert self.utils.to_bytes('fran\xc3\xa7ais') == 'fran\xc3\xa7ais'
assert self.utils.to_bytes(b'fran\xc3\xa7ais') == 'fran\xc3\xa7ais'
# text_type (unicode)
assert self.utils.to_bytes(u'fran\xe7ais') == 'fran\xc3\xa7ais'
# other
with pytest.raises(TypeError):
self.utils.to_bytes(123)
def test_to_bytes_py3(self):
if not self.PY3:
return
# binary_type (bytes)
assert self.utils.to_bytes(b'fran\xc3\xa7ais') == b'fran\xc3\xa7ais'
# text_type (native str as unicode, unicode)
assert self.utils.to_bytes('fran\xe7ais') == b'fran\xc3\xa7ais'
assert self.utils.to_bytes(u'fran\xe7ais') == b'fran\xc3\xa7ais'
# other
with pytest.raises(TypeError):
self.utils.to_bytes(123)
def test_to_utext_py2(self):
if self.PY3:
return
# binary_type (native str, bytes as str)
assert self.utils.to_utext('fran\xc3\xa7ais') == u'fran\xe7ais'
assert self.utils.to_utext(b'fran\xc3\xa7ais') == u'fran\xe7ais'
# text_type (unicode)
assert self.utils.to_utext(u'fran\xe7ais') == u'fran\xe7ais'
# other
with pytest.raises(TypeError):
self.utils.to_utext(123)
def test_to_utext_py3(self):
if not self.PY3:
return
# binary_type (bytes)
assert self.utils.to_utext(b'fran\xc3\xa7ais') == u'fran\xe7ais'
# text_type (native str as unicode, unicode)
assert self.utils.to_utext('fran\xe7ais') == 'fran\xe7ais'
assert self.utils.to_utext(u'fran\xe7ais') == u'fran\xe7ais'
# other
with pytest.raises(TypeError):
self.utils.to_utext(123)
def test_to_ntext_py2(self):
if self.PY3:
return
# str (native str, bytes as str)
assert self.utils.to_ntext('fran\xc3\xa7ais') == 'fran\xc3\xa7ais'
assert self.utils.to_ntext(b'fran\xc3\xa7ais') == 'fran\xc3\xa7ais'
# text_type (unicode)
assert self.utils.to_ntext(u'fran\xe7ais') == 'fran\xc3\xa7ais'
# other
with pytest.raises(TypeError):
self.utils.to_ntext(123)
def test_to_ntext_py3(self):
if not self.PY3:
return
# str (native str)
assert self.utils.to_ntext('fran\xc3\xa7ais') == 'fran\xc3\xa7ais'
assert self.utils.to_ntext(u'fran\xe7ais') == 'fran\xe7ais'
# binary_type (bytes)
assert self.utils.to_ntext(b'fran\xc3\xa7ais') == 'fran\xe7ais'
# other
with pytest.raises(TypeError):
self.utils.to_ntext(123)
def test_is_ascii_py2(self):
if self.PY3:
return
# text_type (unicode)
assert self.utils.is_ascii(u'francais') is True
assert self.utils.is_ascii(u'fran\xe7ais') is False
# str
assert self.utils.is_ascii('francais') is True
assert self.utils.is_ascii('fran\xc3\xa7ais') is False
# other
assert self.utils.is_ascii(123) is False
def test_is_ascii_py3(self):
if not self.PY3:
return
# text_type (str)
assert self.utils.is_ascii('francais') is True
assert self.utils.is_ascii(u'francais') is True
assert self.utils.is_ascii('fran\xe7ais') is False
assert self.utils.is_ascii(u'fran\xe7ais') is False
# other
assert self.utils.is_ascii(123) is False
def test_to_ascii_py2(self):
if self.PY3:
return
# text_type (unicode)
assert self.utils.to_ascii(u'francais') == 'francais'
assert self.utils.to_ascii(u'fran\xe7ais') == 'fran?ais'
assert self.utils.to_ascii(u'fran\xe7ais', 'ignore') == 'franais'
# str
assert self.utils.to_ascii('francais') == 'francais'
assert self.utils.to_ascii('fran\xc3\xa7ais') == 'fran??ais'
assert self.utils.to_ascii('fran\xc3\xa7ais', 'ignore') == 'franais'
with pytest.raises(TypeError):
self.utils.to_ascii(123)
def test_to_ascii_py3(self):
if not self.PY3:
return
# text_type (str)
assert self.utils.to_ascii('francais') == 'francais'
assert self.utils.to_ascii(u'francais') == 'francais'
assert self.utils.to_ascii('fran\xe7ais') == 'fran?ais'
assert self.utils.to_ascii('fran\xe7ais', 'ignore') == 'franais'
assert self.utils.to_ascii(u'fran\xe7ais') == 'fran?ais'
assert self.utils.to_ascii(u'fran\xe7ais', 'ignore') == 'franais'
with pytest.raises(TypeError):
self.utils.to_ascii(123)
def test_is_print_ascii_py2(self):
if self.PY3:
return
# text_type (unicode)
assert self.utils.is_print_ascii(u'francais') is True
assert self.utils.is_print_ascii(u'francais\n') is False
assert self.utils.is_print_ascii(u'fran\xe7ais') is False
assert self.utils.is_print_ascii(u'fran\xe7ais\n') is False
# str
assert self.utils.is_print_ascii('francais') is True
assert self.utils.is_print_ascii('francais\n') is False
assert self.utils.is_print_ascii('fran\xc3\xa7ais') is False
# other
assert self.utils.is_print_ascii(123) is False
def test_is_print_ascii_py3(self):
if not self.PY3:
return
# text_type (str)
assert self.utils.is_print_ascii('francais') is True
assert self.utils.is_print_ascii('francais\n') is False
assert self.utils.is_print_ascii(u'francais') is True
assert self.utils.is_print_ascii(u'francais\n') is False
assert self.utils.is_print_ascii('fran\xe7ais') is False
assert self.utils.is_print_ascii(u'fran\xe7ais') is False
# other
assert self.utils.is_print_ascii(123) is False
def test_to_print_ascii_py2(self):
if self.PY3:
return
# text_type (unicode)
assert self.utils.to_print_ascii(u'francais') == 'francais'
assert self.utils.to_print_ascii(u'francais\n') == 'francais?'
assert self.utils.to_print_ascii(u'fran\xe7ais') == 'fran?ais'
assert self.utils.to_print_ascii(u'fran\xe7ais\n') == 'fran?ais?'
assert self.utils.to_print_ascii(u'fran\xe7ais', 'ignore') == 'franais'
assert self.utils.to_print_ascii(u'fran\xe7ais\n', 'ignore') == 'franais'
# str
assert self.utils.to_print_ascii('francais') == 'francais'
assert self.utils.to_print_ascii('francais\n') == 'francais?'
assert self.utils.to_print_ascii('fran\xc3\xa7ais') == 'fran??ais'
assert self.utils.to_print_ascii('fran\xc3\xa7ais\n') == 'fran??ais?'
assert self.utils.to_print_ascii('fran\xc3\xa7ais', 'ignore') == 'franais'
assert self.utils.to_print_ascii('fran\xc3\xa7ais\n', 'ignore') == 'franais'
with pytest.raises(TypeError):
self.utils.to_print_ascii(123)
def test_to_print_ascii_py3(self):
if not self.PY3:
return
# text_type (str)
assert self.utils.to_print_ascii('francais') == 'francais'
assert self.utils.to_print_ascii('francais\n') == 'francais?'
assert self.utils.to_print_ascii(u'francais') == 'francais'
assert self.utils.to_print_ascii(u'francais\n') == 'francais?'
assert self.utils.to_print_ascii('fran\xe7ais') == 'fran?ais'
assert self.utils.to_print_ascii('fran\xe7ais\n') == 'fran?ais?'
assert self.utils.to_print_ascii('fran\xe7ais', 'ignore') == 'franais'
assert self.utils.to_print_ascii('fran\xe7ais\n', 'ignore') == 'franais'
assert self.utils.to_print_ascii(u'fran\xe7ais') == 'fran?ais'
assert self.utils.to_print_ascii(u'fran\xe7ais\n') == 'fran?ais?'
assert self.utils.to_print_ascii(u'fran\xe7ais', 'ignore') == 'franais'
assert self.utils.to_print_ascii(u'fran\xe7ais\n', 'ignore') == 'franais'
with pytest.raises(TypeError):
self.utils.to_print_ascii(123)
def test_ctoi(self):
assert self.utils.ctoi(123) == 123
assert self.utils.ctoi('ABC') == 65
def test_parse_int(self):
assert self.utils.parse_int(123) == 123
assert self.utils.parse_int('123') == 123
assert self.utils.parse_int(-123) == -123
assert self.utils.parse_int('-123') == -123
assert self.utils.parse_int('abc') == 0
def test_unique_seq(self):
assert self.utils.unique_seq((1, 2, 2, 3, 3, 3)) == (1, 2, 3)
assert self.utils.unique_seq((3, 3, 3, 2, 2, 1)) == (3, 2, 1)
assert self.utils.unique_seq([1, 2, 2, 3, 3, 3]) == [1, 2, 3]
assert self.utils.unique_seq([3, 3, 3, 2, 2, 1]) == [3, 2, 1]

View File

@ -3,6 +3,7 @@
import pytest
# pylint: disable=attribute-defined-outside-init
class TestVersionCompare(object):
@pytest.fixture(autouse=True)
def init(self, ssh_audit):
@ -199,7 +200,7 @@ class TestVersionCompare(object):
versions.append('0.5.{0}'.format(i))
for i in range(0, 6):
versions.append('0.6.{0}'.format(i))
for i in range(0, 4):
for i in range(0, 5):
versions.append('0.7.{0}'.format(i))
l = len(versions)
for i in range(l):

412
test/tools/ci-linux.sh Executable file
View File

@ -0,0 +1,412 @@
#!/bin/sh
CI_VERBOSE=1
ci_err_msg() { echo "[ci] error: $1" >&2; }
ci_err() { [ $1 -ne 0 ] && ci_err_msg "$2" && exit 1; }
ci_is_osx() { [ X"$(uname -s)" == X"Darwin" ]; }
ci_get_pypy_ver() {
local _v="$1"
[ -z "$_v" ] && _v=$(python -V 2>&1)
case "$_v" in
pypy-*|pypy2-*|pypy3-*|pypy3.*) echo "$_v"; return 0 ;;
pypy|pypy2|pypy3) echo "$_v-unknown"; return 0 ;;
esac
echo "$_v" | tail -1 | grep -qi pypy
if [ $? -eq 0 ]; then
local _py_ver=$(echo "$_v" | head -1 | cut -d ' ' -sf 2)
local _pypy_ver=$(echo "$_v" | tail -1 | cut -d ' ' -sf 2)
[ -z "${_py_ver} " ] && _py_ver=2
[ -z "${_pypy_ver}" ] && _pypy_ver="unknown"
case "${_py_ver}" in
2*) echo "pypy-${_pypy_ver}" ;;
3.3*) echo "pypy3.3-${_pypy_ver}" ;;
3.5*) echo "pypy3.5-${_pypy_ver}" ;;
*) echo "pypy3-${_pypy_ver}" ;;
esac
return 0
else
return 1
fi
}
ci_get_py_ver() {
local _v
case "$1" in
py26) _v=2.6.9 ;;
py27) _v=2.7.13 ;;
py33) _v=3.3.6 ;;
py34) _v=3.4.6 ;;
py35) _v=3.5.3 ;;
py36) _v=3.6.1 ;;
py37) _v=3.7-dev ;;
pypy) ci_is_osx && _v=pypy2-5.7.0 || _v=pypy-portable-5.7.0 ;;
pypy3) ci_is_osx && _v=pypy3.3-5.5-alpha || _v=pypy3-portable-5.7.0 ;;
*)
[ -z "$1" ] && set -- "$(python -V 2>&1)"
_v=$(ci_get_pypy_ver "$1")
[ -z "$_v" ] && _v=$(echo "$_v" | head -1 | cut -d ' ' -sf 2)
;;
esac
echo "${_v}"
return 0
}
ci_get_py_env() {
[ -z "$1" ] && set -- "$(python -V 2>&1)"
case "$(ci_get_pypy_ver "$1")" in
pypy|pypy2|pypy-*|pypy2-*) echo "pypy" ;;
pypy3|pypy3*) echo "pypy3" ;;
*)
local _v=$(echo "$1" | head -1 | sed -e 's/[^0-9]//g' | cut -c1-2)
echo "py${_v}"
esac
return 0
}
ci_pyenv_setup() {
[ ${CI_VERBOSE} -gt 0 ] && echo "[ci] install pyenv"
rm -rf ~/.pyenv
git clone --depth 1 https://github.com/yyuu/pyenv.git ~/.pyenv
PYENV_ROOT=$HOME/.pyenv
PATH="$HOME/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
ci_err $? "failed to init pyenv"
[ ${CI_VERBOSE} -gt 0 ] && echo "[ci] pyenv init: $(pyenv -v 2>&1)"
return 0
}
ci_pyenv_install() {
CI_PYENV_CACHE=~/.pyenv.cache
type pyenv > /dev/null 2>&1
ci_err $? "pyenv not found"
local _py_ver=$(ci_get_py_ver "$1")
local _py_env=$(ci_get_py_env "${_py_ver}")
local _nocache
case "${_py_env}" in
py37) _nocache=1 ;;
esac
[ ${CI_VERBOSE} -gt 0 ] && echo "[ci] pyenv install: ${_py_env}/${_py_ver}"
[ -z "${PYENV_ROOT}" ] && PYENV_ROOT="$HOME/.pyenv"
local _py_ver_dir="${PYENV_ROOT}/versions/${_py_ver}"
local _py_ver_cached_dir="${CI_PYENV_CACHE}/${_py_ver}"
if [ -z "${_nocache}" ]; then
if [ ! -d "${_py_ver_dir}" ]; then
if [ -d "${_py_ver_cached_dir}" ]; then
[ ${CI_VERBOSE} -gt 0 ] && echo "[ci] pyenv reuse ${_py_ver}"
ln -s "${_py_ver_cached_dir}" "${_py_ver_dir}"
fi
fi
fi
if [ ! -d "${_py_ver_dir}" ]; then
pyenv install -s "${_py_ver}"
ci_err $? "pyenv failed to install ${_py_ver}"
if [ -z "${_nocache}" ]; then
[ ${CI_VERBOSE} -gt 0 ] && echo "[ci] pyenv cache ${_py_ver}"
rm -rf -- "${_py_ver_cached_dir}"
mkdir -p -- "${CI_PYENV_CACHE}"
mv "${_py_ver_dir}" "${_py_ver_cached_dir}"
ln -s "${_py_ver_cached_dir}" "${_py_ver_dir}"
fi
fi
pyenv rehash
return 0
}
ci_pyenv_use() {
type pyenv > /dev/null 2>&1
ci_err $? "pyenv not found"
local _py_ver=$(ci_get_py_ver "$1")
pyenv shell "${_py_ver}"
ci_err $? "pyenv could not use ${_py_ver}"
[ ${CI_VERBOSE} -gt 0 ] && echo "[ci] pyenv using python: $(python -V 2>&1)"
return 0
}
ci_pip_setup() {
local _py_ver=$(ci_get_py_ver "$1")
local _py_env=$(ci_get_py_env "${_py_ver}")
[ ${CI_VERBOSE} -gt 0 ] && echo "[ci] install pip/venv for ${_py_env}/${_py_ver}"
PIPOPT=$(python -c 'import sys; print("" if hasattr(sys, "real_prefix") else "--user")')
if [ -z "${_py_env##py2*}" ]; then
curl -O https://bootstrap.pypa.io/get-pip.py
python get-pip.py ${PIPOPT}
ci_err $? "failed to install pip"
fi
if [ X"${_py_env}" == X"py26" ]; then
python -c 'import pip; pip.main();' install ${PIPOPT} -U pip virtualenv
else
python -m pip install ${PIPOPT} -U pip virtualenv
fi
ci_err $? "failed to upgrade pip/venv" || return 0
}
ci_venv_setup() {
local _py_ver=$(ci_get_py_ver "$1")
local _py_env=$(ci_get_py_env "${_py_ver}")
[ ${CI_VERBOSE} -gt 0 ] && echo "[ci] create venv for ${_py_env}/${_py_ver}"
local VENV_DIR=~/.venv/${_py_ver}
mkdir -p -- ~/.venv
rm -rf -- "${VENV_DIR}"
if [ X"${_py_env}" == X"py26" ]; then
python -c 'import virtualenv; virtualenv.main();' "${VENV_DIR}"
else
python -m virtualenv "${VENV_DIR}"
fi
ci_err $? "failed to create venv" || return 0
}
ci_venv_use() {
local _py_ver=$(ci_get_py_ver "$1")
local _py_env=$(ci_get_py_env "${_py_ver}")
local VENV_DIR=~/.venv/${_py_ver}
. "${VENV_DIR}/bin/activate"
ci_err $? "could not actiavte virtualenv"
[ ${CI_VERBOSE} -gt 0 ] && echo "[ci] venv using python: $(python -V 2>&1)"
return 0
}
ci_get_filedir() {
local _sdir=$(cd -- "$(dirname "$0")" && pwd)
local _pdir=$(pwd)
if [ -z "${_pdir##${_sdir}*}" ]; then
_sdir="${_pdir}"
fi
local _first=1
while [ X"${_sdir}" != X"/" ]; do
if [ ${_first} -eq 1 ]; then
_first=0
local _f=$(find "${_sdir}" -name "$1" | head -1)
if [ -n "${_f}" ]; then
echo $(dirname -- "${_f}")
return 0
fi
else
_f=$(find "${_sdir}" -mindepth 1 -maxdepth 1 -name "$1" | head -1)
fi
[ -n "${_f}" ] && echo "${_sdir}" && return 0
_sdir=$(cd -- "${_sdir}/.." && pwd)
done
return 1
}
ci_sq_ensure_java() {
type java >/dev/null 2>&1
if [ $? -ne 0 ]; then
ci_err_msg "java not found"
return 1
fi
local _java_ver=$(java -version 2>&1 | head -1 | sed -e 's/[^0-9\._]//g')
if [ -z "${_java_ver##1.8*}" ]; then
return 0
fi
ci_err_msg "unsupported java version: ${_java_ver}"
return 1
}
ci_sq_ensure_scanner() {
local _cli_version="3.0.0.702"
local _cli_basedir="$HOME/.bin"
local _cli_postfix=""
case "$(uname -s)" in
Linux)
[ X"$(uname -m)" = X"x86_64" ] && _cli_postfix="-linux"
[ X"$(uname -m)" = X"amd64" ] && _cli_postfix="-linux"
;;
Darwin) _cli_postfix="-macosx" ;;
esac
if [ X"${_cli_postfix}" = X"" ]; then
ci_sq_ensure_java || return 1
fi
if [ X"${SONAR_SCANNER_PATH}" != X"" ]; then
if [ -e "${SONAR_SCANNER_PATH}" ]; then
return 0
fi
fi
local _cli_fname="sonar-scanner-cli-${_cli_version}${_cli_postfix}"
[ ${CI_VERBOSE} -gt 0 ] && echo "[ci] ensure scanner ${_cli_fname}"
local _cli_dname="sonar-scanner-${_cli_version}${_cli_postfix}"
local _cli_archive="${_cli_basedir}/${_cli_fname}.zip"
local _cli_dir="${_cli_basedir}/${_cli_dname}"
local _cli_url="https://sonarsource.bintray.com/Distribution/sonar-scanner-cli/${_cli_fname}.zip"
if [ ! -e "${_cli_archive}" ]; then
mkdir -p -- "${_cli_basedir}" > /dev/null 2>&1
if [ $? -ne 0 ]; then
ci_err_msg "could not create ${_cli_basedir}"
return 1
fi
[ ${CI_VERBOSE} -gt 0 ] && echo "[ci] downloading ${_cli_fname}"
curl -kL -o "${_cli_archive}" "${_cli_url}"
[ $? -ne 0 ] && ci_err_msg "download failed" && return 1
[ ! -e "${_cli_archive}" ] && ci_err_msg "download verify" && return 1
fi
if [ ! -d "${_cli_dir}" ]; then
[ ${CI_VERBOSE} -gt 0 ] && echo "[ci] extracting ${_cli_fname}"
unzip -od "${_cli_basedir}" "${_cli_archive}"
[ $? -ne 0 ] && ci_err_msg "extract failed" && return 1
[ ! -d "${_cli_dir}" ] && ci_err_msg "extract verify" && return 1
fi
if [ ! -e "${_cli_dir}/bin/sonar-scanner" ]; then
ci_err_msg "sonar-scanner binary not found."
return 1
fi
SONAR_SCANNER_PATH="${_cli_dir}/bin/sonar-scanner"
return 0
}
ci_sq_run() {
if [ X"${SONAR_SCANNER_PATH}" = X"" ]; then
ci_err_msg "environment variable SONAR_SCANNER_PATH not set"
return 1
fi
if [ X"${SONAR_HOST_URL}" = X"" ]; then
ci_err_msg "environment variable SONAR_HOST_URL not set"
return 1
fi
if [ X"${SONAR_AUTH_TOKEN}" = X"" ]; then
ci_err_msg "environment variable SONAR_AUTH_TOKEN not set"
return 1
fi
local _pdir=$(ci_get_filedir "ssh-audit.py")
if [ -z "${_pdir}" ]; then
ci_err_msg "failed to find project directory"
return 1
fi
local _odir=$(pwd)
cd -- "${_pdir}"
local _branch=$(git name-rev --name-only HEAD | cut -d '~' -f 1)
case "${_branch}" in
master) ;;
develop) ;;
*) ci_err_msg "unknown branch: ${_branch}"; return 1 ;;
esac
local _junit=$(cd -- "${_pdir}" && ls -1 reports/junit.*.xml | sort -r | head -1)
if [ X"${_junit}" = X"" ]; then
ci_err_msg "no junit.xml found"
return 1
fi
local _project_ver=$(grep VERSION ssh-audit.py | head -1 | cut -d "'" -f 2)
if [ -z "${_project_ver}" ]; then
ci_err_msg "failed to get project version"
return 1
fi
if [ -z "${_project_ver##*dev}" ]; then
local _git_commit=$(git rev-parse --short=8 HEAD)
_project_ver="${_project_ver}.${_git_commit}"
fi
[ ${CI_VERBOSE} -gt 0 ] && echo "[ci] run sonar-scanner for ${_project_ver}"
"${SONAR_SCANNER_PATH}" -X \
-Dsonar.projectKey=arthepsy-github:ssh-audit \
-Dsonar.sources=ssh-audit.py \
-Dsonar.tests=test \
-Dsonar.test.inclusions=test/*.py \
-Dsonar.host.url="${SONAR_HOST_URL}" \
-Dsonar.projectName=ssh-audit \
-Dsonar.projectVersion="${_project_ver}" \
-Dsonar.branch="${_branch}" \
-Dsonar.python.coverage.overallReportPath=reports/coverage.xml \
-Dsonar.python.xunit.reportPath="${_junit}" \
-Dsonar.organization=arthepsy-github \
-Dsonar.login="${SONAR_AUTH_TOKEN}"
cd -- "${_odir}"
return 0
}
ci_run_wrapped() {
local _versions=$(echo "${PY_VER}" | sed -e 's/,/ /g')
[ -z "${_versions}" ] && eval "$1"
for _i in ${_versions}; do
local _v=$(echo "$_i" | cut -d '/' -f 1)
local _o=$(echo "$_i" | cut -d '/' -sf 2)
[ -z "${_o}" ] && _o="${PY_ORIGIN}"
eval "$1" "${_v}" "${_o}" || return 1
done
return 0
}
ci_step_before_install_wrapped() {
local _py_ver="$1"
local _py_ori="$2"
case "${_py_ori}" in
pyenv)
if [ "${CI_PYENV_SETUP}" -eq 0 ]; then
ci_pyenv_setup
CI_PYENV_SETUP=1
fi
ci_pyenv_install "${_py_ver}" || return 1
ci_pyenv_use "${_py_ver}" || return 1
;;
esac
ci_pip_setup "${_py_ver}" || return 1
ci_venv_setup "${_py_ver}" || return 1
return 0
}
ci_step_before_install() {
if ci_is_osx; then
[ ${CI_VERBOSE} -gt 0 ] && sw_vers
brew update || brew update
brew install autoconf pkg-config openssl readline xz
brew upgrade autoconf pkg-config openssl readline xz
PY_ORIGIN=pyenv
fi
CI_PYENV_SETUP=0
ci_run_wrapped "ci_step_before_install_wrapped" || return 1
if [ "${CI_PYENV_SETUP}" -eq 1 ]; then
pyenv shell --unset
[ ${CI_VERBOSE} -gt 0 ] && pyenv versions
fi
return 0
}
ci_step_install_wrapped() {
local _py_ver="$1"
ci_venv_use "${_py_ver}"
pip install -U tox coveralls codecov
ci_err $? "failed to install dependencies" || return 0
}
ci_step_script_wrapped() {
local _py_ver="$1"
local _py_ori="$2"
local _py_env=$(ci_get_py_env "${_py_ver}")
ci_venv_use "${_py_ver}" || return 1
if [ -z "${_py_env##*py3*}" ]; then
if [ -z "${_py_env##*pypy3*}" ]; then
# NOTE: workaround for travis environment
_pydir=$(dirname $(which python))
ln -s -- "${_pydir}/python" "${_pydir}/pypy3"
# NOTE: do not lint, as it hangs when flake8 is run
# NOTE: do not type, as it can't install dependencies
TOXENV=${_py_env}-test
else
TOXENV=${_py_env}-test,${_py_env}-type,${_py_env}-lint
fi
else
# NOTE: do not type, as it isn't supported on py2x
TOXENV=${_py_env}-test,${_py_env}-lint
fi
tox -e $TOXENV,cov
ci_err $? "tox failed" || return 0
}
ci_step_success_wrapped() {
local _py_ver="$1"
local _py_ori="$2"
if [ X"${SQ}" = X"1" ]; then
ci_sq_ensure_scanner && ci_sq_run
fi
ci_venv_use "${_py_ver}" || return 1
coveralls
codecov
}
ci_step_failure() {
cat .tox/log/*
cat .tox/*/log/*
}
ci_step_install() { ci_run_wrapped "ci_step_install_wrapped"; }
ci_step_script() { ci_run_wrapped "ci_step_script_wrapped"; }
ci_step_success() { ci_run_wrapped "ci_step_success_wrapped"; }

131
test/tools/ci-win.cmd Normal file
View File

@ -0,0 +1,131 @@
@ECHO OFF
IF "%PYTHON%" == "" (
ECHO PYTHON environment variable not set
EXIT 1
)
SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
FOR /F %%i IN ('python -c "import platform; print(platform.python_version());"') DO (
SET PYTHON_VERSION=%%i
)
SET PYTHON_VERSION_MAJOR=%PYTHON_VERSION:~0,1%
IF "%PYTHON_VERSION:~3,1%" == "." (
SET PYTHON_VERSION_MINOR=%PYTHON_VERSION:~2,1%
) ELSE (
SET PYTHON_VERSION_MINOR=%PYTHON_VERSION:~2,2%
)
FOR /F %%i IN ('python -c "import struct; print(struct.calcsize(\"P\")*8)"') DO (
SET PYTHON_ARCH=%%i
)
CALL :devenv
IF /I "%1"=="" (
SET target=test
) ELSE (
SET target=%1
)
echo [CI] TARGET=%target%
GOTO %target%
:devenv
SET WIN_SDK_ROOT=C:\Program Files\Microsoft SDKs\Windows
SET VS2015_ROOT=C:\Program Files (x86)\Microsoft Visual Studio 14.0
IF %PYTHON_VERSION_MAJOR% == 2 (
SET WINDOWS_SDK_VERSION="v7.0"
) ELSE IF %PYTHON_VERSION_MAJOR% == 3 (
IF %PYTHON_VERSION_MAJOR% LEQ 4 (
SET WINDOWS_SDK_VERSION="v7.1"
) ELSE (
SET WINDOWS_SDK_VERSION="2015"
)
) ELSE (
ECHO Unsupported Python version: "%PYTHON_VERSION%"
EXIT 1
)
SETLOCAL ENABLEDELAYEDEXPANSION
IF %PYTHON_ARCH% == 32 (SET PYTHON_ARCHX=x86) ELSE (SET PYTHON_ARCHX=x64)
IF %WINDOWS_SDK_VERSION% == "2015" (
"%VS2015_ROOT%\VC\vcvarsall.bat" %PYTHON_ARCHX%
) ELSE (
SET DISTUTILS_USE_SDK=1
SET MSSdk=1
"%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Setup\WindowsSdkVer.exe" -q -version:%WINDOWS_SDK_VERSION%
"%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Bin\SetEnv.cmd" /%PYTHON_ARCHX% /release
)
GOTO :eof
:install
pip install --user --upgrade pip virtualenv
SET VENV_DIR=.venv\%PYTHON_VERSION%
rmdir /s /q %VENV_DIR% > nul 2>nul
mkdir .venv > nul 2>nul
IF "%PYTHON_VERSION_MAJOR%%PYTHON_VERSION_MINOR%" == "26" (
python -c "import virtualenv; virtualenv.main();" %VENV_DIR%
) ELSE (
python -m virtualenv %VENV_DIR%
)
CALL %VENV_DIR%\Scripts\activate
python -V
pip install tox
deactivate
GOTO :eof
:install_deps
SET LXML_FILE=
SET LXML_URL=
IF %PYTHON_VERSION_MAJOR% == 3 (
IF %PYTHON_VERSION_MINOR% == 3 (
IF %PYTHON_ARCH% == 32 (
SET LXML_FILE=lxml-3.7.3.win32-py3.3.exe
SET LXML_URL=https://pypi.python.org/packages/66/fd/b82a54e7a15e91184efeef4b659379d0581a73cf78239d70feb0f0877841/lxml-3.7.3.win32-py3.3.exe
) ELSE (
SET LXML_FILE=lxml-3.7.3.win-amd64-py3.3.exe
SET LXML_URL=https://pypi.python.org/packages/dc/bc/4742b84793fa1fd991b5d2c6f2e5d32695659d6cfedf5c66aef9274a8723/lxml-3.7.3.win-amd64-py3.3.exe
)
) ELSE IF %PYTHON_VERSION_MINOR% == 4 (
IF %PYTHON_ARCH% == 32 (
SET LXML_FILE=lxml-3.7.3.win32-py3.4.exe
SET LXML_URL=https://pypi.python.org/packages/88/33/265459d68d465ddc707621e6471989f5c2cb0d43f230f516800ffd629af7/lxml-3.7.3.win32-py3.4.exe
) ELSE (
SET LXML_FILE=lxml-3.7.3.win-amd64-py3.4.exe
SET LXML_URL=https://pypi.python.org/packages/2d/65/e47db7f36a69a1b59b4f661e42d699d6c43e663b8fd91035e6f7681d017e/lxml-3.7.3.win-amd64-py3.4.exe
)
)
)
IF NOT "%LXML_FILE%" == "" (
CALL :download %LXML_URL% .downloads\%LXML_FILE%
easy_install --user .downloads\%LXML_FILE%
)
GOTO :eof
:test
SET VENV_DIR=.venv\%PYTHON_VERSION%
CALL %VENV_DIR%\Scripts\activate
IF "%TOXENV%" == "" (
SET TOXENV=py%PYTHON_VERSION_MAJOR%%PYTHON_VERSION_MINOR%
)
IF "%PYTHON_VERSION_MAJOR%%PYTHON_VERSION_MINOR%" == "26" (
SET TOX=python -c "from tox import cmdline; cmdline()"
) ELSE (
SET TOX=python -m tox
)
IF %PYTHON_VERSION_MAJOR% == 3 (
IF %PYTHON_VERSION_MINOR% LEQ 4 (
:: Python 3.3 and 3.4 does not support typed-ast (mypy dependency)
%TOX% --sitepackages -e %TOXENV%-test,%TOXENV%-lint,cov || EXIT 1
) ELSE (
%TOX% --sitepackages -e %TOXENV%-test,%TOXENV%-type,%TOXENV%-lint,cov || EXIT 1
)
) ELSE (
%TOX% --sitepackages -e %TOXENV%-test,%TOXENV%-lint,cov || EXIT 1
)
GOTO :eof
:download
IF NOT EXIST %2 (
IF NOT EXIST .downloads\ mkdir .downloads
powershell -command "(new-object net.webclient).DownloadFile('%1', '%2')" || EXIT 1
)
GOTO :eof

158
tox.ini Normal file
View File

@ -0,0 +1,158 @@
[tox]
envlist =
py26-{test,vulture}
py{27,py,py3}-{test,pylint,flake8,vulture}
py{33,34,35,36,37}-{test,mypy,pylint,flake8,vulture}
cov
skipsdist = true
skip_missing_interpreters = true
[testenv]
deps =
test: pytest==3.0.7
test,cov: {[testenv:cov]deps}
test,py{33,34,35,36,37}-{type,mypy}: colorama==0.3.7
py{33,34,35,36,37}-{type,mypy}: {[testenv:mypy]deps}
py{27,py,py3,33,34,35,36,37}-{lint,pylint},lint: {[testenv:pylint]deps}
py{27,py,py3,33,34,35,36,37}-{lint,flake8},lint: {[testenv:flake8]deps}
py{27,py,py3,33,34,35,36,37}-{lint,vulture},lint: {[testenv:vulture]deps}
setenv =
SSHAUDIT = {toxinidir}/ssh-audit.py
test: COVERAGE_FILE = {toxinidir}/.coverage.{envname}
type,mypy: MYPYPATH = {toxinidir}/test/stubs
type,mypy: MYPYHTML = {toxinidir}/reports/html/mypy
commands =
test: coverage run --source ssh-audit -m -- \
test: pytest -v --junitxml={toxinidir}/reports/junit.{envname}.xml {posargs:test}
test: coverage report --show-missing
test: coverage html -d {toxinidir}/reports/html/coverage.{envname}
py{33,34,35,36,37}-{type,mypy}: {[testenv:mypy]commands}
py{27,py,py3,33,34,35,36,37}-{lint,pylint},lint: {[testenv:pylint]commands}
py{27,py,py3,33,34,35,36,37}-{lint,flake8},lint: {[testenv:flake8]commands}
py{27,py,py3,33,34,35,36,37}-{lint,vulture},lint: {[testenv:vulture]commands}
ignore_outcome =
type: true
lint: true
[testenv:cov]
deps =
coverage==4.3.4
setenv =
COVERAGE_FILE = {toxinidir}/.coverage
commands =
coverage erase
coverage combine
coverage report --show-missing
coverage xml -i -o {toxinidir}/reports/coverage.xml
coverage html -d {toxinidir}/reports/html/coverage
[testenv:mypy]
deps =
colorama==0.3.7
lxml==3.7.3
mypy==0.501
commands =
mypy \
--show-error-context \
--config-file {toxinidir}/tox.ini \
--html-report {env:MYPYHTML}.py3.{envname} \
{posargs:{env:SSHAUDIT}}
mypy \
-2 \
--no-warn-incomplete-stub \
--show-error-context \
--config-file {toxinidir}/tox.ini \
--html-report {env:MYPYHTML}.py2.{envname} \
{posargs:{env:SSHAUDIT}}
[testenv:pylint]
deps =
mccabe
pylint
commands =
pylint \
--rcfile tox.ini \
--load-plugins=pylint.extensions.bad_builtin \
--load-plugins=pylint.extensions.check_elif \
--load-plugins=pylint.extensions.mccabe \
{posargs:{env:SSHAUDIT}}
[testenv:flake8]
deps =
flake8
commands =
flake8 {posargs:{env:SSHAUDIT}}
[testenv:vulture]
deps =
vulture
commands =
python -c "import sys; from subprocess import Popen, PIPE; \
a = ['vulture'] + r'{posargs:{env:SSHAUDIT}}'.split(' '); \
o = Popen(a, shell=False, stdout=PIPE).communicate()[0]; \
l = [x for x in o.split(b'\n') if x and b'Unused import' not in x]; \
print(b'\n'.join(l).decode('utf-8')); \
sys.exit(1 if len(l) > 0 else 0)"
[mypy]
ignore_missing_imports = False
follow_imports = error
disallow_untyped_calls = True
disallow_untyped_defs = True
check_untyped_defs = True
disallow_subclassing_any = True
warn_incomplete_stub = True
warn_redundant_casts = True
warn_return_any = True
warn_unused_ignores = True
strict_optional = True
strict_boolean = True
[pylint]
reports = no
#output-format = colorized
indent-string = \t
disable =
locally-disabled,
bad-continuation,
multiple-imports,
invalid-name,
trailing-whitespace,
missing-docstring
max-complexity = 15
max-args = 8
max-locals = 20
max-returns = 6
max-branches = 15
max-statements = 60
max-parents = 7
max-attributes = 8
min-public-methods = 1
max-public-methods = 20
max-bool-expr = 5
max-nested-blocks = 6
max-line-length = 80
ignore-long-lines = ^\s*(#\s+type:\s+.*|[A-Z0-9_]+\s+=\s+.*|('.*':\s+)?\[.*\],?|assert\s+.*)$
max-module-lines = 2500
[flake8]
ignore =
# indentation contains tabs
W191,
# blank line contains whitespace
W293,
# indentation contains mixed spaces and tabs
E101,
# multiple spaces before operator
E221,
# multiple spaces after operator
E241,
# multiple imports on one line
E401,
# line too long
E501,
# module imported but unused
F401,
# undefined name
F821