cryptofreemedium

Flagportation

hackthebox

Task: Quantum teleportation protocol where flag bits are encoded in qubit states. Solution: Apply Pauli correction gates based on measurement results and decode the flag from qubit 2 measurements.

$ ls tags/ techniques/
quantum_teleportation_protocol

Flagportation — HackTheBox

Description

Every 24 hours, Qubitrix will release a secret message to our partners. Please follow the instructions we sent you by email from [email protected].

Analysis

The server implements a quantum teleportation protocol. The flag is split into pairs of bits. Each pair is encoded into the state of qubit 0:

  • 00 -> $|0\rangle$ (Z basis)
  • 01 -> $|1\rangle$ (Z basis)
  • 10 -> $|+\rangle$ (X basis)
  • 11 -> $|-\rangle$ (X basis)

Then an entangled pair (Bell state) is created on qubits 1 and 2. CNOT(0,1) and H(0) operations are performed, after which qubits 0 and 1 are measured in the Z basis. The measurement results $M_0$ and $M_1$ are communicated to the user.

The user must:

  1. Enter correction gates for qubit 2.
  2. Choose the measurement basis for qubit 2.

According to the quantum teleportation protocol, the state of qubit 2 after measurements $M_0$ and $M_1$ differs from the original state of qubit 0 by Pauli operators:

  • If $M_0=0, M_1=0$: state $| \psi \rangle$ (no correction needed)
  • If $M_0=0, M_1=1$: state $X | \psi \rangle$ (need $X$ correction)
  • If $M_0=1, M_1=0$: state $Z | \psi \rangle$ (need $Z$ correction)
  • If $M_0=1, M_1=1$: state $ZX | \psi \rangle$ (need $XZ$ or $ZX$ correction)

The first bit of the pair is determined by the basis (Z -> 0, X -> 1), the second bit — by the measurement result of qubit 2 in that basis.

Solution

from pwn import * import re def solve(): # host = "94.237.122.188" # port = 52871 # r = remote(host, port) # For local testing or if server is running via docker r = remote("localhost", 1337) flag_bits = "" try: while True: line = r.recvuntil(b"Basis : ", timeout=5).decode() if not line: break # Get qubit number match = re.search(r"Qubit (\d+)/(\d+)", line) if match: current = int(match.group(1)) total = int(match.group(2)) print(f"Processing qubit {current}/{total}") else: print("Could not find qubit number") break basis = r.recvline().decode().strip() print(f"Basis: {basis}") r.recvuntil(b"Measurement of qubit 0 : ") m0 = int(r.recvline().decode().strip()) r.recvuntil(b"Measurement of qubit 1 : ") m1 = int(r.recvline().decode().strip()) print(f"M0: {m0}, M1: {m1}") instructions = "" if m0 == 0 and m1 == 0: instructions = "Z:2;Z:2" # No-op (Z^2 = I) elif m0 == 0 and m1 == 1: instructions = "X:2" elif m0 == 1 and m1 == 0: instructions = "Z:2" elif m0 == 1 and m1 == 1: instructions = "X:2;Z:2" r.recvuntil(b"Specify the instructions : ") r.sendline(instructions.encode()) r.recvuntil(b"Specify the measurement basis : ") r.sendline(basis.encode()) r.recvuntil(b"Measurement of qubit 2 : ") res = int(r.recvline().decode().strip()) print(f"Result: {res}") first_bit = "0" if basis == "Z" else "1" second_bit = str(res) flag_bits += first_bit + second_bit if current == total: break except EOFError: print("Connection closed") except Exception as e: print(f"Error: {e}") print(f"Collected bits: {flag_bits}") # Convert bits to bytes flag_bytes = bytearray() for i in range(0, len(flag_bits), 8): byte_str = flag_bits[i : i + 8] if len(byte_str) == 8: flag_bytes.append(int(byte_str, 2)) print(f"Flag: {flag_bytes.decode(errors='ignore')}") if __name__ == "__main__": solve()

Key Indicators

Use this technique when:

  • The task mentions quantum teleportation.
  • Measurement results of two qubits are given and gates need to be applied to a third.
  • The qutip library or similar quantum computing libraries are used.

$ cat /etc/motd

Liked this one?

Pro unlocks every writeup, every flag, and API access. $9/mo.

$ cat pricing.md

$ grep --similar

Similar writeups