Live reverse engineering of a trojanized medical app — Android/Joker
A few days ago, a tweet reporting an Android malware caught my attention, because it was apparently found inside a health-related application named “Health Index Monitor”.
A tour inside Cordova…
The name of the package is com.monotonous.healthydiat
, and the main activity is com.monotonous.healthydiat.MainActivity
. Its code is extremely simple, and we quickly recognize the use of Cordova:
public class MainActivity extends CordovaActivity {
@Override // org.apache.cordova.CordovaActivity, android.app.Activity
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
loadUrl(this.launchUrl);
}
}
Cordova is a (not malicious) framework for creating cross-platform mobile apps using web technologies, meaning that the app’s code is not to be found in the DEX, but within assets web pages:
Half grumbling because I don’t like to read web files, I started poking into them, and found they were reaching out to a health website. At the time of my analysis, this website was down and could have hosted malicious code, but it just didn’t sound like what I’d expect from a malware.
A dynamically loaded DEX!
I continued inspecting the APK and noticed DroidLysis said the app was using DexClassLoader
, a well-know class for dynamically loading Dalvik Executables, and often used by malware to hide and run malicious payload.
Dex class loading apparently occurred in class b/a/b$a
, for sure an obfuscated name, but I wondered how we got there, the MainActivity
being so small.
Actually, the call occurs before the main activity, from the App
class which extends Application
(this is a known “trick” used by packers). And there I saw the call new b(...)
import a.b.a.c;
import android.app.Application;
import b.a.b;
/* loaded from: classes.dex */
public class App extends Application {
@Override // android.app.Application
public void onCreate() {
super.onCreate();
new b(new c(this).getContext()).setGravity(100);
}
}
Frida hook
To get the payload DEX, we need to retrieve the DEX which is provided to the DexClassLoader
constructor. As usual, I created a Frida hook and ran the malware.
The v1
file is the payload DEX 😃.
Once the DEX is loaded, the packer loads a class named yin.Chao
, and inside that class, calls a method named yin
.
Reversing v1
, the dynamically loaded DEX
There are two places to inspect:
- Method
yin
from classyin.Chao
- A service named
NerService
, insidecom.monotonous.healthydiat
, and mentioned by the app’s manifest. This service is implemented in the dynamically loaded DEX.
Method yin
asks for the end-user to grant permissions for READ_PHONE_STATE
and READ_CONTACTS
, and add the app as a notification listener (this enables the app to read and interact with any notification). Note that this should sound suspicious to an average end-users: why would a health app need those?!
Once this is done, yin
loads a remote JAR from a remote HTTPS website and calls a method named canbye
from com.canbye
.
Before we reverse the remote JAR, let’s finish with NerService
. It is a notification listener, and will catch any SMS notification, read the notification’s text message and send it to via a custom intent.
This is an interesting way to steal SMS: the malware is not reading the SMS (thus no need for READ_SMS permissions) but reading the notification of SMS!
Reversing the remote JAR canbye
This JAR only has a few classes, but they are dense 😉. Method canbye
initializes a shared preferences file (named bshwai
) and sets a few entries such as an identifier based on the phone’s Android ID or MAC address.
Then, the malware registers a SMS receiver. It will process all broadcast messages sent by v1
(previous layer), store the messages and later sent them in JSON object to a remote server. For an uncertain reason, the malware also directly intercepts incoming SMS messages and particularly forwards those beginning with keyword rch
to hxxp://www.canbye.com/op/pair?remote=<int>&device_id=<id>
. This is perhaps to ensure the notification for this SMS is not shown to the victim, thus completely hiding the SMS.
We also notice other functionalities such as retrieving the list of accounts on the victim’s phone and sending SMS messages: this depends on what the remote server instruct.
The canbye
JAR implements a (malicious) Facebook component DEX which can be downloaded from hxxps://canbye.oss-accelerate.aliyuncs.com/fbhx<INT>
. This is a fourth stage DEX!!! I haven’t reversed this one yet.
We notice the first 3 stages with a Frida hook on java.net.URL
and DexClassLoader
:
This malware belongs to the Android/Joker family. The initial APK is detected as Android/Joker.D!tr.dldr. For more references on the Joker family, please read here, here and here.
— the Crypto Girl
Malicious URLs
hxxps://xni.oss-eu-central-1.aliyuncs.com/0302/hindex
hxxps://canbye.oss-accelerate.aliyuncs.com/canbye
hxxps://www.canbye.com/canbye/v1
hxxps://www.canbye.com/canbye/v2
hxxps://www.canbye.com/canbye/op/probe?...
hxxps://www.canbye.com/canbye/op/up?..
hxxps://www.canbye.com/canbye/op/arly...
hxxps://www.canbye.com/canbye/op/crly...
IOC
5613c51caf6bece9356f238f2906c54eaff08f9ce57979b48e8a113096064a46
(this is the APK)0058f2bfc383c164f4263bf0ed6e9252b20c795ace57ca7b686b6133d183bb42
(this is the payload DEX, namedv1
)2da5ad942435714f52204d6955f7ae941d959dc275df75acd6aa15bfe81e653b
(this iscanbye
JAR, loaded byv1
)949a16417b183d55f766fa507cc8c1699cd73ffc5da9856bb35b315b678ac1d8
fbhx1
(a 4th stage DEX)a3f5b26ba8102a63d9864ab8099eed7519244df8bc6464f888c515c7e3575f4e
fbhx2
(another possible 4th stage DEX)