125 challenges across the TLS attack surface.
Ten families cover client configuration and verification, protocol downgrades, RSA, DH/ECDH, ECDSA, RNG failures, KEMs, oracles and key leakage. Most labs ship in both TLS 1.2 and TLS 1.3 variants, plus multi-round gauntlets that mix vulnerabilities.
Client trusts the wrong thing
No chain check · SAN-only match · leaked Superfish CA key
Real client verification bugs
Apple "goto fail" · CVE-2020-0601 forged base point
Protocol downgrade
NULL cipher · FREAK export RSA · Logjam DHE
Broken RSA keys
Fermat · Wiener · Boneh-Durfee · Pollard p±1 · RSA-CRT faults
Weak Diffie-Hellman parameters
Tiny modulus · smooth p-1 · bad generator · invalid curve · MOV
Signing-nonce leakage
Nonce reuse · biased nonce · lattice attack
Post-quantum KEM attacks
ML-KEM/Kyber (lattice) & HQC (code-based) · KAT-exact primitives · genuine KEMTLS handshakes
Post-quantum signatures
ML-DSA/Dilithium (FIPS 204) & SLH-DSA/SPHINCS+ (FIPS 205) · nonce reuse · weak key generation
Weak or backdoored entropy
Predictable ServerHello.random · weak X25519 keys
Padding & compression oracles
Bleichenbacher · Manger · BREACH / CRIME
Key leakage & side channels
FTP · SSH · HTTP · Redis · Postgres · Heartbleed
Examples of real attacks reproduced.
Each family above isn't hypothetical — these are named CVEs and historical incidents the lab rebuilds at the protocol level.
Frequently asked questions
Is this real TLS, or a simplified simulation?
Real. Where a supported library (rustls) has no config knob for the historical
misconfiguration being taught — finite-field DHE, RSA_EXPORT, explicit-curve ECDHE,
static-key KEMTLS — the platform hand-rolls a genuine TLS 1.2/1.3 engine instead:
real record layer, real key schedule, real Finished messages. There is no vendored
X.509/ASN.1 crate anywhere in the project either. And the cryptography is the genuine
article: every algorithm in the lab passes its official Known-Answer Tests,
not just the post-quantum ones. A single audit (audit_kat.sh) validates each
primitive bit-for-bit against the standard's own vectors — ML-KEM-768 (FIPS 203),
ML-DSA-65 (FIPS 204), HQC and SLH-DSA-SHAKE-128f (FIPS 205) against the NIST ACVP / KAT
vectors, and the classical primitives (SHA-2/SHA-3, SHAKE, HMAC, HKDF, AES-GCM, PBKDF2,
RSA PKCS#1 v1.5 & PSS, DSA, ECDSA P-256) against their FIPS / RFC test vectors. Keys
and signatures therefore interoperate with any standard library — the weakness is always
in how a primitive is used, never a toy look-alike.
Do I need to already know the underlying cryptography?
You should be comfortable with TLS fundamentals, a terminal, and modular arithmetic. Levels 1-2 explain enough as you go; Levels 3-4 assume you can follow a lattice-reduction or index-calculus argument.
What do I actually submit to solve a challenge?
A 32-byte secret, as 64 hex characters, that the TLS client sent the server inside the (broken) TLS session. It's checked against an independent validator process, not against a static answer file.
Is the platform's own source code included?
No — deliberately. The student archive ships pre-built Docker images and a launcher script only, so nothing on disk hands you the answer by accident. That's separate from the challenge solutions themselves, which are included in full.
Are solutions really included?
Yes. Every one of the 125 challenges ships with a complete, working exploit script and a written explanation of the technique. Try first — the solution is there the moment you want it.
Does this run on macOS or Windows?
The core attack model needs a genuinely rootful Linux Docker daemon with direct host access to the lab's bridge network for ARP spoofing — something a rootless daemon (and most non-Linux Docker setups) cannot provide. The optional attacker-toolbox container works around this for challenges that don't strictly need a host-level MITM position, but a native Linux host is what this was built and tested against.
What's the resource footprint when it's running?
Small either way. The three core containers (server, client, validator) are
FROM scratch, UPX-packed Rust binaries. The free 12-challenge sample
measures about 2.2 MB combined on disk; the full 125-challenge build compiles in
more challenge code per binary, so it's larger — roughly 5 MB combined, based on
this project's own measured light-vs-full size delta (~50-65% smaller per binary
when only 12 of 125 challenges are compiled in). RAM stays around 10 MB total either
way — only one challenge runs at a time regardless of how many are compiled in, so
RAM tracks the active challenge, not the build size. CPU usage is negligible outside
brief bursts during key generation at startup. Docker Compose caps each container at
2 GB RAM / 2 CPU cores as a safety ceiling, not a requirement — real usage is a small
fraction of that. One documented exception: server_rsa_hundreds_servers_tls12
spawns 501 parallel RSA-2048 key generations at startup and needs
--cpus=8 to finish in reasonable time. The optional attacker toolbox
(nmap, hydra, etc. — only built if you ask for it) adds roughly 70 MB and isn't
required for most challenges.
What if I get stuck?
Every challenge's write-up in the manual explains the vulnerability class and the technique that solves it, and the included solution script is there if you'd rather see it worked end to end. For anything beyond that, reach out — contact details will be provided with the release materials.
Ready to see it running?
Try 12 of the 125 challenges free, or get the full lab.