APOORVCTF CTF Writeup
Table of Contents

Introduction⌗
This write-up takes you through how I solved two challenges at Apoorv CTF. Both the challenges were cryptography
Genjutsu Labyrinth (crypto)⌗

Genjutsu Labyrinth was a grid-based puzzle where I had to move from the top-left corner to the bottom-right using
XOR operations. I could only move down (S) or right (D),
and my goal was to optimize the final XOR value.

I just used the same control order till I hit the point and there was the flag.

Flag: apoorvctf{G3NJUTSU_M4ST3R}
Kowareta Cipher (crypto)⌗

For this one, we had to connect to chals1.apoorvctf.xyz on port 4001. It wanted a hex input and returned ciphertext. My teammate had started solving it, and I jumped in to tweak and improve the script.
Here’s the updated script:
from pwn import *
import time
BLOCK_SIZE = 64
known_flag = b""
def recover_flag_byte(i):
pad_length = BLOCK_SIZE - (i + 1)
prefix = b"A" * pad_length
p = remote("chals1.apoorvctf.xyz", 4001)
try:
p.recvuntil(b"Enter your input: ")
print(f"Recovering byte {i + 1}/{BLOCK_SIZE}...")
p.sendline(prefix.hex().encode())
p.recvuntil(b"Ciphertext: ")
ciphertext_ref = bytes.fromhex(p.recvline().strip().decode())
for b in range(256):
test_input = prefix + known_flag + bytes([b])
p.sendline(test_input.hex().encode())
p.recvuntil(b"Ciphertext: ")
ciphertext_test = bytes.fromhex(p.recvline().strip().decode())
if ciphertext_test[:BLOCK_SIZE] == ciphertext_ref[:BLOCK_SIZE]:
print(f"Recovered: {known_flag.decode(errors='ignore')} + {chr(b)}")
return bytes([b])
return None
except EOFError:
print("Connection dropped. Retrying...")
return None
finally:
p.close()
for i in range(BLOCK_SIZE):
while True:
byte = recover_flag_byte(i)
if byte:
known_flag += byte
break
else:
time.sleep(2)
print("\nRecovered Flag:", known_flag.decode(errors="ignore"))

Boom! The script successfully recovered the flag:
Flag: apoorvctf{3cb_345y_crypt0_br43k}