Classic crypto challenge using classic schemes but with a forensics and legacy software twist.
LegacyDH
Vi installerede Diffie Hellman med en ret dårlig prime og kan ikke opgradere serveren på grund af ældre versioner. Vi har lige opgraderet den gamle NemDH-klient til MitDH-klienten, og vi håber, at modstanderen ikke fik trafik fra de gamle klienter for at gendanne det flag, der var krypteret af serveren!
Author: dfaranha, Rabjho (me)
Category: crypto, forensics
The challenge supplies a network capture traffic.pcap which contains traffic from a few different clients using two different versions, where one is a legacy client. Both clients are supplied.
Diffing the clients
When we diff both the two clients in the handout, we notice that the new client implements safeguards against small prime factors. This hints further that the server may use unsafe public keys.
| |
The vulnerability
The new MitDH client validates the server’s public key to ensure it doesn’t lie in a small subgroup. The old NemDH client does none of this - it blindly accepts whatever the server sends. This means that if the server happens to use a prime $p$ where $p-1$ has small factors, and the server’s public key falls into a small subgroup, the shared secret is confined to a small set of values. We can just brute-force it.
More concretely: in a standard Diffie-Hellman exchange, the shared secret is $s = g_s^{x_c} \mod p$. If the order of $g_s$ is small (say, at most 727 - the largest prime the MitDH client checks for), then $s$ can only take on a small number of values regardless of $x_c$. We can simply try all of them.
Parsing the pcap
The traffic capture contains multiple connections. Each connection exchanges JSON messages over TCP: First the DH parameters (p, g, server_public), then the client’s response (including client_version), and finally an encrypted message from the server (encrypted_data, nonce).
We need to:
- Identify which connections used the legacy NemDH client (since those are the ones without subgroup validation).
- Extract the DH parameters and the encrypted message from each of those connections.
- Brute-force the shared secret.
Solve script
The encryption uses AES-CTR, keyed with the SHA-256 hash of the shared secret. Since the shared secret lives in a small subgroup, we iterate over all possible powers of $g_s \mod p$ and check if the resulting decryption contains the flag prefix.
Solve script by dfaranha:
| |
Tl;Dr
- The challenge provides a pcap and two DH client versions. The new client (MitDH) validates that the server’s public key doesn’t have a small order; the old client (NemDH) doesn’t.
- We filter the pcap for connections that used the legacy NemDH client.
- For those connections, the server’s public key lies in a small subgroup, so the shared secret can only take a handful of values.
- We brute-force through all possible shared secrets (at most 727 candidates), derive the AES key, and decrypt. One of the connections contains the flag.