Pragyan 2020 - AskTheOracle

Posted on mer. 26 février 2020 in CTF

AskTheOracle (150pts)

Mr Robot has worked all night to find the Cipher "TIe8CkeWpqPFBmFcIqZG0JoGqBIWZ9dHbDqqfdx2hPlqHvwH/+tbAXDSyzyrn1Wf" then he faints of Overdose.You are left with a challenge to get the key to the database before EVIL CORP starts backing up the data.

nc ctf.pragyan.org 8500

P.S- After solving you will get a flag in the format of pctf{code}, change it to p_ctf{code} and submit it.
$ nc ctf.pragyan.org 8500
Enter in format '<Ciphertext>|<Initialisation Vector>'
import pwn
from base64 import b64encode, b64decode
pwn.context.log_level = pwn.logging.ERROR

cipher = "TIe8CkeWpqPFBmFcIqZG0JoGqBIWZ9dHbDqqfdx2hPlqHvwH/+tbAXDSyzyrn1Wf"
cipherb = b64decode(cipher)
iv = "VGhpcyBpcyBhbiBJVjQ1Ng=="
ivb = b64decode(iv)
allb = ivb + cipherb


def send(cipher, iv):
    conn = pwn.remote('ctf.pragyan.org', 8500)
    conn.recvuntil('Enter in format \'<Ciphertext>|<Initialisation Vector>\'\n')
    conn.send(f'{cipher}|{iv}\n'.encode())
    conn.recvuntil('VGhpcyBpcyBhbiBJVjQ1Ng==\n')
    res = conn.recv()
    conn.close()
    return b'Cipher Error!\n' in res


plain = []
for block in range(len(allb), 16, -16):
    pad = []
    c2 = b64encode(bytearray(allb[block - 16:block])).decode()

    for byte in range(1, 17):
        c1b = allb[block - 16 - byte]
        c1 = (16 - byte) * [0xf0] + [0] + [p ^ byte for p in pad]

        for i in range(0, 256):
            if c1b ^ (i ^ byte) > 126:
                continue
            c1[-byte] = i

            if send(c2, b64encode(bytes(c1)).decode()):
                pad.insert(0, i ^ byte)
                plain.insert(0, c1b ^ (i ^ byte))
                break
        print(plain)

print(''.join([chr(p) for p in plain]))