[redpwnCTF 2021] – yahtzee

Diberikan source code sebagai berikut :

Jadi code diatas akan membaca quotes.txt dan ambil sebuah random quote. Di dalam quote tersebut terdapat flag, akan tetapi flag diletakkan diantara sebuah quote secara random. Jadi misalnya ada quote “ini quote 100”, maka flag bisa berada di “flag ini quote 100” atau “ini flag quote 100” atau “ini quote flag 100”, atau “ini quote 100 flag”. Disitu nonce dari AES CTR diambil dari penjumlahan 2 buah angka random dari 1-6 (mirip dengan pelemparan 2 buah dadu), sehingga kemungkinan noncenya adalah : [2,3,4,5,6,7,8,9,10,11,12]

Dari ilustrasi dan source code diatas, misalnya kita coba ambil 300 sample ciphertext. Ada kemungkinan dari 300 ciphertext tersebut, kita bisa mendapatkan beberapa ciphertext yang dienkrip dengan key dan nonce yang sama serta string flag berada di paling depan. Karena ada kemungkinan reusing key dan nonce, maka AES CTR menjadi vulnerable. Berikut adalah ilustrasi dari proses enkripsi dengan AES CTR :

Dari flow diatas, misalnya ada 2 plaintext yang dienkrip dengan key dan nonce yang sama. Berarti :

C1 = EncryptedKey ^ P1

C2 = EncryptedKey ^ P2

C1 ^ C2 = EncryptedKey ^ P1 ^ EncryptedKey ^ P2

C1 ^ C2 = P1 ^ P2

C1 ^ C2 ^ P1 = P2

Karena kita tahu format awal dari flag adalah “flag{“ maka kita bisa coba dapetin plaintext lainnya. Pertama, kita kumpulin 300 sample dari ciphertext dengan source code sebagai berikut :

Selanjutnya, dari persamaan C1 ^ C2 ^ P1 = P2, kita ambil setiap ciphertext sebanyak 5 karakter (karena known plaintext “flag{“ terdiri dari 5 karakter) dan di xorkan dengan ciphertext lainnya sebanyak 5 karakter juga. Codenya seperti berikut :

Ciphertext pada index 68 dixor dengan ciphertext pada index 88 dixor dengan “flag{” menghasilkan Every. Ciphertext pada index 68 dixor dengan ciphertext pada index 133 dixor dengan “flag{” juga menghasilkan Every. Karena plaintext dalam bahasa inggris, saya tebak katanya adalah Everything.

Sekarang kita memperoleh known plaintext baru, yaitu Everything. Ganti knownnya menjadi Everything, dan sekarang ambil ciphertextnya 10 karakter, karena jumlah karakter pada string “Everything” ada 10, yang berarti dalam hex adalah 20 :

Jalanin script diatas, kita dapat ciphertext pada index 208 dixor dengan ciphertext pada index 213 dixor dengan “Everything” menghasilkan A truly ri.

Searching di google dan disitu ada autocomplete berupa quote yang dimulai dengan a truly rich man. Terus coba liat google image, disitu kita dapat quote “A truly rich man is one whose children …”.

Saya coba gunakan string diatas dan coba cari string yang terdapat substring “flag{“. Sekarang kita memperoleh known plaintext baru, yaitu A truly rich man is one whose children. Ganti knownnya menjadi A truly rich man is one whose children, dan sekarang ambil ciphertextnya 38 karakter, karena jumlah karakter pada string “A truly rich man is one whose children” ada 38, yang berarti dalam hex adalah 76 :

Jalanin script diatas dan berhasil dapetin flag:

Flag : flag{0h_W41t_ther3s_nO_3ntr0py}

Leave a Reply

Your email address will not be published. Required fields are marked *