Baby RE
HackTheBox Reversing Challenge
Last updated
HackTheBox Reversing Challenge
Last updated
adalah soal CTF kategori Reversing dengan tingkat kesulitan Easy. Soal ini dibuat oleh dan telah dirilis pada 26 Oktober 2019.
Berikut adalah deskripsi dari tantangan ini:
Show us your basic skills! (P.S. There are 4 ways to solve this, are you willing to try them all?)
Setelah mengesktrak archive soal, saya menemukan satu file bernama baby
.
File ini merupakan ELF 64-bit LSB pie executable
yang merupakan file executable Linux.
Ketika saya menjalankan program ini, saya diminta untuk menginputkan key. Jika saya menginputkan sembarang teks, misalnya "test", program akan menampilkan pesan "Try again later" lalu berhenti. Hal ini menunjukkan bahwa program hanya menerima key yang valid.
Pada deskripsi soal dinyatakan bahwa ada empat cara untuk menyelesaikan soal ini. Namun, saya hanya akan membahas tiga cara, sesuai dengan walkthough resmi yang juga hanya mencakup tiga metode, yaitu:
Menggunakan strings
.
Melakukan analisis dinamis menggunakan ltrace
.
Menggunakan decompiler.
Tantangan ini meminta saya untuk mendapatkan key yang valid agar bisa mendapatkan flag. Langkah sederhana yang bisa saya lakukan adalah menggunakan strings
untuk mencoba menemukan key pada file biner.
Hasilnya, saya menemukan beberapa string yang menarik pada file baby
, seperti:
Terdapat potongan flag di sini:
Terdapat string "abcde122313
" di antara "Insert Key" dan "Try again later". Saya menduga ini adalah key yang dikomparasikan dengan inputan pengguna. Jika inputan salah, program akan menampilkan pesan "Try again later".
Dari hasil analisis ini, saya mencoba menginputkan "abcde122313" sebagai key, dan hasilnya program menampilkan flag.
Berdasarkan pengalaman saya, umumnya perbandingan input yang valid atau tidak menggunakan pengkondisian seperti if
. Pada program yang ditulis dalam bahasa C, fungsi untuk membandingkan string adalah strcmp()
.
Untuk mengetahui apakah program menggunakan fungsi strcmp()
, saya mencoba menjalankan perintah ltrace
.
Saya mencoba menjalankan ltrace
pada program baby
:
Ketika saya menginputkan "test", ltrace
mendeteksi bahwa program melakukan pemanggilan fungsi berikut:
Kode ini membandingkan input pengguna dengan "abcde122313", yang ternyata adalah key yang valid untuk mendapatkan flag.
Dekompilasi Ghidra menghasilkan fungsi main()
seperti berikut:
Dari sini, sebenarnya kita sudah mengetahui jawabannya. Perbandingan antara inputan dan key terdapat pada baris kode berikut:
Meskipun saya sudah mendapatkan jawaban dari tantangan ini, saya ingin menganalisis hasil dekompilasi tersebut lebih dalam untuk mempelajarinya secara lebih detail.
Mari kita identifikasi masing-masing variabel:
iVar1
int
Variabel untuk menyimpan hasil dari strcmp()
.
local_48
, local_40
, local_38
, local_34
undefined8
, undefined4
, undefined2
Berisi bagian dari flag.
local_28
char array
Variabel untuk menyimpan input dari pengguna.
local_10
char *
Menyimpan string yang tidak pernah ditampilkan (tersembunyi).
if (iVar1 == 0)
Jika variabel iVar1
bernilai 0, maka flag akan ditampilkan.
Penjelasan flag:
Flag dipecah menjadi 4 bagian, setiap bagian memiliki kapasitas maksimal 8 byte.
Hal ini terjadi karena arsitektur CPU 64-bit (x86-64) lebih efisien membaca data dalam unit 64-bit (8 byte).
Little Endian (dibalik)
CPU x86-64 menggunakan Little Endian, sehingga data hex yang tersimpan di memori harus dibalik agar terbaca dengan benar.
0x594234427b425448
"YB4B{BTH"
"HTB{B4BY"
0x3448545f5633525f
"4HT_VER_"
"_REV_TH4"
0x455f5354
"E_ST"
"TS_E"
0x7d5a
"}Z"
"Z}"
Berikut adalah jika pseudocode tersebut ditulis ulang ke dalam kode C yang lebih readable:
Baca lebih lanjut tentang strings
.
Baca lebih lanjut tentang ltrace
.
Baca lebih lanjut tentang strcmp()
.
Baca lebih lanjut tentang Ghidra .
akan menampilkan string ke layar.
akan menyimpan input pengguna ke dalam variabel local_28
dengan maksimal 20 karakter (0x14).
Fungsi membandingkan input pengguna dengan "abcde122313\n"
. Jika cocok, nilai yang akan dikembalikan bernilai 0.