---
name: harden-tls
description: "Cipher and protocol hardening plus config scanning for TLS/SSL endpoints against downgrade and weak-crypto abuse: deprecated protocols (SSLv2/SSLv3, TLS 1.0/1.1), weak ciphers (RC4, 3DES, EXPORT, NULL), missing forward secrecy, and certificate validation gaps that enable interception, forced downgrade, or passive decryption (MITRE ATT&CK T1557, T1040, T1600, T1562.010; CWE-295, CWE-319, CWE-757). Signals come from config scanners (testssl.sh, sslyze, sslscan, nmap), Zeek ssl.log, Suricata tls events, JA3/JA3S, nginx, Apache, and AWS ALB access logs, and Windows Schannel events. Gives the protocol and cipher baseline to enforce, the scan and network signals that prove it holds, a hunt, and framework-mapped hardening. Use when hardening a TLS endpoint, choosing a cipher suite or minimum protocol version, scanning for weak TLS, reviewing a load balancer or web server TLS config, triaging a weak-cipher finding, or hunting TLS downgrade."
---

# TLS/SSL Cipher and Protocol Hardening - Defensive Methodology

> **Tier 2 - methodology skill.** No bespoke UMBRASEC detection rule ships with this skill yet. It gives the defender's method, the config-scan and network signals, and the hardening, and points to public rule and reference sources. Promotion to Tier 1 (a sourced, tuned UMBRASEC rule) is tracked in [COVERAGE.md](https://github.com/umbrasec-labs/umbra-blue/blob/main/COVERAGE.md). Do not treat the content below as citing a UMBRASEC rule; there is none for this threat yet.

## TL;DR

Most TLS risk is configuration, not a patchable bug. Two moves close the bulk of it. First, **set the floor**: minimum TLS 1.2 (prefer 1.3), restrict to AEAD cipher suites with forward secrecy (ECDHE with AES-GCM or ChaCha20-Poly1305), and remove every deprecated protocol (SSLv2, SSLv3, TLS 1.0, TLS 1.1) and weak cipher (RC4, 3DES, DES, EXPORT, NULL, anonymous DH). Second, **scan to prove it**: run a config scanner (testssl.sh, sslyze, sslscan, or `nmap --script ssl-enum-ciphers`) against your inventory, because a server can still *offer* a weak protocol even if nothing has used it yet. The offer surface is what an attacker downgrades you onto. Pair the scan with network TLS metadata (Zeek `ssl.log`, Suricata tls events, load-balancer access logs) to see what is actually negotiated in production. This skill is defensive: it explains the weaknesses only to the depth needed to find and fix them, and ships no downgrade, interception, pinning-bypass, or decryption tooling.

## What it looks like, defender view

A config scan is the primary lens. On a weak endpoint, testssl.sh or sslyze reports the server offering SSLv3 or TLS 1.0/1.1, CBC ciphers vulnerable to BEAST/Lucky13, RC4, export-grade RSA or DH (FREAK, Logjam, DROWN), 3DES (Sweet32), TLS-level compression (CRIME), client-initiated or insecure renegotiation, a missing TLS 1.3 downgrade sentinel, an expired or hostname-mismatched certificate, or a chain that validates against a weak or deprecated root. On a hardened endpoint the same scan shows TLS 1.2/1.3 only, ECDHE forward-secret AEAD suites, and a clean chain.

In network telemetry the tell is an actual session negotiating a protocol or cipher below policy: a Zeek `ssl.log` row with `version` of `TLSv10` or `SSLv3`, or a `cipher` containing `RC4`, `3DES`, `EXPORT`, `NULL`, or `anon`. A downgrade in progress shows as a client that normally negotiates TLS 1.3 suddenly completing at TLS 1.0/1.1 against the same server, or a flurry of handshake failures (Schannel fatal alerts) as a man-in-the-middle strips protocol options. On Windows, Schannel logs the refusal when a peer demands a protocol the hardened config forbids. Certificate-side, a sudden unexpected issuer or a new certificate for your domain in Certificate Transparency logs is the reconnaissance/interception signal.

## Log sources and signals

