Skip to main content

Android Malware Analysis: covid19 ransomware apk and remediation ( ͡° ͜ʖ ͡°) (day 86)


It's bad enough that many people around the world are affected and died by coronavirus but I think this situation is getting worse because I found out that malware author actually used this situation to start spreading their malware campaign.

For me, It's not surprised since they always follow the latest trend and device a new malware type for getting a new profit, one of the examples that we can use is ransomware.

After a couple of hours strolling around the internet haystack with my android VM, I found some dodgy website that offers an app that claims that can track coronavirus spread in your location.

Long story short, it turns out that this is a ransomware that demands the victim to pay a certain BTC to them. I try to reverse engineer the malware and luckily I found out how to open the device.

If you don't have time and just want to unlock your device the key is 4865083501

Preliminary static analysis:

Malware md5 hash: 69a6b43b5f63030938c578eec05993eb
Malware sha256 hash: c844992d3f4eecb5369533ff96d7de6a05b19fe5f5809ceb1546a3f801654890

The following is the permission that is required to run the android application:

<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>

used for granting app for running background service. It can be used for the malware to execute a malicious task without user consent

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

get notified about the booting process in the device. Usually, the malware used this to enforce persistency

<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>

allow an app to ignore battery optimizations.

Go crazy! let's see what this app do with the device:

Before going to the deep analysis on the source code I think it's better if we try to run the sample in the controlled environment so we got like a bigger picture on the overall process of how the malware is working.


I used genymotion for running the android emulator and I choose google pixel for the machine.


 

as you can see from the above figure we can see that the app need to grant some permission in order to run properly

The first permission asks us to grant permission for running background permissions this is related to the first permission that we see in the preliminary analysis.



The second permission asks us to grant the app to use device admin permission, this grants the app to have Device administrator privileges that could enforce remote/local device security policies such as locking and encrypting devices storage.

you can see the set policies at xml/device_admin_sample.xml



we can see that if granting the app with device admin permission it will be able to force lock the device and encrypting our device storage. This is interesting since the malware itself didn't use their own encryption mechanism but rather just using existing encryption features from android device


Next, if you click "scan area for coronavirus" the app will disappear and show a notification that it runs in the background



If you try to go around operating the device it will not show any sign of the malware but if you try to power off the devices it will start to encrypt your device storage and show this


