Cyberjawara 2015: CJ2015

From Indonesian Research And Development Center
Jump to: navigation, search

Pendahuluan

Tulisan singkat ini akan membahas soal "CJ2015" pada cyberjawara 2015. Soal tersebut berupa skrip python yang diubah menjadi aplikasi untuk sistem operasi Microsoft Windows menggunakan py2exe.


Langkah-langkah

  • Ekstrak paket soal yang diberikan ke subdirektori "soal" dan pindah ke subdirektori tersebut:
% unzip cj2015.zip -d soal && cd $_
Archive:  cj2015.zip
  inflating: soal/cj2015.exe
  inflating: soal/library.zip
  inflating: soal/python27.dll
  • Selanjutnya, lakukan cloning skrip unpy2exe seperti ini:
% git clone git@github.com:matiasb/unpy2exe.git
Cloning into 'unpy2exe'...
remote: Counting objects: 8, done.
remote: Total 8 (delta 0), reused 0 (delta 0), pack-reused 8
Receiving objects: 100% (8/8), 31.82 KiB | 1024 bytes/s, done.
Resolving deltas: 100% (2/2), done.
Checking connectivity... done.
  • Jalankan skrip unpy2exe untuk mengekstrak skrip python dari aplikasi soal "CJ2015" ke subdirektori "decompiled":
% python unpy2exe/unpy2exe.py -o decompiled cj2015.exe
Magic value: 78563412
Code bytes length: 3839
Archive name: library.zip
Extracting C:\Python27\lib\site-packages\py2exe\boot_common.py.pyc
Extracting a.py.pyc
  • Hasil dari perintah di atas berupa file "a.py.pyc" pada subdirektori "decompiled". Selanjutnya, gunakan uncompyle2 untuk mengubah file python bytecode (a.py.pyc) tersebut kembali ke skrip python. Caranya seperti ini:
% uncompyle2 decompiled/a.py.pyc
# 2015.10.10 23:08:22 WIB
# Embedded file name: a.py
print 'Cyber Jawara Online'
print '==================='

def scramble(x):
    return [ chr(i) for i in x ]


def flippity(x):
    return ''.join([ ''.join(i) for i in zip(x[1::2], x[0::2]) ])


def go():
    password = raw_input('Password: ')
    if len(password) != 22:
        return False
    if ord(password[11]) != 89 or ord(password[5]) != 69 or ord(password[16]) != 112 or \
    ord(password[12]) != 111 or ord(password[18]) != 64 or ord(password[21]) != 33 or \
    ord(password[13]) != 117 or ord(password[9]) != 121 or ord(password[14]) != 114 or \
    ord(password[17]) != 64 or ord(password[7]) != 106 or ord(password[1]) != 36 or \
    ord(password[15]) != 95 or ord(password[19]) != 115 or ord(password[20]) != 115 or \
    ord(password[3]) != 121 or ord(password[10]) != 95 or ord(password[8]) != 48 or \
    ord(password[6]) != 110 or ord(password[2]) != 97 or ord(password[4]) != 95 or ord(password[0]) != 101:
        return False
    return flippity(scramble([74,
     67,
     48,
     50,
     53,
     49,
     103,
     123,
     48,
     48,
     66,
     100,
     101,
     121,
     97,
     74,
     75,
     99,
     125,
     33]))


print go()
# okay decompyling decompiled/a.py.pyc
# decompiled 1 files: 1 okay, 0 failed, 0 verify failed
# 2015.10.10 23:08:24 WIB
  • Dari sini, Anda bisa langsung mendapatkan flagnya tanpa harus memasukkan password yang benar. Caranya adalah dengan memanggil fungsi "flippity" dan "scramble" dengan parameter yang diberikan jika password benar:
% python
Python 2.7.10 (default, Sep 24 2015, 17:50:09)
[GCC 5.1.1 20150618 (Red Hat 5.1.1-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> def scramble(x):
...     return [ chr(i) for i in x ]
...
>>> def flippity(x):
...     return ''.join([ ''.join(i) for i in zip(x[1::2], x[0::2]) ])
...
>>> print flippity(scramble([74,67,48,50,53,49,103,123,48,48,66,100,101,121,97,74,75,99,125,33]))
CJ2015{g00dByeJacK!}
  • Namun, jika Anda ingin mengetahui password yang benar, maka Anda dapat dapat menggunakan cara seperti ini:
% python -c "print ''.join([chr(x) for x in [101,36,97,121,95,69,110,106,48,121,95,89,111,117,114,95,112,64,64,115,115,33]])"
e$ay_Enj0y_Your_p@@ss!


Penutup

Sekian tulisan singkat kali ini, semoga bermanfaat. Terima kasih kepada Tuhan Yang Maha Esa, Maxindo, N3 dan Anda yang telah membaca tutorial ini.


Referensi