Diberikan file apk , kami lakukan decompile dengan menggunakan apktool. Kemudian lakukan grep pada string flag dan kami mendapatkan suatu hash.
Selanjutnya kami lakukan crack dengan onlinetools yaitu crackstation.
Flag : itf{Android}
OAT (500 pts)
Description
-
Solution
Diberikan file oat
Disini kami menggunakan oat2dex untuk mendapatkan file dexnya.
Sesudah mendapatkan odex , kita bisa decompile menjadi java dengan jadx.
Kemudian kami mencari “flag” pada direktori com.mxtech karena ini package utama dari APK. Akhirnya kami mendapatkan function decrypt_flag
Karena ini fungsi decrypt flag , jadi cukup salin dan compile menggunakan java untuk dapat flag. Berikut solver yang kami gunakan
Flag : itf{an4lyzing_d33x_l1k3_a_b00ss}
Game #1 (500 pts)
Description
-
Solution
Diberikan sebuah apk, kami coba decompile menggunakan jadx
Terdapat native library yaitu intechfest yang di load dimana 2 fungsi yang dipanggil pada mainActivity adalah init dan check. Kita lakukan decompile pada library tersebut menggunakan IDA
Pada fungsi init , setelah kami analisis terlihat bahwa dilakukan decrypt section .text. Langkah decryptnya simple yaitu dilakukan xor dengan key , dimana key digenerate berdasarkan static value. Jadi disini kami reproduce kode untuk generate key untuk mendapatkan key. Berikut kodenya
#include<stdio.h>intmain(int argc,charconst*argv[]){char g_key[]= {0x6F,0x68,0xF0,0xED,0x66,0x55,0xE2,0x75,0xF0,0x4C,0xD7,0x6B,0x50,0x71,0xD9,0xEB,0xCB,0xED,0x5B,0x6D,0xCE,0x64,0xE7,0x4F,0x6C,0x67,0xE2,0x67,0x62,0xEF,0x31};for ( int i =0; i <=0x1E; ++i ){ g_key[i] = (((((g_key[i] +26) &0x80) !=0) | (2* (g_key[i] +26))) ^0x95^ i) -29; }for (int i =0; i <=0x1e; ++i) {printf("%c", g_key[i]); }printf("\n");return0;}
Dapat flag pertama, setelah dapat flag pertama untuk melakukan decrypt terhadap section main ternyata tidak dimulai dari index ke-0 pada key. Namun kita bisa bruteforce dan validasi manual untuk index key yang digunakan mulai dari nilai berapa. Caranya adalah dengan disassemble fungsi yang didecrypt dan validasi manual .
from elftools.elf.elffile import ELFFilefrom capstone import*import osf =open('./libintechfest.so', 'rb')g = f.read()elf =ELFFile(f)code = elf.get_section_by_name('.text')ops = code.data()start = g.index(ops[:10])length =len(ops)key =b"itf{s1Mpl3_x0r_s1mPl3_d3crYpT}"for ind inrange(0,len(key)): h =list(g)# print(h[0])for i inrange(start,start+length+1): h[i]= h[i]^key[(i+ind)%30] fn ="libpatch_first.so" out =open(fn,"wb") out.write(bytes(h)) out.close()print(ind) os.system("aarch64-linux-gnu-objdump -d libpatch_first.so | grep -A3 \" 10000:\"")
Terlihat index 14 memiliki instruksi yang valid. Jadi gunakan index 14 untuk start index pada key dan lakukan decrypt keseluruhan section .text. Caranya cukup ubah loop ind yang awalnya range(0,len(key)) menjadi range(14,15)
Sampai disini kita telah berhasil decrypt section .text
Flag : itf{s1Mpl3_x0r_s1mPl3_d3crYpT}
Game #2 (500 pts)
Description
-
Solution
Selanjutnya untuk game #2 lanjutkan analisis pada library. Disini kami melakukan analisis terhadap fungsi level1 pada gambar sebelumnya.
level 1 melakukan decrypt terhadap section .level2 , dan sub_104D0 merupakan fungsi string compare, jadi kita bisa mendapatkan keynya dari fungsi SSM::Decrypt((SSM *)((unsigned int)&dword_40 + 1)); . Argument fungsi SSM:Decrypt adalah 0x40+1 . Jadi implementasikan SSM:Decrypt menggunakan python dan dapatkan hasil decrpyt untuk nilai sesuai argumentnya. Berikut implementasi dari SSM:Decrypt.
Setelah mendapatkan key maka selanjutnya decrypt section .level2 . Caranya sama seperti kode decrypt .text sebelumnya, cman beda di validasi address disassembly, section, dan keynya.
from elftools.elf.elffile import ELFFilefrom capstone import*import osf =open('./libpatch_first.so', 'rb')g = f.read()elf =ELFFile(f)code = elf.get_section_by_name('.level2')ops = code.data()start = g.index(ops[:10])length =len(ops)key =b"itf{h1dd3n_bY_w3ak_3ncrypt10n}"for ind inrange(len(key)): h =list(g)for i inrange(start,start+length+1): h[i]= h[i]^key[(i+ind)%30] fn ="libpatch_second.so" out =open(fn,"wb") out.write(bytes(h)) out.close()print(ind) os.system("aarch64-linux-gnu-objdump -d libpatch_second.so | grep -A3 \" 2a60c:\"")
Terlihat index ke-0 sudah merupakan instruksi yang valid, jadi gunakan index ke-0.
Flag : itf{h1dd3n_bY_w3ak_3ncrypt10n}
Game #3 (500 pts)
Description
-
Solution
Selanjutnya analisis level 2
Terlihat terdapat xor terhadap static value dan algoritma semacam caesar cipher. Jadi tinggal implementasi saja untuk mendapatkan v122 dimana v122 ini nanti dibandingkan dengan suatu nilai dan digunakan untuk decrypt section. Maka dari sini bisa kita simpulkan bahwa v122 merupakan keynya.
a = [0x3E,0xA,5,0x1E,0xF,0x10,0x49,0,0x13,0x49,0x27,5,6,4,7]v122 = []for i in a: v122.append(i^0x69)for i inrange(15):if(v122[i]<0x61or v122[i]>0x7a):if(v122[i]>=0x41and v122[i]<=0x5a): v122[i]= (v122[i]-59) %26+65else: v122[i]= (v122[i]-91) %26+97print(''.join(map(chr,v122)))
Selanjutnya decrypt section .level3 dengan key tersebut
from elftools.elf.elffile import ELFFilefrom capstone import*import osf =open('./libpatch_second.so', 'rb')g = f.read()elf =ELFFile(f)code = elf.get_section_by_name('.level3')ops = code.data()start = g.index(ops[:10])length =len(ops)key =b"Circle of Trust"for ind inrange(len(key)): h =list(g)for i inrange(start,start+length+1): h[i]= h[i]^key[(i+ind)%15] fn ="libpatch_final.so" out =open(fn,"wb") out.write(bytes(h)) out.close()print(ind) os.system("aarch64-linux-gnu-objdump -d libpatch_final.so | grep -A3 \" 2aa88:\"")
Terlihat index 7 merupakan instruksi yang valid.
Flag : itf{Circle of Trust}
Game #4 (500 pts)
Description
-
Solution
Terakhir , dilakukan decrypt terhadap game.dex pada assets . Hal ini diketahui dari decrypt menggunakan SSM:Decrypt untuk setiap index yang menjadi argument.
Algoritma decrypt yang diimplementasikan adalah rc4 jadi tinggal dapatkan key (v12) lalu implementasikan decrypt menggunakan rc4.
Ubah value param_1 pada script ssm_dec sebelumnya menjadi 0x202
Read asset dilakukan per 0x400 bytes, jadi implementasikan hal yang sama juga.
from arc4 import ARC4f =open("resources/assets/game.dex","rb").read()out =open("dec.dex","wb")for i inrange(0,len(f),0x400): arc4 =ARC4(b'n1n0_k4w4ii') tmp = arc4.encrypt(f[i:i+0x400]) out.write(tmp)out.close()
Gunakan jadx untuk decompile file dex nya
Terlihat terdapat function getFlag yang dipanggil dari libgame.so . Karena libgame.so juga diobfsucate dan cukup kompleks , maka cara paling mudah adalah dengan mengikuti alur dari awal. Yaitu input key pada apk, patch file name apk . Dari percobaan ketika score 9 maka titik hijau yang ditekan menjadi sangat acak dan tidak bisa ditekan. Jadi disini kami lakukan patch untuk game.dex (patch pada smali) karena entah kenapa kami tidak bisa melakukan hook terhadap beberapa function. Berikut alur patch kami + commandnya
Ubah pengecekan pemanggilan getFlag dari score==10 menjadi score==2 , jangan lupa ubah nilai i<9 juga menjadi i<2. Selanjutnya pada percobaan pertama ternyata ada validasi juga di library , maka kita perlu tambahkan 5 kali pemanggilan submitscore untuk setiap score+=1 . Sehingga saat score ==2 maka dilakukan pemanggilan submitscore sebanyak 10 kali. Berikut alur patch kami
java-jarbaksmali-2.5.2.jardisdec.dex# patch smalijava-jarsmali-2.5.2.jarasoutmvout.dexnHVZeGukN75PpvXrhtOe/assets/game.dexpythonenc.py# ubah app_name pada strings.xml menjadi <string name="app_name">Circle of Trust</string>apktoolbnHVZeGukN75PpvXrhtOermcircle-aligned-debugSigned.apk&&rmcircle.apkcpnHVZeGukN75PpvXrhtOe/dist/nHVZeGukN75PpvXrhtOe.apkcircle.apkjava-jaruber-apk-signer-1.2.1.jar--allowResign-acircle.apk
Jalankan apk dan ketika score==2 maka akan dapat flag, sayangnya flagnya tidak kelihatan. Karena flag tidak kelihatan maka kami gunakan frida untuk hook fungsi yang menggambar flag.