Katla adalah sebuah permainan menebak kata yang sudah diatur setiap harinya sejumlah 5 huruf dan mempunyai kesempatan menebak sebanyak 6x, seperti ini tampilan web permainannya.
Dokumentasi Pribadi [1]
Permainan ini juga menyuguhkan aturannya di awal membuka webnya, seperti ini aturannya
Dokumentasi Pribadi [2]
Secara singkat jika kita memasukan sebuah kata dan ada yang berwarna hijau, berarti huruf itu ada dalam kata Rahasia dan posisinya benar. Lalu jika kita memasukan sebuah kata dan ada yang berwarna kuning, maka huruf tersebut ada di dalam kata namun posisinya masih kurang benar, namun jika kita memasukan sebuah kata yang keluar hanya warna abu-abu maka dipastikan huruf yang kita masukan tidak ada di kata rahasia, mudah bukan? Tapi prakteknya sulit, penulis akan memberikan sebuah contoh. Katla saat tulisan ini ditulis adalah katla ke-15.
Dokumentasi Pribadi [3]
Penulis suka mengawali tebakan dengan kata “SEMUA” karena terdapat 3 huruf vokal yang seharusnya ada di setiap kata. Seperti tangkapan layar di atas, huruf A berwarna kuning, maka bisa dipastikan di kata rahasia terdapat huruf A namun posisinya masih salah. Berarti kita cukup mencari sebuah huruf yang ada “A” tapi tidak ada “SEMU”, ya cukup sulit memang. Percobaan selanjutnya seperti tangkapan layar di bawah ini
Dokumentasi Pribadi [4]
Saya memilih kata “RETAK” (seperti perasaan penulis)[jokes] kenapa kata itu, penulis sejujurnya juga tidak tahu, acak saja. Tapi kabar baiknya huruf “A” sekarang berwarna hijau, yang mana berarti posisinya sudah benar. Susah juga, mari melanjutkan tebakan.
Dokumentasi Pribadi [5]
Dengan kata “KIPAS” penulis mendapatkan sebuah pencerahan kembali, bahwa sekarang ada 2 huruf satunya benar posisinya satunya masih salah “I”, melanjutkan tebakan.
Dokumentasi Pribadi [6]
Dengan kata “INDAH” penulis mendapatkan 3 huruf benar, dengan 1 posisi yang benar dan 2 masih salah, penulis semakin dekat (dengan kekalahan) tetap semangat, melanjutkan tebakan.
Dokumentasi Pribadi [7]
Penulis semakin kehabisan stok kata, maka yang terpikir hanya “DINDA” dan masih 3 huruf yang benar malah semua posisinya salah. Tinggal kesempatan terakhir, apakah penulis mampu? Jika bermain dengan jujur sudah pasti tidak, karena sudah tidak punya stok kata yang mungkin bisa keluar. Mari mencoba berbuat curang sedikit, pertama saya lihat tab “Network” di peramban.
Dokumentasi Pribadi [8]
Pada saat memasukan sebuah tiap-tiap huruf ternyata tidak ada proses “hit” ke sebuah “REST API”, asumsi penulis adalah semua proses dikerjakan di sisi client. Satu-satunya hit ke REST API adalah ke endpoint “api/words” tanpa ada parameter apapun, tapi mengembalikan sebuah kumpulan kata berjumlah sekitar 8000 kata yang berjumlah 5 huruf, seperti berikut ini hasil contohnya.
Dokumentasi Pribadi [9]
Padahal saya berharap ada sebuah hit ke sebuah REST API yang mengirimkan kata yang sedang kita masukan, atau ada sebuah REST API yang digunakan untuk mencocokan kata yang kita masukan dengan kata rahasia yang ada di dalam peladen (server). Jika memang ada akan ada beberapa kemungkinan celah keamanan yang mungkin bisa dimanfaatkan, mulai dari SQL-Injection / IDOR atau yang lainnya. Tapi memang tidak ada :(. Jadi di mana sang pembuat menyimpan “kata rahasianya” ? penulis mengecek Cookies nihil, namun menemukan sesuatu yang menarik di dalam Local Storage, seperti berikut ini isinya.
Dokumentasi Pribadi [10]
Terdapat 3 keys di dalam Local Storage invalidWords, gameState dan lastHash hal yang paling menarik di sini adalah lastHash yang kemungkinan adalah sebuah “kata rahasia” yang telah dilakukan hashing(?) (tapi terlihat sangat pendek bukan?) hashing umumnya sangat panjang, tapi ini terlihat berbentuk encoding dari algoritma base64 bukan? Mari kita menjelajahi lebih dalam. Penulis melihat source code dari HTML page-nya dan mendapatkan sesuatu yang menarik lagi yaitu value hash yang sama dengan Local Storage
Dokumentasi Pribadi [11]
Dan di dalam tangkapan layar terdapat juga value date yang mungkin adalah katla pada hari tersebut. Karena tautannya masih menumpang di subdomain vercel.app yang sepengetahuan saya ini digunakan untuk deploy percobaan, maka asumsi penulis kode sumbernya ada di sebuah Github repository, dan benar saja setelah mencari, penulis mendapati kodenya ada di tautan berikut ini dalam README.md-nya berisi seperti tangkapan layar berikut ini
Dokumentasi Pribadi [12]
Ternyata permainan katla ini sebelumnya sudah ada dengan bahasa inggris di Wordle penulis sendiri tau katla dari lini masa twitter penulis yang beberapa teman membagikan hasil dari jawaban mereka, keren versi lokal! Kembali ke topik awal, di sini penulis ingin tahu bagaimana cara hash dibuat, maka penulis melakukan pencarian dengan kata tersebut di fitur Github itu sendiri, dan mendapatkan banyak kode yang memiliki kata hash di dalamnya, seperti berikut ini tangkapan layarnya.
Dokumentasi Pribadi [13]
Penulis melakukan pencarian dengan dalam di setiap kata yang di-highlight oleh Github, dan paling tertarik dengan potongan kode ini.
Dokumentasi Pribadi [14]
Kode tersebut menurut asumsi dari penulis adalah kode yang digunakan untuk membuat data seperti pada Dokumentasi Pribadi [11], berikut ini potongan penuh dari kodenya.
Dokumentasi Pribadi [15]
Setelah berusaha memahami kode tersebut (penulis tidak pernah ngoding dengan TypeScript tapi masih sedikit bisa Java Script meskipun tidak sangat mahir) penulis baru memahami bahwa kode ini digunakan untuk REST API dengan endpoint https://katla.vercel.app/api/hash. Yang paling menarik di bagian bawah pada bari 30 adalah ada sebuah fungsi yang dipanggil bernama encode, yang mana encode di-import dari kode di “../../utils/codec” akhirnya algoritmanya ketemu. Sebenarnya di bagian itu juga terdapat sebuah fungsi yang digunakan untuk decode tapi agar penulis merasa keren, maka penulis dari awal berusaha tidak melihat method decode-nya sama sekali, dan berniat melakukan Reverse Engineering ala-ala begitu :))). Baiklah inilah bagaimana hash katanya dibuat
Dokumentasi Pribadi [16]
Asumsi awal penulis ternyata benar (sedikit) bahwa bentuknya sama seperti base64 (ternyata memang berperan). Baik, karena algoritmanya cukup sederhana, penulis akan mencoba membedah kodenya (biar terlihat mengerti TS padahal gak pernah ngoding TS).
Pada baris 1 fungsinya benar bernama encode() menerima sebuah input parameter dengan variabel word bertipe string dan akan mengembalikan nilai string. Pada baris ke-2 parameter diubah ke dalam bentuk base64, di baris ke-3 di sini penulis sedikit kebingungan (karena ya begitulah JS family ini), tapi asumsi awal penulis adalah menghitung ada berapa banyak (“=”) di dalam suffix base64 encoding-nya tapi mari dibuktikan.
Dokumentasi Pribadi [17]
Ternyata benar, bagian pada baris ke-3 adalah menghitung berapa banyak “=” di dalam base64 encoding umumnya “=” terbanyak adalah sebanyak 2 saja, dan ada beberapa juga yang tidak ada seperti pada tangkapan layar berikut ini
Dokumentasi Pribadi [16]
Jika panjang data %3 == 0 maka tidak akan menghasilkan “=”. Lalu pada baris ke-4 kode akan mulai menghapus “=” dengan RegeX /=/g. Pada baris ke-5 disediakan sebuah variabel kosong yang nilainya dikembalikan setelah proses loop selesai. Pada baris 6 sampai 10 terdapat sebuah proses loop yang mana tiap iterasi i akan ditambah 1 atau dikurangi 1 tergantung posisi dari bit datanya berada di posisi ganjil atau genap. Mirip seperti caesar shift (sandi goyang) algoritma. Setelah proses algoritmanya selesai hasil akhirnya akan dilakukan penggabungan dengan string dari jumlah “=” di awal. Cukup sederhana bukan, dan sangat crackable mari kita buat sendiri decode algoritmanya, saya menggunakan python karena butuh cepat ngodingnya saja, dan jadinya seperti inilah script solver decode versi saya
Dokumentasi Pribadi [17]
Dan saat dijalankan akan menghasilkan “kata rahasia” yang sebenarnya.
Dokumentasi Pribadi [18]
Dan membuatnya semi “otomatis” maka kita dapat mengambil datanya (hash secret word) dari REST API mereka. Kodenya akan jadi seperti ini
Dokumentasi Pribadi [19]
Dan saat dijalankan akan mendapatkan “kata rahasia” di hari itu, karena pengamatan penulis kata yang muncul yaitu 1 hari sekali. Dan inilah hasil dari percobaan terakhir :D
Dokumentasi Pribadi [20]
Dokumentasi Pribadi [21]
Penulis juga berkolaborasi dengan teman penulis bernama Andry Rachmadany (Java Script master di kantor saya) dan mengembangkan auto solver juga, yang mana teman-teman tinggal melakukan copy paste ke console peramban dengan kode ini
Dokumentasi Pribadi [24]
Dan voila, katla hari ini berhasil diselesaikan dengan cepat dan mudah :)
Dokumentasi Pribadi [23]
Menyenangkan sekali bisa mengerjakan katla dengan cara yang curang :(((( tapi memang menyenangkan bagi penulis. Permainan ini lagi viral di berbagai media sosial, terutama di Twitter, cara yang dilakukan penulis untuk “menang” bukanlah tujuan dari adanya katla ini, teman-teman bisa menyelesaikannya dengan pengetahuan tentang kata saja, cara penulis ini untuk kesenangan pribadi. Lalu untuk katla sendiri mungkin cara “hashing”-nya bisa menggunakan algoritma yang lebih secure seperti AES / RSA atau apapun yang memerlukan sebuah key di bagian enkripsinya, namun menurut penulis juga selama algoritma dan key validasi ada di sisi client maka mungkin masih saja dapat di-crack salah satu solusinya adalah menggunakan server side validasi :D Kudos untuk para pengembang, keren sekali.
Terima kasih telah membaca, cara yang penulis di atas tulis hanya untuk kebutuhan edukasi dan dokumentasi pribadi. Mari bermain katla dengan jujur untuk menambah perbendaharaan kata kita.
Referensi: