How to Test for TLS Vulnerabilities (Heartbleed, POODLE, BEAST) Using testssl.sh

Use the -H, -O, and -A command-line flags to detect Heartbleed, POODLE, and BEAST vulnerabilities by sending crafted payloads that exploit specific weaknesses in the TLS protocol stack.

testssl.sh is a comprehensive, single-file Bash script maintained by drwetter/testssl.sh that orchestrates OpenSSL-based security assessments. When testing for classic TLS vulnerabilities, the driver parses dedicated flags, sets internal Boolean triggers, and executes specialized functions that transmit malicious payloads over raw sockets to determine if a server is susceptible to known CVEs.

Command-Line Options for Vulnerability Detection

Each vulnerability check in testssl.sh is controlled by a specific command-line flag defined in the argument parsing section (around lines 21568–21580):

  • -H, --heartbleed – Triggers the Heartbleed check (CVE-2014-0160) at line 21568
  • -O, --poodle – Triggers the POODLE (SSL 3.0) check (CVE-2014-3566) at line 21577
  • -A, --beast – Triggers the BEAST check (CVE-2011-3389) at line 21580

When you invoke these flags, the script sets corresponding Boolean variables (do_heartbleed, do_poodle, do_beast) in the option handling block (lines 24734–24766). The main execution loop subsequently evaluates these variables in the "offensive" testing block at line 25439:

"$do_heartbleed" && { run_heartbleed;  }
"$do_poodle"    && { run_poodle;     }
"$do_beast"     && { run_beast;      }

How Heartbleed Detection Works

The Heartbleed vulnerability (CVE-2014-0160) allows attackers to read arbitrary memory from a server by exploiting a missing bounds check in the OpenSSL implementation of the TLS heartbeat extension.

Implementation Details

The run_heartbleed function begins at line 17322 in testssl.sh. The implementation follows these steps:

  1. Payload Construction – The script builds a malformed heartbeat request at line 17367 (heartbleed_payload) that asks for more data than the payload contains.
  2. Network Transmission – It transmits the payload using the socksend_x helper at line 17371, which writes directly to the socket without relying on external OpenSSL binaries.
  3. Vulnerability Verification – If the server returns more data than originally sent (indicating memory leakage), the script flags the host as vulnerable.
  4. Severity Grading – Upon detection, the script caps the security grade at F using set_grade_cap "F" at line 17410.

All socket operations reuse the low-level helper functions (socksend, socksend_x, sockread) defined earlier in the script to ensure consistent network handling.

How POODLE Detection Works

POODLE (Padding Oracle On Downgraded Legacy Encryption) targets the SSL 3.0 protocol's implementation of CBC-mode ciphers, allowing attackers to decrypt secure HTTP cookies.

SSL Fallback Test Implementation

The POODLE check is implemented in the SSL-fallback block starting at line 18584. The detection logic operates as follows:

  • JSON Identifier – The test initializes with local jsonID="POODLE_SSL" at line 18584 for structured output logging.
  • Protocol Downgrade – The script attempts a TLS 1.2 handshake, then forces a fallback to SSL 3.0 (lines 18593–18618).
  • Vulnerability Detection – If the server accepts the SSL 3.0 fallback and negotiates a CBC cipher, the vulnerability is confirmed.
  • Severity Grading – Because SSL 3.0 is obsolete but the attack requires man-in-the-middle positioning, the grade is capped at C via set_grade_cap "C" at line 18621.

How BEAST Detection Works

BEAST (Browser Exploit Against SSL/TLS) exploits a vulnerability in TLS 1.0's CBC mode that allows attackers to decrypt data by observing block cipher patterns.

TLS 1.0 CBC Suite Testing

