Finding Secret Key Inside React Native Apps

Aminudin
6 min readJan 18, 2024

--

Gimana perasaan kalian ketika sedang melakukan sniffing sebuah aplikasi, lalu ketika kita check pada HTTP Request nya misal di API Login/Register ternyata payloadnya ter encrypt, dan ketika kita coba utak atik requestnya jadi failed

Sedih bukan ? T_T, seperti case yang saya temukan kali ini saya menemukan payload di salah satu endpoint API nya pada key verificationCode yang bentuknya aneh dan ketika saya rubah lalu saya lakukan request ulang dan boom! error

{"errors":"Failed to decrypt verification code"}

lalu saya coba lagi ketika tidak saya rubah atau utak atik dan ketika saya coba lagi dia memunculkan error

{"errors":"account ID is already taken"}

Jadi dari kedua pesan ini bisa dipastikan bahwa verificationCode itu adalah berupa payload yang di encrypt selain key si verificationCode tersebut. Jadi anggaplah pada body tersebut mempunyai 3 key dibawah ini

{
"accountId": "xxxxxx",
"password": "xxxxx",
"verificationCode": "encryptedpayload=="
}

Jadi si verificationCode itu berisi accounId dan password yang di encrypt.

Ok lanjut ke next step karena sekarang kita tahu bahwa payloadnya di encrypt jadi yang saya cari tau itu adalah pertama Methode cara Encryptnya.

Untuk mengetahui methode cara encryptnya pertama saya coba bongkar dulu Aplikasinya menggunakan apktool dengan command sebagai berikut

$ apktool d namaapps.apk

