Skip to content

Cheat sheet — TLS auditing with testssl.sh & openssl

Companion to Module 05 — TLS Deep Dive · CC BY 4.0 — print it, pin it, share it.

Last reviewed: 2026-07

testssl.sh — full scan and scoping

testssl.sh example.com                     # full scan of :443 (protocols, ciphers, cert, vulns)
testssl.sh https://example.com:8443        # explicit scheme + port
testssl.sh 10.0.0.5:443                    # scan a raw IP:port on the bridge network
testssl.sh --severity HIGH example.com     # only surface HIGH and above (LOW/MEDIUM/CRITICAL also valid)
testssl.sh --sneaky --quiet example.com    # less noisy User-Agent, drop the banner

testssl.sh — target one category

testssl.sh -p example.com                  # protocols only (SSLv2/3, TLS 1.0–1.3)
testssl.sh -E example.com                  # each cipher, per protocol (the "-e" is a shorter list)
testssl.sh -S example.com                  # server-preferred cipher order
testssl.sh -U example.com                  # all vulnerability checks in one pass
testssl.sh -H example.com                  # HTTP headers (HSTS, etc.)
testssl.sh --phone-out example.com         # allow OCSP/CRL lookups that need outbound network

testssl.sh — named-attack checks

testssl.sh --heartbleed example.com        # CVE-2014-0160 — OpenSSL heartbeat over-read
testssl.sh --drown example.com             # CVE-2016-0800 — SSLv2 leaks a modern session key
testssl.sh --poodle example.com            # CVE-2014-3566 — SSLv3 CBC padding oracle
testssl.sh --beast example.com             # CVE-2011-3389 — TLS 1.0 CBC
testssl.sh --robot example.com             # RSA key-exchange padding oracle (Bleichenbacher)

testssl.sh — machine-readable output (for CI)

testssl.sh --jsonfile-pretty out.json example.com   # structured JSON — parse the "severity" field
testssl.sh --csvfile out.csv example.com            # CSV, one finding per row
testssl.sh --logfile out.log example.com            # plain-text log alongside the terminal run
# gate a pipeline: fail if any finding is HIGH or CRITICAL
jq -e '[.[] | select(.severity=="HIGH" or .severity=="CRITICAL")] | length == 0' out.json

openssl s_client — advanced handshake inspection

# pin a protocol version to confirm it is (or isn't) offered
openssl s_client -connect example.com:443 -tls1_3 </dev/null
openssl s_client -connect example.com:443 -tls1_2 </dev/null
openssl s_client -connect example.com:443 -no_tls1_3 </dev/null   # force downgrade attempt

# force a single cipher (TLS 1.2) or ciphersuite (TLS 1.3) to test acceptance
openssl s_client -connect example.com:443 -cipher 'ECDHE-RSA-AES256-GCM-SHA384' </dev/null
openssl s_client -connect example.com:443 -ciphersuites TLS_AES_256_GCM_SHA384 </dev/null

# name the key-exchange group(s) offered — confirms ECDHE / X25519 forward secrecy
openssl s_client -connect example.com:443 -groups X25519:P-256 </dev/null

openssl s_client -connect example.com:443 -servername example.com -status </dev/null  # OCSP staple
openssl s_client -connect example.com:443 -alpn h2,http/1.1 </dev/null                # test ALPN
openssl ciphers -v 'ECDHE+AESGCM'          # expand a cipher string to the suites it selects

Read the New, TLSv1.x, Cipher is ... line and the Server Temp Key: line — the latter names the ephemeral group (e.g. X25519, 253 bits), which is your proof forward secrecy is actually in use.

Gotchas worth remembering

  • Classify before you rank. Every finding is protocol, cipher suite, or certificate — sort it first and the remediation names itself (config-list edit vs. reissue/renew).
  • The scan line is the symptom, not the risk. "SSLv2 enabled" reads like dead weight; it's DROWN and can leak a modern session's key. Map to the named attack before assigning severity.
  • Heartbleed is an implementation axis, not a config one. No weak cipher is involved — a patched OpenSSL is the only fix. Modern protocol + strong ciphers is necessary, not sufficient.
  • **`

Comments

Sign in with GitHub to comment. Choose the type: Feedback (errors or suggestions on this page) · Hints (help for fellow learners — no spoilers) · General (anything else).