Simple (220 pts)

Deskripsi

Cuma maen AES doang. Simple Kan?

nc 103.145.226.206 1945

Mirror: nc 103.145.226.209 1945

Author: Lawson Schwantz

Kita diberikan source code dari soal yakni sebagai berikut.

from Crypto.Cipher import AES
from Crypto.Util.Padding import *
import string
import random
import os
from Crypto.Util.number import *
from secrets import FLAG, enc
 
def generate_random_string(length):
    characters = string.ascii_letters + string.digits + string.punctuation
    return ''.join(random.choice(characters) for _ in range(length))
 
def encrypt(msg,key,iv):
###############################################################################
#                                                                             #
#                    Haduh kena prank opo iki rek jadi ilang                  #
#                   Seinget gw ini AES jg deh cm entah apa ini                #
#                              Gudlak All!! :)                                #
#                                                                             #
###############################################################################
    return enc.hex()
 
key = os.urandom(16)
iv1 = os.urandom(16)
iv2 = os.urandom(16)
plainkey = os.urandom(16)
 
enckey = encrypt(plainkey + os.urandom(16), key, iv1)
 
code = ("Very simple, " + generate_random_string(random.randint(50,60))).encode()
 
cipher = AES.new(plainkey + (os.urandom(2)*8),AES.MODE_CBC, iv2)
 
enccode = cipher.encrypt(pad(code,16))
 
print(f'enckey = {enckey}')
print(f'enccode = {enccode}')
print(f'iv2 = {iv2}')
 
while True:
    print("""      ========================================
        1. Tes Enkripsi
        2. Tebak kode
        3. Exit
        ============================================""")
 
    choose = input(">> ")
    if choose == "1":
        plaintext = input("Masukan pesan: ")
        try:
            plaintext = bytes.fromhex(plaintext)
            ciphertext = encrypt(plaintext, key, iv1)
            print(f'Ciphertext = {ciphertext}')
        except:
            print("woila...")
 
    elif choose == "2":
        cobaan = input("Masukkan kode: ").encode()
        if cobaan == code:
            print(f'dahlah, {FLAG}')
            exit(1)
        else:
            print("salah :(")
            exit(0)
 
    elif choose == "3":
        print("Bye!")
        exit(1)
 
    else:
        print("woi!")
        exit(0)

Intinya begini:

  • kita dimintai code, tapi hanya dikasih enccode (code yang dienkripsi)

  • enkripsi code menggunakan kunci plainkey + random byte (tapi cuma 2 byte jadi bisa di-bruteforce)

  • plainkey tidak diberikan, tapi kita diberikan enckey yang 16 byte pertamanya merupakan hasil enkripsi dari plainkey

  • algoritma enkripsi yang sama yang meng-encrypt plainkey diberikan, dan bebas untuk kita gunakan

Pertama-tama, saya berusaha untuk mendapatkan plainkey. Saya mencoba-coba algoritma โ€œTes Enkripsiโ€ yang diberikan. Rupanya, penambahan byte di akhir plaintext tidak mengubah hasil enkripsi di byte awalnya. Selain itu, hasil enkripsi masing-masing byte dapat berbeda tergantung posisinya di mana. Misalnya:

plain

aa

bb

aabb

aabb1212

cipher

00

11

0033

003378fe

Maka dari itu, saya mencoba untuk melakukan brute-force di mana untuk setiap byte pada enckey, saya berusaha mencari sebuah byte yang apabila diencrypt, hasilnya adalah byte pada enckey tersebut.

Nah kalau plainkeynya sudah ketemu, sekarang kita perlu menghitung nilai berikut.

Di sini yang belum kita ketahui adalah hasil dari os.urandom(2) nya. Karena hanya 2 byte, berarti masih bisa kita brute force. Kalau sudah ketemu kode aslinya, kita bisa submit ke server dan mendapatkan flag. Langsung saja berikut ini saya berikan full kode solvernya.

Flag: NCW23{kenapa_bocor_lagi_yak_keynya?_yang_penting_soalnya_simple_dah}

Last updated