diff --git a/crypto/easy_peasy/flag b/crypto/easy_peasy/flag new file mode 100644 index 0000000..d35eead --- /dev/null +++ b/crypto/easy_peasy/flag @@ -0,0 +1 @@ +very_secret diff --git a/crypto/easy_peasy/key b/crypto/easy_peasy/key new file mode 100644 index 0000000..b45f709 Binary files /dev/null and b/crypto/easy_peasy/key differ diff --git a/crypto/easy_peasy/otp.py b/crypto/easy_peasy/otp.py new file mode 100755 index 0000000..7c31c47 --- /dev/null +++ b/crypto/easy_peasy/otp.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python3 +import os.path + +KEY_FILE = "key" +KEY_LEN = 50000 +FLAG_FILE = "flag" + + +def startup(key_location): + flag = open(FLAG_FILE).read() + kf = open(KEY_FILE, "rb").read() + + start = key_location + stop = key_location + len(flag) + + key = kf[start:stop] + key_location = stop + + result = list(map(lambda p, k: "{:02x}".format(ord(p) ^ k), flag, key)) + print("This is the encrypted flag!\n{}\n".format("".join(result))) + + return key_location + +def encrypt(key_location): + ui = input("What data would you like to encrypt? ").rstrip() + if len(ui) == 0 or len(ui) > KEY_LEN: + return -1 + + start = key_location + stop = key_location + len(ui) + + kf = open(KEY_FILE, "rb").read() + + if stop >= KEY_LEN: + stop = stop % KEY_LEN + key = kf[start:] + kf[:stop] + else: + key = kf[start:stop] + key_location = stop + + result = list(map(lambda p, k: "{:02x}".format(ord(p) ^ k), ui, key)) + + print("Here ya go!\n{}\n".format("".join(result))) + + return key_location + + +print("******************Welcome to our OTP implementation!******************") +c = startup(0) +while c >= 0: + c = encrypt(c) diff --git a/crypto/easy_peasy/solve.py b/crypto/easy_peasy/solve.py new file mode 100755 index 0000000..1582838 --- /dev/null +++ b/crypto/easy_peasy/solve.py @@ -0,0 +1,58 @@ +#!/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()