Both the offer surface (scanners) and the negotiated reality (network and host logs) matter. Use several of:

- **Config scanners (the offer surface).** `testssl.sh`, `sslyze`, `sslscan`, `nmap --script ssl-enum-ciphers,ssl-cert`, and the Mozilla TLS Observatory / Qualys SSL Labs style external graders. These enumerate the protocols, cipher suites, curves, certificate chain, and known-vulnerability flags a server will accept. Running them against your own estate on a schedule is legitimate defensive config scanning and is the core instrument of this skill.
- **Zeek `ssl.log` and `x509.log`.** Fields `version`, `cipher`, `curve`, `server_name`, `resumed`, `established`, `validation_status`, `ja3`, `ja3s`, and in `x509.log` the certificate subject, issuer, and validity dates. This is the richest passive view of what was actually negotiated.
- **Suricata / Zeek TLS events.** `tls.version`, `tls.cipher_suite` / `tls.cipher_security`, `tls.ja3.hash`, `tls.ja3s.hash`, `tls.sni`, `tls.subject`, `tls.issuerdn`, and certificate validity fields in EVE JSON.
- **Load balancer and web server access logs.** nginx `$ssl_protocol` and `$ssl_cipher`; Apache `%{SSL_PROTOCOL}x` and `%{SSL_CIPHER}x`; AWS ALB access logs `ssl_protocol` and `ssl_cipher` columns; Azure Application Gateway and Cloudflare edge logs carry the same two fields. Per-connection protocol and cipher at the point of termination, already attributed to a client IP.
- **Windows Schannel.** The System event log, provider `Schannel`: Event ID **36874** (an incoming connection had no cipher suite in common / a TLS protocol the client requested is not enabled), **36888** (a fatal TLS/SSL alert was generated), and **36871** (a credentials-creation error). The enabled-protocol policy lives in the registry under `HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\*` and the cipher order in `HKLM\SYSTEM\CurrentControlSet\Control\Cryptography\Configuration\Local\Default\00010002` (Group Policy override: `HKLM\SOFTWARE\Policies\Microsoft\Cryptography\Configuration\SSL\00010002`).
- **Certificate Transparency.** Monitor CT logs (for example via `crt.sh`) for unexpected certificates issued for your domains, which is the reconnaissance and interception signal.

**Baseline.** A hardened estate negotiates only TLS 1.2 and 1.3 with ECDHE forward-secret AEAD suites; `validation_status` is `ok`; the steady-state count of sub-TLS-1.2 or weak-cipher sessions and of Schannel 36874/36888 alerts is near zero. Deviations are the signal.

## Detection approach

Alert on policy violations in the negotiated-session streams, and on drift in the offer surface. The high-signal conditions are: (1) any Zeek `ssl.log`, Suricata tls event, or load-balancer log row with `version` below TLS 1.2 or a `cipher` matching `RC4`, `3DES`, `DES`, `EXPORT`, `NULL`, or `anon`; (2) a protocol downgrade, that is a client/server pair that previously completed at TLS 1.3 later completing at TLS 1.0/1.1; (3) `validation_status` other than `ok` (expired, self-signed, hostname mismatch, untrusted chain) on an endpoint that should present a valid certificate; (4) a burst of Schannel 36874/36888 events, which indicates peers demanding protocols your hardened config now refuses (expected right after tightening, suspicious later); and (5) a scheduled config scan reporting a server that newly offers a deprecated protocol or weak cipher (config drift).

