Thousands of HiddenAds Trojan Apps Masquerade as Google Play Apps
The McAfee mobile research team has recently discovered a new variant of the HiddenAds Trojan. HiddenAds Trojan is an adware app used to display advertising and collect user data for marketing. The goal of such apps is to generate revenue by redirecting users to advertisements. There are usually two way to make money with adware; the display of advertising to a user’s computer and a per-click payment made if a user clicks on the ad.
Although it can be used for spreading and displaying advertising in an affiliate marketing program, adware can also be used to spread malware in an affiliate fraud program. Most adware programs will abuse a legitimate application to trick the user and increase the number of installations. In our analysis we focus on two fake versions of popular Android apps:
- FaceApp: an app used to modify photos with machine learning.
- Call of Duty: a famous game adapted for Android.
We notice that these applications are very popular and are usually downloaded by young people. Additionally, both apps are using the in app-purchase business model. These two elements are interesting because they increase the chance that people will search for free versions and have potentially low concerns regarding security. We also noticed several other HiddenAds variants masquerading as genuine apps, such as Spotify or other well-known games.
Globally, we observed more than 30,000 samples related to this HiddenAds campaign.
Figure 1. Multi-tricks HiddenAds campaign
Analyzed samples are not available on the Google Play Store; the delivery of the latest variants is mostly from untrusted parts of the internet that propose APK file downloads. YouTube channels have also been spotted with malicious links to download the fake apps.
These variants of HiddenAds use some other interesting technologies to trick users and thwart the analysis of malware researchers. In this blogpost, we will deep dive into the analysis of a fake FaceApp application.
These malware samples masquerade as popular applications so, when a user wants to find the apps from an unknown source, they could be infected by malware. For example, “Call of Duty” is a popular game, with many people searching for the mobile version online. If they are unfortunate, they may find the result shown below:
Figure 2. Distribution channel
In the video, the author provides download links. If we click the link to download the file, we receive “Call of Duty_1.0.4.apk” (as seen in Table 1). If we install this sample on our devices, we will be infected by this malware. Additionally, we spotted this malware on other untrusted sources.
- Application name trick.
As a user, we recognize an app by its name and icon. As a researcher, the package name is an identification of an application. This variant uses popular application names, icons and package names on the Google Play store, to trick users into thinking they are genuine applications.
Table 1: Basic Information of some threat samples.
We search for the application name on Google Play and click the search result to view its details.
Figure 3. FaceApp information on Google Play.
This is a very popular application with in-app purchases. If victims want to find a free cracked version from alternative sources, they may end up with our analysis sample. The application name, icon and version number of the Google Play app and the fake app are very similar. The file size, however, is very different so we should keep that very firmly in mind.
- Icon trick.
Normally, users expect the icons seen before and after installation to be the same. In this sample, they are different. The sample defines two icons in the AndroidManifest.xml file; the label of activity is “Settings”.
Figure 4.1. Two icons are defined in AndroidManifest.xml
Before we install the sample, we see it in File Explorer, showing the first icon (tv_icon.png). At the system installation view, we see the first icon too. Once we click the “Done” button, the sample is installed onto the device and the system shows the second icon (but_invertc.png).
Figure 4.2. Icons before/during/after installation
This is the icon trick. Users are surprised after they install the sample as they cannot find the expected icon on their devices; they maybe think something went wrong during installation and the application failed to install. In reality, the application has already been installed; it is next to the system “Settings” application icon. When a user goes to launch the system “Settings” application, they have the possibility to click the fake icon instead, launching the malicious application.
- Launcher trick.
Once a victim clicks the fake “Settings” icon, the malicious app launches, as does the next stage of the trick.
Figure 5. Hidden icon after clicking “ok” button
The sample shows this alert dialog immediately; it does not perform country available checking. This is a deceptive message, to make victims believe that the icon is hidden because “Application is unavailable in your country”. In fact, the application is still running in the background. It is not unavailable in a given country, it is just unavailable for victims.
Above are the ways the app is used to defraud victims. Now, we look at the anti-analysis techniques of this sample. At the start of the application, it invokes a function MultiDex.install. MultiDex is a popular and valid Android module which is used to support multi DEX files. When we investigate this function, we are curious why a popular Android module invokes a function in a specific application module.
Figure 6. The malicious code in the “MultiDex.install” function
The question prompts us to do more analysis. Finally, we find that this is the malicious code entrance. It mainly does 2 things here:
- Decrypt so library
The decrypted function is very obfuscated, not only obfuscating the variable name such that it makes no sense, but also splitting a simple function into lots of sub-functions, each of which inserts lots of nonsense code, designed to thwart analysis.
- Fortunately, we can understand the code and get the decryption process.
Figure 7.1. Splits into lots of sub-functions
Figure 7.2. One sub-function, lots of code is nonsense
Reading data from resource/string.xml file according to CPU type (Figure 8.2):
- If CPU is arm64, read x1 value.
- If CPU is armeabi, read x0 value.
- Other CPUs are not supported.
Figure 8.1. Read data from resource string.xml file
The data has 2 parts, the first part is the header of the ELF file, the second part is an index of array.
- From the index (“a58ax”) in the last step, we find base64 encoding data from the arrays.xml file.
- Use base64 and XOR operation to decode the array and generate native code library.
Figure 8.2. Base64 encoding data in the file resources.arsc/res/values/arrays.xml
3) Load so library to extract the DEX payload and, finally, the malicious code invokes system.load to load the so library and calls a native function.
Figure 9. Load so library and call a native function
In the native function, it will extract and decrypt the file assets/geocalc_lite.dat and restore the DEX payload to path /data/data/de.fastnc.android.geocalc_lite/app_app_apk/geocalc_lite.dat.jar.
DEX Payload Analysis
The DEX Payload is used for showing advertisements. The advertisement data comes from the server. Once the payload gets the data, it will show it on the device. From the code analysis, we see there are dozens of advertisement types (Figure 12.2). The payload, which is very complex, will load and show the data in different ways for each type.
- Default Setting Parameters
The DEX payload defines a base64 encoding string in code; we get lots of default setting parameters after decoding it:
Figure 10.1. Default setting parameters (Encoding)
Figure 10.2. Default setting parameters (Decoding)
This is a json object; it is very complex and below is the usage of some parameters:
- metricsApiKey: The API Key of Yandex Metrica SDK.
- installFrequencySeconds : This is used to control the frequency of ‘install’ request. The value decides the minimum time interval of sending ‘install’ requests (see the Request & Response section) which, in this instance, is 1000 seconds(16 minutes 40 seconds). The install request can only be triggered by the application launcher. However many times we restart the application, it only sends one request in 1000 seconds.
- overappStartDelaySeconds : This is designed to control the delay of http requests. It is intended to execute malicious payloads after 30000 seconds (5 hours 20 minutes) from the first launch. But in the current version, this value is the same as ‘installFrequencySeconds’ and is used to control install frequency. The smaller value of ‘overappStartDelaySeconds’ and ‘installFrequencySeconds’ is used as the minimum time interval of sending install requests.
- bundles_*(b,c,l,n): It looks like these are used for determining whether to show advertisements in these packages or not.
The parameter “domains” is an important one; it defines the remote server candidate list. Payload selects a random one as the remote server; if the selected one is unavailable, it will switch to the next one.
Request & Response
There are 3 types of requests in the payload, with different requests having different trigger conditions. We can only capture 2 types of requests:
Figure 11.1. Request & response capture
- ‘install’ Request
During application launch, if the trigger conditions are satisfied, the payload will send an ‘install’ request to the remote server. This request has a file named “type” whose value is “install”.
Figure 11.2. Install request
The client filed is a json object too; it contains the versionName and sdkEdition information, both of which show that this payload is very new.
Figure 11.3 VersionName and sdkEdition definition
The responses from the remote server are often an empty json which increases the difficulty of our analysis. We continued testing for a few days and captured a non-empty response.
Figure 11.4. Response data
The remote server settings cover the default settings:
- Enabled: Advertisement enabled flag, including below ‘b/request’ request. The default is False, and True is set from a remote server response.
- 7 new domains in response: ‘http://hurgadont.com’, ‘http://asfintom.com’, ‘http://eklampa.com’, ‘http://glanmoran.com’, ‘http://cantomus.com’, ‘http://fumirol.com’ and ‘http://bartingor.com’
- 7 default domains: “http://minasorp.com”,”http://omatist.com”,”http://retinba.com”,”http://baradont.com”,”http://lindostan.com”, “http://avgon.net” and “http://dorontalka.com”
There are 7 new servers and 7 default servers, a total 14 servers, and we can ping all of them; they are alive.
2. ‘b/request’ request
This is a core request. There is a field named ‘type’ and its value is ‘b/request’ in this request.
Figure 12.1 b/request request
The library registers lots of event filters/observers and, when these events happen, the trigger conditions are satisfied, causing the library to send appropriate requests to the remote server.
Table 2: Event monitoring
Banner Type is used to identify the banner and Spot is used to identify the spotting of events.
Figure 12.2. Banner Type & Spot Type
The response data is as below. It has 3 main functionalities:
- ‘sdkUpdate’ data: Used to load updated versions of the SDK file.
- ‘banners’ data: Used to show banner advertisements.
- ‘mediatorSDKs’ data: Used to post mediatorSDKs requests on victims’ devices.
Figure 12.3. ‘b/request’ Response
- Banner data
We mentioned that we captured a response of ‘b/request’ in Figure 11.1. The response contains one banner data, the fields of banner data are as below after decoding.
Figure 12.4. Banner data and ‘html’ field content
‘html’ is the most important field – payload content is loaded in a WebView by invoking the loadDataWithBaseURL API. According to the html, WebView will load the page from the first URL, hxxp://bestadbid.com/afu.php?zoneid=1558701. This is a redirect URL that will redirect to different URLs each time we open it. In our test, it redirects to a gambling website.
Figure 12.5. Redirect to a gambling website
- mediatorSdks data: mediatorSdks data is a json array. Each item definition is as below. We cannot capture this type of data from the remote server as we do not know the real value of each field. According to our analysis, “tracking” is a URL list. Each URL will be executed on the device and the executed result sent to the remote server.
Figure 12.6. mediatorSdks item definition
3) Mediator Stat requests: After the Tracking URL executes, it will execute /sdk/stat/mediator_* requests to the remote server which just reports the execute results. There are 4 types of mediator requests, one is for reporting failure status, the other 3 types are for reporting success status. There are 3 types of success status; we guess that there are 3 types of Tracking URL in mediatorSdks data (Figure 12.6). Each type of Tracking URL uses each mediator stat request to report status.
Figure 12.7. 4 types of mediator stat request
This is a traditional Hidden Icon Ads malware; it hides the application’s icon first, then shows advertisements from the DEX payload. But it applies lots of technology to implement its purpose, to trick users into believing it is a normal application, to stymie the detection of security tools. The DEX payload is a very complex SDK – more than 14 candidates of remote servers are found, lots of event monitoring and remote trigger control, all of which mean this is a well-designed malware. Once victims are infected with this malware they are unlikely to realize it and, even if they do, they may not be able to locate and remove it.
McAfee Mobile Security detects this threat as Android/HiddenAds. To protect yourselves from this and similar threats, employ the McAfee Mobile Security application on your mobile devices and do not install apps from unknown sources.
For more information about McAfee Mobile Security, visit https://www.mcafeemobilesecurity.com.