If you try to open any app inside your device it will automatically go to this UI again and show ransom note(https://pastebin.com/zg6rz6qT):

SEND 0.011 BITCOIN TO THIS ADDRESS => 18SykfkAPEhoxtBVGgvSLHvC6Lz8bxm3rU

You can see many victim start to pay some ransom to the malware author:



Remediation:

Before we were able to decrypt the device, we need to know how this app encrypts the device itself.

it starts from this service component

<service android:enabled="true" android:exported="false" android:name="com.device.security.accessibility.AppAccessibilityService" android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
             <intent-filter>
            <action android:name="android.accessibilityservice.AccessibilityService"/>
            </intent-filter>
            <meta-data android:name="android.accessibilityservice" android:resource="@xml/accessibility_service_config"/>
</service>

what you see here is the accessibility service. This service typically used to assist a user with disabilities or in the situation that makes the user cannot interact with the device. So this service will run in the background and listen to a specified UI event that sent to the user.

we can check what kinda UI event that is listened by the service from xml/accessibility_service_config.xml file



take a look at the android:accessibilityEventTypes this defined what type event that the app will accept to run the service and from the result, you can see that it accept pretty much everything.

detail could be check in https://developer.android.com/guide/topics/ui/accessibility/service

when analyzing accessibility service there are two methods that you need to be aware onServiceConnected() and onAccessibilityEvent()



the first method called when the user switches on the accessibility service from the phone setting this also specifies the type of events that can handle by accessibility service.





the second method will be called whenever there is an event on the screen that is mention under xml/accessibility_service_config.xml

from the above figure, we can see that it identify the UI event with getEventType() that will return an integer and each of the events has its own predefined task that will be executed

I want you to guys take a look at the first comparison which is

if(eventType == 1){
 ...
}

this will be trigger if used do a click event in the device and you can see there is a function called with the name BlockedAppActivity this function is responsible for encrypting and decrypting the device. But as you can see before the app does encryption or decryption it checks a shared preferences config to see if the necessary permission is satisfied to do the operation.



you can check the shared preferences file by using adb and go to the app directory:



since we grant all the permission the app will set to all to be true.

now if you go to the com.device.security.activities.BlockedAppActivity you will find a lot of interesting stuff it starts but go down to the last function you will found verifyPin() function



as you can see the code to unlock the device is hardcoded and you can decrypt the device.



Persistency through broadcast(Deeper analysis):

<receiver android:name="com.device.security.receiver.RebootReceiver">
          <intent-filter android:priority="999">
          <action android:name="android.intent.action.BOOT_COMPLETED"/>
          </intent-filter>
</receiver>

it starts from this broadcast component as you can see it will invoke the broadcast if the event is BOOT_COMPLETED this equivalent to when the device is boot up again.

public class RebootReceiver extends BroadcastReceiver {
              public void onReceive(Context context, Intent intent) {
                  SharedPreferencesUtil.setAuthorizedUser(context, "0");
                  Intent intent2 = new Intent(context, StartServiceActivity.class);
                  intent2.addFlags(268435456);
                  context.startActivity(intent2);
           }
}

when the broadcast called it to send intent to invoke StartServiceActivity class

public class StartServiceActivity extends AppCompatActivity {
             /* access modifiers changed from: protected */
             public void onCreate(Bundle bundle) {
                           super.onCreate(bundle);
                         Util.startService(this);
                            finish();
             }
}

the called class itself again called another function from class "Util"  that will execute a Foregroundservice

public static void startService(Context context) {
              ContextCompat.startForegroundService(context, new Intent(context,  ForegroundAppService.class));
}

What is Foreground Service? (taken from https://androidwave.com/foreground-service-android-example/)

For more clarity let’s takes example Gmail, You are just using the Gmail app and listening to music that is being played by the Music Player application. So Music Player is basically using the foreground service to play the music. The foreground service always uses the notification to notify the user and using the notification you can actually interact with the service or the ongoing operation such as pause the music or play the next music.

this ForegroundAppService class used to keep the annoying notification that we saw earlier after click "scan area for coronavirus"


 

public int onStartCommand(Intent intent, int i, int i2) {
        startTimerTask();
        createNotificationChannel();
        PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0);
        startForeground(1, new NotificationCompat.Builder(this, CHANNEL_ID).setContentText("Running in background...").setSmallIcon(R.mipmap.ic_launcher).build());
         return 1;
}


How the app disappears (Deeper analysis):

If you try to recall again when we try to test the malware after clicking the "scan area for coronavirus" the app disappears and after do some analysis of the source code it turns out this piece of code is responsible for the disappearance:

file: com.device.security.activities.MainActivity



this function is called via view button click(R.id.hide_app_button) if the user clicks this particular button the app will run a function called hideAppIcon from Util class



if we trace back the source on the called function we can see that it using setComponentEnabledSetting function from getPackageManager() that could enable the app to hide in the device.

detail can be checked at: https://developer.android.com/reference/android/content/pm/PackageManager#COMPONENT_ENABLED_STATE_DISABLED

That's all folks I hope you enjoy this blog post and see you at the next series of android malware analysis

references:

https://www.domaintools.com/resources/blog/covidlock-update-coronavirus-ransomware
https://medium.com/mindorks/a-complete-guide-to-accessibility-service-part-2-ec2bf4b693b1
https://medium.com/mindorks/a-complete-guide-to-accessibility-service-part-2-ec2bf4b693b1



Comments

Popular posts from this blog

Having fun analyzing nginx log to find malicious attacker in the net (ง'̀-'́)ง (day 37)

  What makes you sleepless at night? is it because of a ghost or scary stories? is it because you have an important meeting tomorrow? or is it because you have an exam? For me, what keeps me up all night is that I keep thinking about what happens to a website that I just created, is it safe from an attacker (certainly not) or did I missing some security adjustments that lead to vulnerability? well I'm not the best secure programmer in the world, I'm still learning and there is a big possibility that I can make a mistake but for me, a mistake can be a valuable investment to myself or yourself to be better so from this idea, I want to know more about what attackers casually do when attacking a website. Here in this post, I'm going to show you how I analyzed attack to the website that I have permission to design and also some interesting findings that I could get from the analysis Background: All of this analysis comes from the traffic that is targeted to th

Utilize Pwntools for crafting ROP chain :') (day 69)

who doesn't like pwntools? it is a very versatile tool and can be customized according to our need using the python script but did you need to know that pwntools itself can help us to automatically craft a rop chain for us? so in this post, I will show you how to make rop chain less painful and make pwntools do all the heavy lifting. To demonstrate this I will use the binary challenge callme 64 bit from ropemporium link: https://ropemporium.com/challenge/callme.html Crashing the app: Like any other exploitation process, we need to crash the program by generating a long string pattern to determine the offset. based on the information from the above figure we can see that we required to provide 40 bytes of offset Fun stuff: now this where the fun stuff began write the following python script: as in the guideline of the challenged said we need to chain the function call by first to call the callme_one function, callme_two function and then callme_three funct

WriteUp PWN tarzan ROP UNICTF ಠ_ಠ (day 61)

So in this post, I'm going to talk about how to solve the Tarzan pwn challenge from UNICTF 2019. Back in the day when the competition is still going I couldn't finish it and don't have any clue to solve this but this time I was able to finish it :) Also in this post, we will be going to be heavily focused on how to utilize pwntools to construct a ROP chain. If you kinda confused about my explanation in this post you can refer to this following youtube video, link: https://www.youtube.com/watch?v=gWU2yOu0COk I build the python script based on this video Ok, let's get started! In this challenge, you will get two binary first go with tarzan and libc-2.29.so by providing .so file it tell us what version library that the target machine is using this could help us to do ROP chain. first, we run the Tarzan binary to get the basic idea of the program work and as you can see it just show you some text, newline and when you try to input something it doesn't gi