π One-Time Pad Tampering β Integrity Flaw Exploit
Writeup from Cryptography
Challenge Title: One-Time-pad
Platform: pwn.college
Category: Cryptography
Difficulty: Easy
Tags: OTP, XOR, message integrity
π Description
The One-Time Pad is known for being perfectly secure, but only for confidentiality.
It does not provide integrity β meaning, if an attacker can tamper with the ciphertext, they can manipulate the message undetected.This challenge demonstrates that by letting you interact with a script that:
- XORs a plaintext command (like
sleep) with a secret key- And prints the resulting ciphertext
You are then allowed to send your own ciphertext to the server.
π₯ Goal: Modify the ciphertext so that the server thinks it received
flag!instead ofsleep.
π Given Files
dispatcher
from Crypto.Util.strxor import strxor
key = open("/challenge/.key", "rb").read()
ciphertext = strxor(b"sleep", key[:5])
print(f"TASK: {ciphertext.hex()}")
Worker
from Crypto.Util.strxor import strxor
import time, sys
key = open("/challenge/.key", "rb").read()
while line := sys.stdin.readline():
if not line.startswith("TASK: "): continue
data = bytes.fromhex(line.split()[1])
cipher_len = min(len(data), len(key))
plaintext = strxor(data[:cipher_len], key[:cipher_len])
print(f"Hex of plaintext: {plaintext.hex()}")
print(f"Received command: {plaintext}")
if plaintext == b"sleep":
print("Sleeping!")
time.sleep(1)
elif plaintext == b"flag!":
print("Victory! Your flag:")
print(open("/flag").read())
else:
print("Unknown command!")
Understanding the Logic
- The dispatcher encrypts bβsleepβ with the unknown key:
cipher = XOR(sleep, key) - We can reverse it:
Key = XOR(cipher, sleep) - Now that we have the key, we can forge a new ciphertext:
new_cipher = XOR(key, b"flag!")βExploitation Steps
1. Get the ciphertext
$ /challenge/dispatcher TASK: 12cb6cabf12. Reverse XOR to extract the key
>>> c = bytes.fromhex('12cb6cabf1') >>> p = b'sleep' >>> key = bytes([a ^ b for a, b in zip(c, p)]) >>> key.hex() '61a709ce81'3. Craft new command: flag!
>>> p = b'flag!' >>> forged_cipher = bytes([a ^ b for a, b in zip(p, key)]) >>> forged_cipher.hex() '07cb68a9a0'4. Send the forged ciphertext to the worker
$ /challenge/worker TASK: 07cb68a9a0 Hex of plaintext: 666c616721 Received command: b'flag!' Victory! Your flag: pwn.college{MeLKBB0BFKbG27bEGfXW-q6rujV.01M3kjNxwSM0IzMyEzW}