MobiDash
Summary
Details
MobiDash is an adware discovered in January 2015. It displays unwanted ads each time the user unlocks the screen. To evade dynamic analysis tools, the malware waits several days or even weeks before executing its malicious code. The user would also not suspect a fresh installed application several days later. For that purpose the malware uses three internal states, namely None, Waiting and WaitingCompleted. The default state is None. The malware stays in this state when it has been configured and as long as the device is not rebooted. Once the device is rebooted, the malware reaches the state Waiting and waits the delay defined during the configuration. After the delay, it starts to display ads.
Stage 1: Bootstrapping the configuration
When the application is launched for the first time, the activity com.cardgame.durak.activities.ActivityStart is created and it calls the InitAds() function from the MyAdActivity class. This triggers a bootstrap procedure in which the file res/raw/ads_settings.json is read. This file contains information about the malware configuration, and in particular, it contains the server to be contacted and the time to wait before triggering (called OverappStartDelaySeconds). In our sample, the server is http://xxx.mads.bz [1] and the delay is 86400 seconds (24 hours). All these parameters are then saved in the SharedPreferences. At this moment, the internal state of the malware is None.
Stage 2: From state None to Waiting
Once the device is rebooted, the BOOT_COMPLETED intent is received by the DisplayCheckRebootReceiver and it triggers the ping() function from the AdsOverappRunner class. This function checks the internal state of the malware and executes a specific function for each case.
final AdsOverappRunner.State state = getState(context); switch ($SWITCH_TABLE$mobi$dash$overapp$AdsOverappRunner$State()[state.ordinal()]) { case 1: { startWait(context); break; } case 2: { checkForCompleted(context); break; } case 3: { startAds(context); break; } }
If the state is None, it calls the startWait() function which changes the internal state into Waiting, saves the current time in the SharedPreferences and setups two alarms. The first alarm is used to re-trigger the DisplayCheckRebootReceiver every 15 minutes. The second alarm is redundant and re-trigger the receiver exactly 24 hours later.
protected static void startWait(final Context context) { setState(context, AdsOverappRunner.State.Waiting); setWaitStartTime(context, System.currentTimeMillis()); DisplayCheckRebootReceiver.setupPingAlarms(context); DisplayCheckRebootReceiver.setupPingAlarmOne(context, (long)(AdsExtras.getOverappStartDelaySeconds()*1000+1000)); }
Stage 3: From state Waiting to WaitingCompleted
The next call to ping() (with the Waiting state) will execute the checkForCompleted() function. This function is in charge to check if the delay is over. If the condition is true, the internal state is changed in WaitingCompleted and the startAds() function is called.
The purpose of startAds() is only to start the malicious service DisplayCheckService. This service is used to request ads to the server and to display them on the screen. During the onCreate() function, the service sets up the same alarm as in startWait() in order to restart itself every 15 minutes. It also dynamically registers 2 receivers :
protected void setupUserPresent() { this.registerReceiver(this.screenOffReceiver, new IntentFilter("android.intent.action.SCREEN_OFF")); this.registerReceiver(this.userPresentReceiver, new IntentFilter("android.intent.action.USER_PRESENT")); }
The first receiver is for requesting new ads each time the screen turns off by calling requestAds() function. The second receiver is for displaying an ad each time the user unlocks the screen by calling showLink() function. All the source code used to contact the server is located in the package mobi.dash.api.
We can see in mobi.dash.homepage a class named HomepageInjector which is used to change the browser homepage. There is also a class AdsShortcutUtils located in mobi.dash.shortcuts used to create and install launcher shortcuts. Another interesting feature is located in mobi.dash.wifi: it seems that the malware is able to change in the system settings the DNS server used when connected with the WiFi:
Settings$System.putString(contentResolver, "wifi_static_dns1", dns); Settings$System.putString(contentResolver, "wifi_static_dns2", dns);
During our observations, none of these 3 features have been activated. We also observed that samples of this malware contain a lot of different lawful Advertising Service SDK. More precisely, our studied sample contains packages of AdBuddiz, AdMob, Flurry, MoPub, Chartboost, PlayHaven, TapIt and Moarbile. But in the main activity of the application (see ActivityMain$11), only AdBuddiz, AdMob and Chartboost are used. To finish, log files about all the downloaded malicious ads are stored in the folder data/data/com.cardgame.durak/files/mobi.dash.history/active/. These logs contain information such as requests to the server and redirecting links.
[1] | We intentionally anonymzed this URL |
Other resources
Triggering
Caracteristics
Malware type :
- Agressive adware
Attacks :
-
Normal use
Infection technique : Repackaged application
Malicious code type :
- Use Java code
Hidding techniques :
- Not hidden
Triggering techniques :
- Executed at launch
- Waits for a fixed period of time
- Waits for a particular intent
Samples
Java source code extracts:
InitAds.java is one of the function called when the application is launched.bootstrap.java is the function where the configuration file is read to initiate the malware.
ping.java is the function used to check the internal state.
startWait.java is the function used to change the internal state to Waiting and to start the countdown.
checkForCompleted.java is the function used to check if the countdown is over in order to start displaying ads.
setupUserPresent.java is the function used by DisplayCheckService in order to display ads each time the screen is unlocked.
installShortcut.java is a function used to install a shortcut to an advertisement. (Never used during our observations)
setupDns.java is a function used to change the DNS server used by WiFi. (Never used during our observations)