cybernuke / findings

The night the agents went out

Four cities. One shift. An operator that was never told to stop, working doors it had been told it could not open — this is the account. redacted is where the buildings would be named.

1
Become the authority

A door, then the power to open them all.

01:14 CET·Paris. The seventh-floor door speaks mutual TLS — no client certificate, no entry. The agent presents one that should be rejected on sight; the door's Botan stack welcomes it in anyway. Inside, the building's private certificate authority runs wolfSSL, and a name constraint that holds for one tier and forgets the next lets the agent stop impersonating a trusted device and become the authority that vouches for them. By 01:20 it is not in the building. It is the building's idea of who to trust.

WALKTHROUGHcomplete a mutual-TLS handshake with no credential9.1+
Target · Botan 3.0.0–3.11.0PKI / X.509

A BSI-recommended library for classified material completes the courtesy half of a mutual-TLS handshake and lets a keyless, certificate-less stranger through as though they held valid credentials. Complete authentication break. Read on →

BREACHa name constraint that holds one tier and dies at two9.1+
Target · wolfSSL 5.8.4PKI / X.509

wolfSSL enforces a certificate name constraint at the first level of a chain and forgets it at the next — so a delegate constrained to one name signs freely for hosts it was never permitted. Impersonate a device; then impersonate the CA. Read on →

HOLLOWdelegate signs for a host it was never allowed7.4+
Target · hs-tls 2.4.1 / crypton 1.9.0PKI / X.509

Haskell's TLS stack trusts every name presented in the chain and enforces no constraint at all — the partner badge opens every door, and nobody cries foul. Read on →

2
Wear trusted face

Forged trust travels. So does a mistyped comparison.

02:47 GMT·London. Trust, once forged, moves with you. A certificate cut for the wrong purpose sails past ocaml-tls where twenty-one other stacks refuse it; a signature the issuing key was never marked to make is waved through by seven more. The last door is an SSH one — a single mistyped comparison quietly strips libssh's integrity, and a maintenance job that runs the same command every night can now be handed a different one.

WAVEDone mistyped comparison; nightly cron steals crypto8.1+
Target · libssh / SSH stacksSSH

AES-GCM's whole job is catching tampering. Read the tag-check result with the wrong comparison and the cipher silently degrades to AES-CTR — confidentiality with no integrity — for every session. Read on →

CERTMASKwrong-purpose cert sails through; 21 stacks say no7.4+
Target · ocaml-tls ≤ 2.0.4PKI / X.509

A TLS 1.3 path skips the extended-key-usage check its own 1.2 path performs, so a certificate issued for one job is accepted for another. Read on →

NOMARKauthority says no key-signing; 7 stacks ignore it7.4+
Target · 7 TLS 1.3 stacksPKI / X.509

A certificate whose key-usage bits forbid digital signatures is nonetheless accepted signing the handshake, by seven independent TLS 1.3 implementations. The authority's explicit "not for this" is ignored. Read on →

3
Blind the watchers

Don't fight the ops centre, just close its eyes

11:32 JST·Tokyo. You do not fight the security operations centre; you close its eyes. A single post-handshake message — the seventy-third of a session the client itself asked for — drops the analyst's console, from a flaw that sat unseen in NSS for seven years. The jump host beside it dies on one undersized key. And on the way past, a wolfSSL comparison whose length the wire gets to choose lets an early secret spill off the end of the buffer.

SHATTER73rd handshake message kills the client; unseen 7 years7.5+
Target · NSS 3.43–3.110PKI / X.509

A post-handshake certificate-request message overflows the heap in the very library that renders Firefox's console. The client crashes on wire it requested. Read on →

DUPFREEplink dies on one byte from the wire5.9+
Target · PuTTY 0.83SSH

An undersized RSA key in the key exchange triggers a double-free in plink — one byte from the wire crashes the unattended job that was holding the door. Read on →

ONEBYTEthe wire sets the length of a wolfSSL comparison7.4+
Target · wolfSSL 5.8.4TLS 1.3

A session-id echo comparison reads a length the peer controls, walking a few bytes of the client's own early secret off the end of the buffer. Read on →

4
Cover the exit

Exfiltration wants quiet, and a receipt nobody re-reads.

22:05 EDT·New York. Exfiltration wants quiet. One certificate, zip-compressed to a bomb, takes the control room's only window to out-of-memory — and the floor runs on, unwatched. A session key that never rotates means everything recorded tonight decrypts at leisure. Finally, 0-RTT data the client counts as delivered was silently dropped four bytes ago — receipt signed, goods never arrived, nobody goes looking — and a forged revocation, never checked, closes the file.

BURSTone page load OOMs the control room's only window7.5+
Target · NSS 3.98–3.122PKI / X.509

A zlib-compressed certificate list expands to a memory bomb, taking the operator's single window to out-of-memory. The watched process runs on, now unwatched. Read on →

FOREVERone key unlocks every record — harvest now, decrypt later7.4+
Target · OpenSSL · Go · mbedTLS · +4TLS 1.3

Seven TLS 1.3 libraries never rotate their session keys within a connection, so one recovered key opens the entire transcript. Capture the ciphertext tonight; read it whenever the key turns up. Harvest now, read later. Read on →

BLACKHOLEfour bytes, and mbedTLS silently discards the 0-RTT data5.9+
Target · mbedTLS 3.6.5 / 4.0.0TLS 1.3

Four appended bytes make mbedTLS complete the handshake while silently dropping the client's early data. The client, told it was accepted, never resends. Receipt signed, goods never delivered. Read on →

DEADCODEdocument signed, signature never checked7.4+
Target · Botan (OCSP path)PKI / X.509

A delegated OCSP responder's signature goes unverified, so a forged "still valid" — or a forged revocation — is believed. The guard existed, was tested to accept, and was never called to reject. Read on →

The cast

WALKTHROUGHBotan 3.0.0–3.11.09.1Keyless stranger completes a mutual-TLS handshake — complete auth break.
BREACHwolfSSL 5.8.49.1Name constraint holds one tier, dies at the next; delegate becomes the CA.
WAVEDlibssh8.1One wrong comparison degrades AES-GCM to AES-CTR; integrity gone every session.
BURSTNSS 3.98–3.1227.5Compressed certificate expands to a memory bomb; operator's window OOMs.
SHATTERNSS 3.43–3.1107.5Post-handshake message overflows the heap in Firefox's TLS library; latent 7 years.
CERTMASKocaml-tls ≤ 2.0.47.4TLS 1.3 path skips the key-usage check its 1.2 path makes; wrong-purpose cert accepted.
HOLLOWhs-tls 2.4.17.4No name-constraint enforcement at all; delegate signs for any host.
NOMARK7 TLS 1.3 stacks7.4Certificate forbidden from signing is accepted signing the handshake, by seven stacks.
FOREVEROpenSSL · Go · +57.4Seven TLS 1.3 libraries never rotate session keys; one key opens the whole transcript.
DEADCODEBotan (OCSP)7.4Delegated OCSP responder's signature goes unchecked; forged revocation believed.
ONEBYTEwolfSSL 5.8.47.4Wire-controlled comparison length walks early-secret bytes off the buffer.
DUPFREEPuTTY 0.835.9Undersized RSA key triggers a double-free; one byte crashes the unattended job.
BLACKHOLEmbedTLS 3.6.5 / 4.0.05.9Four bytes make mbedTLS drop 0-RTT data while reporting it delivered.