sslscan: Tests SSL/TLS ciphers and vulnerabilities

sslscan: Tests SSL/TLS ciphers and vulnerabilities

Sometimes I don’t need a full compliance report — I just need to know, right now, exactly which ciphers a server accepts and whether it’s still vulnerable to something like Heartbleed. That’s the itch sslscan scratches. It’s a compact, fast, C-based tool that queries a server directly and lists supported SSL/TLS versions, cipher suites, and certificate details in one quick pass. I use it constantly as a companion (or sanity check) to sslyze.

This article covers what sslscan is, how it works internally, installation, syntax, real command examples, and how it fits into a broader testing workflow.

What SSLScan Does

sslscan connects to an SSL/TLS-enabled service and reports:

  • Supported SSL/TLS protocol versions (SSLv2/3, TLS 1.0–1.3)
  • Every cipher suite accepted per protocol, along with key strength
  • Certificate details (subject, issuer, expiration, signature algorithm)
  • Compression and renegotiation support (relevant to CRIME and secure renegotiation issues)
  • Basic Heartbleed detection

Architecture and Internal Working

sslscan is written in C and links directly against a (often bundled, statically compiled) OpenSSL library — frequently a patched version that still supports legacy protocols disabled in modern system OpenSSL builds, which is precisely why it can detect servers still accepting SSLv2 or SSLv3 even when your system’s own OpenSSL refuses to negotiate them.

Its internal loop is straightforward:

  1. For each protocol version compiled in, sslscan iterates through its full cipher list.
  2. For each cipher, it attempts a handshake specifying only that cipher.
  3. If the handshake succeeds, the cipher is marked accepted; if it fails, it’s marked rejected.
  4. Once all ciphers/protocols are tested, it performs a final handshake to pull the certificate chain and print certificate details.

This brute-force-style, cipher-by-cipher approach is simpler than SSLyze’s plugin architecture but very fast for a single-host check.

Installation

Debian/Kali:

sudo apt update
sudo apt install sslscan -y

From source:

git clone --recursive https://github.com/rbsec/sslscan.git
cd sslscan
make static
sudo make install

Verify:

sslscan --version

Basic Syntax

sslscan [options] host[:port]

Command Examples

1. Basic scan

sslscan example.com

Sample output:

Testing SSL server example.com on port 443

  TLS Fallback SCSV:
Server supports TLS Fallback SCSV

  TLS renegotiation:
Secure session renegotiation supported

  TLS Compression:
Compression disabled

  Heartbleed:
TLS 1.2 not vulnerable to heartbleed
TLS 1.3 not vulnerable to heartbleed

  Supported Server Cipher(s):
Preferred TLSv1.3  128 bits  TLS_AES_128_GCM_SHA256
Accepted  TLSv1.2  256 bits  ECDHE-RSA-AES256-GCM-SHA384
Accepted  TLSv1.2  128 bits  ECDHE-RSA-AES128-GCM-SHA256

  Server Key Exchange Group(s):
TLSv1.3  128 bits  secp256r1

  SSL Certificate:
Signature Algorithm: sha256WithRSAEncryption
RSA Key Strength:    2048
Subject:  example.com
Not valid before: Jan  1 00:00:00 2026 GMT
Not valid after:  Dec 31 23:59:59 2026 GMT

2. Scanning a non-standard port

sslscan example.com:8443

3. Testing STARTTLS services (SMTP)

sslscan --starttls-smtp mail.example.com:25

4. Show only certificate information

sslscan --show-certificate example.com

5. Only test specific protocol versions

sslscan --no-ssl2 --no-ssl3 --tlsv1_2 example.com

6. XML output for automation

sslscan --xml=results.xml example.com

Configuration Options

FlagPurpose
--no-ciphersuitesSkip full cipher enumeration for a faster protocol-only check
--no-check-certificateSkip certificate validation (useful for self-signed certs in a lab)
--ipv4 / --ipv6Force IP version
--timeout=<n>Adjust connection timeout
--connect-timeout=<n>Adjust the initial TCP connect timeout