The run_beast function starts at line 19401 and specifically tests for exploitable cipher suite configurations:

  • Targeted Protocol – The function forces a TLS 1.0 connection using CBC-mode cipher suites known to be vulnerable to the BEAST attack.
  • Negotiation Analysis – If the server agrees to negotiate a weak CBC suite under TLS 1.0, the host is flagged as susceptible.
  • Severity Grading – The script assigns a grade cap of B using set_grade_cap "B" at line 19677, reflecting that while the vulnerability is serious, modern browser mitigations (such as record splitting) reduce practical exploitability compared to Heartbleed.

Practical Usage Examples

Execute individual vulnerability tests or combine them for comprehensive assessment:


# Test a single host for Heartbleed only

./testssl.sh --heartbleed example.com

# Scan for all three vulnerabilities simultaneously

./testssl.sh -H -O -A example.com

# Short-form combined flags (equivalent to above)

./testssl.sh -HOA example.com

# Test on a non-standard HTTPS port

./testssl.sh -HOA example.com:8443

# Quiet mode showing only vulnerable findings

./testssl.sh -HOA -q example.com

Typical output format:


SSL Heartbleed (CVE-2014-0160)               : VULNERABLE
SSL POODLE (SSL) (CVE-2014-3566)            : VULNERABLE
TLS BEAST (CVE-2011-3389)                   : VULNERABLE - but mitigated server-side (OK: TLS 1.1 or 1.2 enabled)

Understanding the Automated Severity Grades

testssl.sh assigns letter grades based on exploitability and impact:

  • F (Heartbleed) – Critical; allows direct memory access without authentication.
  • C (POODLE) – High; requires protocol downgrade attack but exposes plaintext.
  • B (BEAST) – Medium-High; primarily affects TLS 1.0 with CBC ciphers, partially mitigated by client-side protections.

These grades are enforced through the set_grade_cap function calls embedded in each vulnerability detection routine.

Summary

  • Use -H, -O, and -A to activate Heartbleed, POODLE, and BEAST tests respectively in testssl.sh.
  • Heartbleed detection sends a malformed heartbeat payload via socksend_x (line 17371) and caps the grade at F if the server leaks memory.
  • POODLE testing forces SSL 3.0 fallback (lines 18593–18618) and caps the grade at C upon successful downgrade.
  • BEAST verification checks for TLS 1.0 CBC cipher acceptance and caps the grade at B (line 19677).
  • All checks utilize native Bash socket functions without requiring external OpenSSL binaries for payload transmission.

Frequently Asked Questions

What is the difference between POODLE and POODLE_TLS?

POODLE specifically refers to the SSL 3.0 vulnerability (CVE-2014-3566) tested with the -O flag, while POODLE_TLS affects TLS 1.0–1.2 implementations with improper CBC padding checks. The -O flag in testssl.sh specifically targets the SSL 3.0 protocol downgrade scenario implemented at line 18584, whereas POODLE_TLS requires separate testing using TLS protocol versions.

Can I test for these vulnerabilities on non-standard ports?

Yes. Append the port number to the target host using the syntax host:port. For example, ./testssl.sh -HOA internal-app.example.com:8443 routes the socket connections to port 8443 instead of the default 443, applying the same run_heartbleed, POODLE, and run_beast detection logic regardless of the destination port.

How does testssl.sh send the Heartbleed payload without installing OpenSSL?

The script implements raw socket communication through Bash file descriptors and the socksend_x helper function (line 17371). It constructs the binary heartbeat payload at line 17367 using printf and hexadecimal encoding, then writes directly to the TCP socket. This approach bypasses the need for OpenSSL binaries on the client side while still triggering the vulnerability in the server's OpenSSL implementation.

Why does BEAST detection cap the grade at B instead of F?

BEAST receives a B grade cap (line 19677) rather than F because the attack requires a man-in-the-middle position and is partially mitigated by modern browser record-splitting defenses. Additionally, if a server supports TLS 1.1 or 1.2, clients can avoid the vulnerable TLS 1.0 CBC ciphers, reducing practical risk compared to Heartbleed's unauthenticated memory exposure, which warrants an F grade.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →