$ cat writeup.md…
$ cat writeup.md…
hackthebox
Task: recover an AES-128 key from a remote embedded device that exposes chosen-plaintext power traces over a socket. Solution: apply first-round AES CPA with a Hamming-weight leakage model, recover the key from 800 traces, then submit it to receive the flag.
$ cat /etc/rate-limit
Rate limit reached (20 reads/hour per IP). Showing preview only — full content returns at the next hour roll-over.
Project Power Challenge Scenario
The provided artifacts were a Python socket client and a lab layout image. The goal was to recover the embedded device's AES-128 key and use it against the live instance at 154.57.164.74:31688.
At first glance this looked like a remote exploitation challenge, but the supplied interface was not a memory-corruption target. socket_interface.py exposed a much more direct side channel:
1: send a 16-byte plaintext and receive a base64-encoded NumPy power trace2: send a 32-hex-char AES-128 key and receive the flag if the key is correctremote_lab_layout.png clarified the architecture: plaintext is sent to the embedded device, an oscilloscope captures the AES power consumption, and Laptop-2 forwards the trace back over the socket. That makes this a standard AES side-channel problem, not a pwn or reverse challenge.
The useful prior-art match was CTFBase writeup 20260123_0xl4ugh_sca1, which used classic Correlation Power Analysis (CPA) against AES. The right first-round leakage model here was:
HW(SBOX[plaintext[i] XOR key[i]])
CPA works because the real power trace contains samples that correlate with the number of switching bits in this intermediate AES state. For each key-byte guess 0..255, we compute the hypothetical Hamming weights across many chosen plaintexts and measure which guess correlates best with the observed traces. The correct key byte stands out with the highest correlation.
Live collection confirmed that traces decoded as float64 arrays of length 1042, and 800 traces were already enough for a clean recovery. Alternate leakage models and dtype overrides were unnecessary.
...
$ grep --similar