# Phân tích mã độc android ## Thông tin cơ bản MD5: `ec054b7025b9c35692d42163d1e0bd9f` App name: `DỊCH VỤ CÔNG` Package name: `com.phommvb.dotihanj` Arch: `arm64-v8a, armeabi-v7a` Target SDK: `32: Android 12.0L` Permission: ``` android.permission.CAMERA android.permission.BIND_ACCESSIBILITY_SERVICE android.permission.REQUEST_DELETE_PACKAGES android.permission.QUERY_ALL_PACKAGES android.permission.GET_INSTALLED_APPS android.permission.VIBRATE android.permission.WRITE_EXTERNAL_STORAGE android.permission.READ_EXTERNAL_STORAGE android.permission.GRANT_RUNTIME_PERMISSIONS android.permission.READ_SYNC_STATS android.permission.READ_SYNC_SETTINGS android.permission.DISABLE_KEYGUARD android.permission.WAKE_LOCK android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS android.permission.RECEIVE_BOOT_COMPLETED android.permission.SYSTEM_ALERT_WINDOW android.permission.WRITE_SETTINGS android.permission.FOREGROUND_SERVICE android.permission.READ_SMS android.permission.SEND_SMS android.permission.ACCESS_NETWORK_STATE android.permission.ACCESS_WIFI_STATE android.permission.USE_FULL_SCREEN_INTENT android.permission.SET_WALLPAPER android.permission.CALL_PHONE android.permission.INTERNET android.permission.BATTERY_STATS ``` ApkID: ![image](https://hackmd.io/_uploads/BkGJMx2uC.png) Qua các thông tin trên, ta thấy được mã độc yêu cầu cấp nhiều quyền nhạy cảm. Đồng thời, sử dụng trình protector `Virbox` đối với các lib `l4ccd64a6_***.so`. ## Phân tích chi tiết AndroidManifest.xml: ```xml ................. <application android:theme="@style/md2" android:label="@string/ehv" android:icon="@mipmap/b1w" android:name="v4ccd64a6.l4ccd64a6" android:screenOrientation="portrait" android:allowBackup="true" android:hardwareAccelerated="true" android:supportsRtl="true" android:usesCleartextTraffic="true" android:networkSecurityConfig="@xml/ebz" android:appComponentFactory="androidx.core.app.CoreComponentFactory" android:requestLegacyExternalStorage="true"> <meta-data android:name="SAPP_NAME" android:value="com.yiwuzhibo.BaseApplication"/> <activity android:name="com.yiwuzhibo.activity.NNNNNNNAAAAActivity" android:screenOrientation="portrait"/> <activity android:label="@string/xao" android:icon="@mipmap/b1w" android:name="com.yiwuzhibo.activity.SplashActivity" android:exported="true" android:screenOrientation="portrait"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> ....... ``` Theo file AndroidManifest.xml, `v4ccd64a6.l4ccd64a6` sẽ là entrypoint được chạy khi người dùng nhấn vào icon để mở ứng dụng. ![image](https://hackmd.io/_uploads/HJ4X5l3d0.png) Chúng ta thấy có string "virbox", trình protector được sử dụng cho các lib trong asset. Rename lại class,method để thuận tiện hơn. Drop file lib `.so` và load: ![image](https://hackmd.io/_uploads/S1_EFHpdA.png) Overload `onCreate`: ![image](https://hackmd.io/_uploads/H1-4qBadC.png) Tất cả mã nguồn tại entrypoint của chương trình tại đây:[source](https://gist.github.com/h1bAna/d13786debda788a5a4c61c719bfcad12) Tổng quát lại, tại entrypoint của chương trình, mã nguồn thực hiện các hành vi sau: + drop file lib và load + Khởi tạo môi trường phù hợp để phục vụ cho việc dynamic loading. Mình đọc qua 3 hàm `swapApplicationReferences`, `updateAssetManager`,`reinstallContentProviders` thì thấy có chút liên quan đến bài [này](https://mp.weixin.qq.com/s/Uwr6Rimc7Gpnq4wMFZSAag?utm_source=androidweekly&utm_medium=website) File `index.html, kqkticwjgzy.dat` cũng đã được encrypt: ![image](https://hackmd.io/_uploads/rJYx7b2uC.png) ![image](https://hackmd.io/_uploads/Sk7QQbh_R.png) Khi thử phân tích tĩnh file thư viện trong `asset`, ta cũng không thu được gì. Do file đã được bảo vệ bằng `virbox`, rất có thể thư viện đã bị obfuscate. Rất nhiều đoạn tại phân vùng `.text` công cụ không nhận diện được, các hàm thì rất khó đọc và phân tích code. ![image](https://hackmd.io/_uploads/ByUMz7huR.png) Tiến hành cái ứng dụng lên môi trường test, ứng dụng có sử dụng các cơ chế detect root, detect developer mode, detect unlock bootloader,.... để phát hiện môi trường test. Có thể bypass bằng các cài thêm các module ẩn root, ẩn developer mode,.... Giao diện ứng dụng khi truy cập: ![image](https://hackmd.io/_uploads/ryipzm2_R.png) Sử dụng frida để dump các class trong quá trình runtime: [script](https://github.com/apkunpacker/DexDumper/tree/main) ![image](https://hackmd.io/_uploads/S19F7Q2dR.png) ![image](https://hackmd.io/_uploads/ryqvV73dA.png) Các string từ các class được dump từ dex ra đã bị mã hóa, được giải mã trong lúc runtime bằng method `m4ccd64a6.F4ccd64a6_11()`. Tuy nhiên, hàm này là hàm native code, load từ thư viện. Điều này khiến việc decrypt string khó khăn hơn. Vì chưa tìm được cách reverse được method này nên mình dùng hook để bắt input và output. Recover lại được kha khá string. ![image](https://hackmd.io/_uploads/ryLUZ3RuR.png) ```javascript= Java.perform(function() { console.log("[*] Starting script"); Java.enumerateLoadedClasses({ onMatch: function(className) { if (className.includes("m4ccd64a6")) { console.log(`[*] Potential target class found: ${className}`); hookTargetClass(className); } }, onComplete: function() { console.log("[*] Finished enumerating loaded classes"); } }); function hookTargetClass(targetClassName) { Java.perform(function() { try { var targetClass = Java.use(targetClassName); var targetMethod = targetClass.F4ccd64a6_11.overload('java.lang.String'); targetMethod.implementation = function(arg0) { console.log(`[*] Hooked ${targetClassName}.F4ccd64a6_11`); console.log(`[*] Input: ${arg0}`); var result = this.F4ccd64a6_11(arg0); console.log(`[*] Output: ${result}`); return result; }; console.log(`[*] Hooking successful for ${targetClassName}.F4ccd64a6_11`); } catch (e) { console.log(`[*] Error: ${e}`); } }); } }); ``` Sau khi đã có thể hook được thành công, mình nghĩ liệu mình có thể tự gọi hàm bằng frida? Và câu trả lời là có. Đây là ví dụ: ```javascript= Java.perform(function() { console.log("[*] Starting script"); // Liệt kê tất cả các class đã được load Java.enumerateLoadedClasses({ onMatch: function(className) { if (className.includes("m4ccd64a6")) { console.log(`[*] Potential target class found: ${className}`); callTargetMethod(className); } }, onComplete: function() { console.log("[*] Finished enumerating loaded classes"); } }); function callTargetMethod(targetClassName) { Java.perform(function() { try { // Sử dụng class được load động var targetClass = Java.use(targetClassName); // Gọi hàm F4ccd64a6_11 với tham số truyền vào var inputArg = "^L23230F323C2A402C403E2638454C37377C3B35518042454F3D533F5351938A"; var result = targetClass.F4ccd64a6_11(inputArg); console.log(`[*] Called ${targetClassName}.F4ccd64a6_11`); console.log(`[*] Input: ${inputArg}`); console.log(`[*] Output: ${result}`); } catch (e) { console.log(`[*] Error: ${e}`); } }); } }); ``` ![image](https://hackmd.io/_uploads/Bk_NLnAdA.png) Lúc này, nếu muốn decrypt hết tất cả các strings ta có 2 cách. + bung file dex thành smali code, tìm tất các cả string cần decrypt. Chạy frida script để decrypt tất cả đống này, thường là các const-string. Ví dụ như: ![image](https://hackmd.io/_uploads/BysP1T0dA.png) cách này khá hiệu quả và dễ thực hiện + Viết jeb script, cách này khó hơn nhưng đổi lại đọc source dễ hơn. https://blog.viettelcybersecurity.com/mot-vai-phuong-phap-deobfuscate-trong-qua-trinh-phan-tich-ma-doc-android/ Sau khi dịch ngược mã nguồn, có thể thấy ứng dụng này là một banking trojan. Ứng dụng yêu cầu cấp quyền để đăng ký Accessiblity Service. Tính năng này cho phép ứng dụng quay lại màn hình, keylogger,.... Nhằm đánh cắp các thông tin liên quan đến các ứng dụng ngân hàng. Chi tiết hơn: trong libstrategy.so của ứng dụng có các string liên quan đến phone brand, các ứng dụng ngân hàng: ![image](https://hackmd.io/_uploads/rJ6lRtzF0.png) ![image](https://hackmd.io/_uploads/ryA9KdGY0.png) ![image](https://hackmd.io/_uploads/BJuM9uft0.png) Ứng dụng có thể tự thao tác chạm với màn hình, không cần người dùng chạm vào màn hình điểu khiển. ![image](https://hackmd.io/_uploads/r1dbsKfKA.png) ![image](https://hackmd.io/_uploads/BkNpjFGt0.png) ![image](https://hackmd.io/_uploads/rJdk2FfFC.png) ghi lại quá trình authen của user, sau đó có thể tự click lại giống vậy. ![image](https://hackmd.io/_uploads/Sky3RKMFC.png) TouchAccessibilityService ![image](https://hackmd.io/_uploads/rk6ikqzFA.png) LockManager$swipeUp$1 Tự động swipeup, mở khóa màn hình. ![image](https://hackmd.io/_uploads/H18xeqMtR.png) PasswordCapture2 capture mật khẩu ![image](https://hackmd.io/_uploads/SkdMeqzYR.png) RemoteCommandClient tạo connect đến C2 ![image](https://hackmd.io/_uploads/Byjne9Mt0.png) 1 số endpoint của c2, tuy nhiên máy chủ đã không thể connect đến. Kết luận lại: Ứng dụng là trojan banking, khi người dùng cài đặt có nguy cơ bị mã độc ghi lại các thao tác đăng nhập, đánh cắp mật khẩu. Kết hợp với các quyền được cấp khác như đọc sms, ứng dụng có thể tự mở khóa màn hình, mở ứng dụng banking, đăng nhập, tạo giao dịch chuyển tiền, đọc otp từ sms.