Pada postingan kali ini saya memaparkan bagaimana cara mendapatkan flagnya dengan mereverse engineer programnya.
Challenge dirilis pada hari Senin 28 Juli 2024, sama seperti format pada umumnya, yang mana kita harus menemukan cara untuk mendapatkan flagnya.
![]() |
Jika deskripsi challengenya sedikit aneh, mohon agar dimaafkan |
Informasi file
Di sini diberikan sebuah file zip yang di dalamnya terdapat beberapa file executable.
Ketika mencoba menjalankannya, program ini akan meminta menginput password. Setelah menginputkan password, output yang diterima akan blank/kosong dan pesan akan muncul hanya ketika kita terminate programnya.
![]() |
Output program blank |
![]() |
Pesan coba lagi muncul hanya ketika program diterminate |
Notifikasi
Ketika memasukkan file ini ke IDA Freeware, Sebuah notifikasi akan muncul untuk memberitahukan bahwa segmen pada file ini rusak, dan notifikasi ini biasanya muncul ketika program yang dimasukkan masih dalam kondisi terpack dan dengan melihat nama segmen yang ada, diketahui bahwa file ini dipacking dengan UPX.
![]() |
Notifikasi dari IDA |
![]() |
Nama segmen program ketika kondisi dipack |
FYI : Fungsi packer untuk mengurangi ukuran dan mempersulit analisis.
Jadinya di sini hanya perlu mengunpacknya, setelah itu tinggal memasukkan kembali ke dissasembler.
![]() |
Setelah diunpack ukuran programnya menjadi lebih besar |
![]() |
Segmen seperti text juga sudah terlihat |
Program ini juga ditulis dengan bahasa golang. Untuk mengetahuinya sebenarnya cukup mudah, bisa dengan melihat terdapatnya fungsi seperti fmt dan nama fungsi yang sangat banyak.
Dan ini terjadi karena di Golang, library yang ada akan di linked secara statis, yang berarti segala library yang dibutuhkan akan dimasukkan juga ke dalam program.
Jadi jangan heran kalau program sesederhana hello world di Golang ukurannya akan cukup besar.
Perulangan
Pada fungsi main, akan terdapat potongan kode pada alamat loc_494918 seperti ini:
loc_494918:
test al, al
jz short loc_494960
mov eax, dword_585F00
test eax, 1
jz short loc_494912
Yang mana register al dengan al akan dibandingkan untuk mengatur status zero flag dan jika nilai dari zero flag bernilai 1, maka akan melompat ke alamat loc_494960 dan jika zero flag bernilai 0, maka program akan berlanjut sampai bertemu alamat loc_494912.
![]() |
Alur loc_494918 |
Yang menambah keseruan challenge ini ialah ketika mencoba menginput password apa pun, nilai zero flag akan tetap 0, yang berarti kita akan selalu terlempar ke alamat loc_494912, dan akan terus melakukan perulangan tanpa henti.
![]() |
Alur loc_494912 |
Maka dari itu kenapa setelah menginputkan password, output yang kita terima akan blank. Sedangkan untuk mendapatkan flag yang dibutuhkan, kita harus melompat ke alamat loc_494960.
Untuk mengatasi ini kita hanya perlu mengubah alur agar alamat loc_494960 tereksekusi dengan mengubah jz short loc_494960 menjadi jnz short loc_494960.
![]() |
Sebelum loc_494960 diubah |
![]() |
Setelah loc_494960 diubah |
![]() |
Alur loc_494918 setelah diubah |
Ada kelanjutannya
Memang setelah mengubah alur seperti di atas masalah perulangan tanpa henti bisa diatasi. Namun untuk mendapatkan flagnya tidak cukup sampai disitu.
Karena pada fungsi getFlag ini, akan terjadi pengecekan sekali lagi.
Nilai register eax akan diisi dengan angka acak lalu ditambahkan dengan 50 (32h kalau dalam hexa), setelah itu akan dibandingkan dengan nilai dword_585EFC seperti potongan kode di bawah ini:
mov [esp+38h+var_38], 32h
call math_rand_Intn
mov eax, [esp+38h+var_34]
add eax, 32h ;
cmp dword_585EFC, eax
jl loc_494C33
Jika nilai dword_585EFC lebih kecil dari nilai register eax maka akan melompat ke alamat loc_494C33.
Yang mana, jika mengikuti alur alamat ini, kita akan berakhir pada pemanggilan fungsi runtime_gopanic.
Namun jika nilai dword_585EFC lebih besar atau sama dengan nilai register eax, flag akan dimunculkan.
![]() |
Alur loc_494B54 |
Jadi pada tahap ini hanya perlu mengubah nilai jl loc_494C33 menjadi jge loc_494C33.
![]() |
Sebelum loc_494C33 diubah |
![]() |
Setelah loc_494C33 diubah |
![]() |
Alur loc_494B54 setelah diubah |
Setelah mengubah alur program dan menjalankan programnya, kita tinggal memasukkan password apa saja, maka flag yang dicari akan muncul.
![]() |
Program berhasil menampilkan flag |
Cara Alternatif
Selain dengan mengubah alur program, kita juga bisa mendapatkan flag dengan cara yang cukup mudah daripada mengubah alur program, yaitu dengan mencari langsung flagnya di dalam program.
Di sini kita hanya perlu mengunjungi fungsi skill_issue_org_stasiun_balapan_pkg_vars_init dan mengubah nilai hex menjadi char pada word_586180 sampai dengan dword_586192.
Nilai yang tersimpan akan terbalik, ini dikarenakan arsitektur Intel menyimpan alamat dengan format little endian.
Setelah dibalik akan menjadi seperti berikut:
n1ng$etasiyun\xE2\x82\xBFalapan
Tapi tidak seperti challenge sebelumnya yang flagnya bisa terbaca jelas, di challenge ini akan ada 3 byte yang tidak terkonversi ke char.
Untuk mengetahui 3 byte tersebut merepresentasikan apa, kita hanya perlu tahu bagaimana komputer mengenali simbol emoticons atau huruf selain alfabet seperti kanji.
Ya benar sekali, UTF/Unicode.
xE2\x82\xBF jika dikonversi ke UTF-8 akan menjadi Bitcoin Sign atau ₿.
Penutup
Selain dua cara di atas, sebenarnya masih ada beberapa cara yang bisa digunakan untuk menyelesaikan challenge ini, seperti memasukan input terus-menerus sampai dword_585EFC menjadi lebih dari 50. Namun pendekatan seperti mengubah alur program lebih menarik buat saya.
Menurut saya challenge ini tentunya lebih menantang dari challenge sebelumnya karena alurnya lebih rumit dan flag yang disimpan di dalam program juga tidak serta merta terlihat.
Selain itu, penggunaan bahasa golang juga semakin menyulitkan dalam melakukan analisis, konsep seperti mutex dan gouroutine tentunya cukup menyulitkan, apa lagi yang kurang familier dengan bahasa yang satu ini seperti saya contohnya.
Tapi sebagai reverser, tentu kita tidak bisa memaksa pembuat program harus memakai bahasa yang kita tahu saja. Kita perlu fleksibel dan siap beradaptasi dengan berbagai bahasa pemrograman yang digunakan.
Jika terdapat kesalahan dalam penulisan, istilah, ataupun metode yang digunakan, saya menerima kritik dan sarannya dengan terbuka.
Akhir kata saya mengucapkan terima kasih kepada seluruh member Komunitas Skill Issue.