$ cat writeup.md…
$ cat writeup.md…
HackTheBox
Server: 83.136.251.105:37930
"Qubitrix doesn't store data the way others do. Deep within its core, every secret stays in a silent quantum spiral, beyond classical reach. Engineers swore it was flawless — yet something in its design hums and breathes. To them, madness. To us, clarity."
Server: 83.136.251.105:37930
The server uses Qiskit to encode the flag into quantum states. Each byte of the flag is converted to a rotation angle (byte * π/180 radians) and applied to the corresponding qubit:
i % 3 == 0: RX(θ) — rotation around X axisi % 3 == 1: RY(θ) — rotation around Y axisi % 3 == 2: H then RZ(θ) — Hadamard + rotation around Z axisThe server allows:
For RX and RY gates: After applying RX(θ) or RY(θ) to |0⟩:
cos(θ/2)|0⟩ ± sin(θ/2)|1⟩P(1) = sin²(θ/2)θ = 2·arcsin(√P(1)), then byte = θ × 180/πFor RZ gates (after H): After H·RZ(θ)|0⟩:
(e^{-iθ/2}|0⟩ + e^{iθ/2}|1⟩)/√2P(1) = sin²(θ/2)#!/usr/bin/env python3 """ Phase Madness Solver - HackTheBox Quantum state tomography attack on phase-encoded flag """ from pwn import * import json import math HOST = "83.136.251.105" PORT = 37930 def get_measurement(r, qubit, instructions=""): """Send measurement request and get results""" r.recvuntil(b"Specify the qubit index you want to measure : ") r.sendline(str(qubit).encode()) r.recvuntil(b"Specify the instructions : ") r.sendline(instructions.encode()) return json.loads(r.recvline().decode().strip()) def prob_one(result): """Calculate probability of measuring |1⟩""" total = sum(result.values()) return result.get("1", 0) / total if total > 0 else 0 def recover_byte(r, qubit): """Recover a single byte from qubit measurement""" pos_in_group = qubit % 3 if pos_in_group == 0: # RX gate result = get_measurement(r, qubit, "") elif pos_in_group == 1: # RY gate result = get_measurement(r, qubit, "") else: # RZ gate (after H) - need basis transformation # Apply RY(-90) to measure in X-basis and reveal phase result = get_measurement(r, qubit, f"RY:-90,{qubit}") p1 = prob_one(result) # Recover angle from probability # P(1) = sin²(θ/2) → θ = 2·arcsin(√P(1)) theta = 2 * math.asin(math.sqrt(min(p1, 1.0))) byte_val = round(theta * 180 / math.pi) return byte_val def main(): flag_len = 79 # Determined by probing flag = [] r = remote(HOST, PORT) for i in range(flag_len): try: byte_val = recover_byte(r, i) char = chr(byte_val) if 32 <= byte_val <= 126 else '?' flag.append(char) print(f"Qubit {i:2d}: {byte_val:3d} -> '{char}'") except Exception as e: print(f"Error at qubit {i}: {e}") flag.append('?') print(f"\nFlag: {''.join(flag)}") r.close() if __name__ == "__main__": main()
| Gate | Matrix | Effect on |0⟩ | |------|---------|-----------| | RX(θ) | [[cos(θ/2), -i·sin(θ/2)], [-i·sin(θ/2), cos(θ/2)]] | cos(θ/2)|0⟩ - i·sin(θ/2)|1⟩ | | RY(θ) | [[cos(θ/2), -sin(θ/2)], [sin(θ/2), cos(θ/2)]] | cos(θ/2)|0⟩ + sin(θ/2)|1⟩ | | RZ(θ) | [[e^{-iθ/2}, 0], [0, e^{iθ/2}]] | e^{-iθ/2}|0⟩ (phase only) |
RZ on |0⟩ gives only a global phase — measurement always yields |0⟩.
But after H: H|0⟩ = (|0⟩ + |1⟩)/√2
Then RZ: (e^{-iθ/2}|0⟩ + e^{iθ/2}|1⟩)/√2
The phase is now relative! By applying RY(-π/2), we rotate the state so that the phase difference becomes an amplitude difference, which can be measured.
$ cat /etc/motd
Liked this one?
Pro unlocks every complete writeup and expanded API access. $9/mo.
$ cat pricing.md$ grep --similar