ssh-audit is a tool for ssh server & client configuration auditing.
jtesta/ssh-audit (v2.0+) is the updated and maintained version of ssh-audit forked from arthepsy/ssh-audit (v1.x) due to inactivity.
usage: ssh-audit.py [-h] [-1] [-2] [-4] [-6] [-b] [-c] [-d]
[-g <min1:pref1:max1[,min2:pref2:max2,...]> / <x-y[:step]>] [-j] [-l {info,warn,fail}] [-L]
[-M custom_policy.txt] [-m] [-n] [-P "Built-In Policy Name" / custom_policy.txt] [-p N]
[-T targets.txt] [-t N] [-v] [--conn-rate-test N[:max_rate]] [--dheat N[:kex[:e_len]]]
[--lookup alg1[,alg2,...]] [--skip-rate-test] [--threads N]
[host]
positional arguments:
host target hostname or IPv4/IPv6 address
optional arguments:
-h, --help show this help message and exit
-1, --ssh1 force ssh version 1 only
-2, --ssh2 force ssh version 2 only
-4, --ipv4 enable IPv4 (order of precedence)
-6, --ipv6 enable IPv6 (order of precedence)
-b, --batch batch output
-c, --client-audit starts a server on port 2222 to audit client software config (use -p to change port; use -t
to change timeout)
-d, --debug enable debugging output
-g <min1:pref1:max1[,min2:pref2:max2,...]> / <x-y[:step]>, --gex-test <min1:pref1:max1[,min2:pref2:max2,...]> / <x-y[:step]>
conducts a very customized Diffie-Hellman GEX modulus size test. Tests an array of minimum,
preferred, and maximum values, or a range of values with an optional incremental step amount
-j, --json enable JSON output (use -jj to enable indentation for better readability)
-l {info,warn,fail}, --level {info,warn,fail}
minimum output level (default: info)
-L, --list-policies list all the official, built-in policies. Combine with -v to view policy change logs
-M custom_policy.txt, --make-policy custom_policy.txt
creates a policy based on the target server (i.e.: the target server has the ideal
configuration that other servers should adhere to), and stores it in the file path specified
-m, --manual print the man page (Docker, PyPI, Snap, and Windows builds only)
-n, --no-colors disable colors (automatic when the NO_COLOR environment variable is set)
-P "Built-In Policy Name" / custom_policy.txt, --policy "Built-In Policy Name" / custom_policy.txt
run a policy test using the specified policy (use -L to see built-in policies, or specify
filesystem path to custom policy created by -M)
-p N, --port N the TCP port to connect to (or to listen on when -c is used)
-T targets.txt, --targets targets.txt
a file containing a list of target hosts (one per line, format HOST[:PORT]). Use -p/--port
to set the default port for all hosts. Use --threads to control concurrent scans
-t N, --timeout N timeout (in seconds) for connection and reading (default: 5)
-v, --verbose enable verbose output
--conn-rate-test N[:max_rate]
perform a connection rate test (useful for collecting metrics related to susceptibility of
the DHEat vuln). Testing is conducted with N concurrent sockets with an optional maximum
rate of connections per second
--dheat N[:kex[:e_len]]
continuously perform the DHEat DoS attack (CVE-2002-20001) against the target using N
concurrent sockets. Optionally, a specific key exchange algorithm can be specified instead
of allowing it to be automatically chosen. Additionally, a small length of the fake e value
sent to the server can be chosen for a more efficient attack (such as 4).
--lookup alg1[,alg2,...]
looks up an algorithm(s) without connecting to a server.
--skip-rate-test skip the connection rate test during standard audits (used to safely infer whether the DHEat
attack is viable)
--threads N number of threads to use when scanning multiple targets (-T/--targets) (default: 32)
-46
or -64
.-b
will output sections without header and without empty lines (implies verbose flag).-v
will prefix each line with section type and algorithm name.Basic server auditing:
ssh-audit localhost
ssh-audit 127.0.0.1
ssh-audit 127.0.0.1:222
ssh-audit ::1
ssh-audit [::1]:222
To run a standard audit against many servers (place targets into servers.txt, one on each line in the format of HOST[:PORT]
):
ssh-audit -T servers.txt
To audit a client configuration (listens on port 2222 by default; connect using ssh -p 2222 anything@localhost
):
ssh-audit -c
To audit a client configuration, with a listener on port 4567:
ssh-audit -c -p 4567
To list all official built-in policies (hint: use resulting policy names with -P
/--policy
):
ssh-audit -L
To run a policy audit against a server:
ssh-audit -P ["policy name" | path/to/server_policy.txt] targetserver
To run a policy audit against a client:
ssh-audit -c -P ["policy name" | path/to/client_policy.txt]
To run a policy audit against many servers:
ssh-audit -T servers.txt -P ["policy name" | path/to/server_policy.txt]
To create a policy based on a target server (which can be manually edited):
ssh-audit -M new_policy.txt targetserver
To run the DHEat CPU exhaustion DoS attack (CVE-2002-20001) against a target using 10 concurrent sockets:
ssh-audit --dheat=10 targetserver
To run the DHEat attack using the diffie-hellman-group-exchange-sha256
key exchange algorithm:
ssh-audit --dheat=10:diffie-hellman-group-exchange-sha256 targetserver
To run the DHEat attack using the diffie-hellman-group-exchange-sha256
key exchange algorithm along with very small but non-standard packet lengths (this may result in the same CPU exhaustion, but with many less bytes per second being sent):
ssh-audit --dheat=10:diffie-hellman-group-exchange-sha256:4 targetserver
Below is a screen shot of the standard server-auditing output when connecting to an unhardened OpenSSH v5.3 service:
Below is a screen shot of the policy auditing output when connecting to an un-hardened Ubuntu Server 20.04 machine (hint: use -L
/--list-policies
to see names of built-in policies to use with -P
/--policy
):
After applying the steps in the hardening guide (see below), the output changes to the following:
Below is a screen shot of the client-auditing output when an unhardened OpenSSH v7.2 client connects:
Guides to harden server & client configuration can be found here: https://www.ssh-audit.com/hardening_guides.html
Pre-built packages are available for Windows (see the Releases page), PyPI, Snap, and Docker:
To install from PyPI:
$ pip3 install ssh-audit
To install the Snap package:
$ snap install ssh-audit
To install from Dockerhub:
$ docker pull positronsecurity/ssh-audit
(Then run with: docker run -it --rm -p 2222:2222 positronsecurity/ssh-audit 10.1.1.1
)
The status of various other platform packages can be found below (via Repology):
For convenience, a web front-end on top of the command-line tool is available at https://www.ssh-audit.com/.
getopt
module to argparse
; partial credit oam7575.-P
and -T
options simultaneously.--conn-rate-test
feature on Windows.-T
/--targets
), the -p
/--port
option will now be used as the default port (set to 22 if -p
/--port
is not given). Hosts specified in the file can override this default with an explicit port number (i.e.: "host1:1234"). For example, when using -T targets.txt -p 222
, all hosts in targets.txt
that do not explicitly include a port number will default to 222; when using -T targets.txt
(without -p
), all hosts will use a default of 22.grasshopper-ctr128
.mlkem768x25519-sha256
, sntrup761x25519-sha512
.--dheat
option; CVE-2002-20001).ecdsa-sha2-nistp*
CA signatures on host keys. Additionally, they are now flagged as potentially back-doored, just as standard host keys are.-m
, --manual
) is now available on Docker, PyPI, and Snap builds, in addition to the Windows build.python:3-slim
to python:3-alpine
, resulting in a 59% reduction in image size; credit Daniel Thamdrup.-L -v
to view them).allow_algorithm_subset_and_reordering
directive to allow targets to pass with a subset and/or re-ordered list of host keys, kex, ciphers, and MACs. This allows for the creation of a baseline policy where targets can optionally implement stricter controls; partial credit yannik1015.allow_larger_keys
directive to allow targets to pass with larger host keys, CA keys, and Diffie-Hellman keys. This allows for the creation of a baseline policy where targets can optionally implement stricter controls; partial credit Damian Szuberski.NO_COLOR
environment variable is set (see https://no-color.org/).gss-nistp384-sha384-*
.aes128-ocb@libassh.org
.sk-ssh-ed25519@openssh.com
and ssh-ed25519
to the end of all certificate types.additional_notes
field to the JSON output.ecdsa-sha2-curve25519
, ecdsa-sha2-nistb233
, ecdsa-sha2-nistb409
, ecdsa-sha2-nistk163
, ecdsa-sha2-nistk233
, ecdsa-sha2-nistk283
, ecdsa-sha2-nistk409
, ecdsa-sha2-nistp224
, ecdsa-sha2-nistp192
, ecdsa-sha2-nistt571
, ssh-dsa
, x509v3-sign-rsa-sha256
.curve448-sha512@libssh.org
, ecdh-nistp256-kyber-512r3-sha256-d00@openquantumsafe.org
, ecdh-nistp384-kyber-768r3-sha384-d00@openquantumsafe.org
, ecdh-nistp521-kyber-1024r3-sha512-d00@openquantumsafe.org
, ecdh-sha2-brainpoolp256r1@genua.de
, ecdh-sha2-brainpoolp384r1@genua.de
, ecdh-sha2-brainpoolp521r1@genua.de
, kexAlgoDH14SHA1
, kexAlgoDH1SHA1
, kexAlgoECDH256
, kexAlgoECDH384
, kexAlgoECDH521
, sm2kep-sha2-nistp256
, x25519-kyber-512r3-sha256-d00@amazon.com
, x25519-kyber512-sha512@aws.amazon.com
.aes192-gcm@openssh.com
, cast128-12-cbc
, cast128-12-cfb
, cast128-12-ecb
, cast128-12-ofb
, des-cfb
, des-ecb
, des-ofb
.cbcmac-3des
, cbcmac-aes
, cbcmac-blowfish
, cbcmac-des
, cbcmac-rijndael
, cbcmac-twofish
, hmac-sha256-96
, md5
, md5-8
, ripemd160
, ripemd160-8
, sha1
, sha1-8
, umac-128
.sntrup761x25519-sha512@openssh.com
.-g
and --gex-test
for granular GEX modulus size tests; credit Adam Russell.dsa2048-sha224@libassh.org
, dsa2048-sha256@libassh.org
, dsa3072-sha256@libassh.org
, ecdsa-sha2-1.3.132.0.10-cert-v01@openssh.com
, eddsa-e382-shake256@libassh.org
, eddsa-e521-shake256@libassh.org
, null
, pgp-sign-dss
, pgp-sign-rsa
, spki-sign-dss
, spki-sign-rsa
, ssh-dss-sha224@ssh.com
, ssh-dss-sha384@ssh.com
, ssh-dss-sha512@ssh.com
, ssh-ed448-cert-v01@openssh.com
, ssh-rsa-sha224@ssh.com
, ssh-rsa-sha2-256
, ssh-rsa-sha2-512
, ssh-rsa-sha384@ssh.com
, ssh-rsa-sha512@ssh.com
, ssh-xmss-cert-v01@openssh.com
, ssh-xmss@openssh.com
, webauthn-sk-ecdsa-sha2-nistp256@openssh.com
, x509v3-ecdsa-sha2-1.3.132.0.10
, x509v3-sign-dss-sha1
, x509v3-sign-dss-sha224@ssh.com
, x509v3-sign-dss-sha256@ssh.com
, x509v3-sign-dss-sha384@ssh.com
, x509v3-sign-dss-sha512@ssh.com
, x509v3-sign-rsa-sha1
, x509v3-sign-rsa-sha224@ssh.com
, x509v3-sign-rsa-sha384@ssh.com
, x509v3-sign-rsa-sha512@ssh.com
.diffie-hellman-group14-sha224@ssh.com
, diffie-hellman_group17-sha512
, diffie-hellman-group-exchange-sha224@ssh.com
, diffie-hellman-group-exchange-sha384@ssh.com
, ecdh-sha2-1.2.840.10045.3.1.1
, ecdh-sha2-1.2.840.10045.3.1.7
, ecdh-sha2-1.3.132.0.1
, ecdh-sha2-1.3.132.0.16
, ecdh-sha2-1.3.132.0.26
, ecdh-sha2-1.3.132.0.27
, ecdh-sha2-1.3.132.0.33
, ecdh-sha2-1.3.132.0.34
, ecdh-sha2-1.3.132.0.35
, ecdh-sha2-1.3.132.0.36
, ecdh-sha2-1.3.132.0.37
, ecdh-sha2-1.3.132.0.38
, ecdh-sha2-4MHB+NBt3AlaSRQ7MnB4cg==
, ecdh-sha2-5pPrSUQtIaTjUSt5VZNBjg==
, ecdh-sha2-9UzNcgwTlEnSCECZa7V1mw==
, ecdh-sha2-D3FefCjYoJ/kfXgAyLddYA==
, ecdh-sha2-h/SsxnLCtRBh7I9ATyeB3A==
, ecdh-sha2-m/FtSAmrV4j/Wy6RVUaK7A==
, ecdh-sha2-mNVwCXAoS1HGmHpLvBC94w==
, ecdh-sha2-qCbG5Cn/jjsZ7nBeR7EnOA==
, ecdh-sha2-qcFQaMAMGhTziMT0z+Tuzw==
, ecdh-sha2-VqBg4QRPjxx1EXZdV0GdWQ==
, ecdh-sha2-wiRIU8TKjMZ418sMqlqtvQ==
, ecdh-sha2-zD/b3hu/71952ArpUG4OjQ==
, ecmqv-sha2
, gss-13.3.132.0.10-sha256-*
, gss-curve25519-sha256-*
, gss-curve448-sha512-*
, gss-gex-sha1-*
, gss-gex-sha256-*
, gss-group14-sha1-*
, gss-group14-sha256-*
, gss-group15-sha512-*
, gss-group16-sha512-*
, gss-group17-sha512-*
, gss-group18-sha512-*
, gss-group1-sha1-*
, gss-nistp256-sha256-*
, gss-nistp384-sha256-*
, gss-nistp521-sha512-*
, m383-sha384@libassh.org
, m511-sha512@libassh.org
.3des-cfb
, 3des-ecb
, 3des-ofb
, blowfish-cfb
, blowfish-ecb
, blowfish-ofb
, camellia128-cbc@openssh.org
, camellia128-ctr@openssh.org
, camellia192-cbc@openssh.org
, camellia192-ctr@openssh.org
, camellia256-cbc@openssh.org
, camellia256-ctr@openssh.org
, cast128-cfb
, cast128-ecb
, cast128-ofb
, cast128-12-cbc@ssh.com
, idea-cfb
, idea-ecb
, idea-ofb
, rijndael-cbc@ssh.com
, seed-ctr@ssh.com
, serpent128-gcm@libassh.org
, serpent256-gcm@libassh.org
, twofish128-gcm@libassh.org
, twofish256-gcm@libassh.org
, twofish-cfb
, twofish-ecb
, twofish-ofb
hmac-sha1-96@openssh.com
, hmac-sha224@ssh.com
, hmac-sha256-2@ssh.com
, hmac-sha384@ssh.com
, hmac-whirlpool
.-jj
is used (useful for debugging).-d
/--debug
option for getting debugging output; credit Adam Russell.rsa-sha2-512
and rsa-sha2-256
.gss-gex-sha1-eipGX3TCiQSrx573bT1o1Q==
, gss-group1-sha1-eipGX3TCiQSrx573bT1o1Q==
, and gss-group14-sha1-eipGX3TCiQSrx573bT1o1Q==
.hmac-ripemd160-96
, AEAD_AES_128_GCM
, and AEAD_AES_256_GCM
.-m
/--manual
); credit Adam Russell.sntrup761x25519-sha512@openssh.com
.rsa-sha2-256-cert-v01@openssh.com
and rsa-sha2-512-cert-v01@openssh.com
host key types.ssh-rsa-cert-v01@openssh.com
as a failure due to SHA-1 hash.--lookup
) now performs case-insensitive lookups of similar algorithms; credit Adam Russell.des-cbc@ssh.com
.-L
/--list-policies
, -M
/--make-policy
and -P
/--policy
). For an in-depth tutorial, see https://www.positronsecurity.com/blog/2020-09-27-ssh-policy-configuration-checks-with-ssh-audit/.ssh-audit.1
file).--lookup
); credit Adam Russell.ssh-rsa1
, ssh-dss-sha256@ssh.com
, ssh-gost2001
, ssh-gost2012-256
, ssh-gost2012-512
, spki-sign-rsa
, ssh-ed448
, x509v3-ecdsa-sha2-nistp256
, x509v3-ecdsa-sha2-nistp384
, x509v3-ecdsa-sha2-nistp521
, x509v3-rsa2048-sha256
.diffie-hellman-group1-sha256
, kexAlgoCurve25519SHA256
, Curve25519SHA256
, gss-group14-sha256-
, gss-group15-sha512-
, gss-group16-sha512-
, gss-nistp256-sha256-
, gss-curve25519-sha256-
.blowfish
, AEAD_AES_128_GCM
, AEAD_AES_256_GCM
, crypticore128@ssh.com
, seed-cbc@ssh.com
.chacha20-poly1305@openssh.com
, hmac-sha3-224
, crypticore-mac@ssh.com
.ssh-rsa
as weak due to practical SHA-1 collisions.ecdsa-sha2-1.3.132.0.10
, x509v3-sign-dss
, x509v3-sign-rsa
, x509v3-sign-rsa-sha256@ssh.com
, x509v3-ssh-dss
, x509v3-ssh-rsa
, sk-ecdsa-sha2-nistp256-cert-v01@openssh.com
, sk-ecdsa-sha2-nistp256@openssh.com
, sk-ssh-ed25519-cert-v01@openssh.com
, and sk-ssh-ed25519@openssh.com
.diffie-hellman-group14-sha256@ssh.com
, diffie-hellman-group15-sha256@ssh.com
, diffie-hellman-group15-sha384@ssh.com
, diffie-hellman-group16-sha384@ssh.com
, diffie-hellman-group16-sha512@ssh.com
, diffie-hellman-group18-sha512@ssh.com
, ecdh-sha2-curve25519
, ecdh-sha2-nistb233
, ecdh-sha2-nistb409
, ecdh-sha2-nistk163
, ecdh-sha2-nistk233
, ecdh-sha2-nistk283
, ecdh-sha2-nistk409
, ecdh-sha2-nistp192
, ecdh-sha2-nistp224
, ecdh-sha2-nistt571
, gss-gex-sha1-
, and gss-group1-sha1-
.camellia128-cbc
, camellia128-ctr
, camellia192-cbc
, camellia192-ctr
, camellia256-cbc
, camellia256-ctr
, aes128-gcm
, aes256-gcm
, and chacha20-poly1305
.aes128-gcm
and aes256-gcm
.rsa-sha2-256-cert-v01@openssh.com
, rsa-sha2-512-cert-v01@openssh.com
.des
, 3des
.-c
/ --client-audit
option).-j
/ --json
option; credit Andreas Jaggi).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
.ecdsa-sha2-1.3.132.0.10
.idea-cbc
, serpent128-cbc
, serpent192-cbc
, serpent256-cbc
.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
.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
.des-cbc-ssh1
, blowfish-ctr
, twofish-ctr
.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
.-t
/ --timeout
) for connection & reading timeouts.