Kenapa e-money Bank Mandiri? Ada beberapa alasan mengapa saya penasaran dengan keamanan produk e-money ini.
Saat ini produk e-money yg ada di dompet saya- Saat ini produk e-money yg meluncurkan aplikasi reader (mandiri e-money info)
Dari dua alasan tersebut saya coba mem-“bedah” keamanan untuk produk e-money tersebut. Kenapa? Saya pikir memberikan aplikasi pembaca kartu seperti memberikan kunci yang patah untuk mengintip isi sebuah kotak yang dikunci dengan gembok. Pertanyaan selanjutnya apakah kunci patah tadi hanya bisa untuk mengintip saja? atau bahkan bisa membuka isi kotak?
Jika belum mudeng maksud analogi saya di atas, ada analogi lain: bayangkan anda akan masuk ke sebuah rumah yang memiliki dua lapis pintu. Di balik pintu pertama terdapat ruang tamu dengan foto-foto harta benda yang berada di dalam rumah itu. Di balik pintu kedua kemungkinan kita bisa menemukan harga yang sebenarnya. Di depan rumah tersebut ada pelayan yang bertugas hanya mengantar anda untuk masuk rumah melewati pintu pertama. Pelayan tersebut membawa beberapa kunci, bisa jadi salah satu kunci yang lain merupakan kunci untuk memasuki pintu kedua.
Mari kita cari tahu..
Anggap saja aplikasi mandiri e-money info itu adalah pelayan tadi. Pelayan ini bisa membuka pintu pertama yaitu informasi saldo dalam kartu e-money.
Teknis..
Aplikasi mandiri e-money info merupakan aplikasi Android yang akan berjalan di atas Dalvik VM. Format executable Dalvik (yang biasa dikenal sebagai format .dex
) tidak lebih sama dengan Java bytecode (atau .class
file). Jaman awal-awal Android dulu saya sempat terpesona dengan ide Dan Bornstein yaitu menyederhanakan bytecode Java kedalam format baru Dalvik ini.
Namun pada akhirnya VM tetaplah VM. Keamanan sebuah sourcecode dipertanyakan, karena akan mudah dalam merubah bytecode Java ke bentuk source code nyaris sesuai dengan aslinya.
Oke, ini kan .dex bukan .class
Tidak masalah, .dex
bisa dengan mudah diconvert ke bentuk .jar
atau .class
. Mari coba kita intip file .apk
dari mandiri e-money info ini dengan aplikasi 7zip.
1 2 3 4 5 6 7 |
... 2013-10-09 16:31:54 ..... 4632 1245 res\layout-xlarge\main.xml 2013-10-09 16:31:52 ..... 60824 27475 classes.dex 2013-09-03 19:01:54 ..... 13432 5348 lib\armeabi\libmandirinfc.so 2013-10-09 16:31:54 ..... 10915 3889 META-INF\MANIFEST.MF 2013-10-09 16:31:54 ..... 10968 4071 META-INF\CERT.SF 2013-10-09 16:31:54 ..... 1504 1145 META-INF\CERT.RSA |
Sekilas dari isi file .apk
terlihat selain classes.dex
terdapat pula libmandirinfc.so
. Oke, ini menantang. Kenapa? karena ternyata beberapa bagian code aplikasi ini ditulis dengan native library (NDK). Yang artinya untuk mengintip logic dibalik code perlu analisa lebih jauh dengan disassembler, atau proses reverse engineering yang sesungguhnya (IMHO).
Sangat cerdas, tapi perlu diperhitungkan keefektifan metode ini jika diimplementasikan dengan VM. Karena Dalvik tidak jauh dengan Java, maka Dalvik juga mengenal dengan JNI. Ini adalah implementasi Java untuk dapat memanggil atau berinteraksi dengan fungsi-fungsi dari sebuah native library.
Maksud saya efektif adalah setiap native library harus punya exported function(s) atau variable(s). Yang harus didefinisikan secara jelas dalam source java-nya. Dengan begitu setidaknya ada bagian dari native library yang “mudah” terekspos. Attacker dapat menganalisa parameter apa saja yang dilempar dari native library ke java vice versa.
Mari kita lihat lebih jauh..
Setelah menganalisa classes.dex
, dapat di ambil beberapa java class yang berfungsi sebagai definisi java untuk native library yang dipergunakan. Berikut adalah potongan source hasil analisa:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
package noi.mandiri.util; public class xxx { static { System.loadLibrary("mandirinfc"); } public static native String appID(); public static native byte[] commandAPDUforBalance(); public static native byte[] commandAPDUforNumber(); public static native byte[] commandAPDUforPrepaid(); public static native String ivKey(); public static native String sKey(); } |
Dapat disimpulkan, native library tadi melempar beberapa parameter berupa array byte
dan string
. Dari nama fungsi dapat diketahui apa kira-kira data array byte tersebut. 😀
Kembali ke analogi sebelumnya tentang pelayan. Saya sengaja tidak menjabarkan secara detil mengenai hasil exploit saya. Tapi intinya dapat disimpulankan bahwa jawaban dari pertanyaan di awal sudah terjawab. Yaitu ternyata pelayan tadi hanya memegang kunci pintu pertama. Kunci-kunci yang lain ternyata hanya kunci dummy. Syukurlah 🙂
Saran perbaikan untuk pengembang Bank Mandiri
- Proteksi java sourcecode dengan obfuscator
- Proteksi export function name dengan merubah nama fungsi native library
Atau bahkan porting semua ke NDK, dan menyisakan java hanya untuk UI (jika memungkinkan)Since NDK has no access to NFC at all, except by means of calling back into Java code