Mobile Malware Analysis : Overlay and How to Counter it (partly)

Defeating Overlay

In my last anubis post I touched on overlay and how malware use process scanning to get top process. If somehow we can bypass those techniques, in a way overlay can be defeated. In this
post I will try to explain my way of finding a protection for some android versions.

TLDR;

You can use

1
2
3
4
5
6
7
try { 
Method setter = android.os.Process.class.getMethod("setArgV0", String.class);
setter.invoke(android.os.Process.class, text); }
catch (NoSuchMethodException e) { e.printStackTrace(); }
catch (IllegalAccessException e) { e.printStackTrace(); }
catch (InvocationTargetException e) { e.printStackTrace(); }
}

to change your application’s name to protect users that have android 5.1 and 6.0

What is process scanning and why malware use it?

Process scanning is a way for getting list of running processes. Most of the android malware use process scanning to get top activity currenlty running. Then they use this information for deploying overlay attacks. Knowing which processes is currenly top active, helps to select which phishing overlay page malware will use and make attack more believable. Android was aware of this attack vector and take some steps to disable these functions. Here is a blogpost cover overall situtation.

Generally android is secure environment for processes. Each application have different userid and none of application/process have rights to read/write of other processes data. But up until API 23, there was always a way to read process list without any permission. After API 23, applications need to get PACKAGE_USAGE_STATS (system permission) or Accessibility permissions to read process list.

Problem

Lets say com.x.bank is targeted application by malware. Malware infected the device and overlays com.x.bank. Mechanism of overlaying itself can be divided in two elements. First one is triggering when com.x.bank started (achieved via process scanning) and second one is how an app can overlay itself on top of another app. Second element is functionality of android applications. Any app can open itself with the help of services/receivers/intents. We can’t interfere that functionality. What about first element of overlay mechanism ? Is there a way for an application to defend itself by not being in process list or giving randomized name to process list ? This was in my head for a long time.

Thoughts

Randomize package name
Change process name
Hide from usage stats service ? :)

Android Version vs Technique

Each android version invervals malware use different techniques to list process/package names.

API Technique
<= 19 runningTask.get(0).topActivity
20,21 getRunningAppProcesses().get(0).processName
22 23 /proc/pid/cmdline, /proc/pid/stat
>23 UsageStats (anubis) or Accessibility (hydra)

According to Android usage distrubition chart of android versions as follows :

Version Codename API Usage Percent
4.4 Kitkat 19 %7.6
5.0 Lollipop 21 %3.5
5.1 22 %14.4
6.0 Marshmallow 23 %21.3
7.0 Nougat 24 %18.1
7.1 25 %10.1
8.0 Oreo 26 %14.0
8.1 27 %7.5

Processes in Android

If I can change process name of the application, since malware checks static package names, I can avoid being detected.

Sadly I can only do something for /proc/pid listing techniques. (which is %35.7 of android users tho) To get information about process there are several places. You can try yourself also.

  • /proc/pid/cmdline
  • /proc/pid/stat
  • /proc/pid/status

To change process name I came across to prctl system call. Using PR_SET_NAME and New name as argument one can change current process’ name. Maybe I could call prctl from native side of application and change process name. But before writing code I tried it with frida. I hooked prctl and checked if its called with PR_SET_NAME (15). Then I replaced called string with another string.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var prctlPtr = Module.findExportByName(null, 'prctl');
var prctlOri = new NativeFunction(prctlPtr,'int',['int','int','int','int','int'])
Interceptor.replace(prctlPtr, new NativeCallback( function (a,b,c,d,e){
if (a == 15){
pname = Memory.readUtf8String(ptr(b))
if (pname.includes("cbunlkwsqtz")){
console.log(a,b,c,d,e)
for ( i=0; i< 9 ;i++){
pname = Memory.readUtf8String(ptr(b-i))
console.log("Brute: "+i+ " "+pname)
}
Memory.writeS64(ptr(b-9),0x306362617830)
pname = Memory.readUtf8String(ptr(b-9))
console.log("YAY ! new process name : ",pname)
var fd = prctlOri(a,b-9,c,d,e)
return fd
}
}
var fd = prctlOri(a,b,c,d,e)
return fd
}, 'int', ['int','int','int','int','int']));

And voila

frida

Ps commands shows new process name but malware doesn’t get changed name. Because proc/pid/cmdline didn’t change. Also why prctl even called ? Since I didnt know much about how android processes get their names I searched up again. How can process change its cmdline or stat value ? Stackoverflow. But does Android application have argc or argv ? So I searched aosp project and come across to this :) See the comment

1
2
3
4
5
6
7
8
// Also note that this is a constant for "normal" android apps.
// Since they're forked from zygote, the size of their command line
// is the size of the zygote command line.
//
// We change the process name of the process by over-writing
// the start of the argument block (argv[0]) with the new name of
// the process, so we'd mysteriously start getting truncated process
// names if the zygote command line decreases in size.

In android there is a process called Zygote. Zygote is the ancestor of all processes like init0. Every process is fork of zygote.
After being forked from zygote, application’s process name changes within app_main.cpp. Knowing that I looked up which function I could used and saw setArgv0 which sound right. Then I tried with application. Opened up android studio.

1
2
import os.Process
Process.setArgv0("0xabc0");

But android studio didn’t resolve setArgv0. If I go to declartion of Process class I can see setArgv0 there.

huh

So whats happenning ?
See @hide tag. That tag means its hidden from developer because they are internally used and can be changed in future APIs. Also these methods can be classified in four list after Android 9. But we are trying to protect users that use Android 6. So there is no problem.

You can’t directly call these hidden methods but you can use reflection (big thanks to @ibrahimsn98!)

1
2
3
4
5
6
7
try { 
Method setter = android.os.Process.class.getMethod("setArgV0", String.class);
setter.invoke(android.os.Process.class, text); }
catch (NoSuchMethodException e) { e.printStackTrace(); }
catch (IllegalAccessException e) { e.printStackTrace(); }
catch (InvocationTargetException e) { e.printStackTrace(); }
}

With this, process name is changed everywhere cmdline,stat,status. YAY!

I created 2 apk to test this. One apk is getting processes. I used this project which is used in Anubis. And other app is changing its process name with setArgv0.

gif

The reason why app is not in process list is scanner app tries to access /data/app/package-name folder. Since we changed the name, it tries to access /data/app/0xabc0 which is not there. So it doesn’t display it.

Thoughts

For other methods I couldn’t find anything. Android can give rights/permissions to applications for not being in stats menu to avoid being detected by USAGE_STATS or by Accessibility maybe . Targeted apps can be saved from overlaying attacks with these rights.

Conclusion

With little code you can change your application’s process name in certain API versions. It can be used to protect users from malware :)

References

https://www.geeksonsecurity.com/android-overlay-malware/2016/07/27/android-overlay-malware-analysis/

https://www.symantec.com/connect/blogs/android-malware-finds-new-ways-derive-current-running-tasks

https://www.nowsecure.com/blog/2017/05/25/android-overlay-malware-system-alert-window-permission/