Real-World Use Cases

Quick sanity check mid-engagement: When I’ve already run a full SSLyze scan but want to confirm one specific finding (like whether a legacy cipher is really accepted), a targeted sslscan run is faster than re-running a full report.

Mail server security review: Using --starttls-smtp, --starttls-imap, or --starttls-pop3 to check whether internal mail servers still allow weak ciphers over STARTTLS connections.

Compliance spot-checks: Confirming a single remediated host no longer accepts SSLv3 or export-grade ciphers after a patch, without needing a full audit report.

Forensic review post-incident: After identifying a downgrade attack in packet captures, running sslscan against the affected server to confirm what cipher suites were actually available for an attacker to exploit at the time.

Workflow and Tool Integration

# Quick fleet-wide protocol/cipher spot check
for host in $(cat hosts.txt); do
  echo "== $host ==" >> sslscan_fleet.txt
  sslscan --no-ciphersuites "$host" >> sslscan_fleet.txt
done

# Follow up with a deep dive on any host showing weak protocol support
sslscan --show-certificate weakhost.example.com

I typically run sslscan and sslyze back to back on the same host early in an engagement — if their cipher lists disagree, that’s usually worth a closer manual look with openssl s_client.

Performance Optimization

  • Use --no-ciphersuites when you only care about protocol version support, cutting scan time significantly.
  • Lower --connect-timeout on local/lab networks to speed up scans against many hosts.
  • Batch hosts through a shell loop with output redirected to a single file rather than running interactively one at a time.

Troubleshooting

  • “connect() failed” — verify the port is open and not filtered; try nc -zv host port first.
  • Certificate validation errors on internal/self-signed hosts — add --no-check-certificate to bypass validation for lab or internal CA-signed certs.
  • Handshake failures on legacy protocol tests — some modern OpenSSL system libraries block SSLv2/SSLv3 negotiation entirely; use a statically compiled sslscan build (make static) which bundles a patched OpenSSL supporting legacy protocol testing.

Best Practices and Common Mistakes

  • Don’t assume a clean sslscan result means the whole TLS stack is secure — always check certificate chain trust and hostname matching separately.
  • Explicitly test STARTTLS-capable services; a plain scan against port 25 or 143 without the STARTTLS flag will just fail to negotiate.
  • Keep the static build up to date — legacy cipher/protocol testing depends on the bundled OpenSSL version being current with known CVE checks.

FAQ

How is sslscan different from sslyze? sslscan is a lightweight, single-binary, cipher-by-cipher brute-force tester written in C; sslyze is a Python-based platform with a plugin architecture, JSON output, and deeper compliance baseline comparisons (like Mozilla configuration levels).

Can sslscan detect Heartbleed? Yes, it includes a basic Heartbleed check as part of its default scan output.

Does sslscan need root privileges? No, it operates as a normal TCP/TLS client and doesn’t need elevated privileges.

Lab Example

Deploy an Apache server in a lab VM with mod_ssl configured to allow both modern and legacy ciphers, then run:

sslscan --show-certificate 192.168.56.30

Identify which legacy ciphers are accepted, update the Apache SSLCipherSuite directive to remove them, restart Apache, and re-run the scan to confirm the fix.

Summary

sslscan is the fast, no-nonsense counterpart to more comprehensive tools like sslyze — perfect for quick cipher and protocol checks, STARTTLS testing, and Heartbleed spot-checks. I keep it in my toolkit specifically for those moments when I need a fast, authoritative answer about a single host’s TLS configuration without spinning up a full audit.

References

  • Official GitHub repository: https://github.com/rbsec/sslscan
  • Man page: man sslscan
Total
0
Shares
Leave a Reply
Previous Post
sslh: Multiplexer for SSL and non-SSL connections

SSLH: Sharing a Single Port Between SSL and Non-SSL Services

Next Post
sslyze: Audits SSL/TLS configurations

SSLyze: Auditing SSL/TLS Configurations Like a Pro

Related Posts