Because this is configuration and protocol hygiene rather than a single exploit signature, **a tuned UMBRASEC rule is not yet shipped for this threat.** Describe the logic against your own schema and lean on public, maintained sources rather than inventing a rule: the [SigmaHQ repository](https://github.com/SigmaHQ/sigma) (the `rules/network/zeek` directory carries TLS and x509 analytics, and `rules/windows` carries Schannel event rules); the **Suricata / Emerging Threats** open ruleset, which ships JA3-hash and TLS-anomaly signatures ([rules.emergingthreats.net](https://rules.emergingthreats.net)); the **abuse.ch SSLBL** JA3 fingerprint and SSL certificate blocklist feeds ([sslbl.abuse.ch](https://sslbl.abuse.ch)); and MITRE **D3FEND** [Protocol Metadata Anomaly Detection (D3-PMAD)](https://d3fend.mitre.org/technique/d3f:ProtocolMetadataAnomalyDetection/) for the countermeasure model. For the config-scan side, [testssl.sh](https://github.com/testssl/testssl.sh) and [sslyze](https://github.com/nabla-c0d3/sslyze) emit machine-readable JSON that feeds a drift detector directly.

## Threat hunt

Hypothesis: a service in the estate still offers or negotiates a protocol or cipher below policy, or presents an invalid certificate.

1. **Scan the offer surface.** Run `testssl.sh` or `sslyze` across the inventory of TLS-terminating endpoints (web servers, load balancers, mail, LDAP, database, management interfaces, internal APIs). Export JSON. Flag every endpoint offering SSLv2/SSLv3/TLS 1.0/TLS 1.1, any RC4/3DES/DES/EXPORT/NULL/anon cipher, missing forward secrecy, or TLS compression enabled. Internet-facing and sensitive-data endpoints rank first.
2. **Confirm against reality.** Pivot to Zeek `ssl.log` (or load-balancer logs) over the last 60 to 90 days and list every session that actually negotiated `version < TLSv12` or a weak `cipher`, grouped by `server_name` and `id.resp_h`. A server that offers weak crypto *and* has real sessions using it is the top priority; one that merely offers it is still a finding.
3. **Audit certificates.** From `x509.log` / scan output, list endpoints with expired, self-signed, hostname-mismatched, or weak-signature (SHA-1, RSA < 2048) certificates, and cross-check Certificate Transparency for certificates issued for your domains that you did not request.
4. **Check the Windows policy.** On Schannel hosts, read `HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols` and confirm SSL 2.0/3.0 and TLS 1.0/1.1 client and server keys are disabled; a missing or `Enabled=1` legacy key is a finding regardless of observed traffic.

## Hardening

Shrink the surface by fixing the configuration, then detection is a backstop rather than the primary control. The mappings below follow the Essential Eight control codes grounded in the UMBRASEC [foundation guide](https://umbrasec.dev/guide/foundation.html); a cell is left blank where no single Essential Eight strategy maps, because the Essential Eight is a Windows-estate maturity model and the selection of cryptographic algorithms itself sits in ISO A.8.24 Use of cryptography, which is outside that model's scope. The authoritative algorithm-selection references are NIST SP 800-52 Rev. 2 and the Mozilla Server Side TLS guidance, cited below.

| Control | What it does | Essential Eight | ISO 27001:2022 | NIST CSF 2.0 |
|---|---|---|---|---|
| Inventory TLS-terminating endpoints and certificates | You cannot harden what you have not enumerated; feeds the scan and the hunt | Know what you own (prerequisite) | A.5.9 Inventory of assets | ID.AM |
| Disable weak protocols and ciphers (config hardening baseline) | TLS 1.2 minimum (prefer 1.3), ECDHE forward-secret AEAD suites only, remove SSLv2/v3, TLS 1.0/1.1, RC4, 3DES, DES, EXPORT, NULL, anon DH, and TLS compression | User application hardening | A.8.19 Software on systems | PR.PS Platform Security |
| Patch TLS libraries and remove protocols requiring updates | Closes implementation bugs (for example OpenSSL Heartbleed) and ships the deprecations that only arrive via updates | Patch applications; Patch operating systems | A.8.8 Technical vulnerabilities | ID.RA; PR.PS Platform Security |

Beyond the table, in prose: enable HSTS (with a sane max-age and, where appropriate, preload) so clients refuse to downgrade to cleartext; enable OCSP stapling and keep certificate revocation working; prefer the server's cipher order; disable client-initiated renegotiation and ensure secure renegotiation (RFC 5746) is on; ensure the TLS 1.3 downgrade sentinel and `TLS_FALLBACK_SCSV` are honored so a forced downgrade is detected; use certificates with RSA 2048 or ECDSA P-256 minimum and SHA-256 signatures; and rotate keys and certificates on a defined lifecycle. The Mozilla SSL Configuration Generator produces copy-ready Modern or Intermediate profiles for common servers, and NIST SP 800-52 Rev. 2 is the authoritative baseline for US-facing systems.

## Honest limitations

A config scan sees the offer surface but not who is being attacked; passive network logs see what was negotiated but not the full set of what the server would accept, and only for traffic you can observe. You need both, and internal east-west TLS is frequently unmonitored, so weak internal services hide. JA3/JA3S fingerprinting is useful but increasingly evadable (GREASE and client randomization change the hash), so treat it as enrichment, not a sole detector. Enforcing a modern floor will break genuinely legacy clients and embedded devices that only speak TLS 1.0 or RC4; inventory them before enforcing and give them a controlled exception or a replacement path rather than leaving the floor low for everyone. Finally, cipher and protocol hardening does not address application-layer issues in the same family: HTTP-level compression oracles (BREACH), TLS 1.3 0-RTT replay against non-idempotent endpoints, and application-side certificate-validation or pinning flaws all need code and application changes, not just a server cipher list. Name those gaps rather than imply a strong cipher suite closes them.

## ATT&CK and D3FEND

- MITRE ATT&CK: [T1557 Adversary-in-the-Middle](https://attack.mitre.org/techniques/T1557/) (Credential Access, Collection) for downgrade and interception; [T1040 Network Sniffing](https://attack.mitre.org/techniques/T1040/) (Credential Access, Discovery) for passive decryption of weak or export sessions; [T1600 Weaken Encryption](https://attack.mitre.org/techniques/T1600/) with [T1600.001 Reduce Key Space](https://attack.mitre.org/techniques/T1600/001/) and (Defense Evasion) for export-grade and reduced-strength crypto (note: T1600 and its sub-techniques describe an adversary weakening a compromised network device's own encryption; T1600.002 Disable Crypto Hardware does not cover cipher-suite downgrade); [T1562.010 Impair Defenses: Downgrade Attack](https://attack.mitre.org/techniques/T1562/010/) (Defense Evasion) for forcing a legacy protocol. Underlying weaknesses: CWE-295 Improper Certificate Validation, CWE-319 Cleartext Transmission of Sensitive Information, CWE-757 Selection of Less-Secure Algorithm During Negotiation.
- MITRE D3FEND: [Application Configuration Hardening (D3-ACH)](https://d3fend.mitre.org/technique/d3f:ApplicationConfigurationHardening/) for the protocol and cipher baseline; [Message Encryption (D3-MENCR)](https://d3fend.mitre.org/technique/d3f:MessageEncryption/) for enforcing strong forward-secret encryption; [Protocol Metadata Anomaly Detection (D3-PMAD)](https://d3fend.mitre.org/technique/d3f:ProtocolMetadataAnomalyDetection/) and [Network Traffic Analysis (D3-NTA)](https://d3fend.mitre.org/technique/d3f:NetworkTrafficAnalysis/) for the downgrade and weak-cipher detection side; [Certificate Rotation (D3-CERO)](https://d3fend.mitre.org/technique/d3f:CertificateRotation/) for certificate and key lifecycle.
- Public rule and reference sources: [SigmaHQ repository](https://github.com/SigmaHQ/sigma) (`rules/network/zeek`, `rules/windows` Schannel); [Suricata / Emerging Threats](https://rules.emergingthreats.net) JA3 and TLS-anomaly signatures; [abuse.ch SSLBL](https://sslbl.abuse.ch) JA3 and certificate blocklists; [testssl.sh](https://github.com/testssl/testssl.sh) and [sslyze](https://github.com/nabla-c0d3/sslyze) for config scanning; [NIST SP 800-52 Rev. 2](https://csrc.nist.gov/pubs/sp/800/52/r2/final) and the [Mozilla Server Side TLS guidance](https://ssl-config.mozilla.org/) for the hardening baseline.

**Scope note.** This is a defensive skill. It explains TLS weaknesses only to the depth needed to scan for, harden against, and detect them, and deliberately ships no downgrade, interception, certificate-pinning-bypass, or session-decryption tooling. UMBRASEC publishes defense, not offense.
