Baby AES (451 pts)

I recently learned about AES encryption, and now I'm offering an AES encryption service to anyone. Please provide a message that you would like encrypted.

Author: Chovid99

nc ctf.gemastik.id 10004

Pada soal ini, kita diberikan source code serta sebuah service oracle.

#!/usr/local/bin/python

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import os

def encrypt(key, pt):
	cipher = AES.new(key, AES.MODE_CBC)
	ct = cipher.decrypt(pad(pt, 16))
	return cipher.iv + ct

print(f'Welcome to the AES CBC Machine')
print(f'Give me some input, and I will encrypt it for you')

with open('flag.txt', 'rb') as f:
    flag = f.read().strip()
assert len(flag) == 67

key = os.urandom(16)
out = encrypt(key, flag)
print(f'This is the example of the encryption result: {out.hex()}')
while True:
    msg = bytes.fromhex(input('Give me your message: '))
    print(f'Encryption result: {encrypt(key, msg).hex()}')

Ada beberapa hal yang bisa dicatat sejauh ini:

  • Mode AES yang digunakan adalah CBC.

  • Pada fungsi โ€œencrypt(key, pt)โ€, method yang digunakan adalah decrypt(), bukan encrypt().

  • Panjang flag persis 67, artinya ada 4 block + block kelima yang berisi 2 karakter tertentu, karakter โ€˜}โ€™, dan sisanya padding.

  • Pada oracle, key yang sama dengan key untuk meng-encrypt flag digunakan berulang kali.

Karena menggunakan fungsi decrypt untuk meng-encrypt, maka alurnya menjadi seperti berikut.

Jika kita bisa mengetahui nilai dk5, kita akan mendapatkan nilai pt4. Jika kita tahu nilai pt4, kita bisa menghitung dk4 dan mendapatkan pt3, begitu seterusnya.

Kita bisa mendapatkan dk5 dengan memanfaatkan oracle yang diberikan. Kita akan mencoba semua kemungkinan kombinasi 2 karakter dari flag aslinya lalu memasukkannya ke oracle. Katakanlah hasilnya et5, nah kita bisa mendapatkan dk5 dengan melakukan xor antara et5 dengan iv yang digunakan oracle pada saat itu. Cara kita memastikan bahwa kombinasinya benar adalah dengan mencoba decode hasil pt4-nya dan memastikan bahwa string pt4 tersebut terdiri dari 100% karakter printable.

Berikut adalah kode untuk mendapatkan dua karakter flag tersebut.

Karena pt5 dan pt4 sudah didapatkan, berikutnya tinggal melanjutkan alur penyelesaian yang sudah saya sebutkan sebelumnya. Berikut adalah kode solver full-nya.

Flag: gemastik{i_am_so_sorry_coz_it_should_be_encrypt_not_decrypt_bZzZ Zz}

Last updated