PICOCTF‌ ‌2021‌ ‌WRITEUP‌

Pada artikel CTF kali ini, kami akan membahas mengenai PICOCTF 2021 yang bisa kalian akses soalnya di https://picoctf.org/. Soal yang akan kami jelaskan adalah soal Reverse Engineering yang bernama Transformation dengan nilai 20 poin.

Attached file content:

enc :

灩捯䍔䙻ㄶ形楴獟楮獴㌴摟潦弸彥ㄴㅡて㝽

Analisa Soal

Diberikan sebuah text yang nampaknya sudah terenkripsi menggunakan code python yang telah diberikan. Kami mencoba untuk memodifikasi code tersebut agar lebih mudah dimengerti. Setelah dianalisa, code tersebut dapat kita rekonstruksi menjadi seperti ini: 

def encrypted(flag):
    enc = “”
    for i in range(0, len(flag), 2):
  enc += chr((ord(flag[i]) << 8) + ord(flag[i + 1]))

    dec = .join(enc)
    print(dec)

Alur code:

  1. Fungsi encrypted akan menerima string flag.
  2. Fungsi akan mengambil per 2 karakter. Dimana karakter pertama akan diubah ke bentuk desimal dan di-shift sebanyak 8 bit ke kiri. Kemudian hasilnya akan ditambahkan dengan nilai desimal karakter setelahnya. Jumlah nilai ini akan dijadikan karakter baru melalui fungsi chr().
  3. Proses ini dilakukan secara repetitif hingga seluruh karakter dari string flag terenkripsi.

*catatan: Karena fungsi mengambil per 2 karakter, maka total panjang hasil enkripsi akan berjumlah setengahnya dari string flag. Hal itu menandakan bahwa panjang flag pasti genap.

Solusi

Berarti yang harus kami lakukan adalah men-shift setiap karakter yang telah dienkripsi sebanyak 8 kali ke kanan. Dan beginilah scriptnya: 

file = open(“enc”, “r”).read()
shifted = “”
for i in file:
    shifted += chr(ord(i) >> 8)
print(shifted)

Output:

pcCF1_isis3do__1107

Dari pola output yang kita temukan, mulai terbentuk format flag “picoCTF{”. Jika kita perhatikan, ada huruf-huruf yang hilang dari flag orisinil, yaitu setiap karakter di urutan genap. Jadi apabila digambarkan flag sesungguhnya akan berbentuk seperti di bawah ini:

p*c*C*F*1*_*i*s*i*s*3*d*o*_*_*1*1*0*7*

Bagaimana cara mendapatkan karakter-karakter yang hilang tersebut? Sebelumnya kita ketahui bahwa karakter hasil enkripsi tersusun dari karakter yang sudah di-shift 8 kali dan dijumlahkan dengan nilai desimal karakter setelahnya. Sekarang coba kita bandingkan nilai desimal karakter-karakter hasil enkripsi dengan nilai desimal karakter output yang kita temukan, namun di-shift 8 ke kanan. 

Decimal Karakter Hasil Enkripsi Decimal 8 bit Shifted Output
28777 28672
25455 25344
17236 17152
18043 17920
12598 12544
24418 24320
26996 26880
29535 29440
26990 26880
29556 29440
13108 13056
25695 25600
28518 28416
24376 24320
24421 24320
12596 12544
12641 12544
12390 12288
14205 14080


Jika dibandingkan, ada selisih antara hasil enkripsi dengan shifted output. Nilai selisih itu adalah nilai desimal dari karakter-karakter yang hilang. Mengapa? Karena pada proses enkripsi nilai yang ter-shift dijumlahkan dengan angka-angka ini. Jadi, yang perlu kita lakukan adalah mengubah nilai selisih tersebut menjadi bentuk karakter.  Contohnya, selisih nilai pada karakter pertama adalah 105 atau “i” dalam bentuk desimal. Artinya, karakter flag yang kedua adalah “i”.

Untuk mempermudah, bisa kita gunakan kode seperti ini:

shifted2 = “”
for j in range(len(file)):
    shifted2 += chr(ord(file[j])-(ord(shifted[j]) << 8))
print(shifted2)

Output:

ioT{6bt_nt4_f8e4af}

Dikarenakan kita sudah mendapatkan setiap karakter urutan genap. Kita dapat menggabungkan output hasil ganjil dengan output hasil genap. Berikut script lengkap yang digunakan: 

file = open(“enc”, “r”).read()
shifted = “” #pcCF1_isis3do__1107
for i in file:
    shifted += chr(ord(i) >> 8)

shifted2 = “” #ioT{6bt_nt4_f8e4af}
for j in range(len(file)):
    shifted2 += chr(ord(file[j])-(ord(shifted[j]) << 8))

for i in range(len(shifted)):
    print(shifted[i], end=“”)
    print(shifted2[i], end=“”)

Output:

picoCTF{16_bits_inst34d_of_8_e141a0f7}

Delbert Giovanni Lie & Nuel Siahaan