picoctf/crypto/easy_peasy/solve.py

59 lines
1.4 KiB
Python
Raw Normal View History

2024-09-06 18:45:32 +02:00
#!/usr/bin/env nix-shell
#!nix-shell -i python3 -p python3 python3Packages.pwntools
from pwn import *
from pathlib import Path
addr, port, *_ = "mercury.picoctf.net 36449".split(" ")
def chunks(l, n):
for i in range(0, len(l), n):
yield l[i:i + n]
def unhex(hex: str) -> list[int]:
return [int(x, 16) for x in chunks(hex, 2)]
def xor_bytes(a: bytes, b: bytes) -> bytes:
assert len(a) == len(b)
return bytes(x ^ y for x, y in zip(a, b))
KEYLEN = 50000
def conn():
if args.REMOTE:
return remote(addr, int(port))
else:
return process([str(Path(__file__).parent / "otp.py")])
def main():
r = conn()
r.recvuntil(b'This is the encrypted flag!\n')
enc_flag = r.recvline().strip()
print(f"{enc_flag=}")
flag_len = len(enc_flag) // 2
assert flag_len % 2 == 0
remaining_bytes_until_key_reset = KEYLEN - flag_len
r.recvuntil(b'What data would you like to encrypt? ')
r.sendline(b'A'*remaining_bytes_until_key_reset)
# Ignore output, we're only trying to make the program
# reset the key offset
r.recvuntil(b'What data would you like to encrypt? ')
payload = b"A" * flag_len
r.sendline(payload)
r.recvuntil(b'Here ya go!\n')
response = r.recvline().strip()
key = xor_bytes(payload, unhex(response))
print(f"{key=}")
flag = xor_bytes(unhex(enc_flag), key).decode().strip()
print(f"picoCTF{{{flag}}}")
if __name__ == "__main__":
main()