// log
I: Using Apktool 2.7.0 on namaapps.apk
I: Loading resource table...
I: Decoding AndroidManifest.xml with resources...
I: Loading resource table from file: /Users/aminudin/Library/apktool/framework/1.apk
I: Regular manifest package...
I: Decoding file-resources...
I: Decoding values */* XMLs...
I: Baksmaling classes.dex...
I: Baksmaling classes2.dex...
I: Baksmaling classes3.dex...
I: Baksmaling classes4.dex...
I: Copying assets and libs...
I: Copying unknown files...
I: Copying original files...
I: Copying META-INF/services directory

Setelah selesai akan menghasilkan folder bernamakan aplikasi yang di bongkar pakai apktools tersebut lalu kita buka foldernya, untuk membukanya disini saya pakai visual studio code. Setelah dibuka kita cari kata kuncinya langsung disini misal karena kita mau cari methode encrypt payload verificationCode maka “verificationCode” adalah kata kuncinya

Ok bisa diliat dari ss diatas ternyata kata kunci “verificationCode” ini ditemukan didalam file bernama index.android.bundle yang dimana artinya aplikasi ini dibuild menggunakan React Native

Ketika dibuka index.android.bundle nya saya beruntung karena isinya hanya di minify saja tidak di compile ke Hermes VM bytecode (HBC), karena kalau misal di compile ke hermes kalian perlu gerakan tambahan pencak silat dan untuk decompilenya saya menggunakan ini jika index.android.bundlenya ter compile ke HBC hermes-dec.

Ok lanjoot karena scriptnya hanya terminify dari ss yang saya tunjukan saja buat yang biasa baca script javascript pasti paham dan sudah mudah dibaca.

kita bisa baca bahwa

  a = yield w.encrypt(i, {
accountId: t,
password: e
});

fungsi encrypt ini terdapat 2 parameter dan yang saya ketahui di parameter pertama itu berupa encryption key nya lalu parameter kedua adalah message/payload yang akan di encrypt, seperti tebakan saya di awal bahwa yang di encrypt itu adalah payload body selain “verificationCode”.

Dan dari yang kita tau bahwa variable i terduga adalah encryption keynya, dan variable i berasal dari

var i = yield w.getGeneratedCode('8e76234fe8a4050169c97c2b206105914e244d5039d4f3514a0271e5619b188c')

Tapi dari script diatas walaupun ada kode hex saya beranggapan bahwa itu bukan keynya tapi string itu di proses pada fungsi getGeneratedCode() lalu baru menghasilkan sebuah encryption key yang benar. Tapi, karena misi pertama kita adalah buat cari tau methode encryptnya kita cari tahu dulu apa yang ada didalem fungsi encrypt() tersebut, jadi kita cari di vscode

Dan ketemu bahwa encryptnya menggunakan AES.encrypt, tapi kita tidak tahu dia pakai modules atau bikin modules sendiri untuk prosesnya. Nah, untuk mengetahuinya simple pertama copy inti scriptnya, disini yang saya copy adalah

.AES.encrypt(

lalu saya coba cari di github dan kalau ada dan banyak yang pakai kemungkinan modules yang dipakai sama, tapi kalau unique dan notfound kemungkinan aplikasinya pake modules bikinin sendiri dan kita harus tambah gerakan silat lagi, ok langsung kita cari di github

Setelah dicek bisa kalian lihat ternyata banyak juga yang memakai dan polanya sama yaitu “AES.encrypt(“ lalu didalam fungsi AES.encrypt terdapat 2 parameter yaitu parameter pertama messagenya dan parameter kedua adalah secret keynya, dan terakhir penggunaan fungsi .toString() untuk merubah response encryptnya kedalam bentuk string

Setelah dicek lagi aplikasinya menggunakan modules dengan nama “crypto-js” langsung kita coba saja, btw saya nyobanya di repl.it males dilocal menuh menuhin memory aowkaowkoawokawkaw.

Dan untuk nyobanya pertama saya akan membuat fungsi decryptnya jadi agar bisa tau terlebih dahulu encryption keynya bener atau ngga, jadi pertama saya coba pakai kode hex yang ada pada parameter getGeneratedCode()

Dan hasilnya sesuai dugaan saya tidak ada result apa apa yang kemungkinan keynya salah, jadi saya coba mereka reka fungsi si getGeneratedCode(), tapi nampaknya aga sulit jadi saya coba cara gampang saja saya bikin alert pada variable i

Lalu saya build APK nya pake apktool

$ apktool b -o namaapk.unsign.apk foldernamaapk

// log

I: Using Apktool 2.7.0
I: Checking whether sources has changed...
I: Checking whether sources has changed...
I: Checking whether sources has changed...
I: Checking whether sources has changed...
I: Checking whether resources has changed...
I: Building resources...
I: Building apk file...
I: Copying unknown files/dir...
I: Built apk into: namaapk.unsign.apk

Lalu saya sign apknya pake uber-apk-signer

$ java -jar uber-apk-signer-1.2.1.jar --apks namaapk.unsign.apk

// log

source:
/Users/aminudin/penetrationtest/apk/app
zipalign location: PATH
/Users/aminudin/Library/Android/sdk/build-tools/28.0.3/zipalign
keystore:
[0] 161a0018 /private/var/folders/s8/cmrzj5r95t96b2x5sm8ds27h0000gn/T/temp_16022055586763326239_debug.keystore (DEBUG_EMBEDDED)

01. namaapk.unsign.apk

SIGN
file: /Users/aminudin/penetrationtest/apk/app/namaapk.unsign.apk (39.94 MiB)
checksum: 9cb1d6fdf5e3408938be2c2ba70e57e6ccad74c74dbfc88f9262eb31a7401130 (sha256)
- zipalign success
- sign success

VERIFY
file: /Users/aminudin/penetrationtest/apk/app/namaapk.unsign-aligned-debugSigned.apk (40.03 MiB)
checksum: 6b5cb2ba7c75b959ea97bdaf05a922f99e74f6333f858676a8275bd4649b85c6 (sha256)
- zipalign verified
- signature verified [v1, v2, v3]
5 warnings
Subject: CN=Android Debug, OU=Android, O=US, L=US, ST=US, C=US
SHA256: 1e08a903aef9c3a721510b64ec764d01d3d094eb954161b62544ea8f187b5953 / SHA256withRSA
Expires: Fri Mar 11 03:10:05 WIB 2044

[Thu Jan 18 05:33:23 WIB 2024][v1.2.1]
Successfully processed 1 APKs and 0 errors in 6.78 seconds.

Lalu install kembali aplikasinya dan jalankan seperti biasa dan ikutin flownya, misal kaya saya disini alertnya saya bikin setelah encrypt dan decrypt maka saya jalankan sampe create akun dan boom

Muncul secret key yang asli, tapi untuk memastikan bahwa ini static dan tidak berubah ubah saya coba berulang kali flownya. Dan setelah saya coba beberapa kali betul bahwa ini tidak berubah ubah, jadi saya langsung coba ke script yang tadi saya sudah buat di repl.it

Dan boom! ternyata encryption keynya sesuai, sekarang kita coba request ulang dari burpnya pakai repeater

Dan ya boom boom boom!!! mission succes, saya sudah bisa melakukan request dan sukses mendaftarkan akun!

--

--