CDDC 2025

Network | Qualifier

Extract H.264 video payloads from RTP packets in a .pcap file using rtp_h264_extractor.lua.

Extracted H.264 Video

└─$CDDC2025{5tr3@m1ng_53rv1ce35_u53_th3_RT5P_pr0t0c01}

Cryptography | Qualifier

The overall solution is:

  1. Using given signatures to compute the private key using ECDSA Nonce Reuse Attack

  2. Brute-force candidate 12-word BIP-39 mnemonics from the given dictionary, derive their corresponding private keys using bip32utils and compare them against the recovered key

from ecdsa.numbertheory import inverse_mod
from itertools import product
import mnemonic
import bip32utils

# Provided constants
r  = 81210355722750344493541519494641458710145722871994877785183554697310523407018
h1 = 45643200378651069483892104393394606812504455659831083323743202489147422538955
h2 = 74831345439009646272332597737070016777412939113737083148228963710487431876647
s1 = 110764343964105699917226529930289538481215574456544978805357332521308340464732
s2 = 90138993253633063487274662700800979929978777245182171200537527514756442604713

# SECP256k1 curve order
N = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141

# Step 1: Recover the private key
numerator = (s2 * h1 - s1 * h2) % N
denominator = inverse_mod(r * ((s1 - s2) % N), N)
private_key = hex((numerator * denominator) % N)

print(f"[+] Recovered Private Key:\n{private_key}")
# 0x9f9068a0cc25f39b9c5fba5bb88d75bc5e4503a8406101a3195dc395194ea690

# Step 2: Brute-force message
words = [
    "v1ew", "5tr0ng", "app1e", "fr13nd", "7hank5", "sch00l", "c0d3", "kn0w1edg3", "g00d",
    "b4d", "dr34m", "r1v3r", "mou7a1n", "f0r3st", "5kyb1u3", "p14n3t", "c4r", "b1k3", "b00k",
    "5tor3", "l4ugh", "sm1l3", "v1ct0ry", "p0w3r", "3n3rgy", "7r4v3l", "p3ac3", "f1gh7", "h0p3",
    "4n7", "1i0nkin9", "7ig3r", "p4d0c0in", "0c34n", "w4v3", "5h0r3", "c4v3", "m00n", "5un",
    "5tar", "7r33", "fl0w3r", "5e3d", "gr455", "b3", "4ir", "c10ud", "r41n", "5n0w", "5t0rm"
]

template = "BIP-39 SECP256k1 {} 5eed r4nd0m {} g00d 5olve c0ffe {} pe4nut 5mart"

print("[*] Brute-forcing possible message...")

m = mnemonic.Mnemonic('english')
found = False
for w1, w2, w3 in product(words, repeat=3):
    msg = template.format(w1, w2, w3)
    seed = m.to_seed(msg, passphrase="")
    h = bip32utils.BIP32Key.fromEntropy(seed).PrivateKey().hex()
    if h == private_key[2:]:
        print(w1, w2, w3)
        found = True
        break

if not found:
    print("[-] No match found.")

└─$CDDC2025{p4d0c0in_b3_5tr0ng_(private key in hex)}

Last updated