kcsc-club / ctfs

repository for kscs-ctfs
8 stars 1 forks source link

Kinda AESthetic - Crypto - PragyanCTF2022 #17

Closed gnol719 closed 2 years ago

gnol719 commented 2 years ago

Đề bài cung cấp file Kinda_AESthetic.py

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import os, sys
import string
import random

KEY = os.urandom(16)
IV = os.urandom(16)
flag = REDACTED

def encrypt(msg):
    msg = pad(msg, 16)
    cipher = AES.new(KEY, AES.MODE_CBC, IV)
    encrypted = cipher.encrypt(msg)
    encrypted = encrypted.hex()
    msg = IV.hex() + encrypted
    return msg

def decrypt(msg, iv):
    cipher = AES.new(KEY, AES.MODE_CBC, iv)
    decrypted = unpad(cipher.decrypt(msg), 16).decode()
    return decrypted

def parse(inp):
    iv = bytes.fromhex(inp[:32])
    msg = bytes.fromhex(inp[32:])
    msg = decrypt(msg,iv)
    return msg

chars = string.printable[:-5]
x = random.randint(5, 15)
passwd = ''.join(random.choice(chars) for _ in range(x))

secrets = {
    'abrac': 'iloveyou',
    'sudo': REDACTED, # ;)
    'gg': passwd,
    'yeager': 'ironman'
}

x = random.randint(5, 13)
token = ''.join(random.choice(chars) for _ in range(x))

def lookup(inp):
    try:
        cipher = AES.new(KEY, AES.MODE_CBC, inp[:16])
        inp = unpad(cipher.decrypt(inp[16:]), 16)
    except:
        return 'idek'
    try:
        name = inp.decode()
        assert name[:len(token)] == token
        name = name[len(token):]
        return secrets[name]
    except:
        return 'idk'

print('Here is an encrypted token for you:')
print(encrypt(token.encode()))

while True:
    try:
        inp = input()
        try:
            user = parse(inp)
            assert user == 'gg'
            print('Welcome gg! Enter your secret passphrase:')
            inp = input()
            password = parse(inp)
            if password == secrets['gg']:
                print(flag)
                sys.exit(0)
            else:
                print(r'p_ctf{potato}')
        except:
            inp = bytes.fromhex(inp)
            print(lookup(inp))
    except:
        print('')
        sys.exit(0)

Chúng ta có thể thấy được challenge này liên quan đến CBC Bit Flipping và Padding Oracle Attack Tham khảo thêm: https://ichi.pro/vi/huong-dan-hackthebox-flippin-bank-gioi-thieu-ve-cuoc-tan-cong-lat-bit-cbc-231420708308392

from hashlib import new
from pwn import remote, xor
from Crypto.Util.Padding import pad, unpad

# idek -> wrong padding
# idk -> correct padding
# gg
# lookup token||gg

r = remote("crypto.challs.pragyanctf.tech", 5001)
r.recvline()
token = bytes.fromhex(r.recvline().strip().decode())
iv,ct = token[:16], token[16:]

decrypted = [0]*16
for i in range(1,17):
    new_iv = decrypted.copy()
    for j in range(i):
        new_iv[-j] = new_iv[-j] ^ i
    for j in range(256):
        print(j)
        new_iv[-i] = j
        r.sendline((bytes(new_iv)+ct).hex().encode())
        if b'idk' in r.recvline():
            decrypted[-i] = j ^ i
            print(decrypted)
            break

token = unpad(xor(iv,bytes(decrypted)),16)
print("Token:",token)
new_iv = xor(pad(token+b"gg",16),bytes(decrypted))
r.sendline((new_iv+ct).hex().encode())
pw = r.recvline().strip()
print("passwd:",pw)

new_iv = xor(pad(b"gg",16),bytes(decrypted))
r.sendline((new_iv+ct).hex().encode())
print(r.recvline())
new_iv = xor(pad(pw,16),bytes(decrypted))
r.sendline((new_iv+ct).hex().encode())
print(r.recvline())

Sau khi chạy chương trình ta thu được flag image flag: p_ctf{4_l1ttl3_p4d4tt4ck_h3r3_&4_l1ttl3_x0r_THERE}