Researchers: Nico Agnese, Inna Vasilyeva, John Laycock, Dina Haines
Here’s a riddle: if an app that’s committing ad fraud takes out all of the fraud code, is the app still fraudulent?
The answer: probably, we just don’t know when, how, or who.
The White Ops Satori Threat Intelligence and Research Team recently identified and tracked a fraud operation that rendered fraudulent advertising in users’ devices. These apps amassed more than 20 million downloads.
What these apps all have in common—besides their fraudulent tactics—is their focus on beauty. Most purport to be selfie apps that add beauty filters to users’ pictures, while at the same time showing ads out of context and making it nearly impossible to remove the apps themselves.
To wit, the specific fraud these apps commit is:
We associated 38 apps with this threat, all of which have been taken down by the Play Store.
If you look at the evolution of this specific group of apps, you can imagine some strategies the fraud actor may have used, as well as their reactions when apps were removed from the Play Store. The timeline of this operation offers a great case study of fraud development, publishing, adaptation, and pulling back resources to reserve them for potential future use.
In the chart below, we’ve plotted a sample of the apps in this operation. The bars correspond with the apps’ lifespans, from publishing date to when the app was removed from the Play Store.
Chart 1 - Apps lifespan from installation to removal
Source: White Ops Satori Threat Intelligence and Research Team
The first application, at the bottom of the chart, was published in January 2019 and was active on the Play Store for approximately 3 months.
In the time since that first app was published, the fraudsters published a new app every 11 days on average. And on average, those apps were pulled down from the Play Store 17 days later. These numbers tell a story of a cat and mouse game, in which the Play Store hunts down the fraudster and keeps them in check by removing fraudulent apps as quickly as they’re discovered. But even with an average of less than three weeks of time on the Play Store, the apps found an audience: the average number of installs for the apps we analyzed was 565,833.
By September 2019, the threat actor had already had 21 apps removed (almost all of the apps they had published to that point), so they adapted their tactics. The fraudster likely developed a more robust mechanism to avoid detection and removal. A batch of 15 apps, all published after September 2019, had a much slower removal rate using those new techniques.
Here’s where it gets interesting: in November 2019, two apps published the previous month that contained fraudulent code were updated with most of the fraudulent code being deactivated:
App Name |
Installs |
Published |
Last updated |
Latest version |
Fraud Removed? |
Rose Photo Editor & Selfie Beauty Camera |
1,000,000+ |
Oct 10, 2019 |
Nov 20, 2019 |
11 |
Yes |
Pinut Selife Beauty Camera & Photo Editor |
1,000,000+ |
Oct 20, 2019 |
Nov 19, 2019 |
3 |
Yes |
Table 1 - Apps with fraud logic removed in last code update
Source: White Ops Satori Threat Intelligence and Research Team
To be clear, not all of the fraudulent code was removed. Some classes were removed, enough to render the fraud activity inactive, but several pieces are still there, like the default config class including keys and values that were used exclusively for fraud control.
Here’s a look at some of the changes we observed between the versions for the app Rose Photo Editor & Selfie Beauty Camera:
Version 10 (fraud active) |
Version 11 (fraud inactive) |
|
|
Table 2 - Version changes in app with fraud removed
Source: White Ops Satori Threat Intelligence and Research Team
In Version 11, path com.photoeditorrosy.beautycamera.selfieapp.s is missing, including the services: InsService, LinkService & NInsService.
xdandroid.hellodaemon is also missing (used for persistence).
Version 10 (fraud active) |
Version 11 (fraud inactive) |
|
|
Table 3 - Version changes in app with fraud removed
Source: White Ops Satori Threat Intelligence and Research Team
In Version 11, ad rendering activities are gone: lengqi, mimeng, shancheng.
xdandroid.hellodaemon is missing also (used for persistence).
Version 10 (fraud active) |
Version 11 (fraud inactive) |
|
|
(click images to enlarge)
Table 4 - Version changes in app with fraud removed
Source: White Ops Satori Threat Intelligence and Research Team
In Version 11, the Settings class was reduced, but several of the config values used for fraud are present.
These might have been the first two apps using the new techniques for avoiding detection. These apps receive remote configuration from their Command and Control (C2) masters, meaning there’s no need to remove code to deactivate fraud.
The changes the fraudsters have made may be an attempt to test if the removed code was the catalyst for the previous apps being removed from the Play Store. The fraudsters might be trying to pinpoint exactly what criteria are being used by the Play Store as justification for removal of their earlier apps.
Another explanation is that the actors may have decided to remove the fraudulent activity to try to keep these apps active on the Play Store for later use. It is worth noting that each “publisher” in this threat model posted only one app, and many apps had a large number of installations in a relatively short period of time. The reviews of the apps show a large number of 5-star and 1-star ratings, resulting in a U-shaped distribution.
Figure 1 - Play store reviews for Rose Photo Editor & Selfie Beauty Camera
Source: White Ops Satori Threat Intelligence and Research Team
In this scenario, if (or when) the threat actors decide to reactivate the fraud code in these apps by updating them and reinstating the fraud classes, millions of users would become immediate victims of the scheme.
The Satori Team reproduced the fraud behavior in our lab, using the app “Rose Photo Editor & Selfie Beauty Camera”:
Icon |
Package ID |
Version |
Installs |
SHA256 Hash |
|
com.photoeditor.selfie.beautycamera |
10 |
1000000 |
76ef1df5abbeecdff982a1df051b32998 |
Table 5 - Details of app used for reproduction of fraud in the lab
Source: White Ops Satori Threat Intelligence and Research Team
This is one of the two apps noted above that had fraudulent code removed on Nov 20, 2019.
The video below, from early Nov 2019, demonstrates the app launching a fraudulent Out-of-Context (OOC) ad. The app was installed only hours before, and its services are running. The user unlocks the device, uses it for a few seconds, and while still in the launcher, an OOC ad pops up.
Source: White Ops Satori Threat Intelligence and Research Team
We can see which app is displaying the OOC ad by checking the activity in focus, by pulling the activity listed as “mCurrentFocus”:
mCurrentFocus=Window{f731de2 u0 com.photoeditor.selfie.beautycamera/com.photoeditorrosy.beautycamera.selfieapp.mimeng} |
Code 1 - Fraud activity in focus references Rose Photo Editor & Selfie Beauty Camera app
Source: White Ops Satori Threat Intelligence and Research Team
Most of the apps in this threat use “packers.” This means that the APK contains extra DEX files. DEX files are Dalvik Executables, files with optimized logic that are executed in the Android Dalvik virtual machine. Those extra DEX files are stored in the APK in an obfuscated way, so they do not look like DEX files. Those extra DEX files are unpacked and loaded in memory by the packer software the first time the app is opened. Standard APK analysis tools like APKTool, JEB, jadx, or Android Studio can’t see the contents of those DEX files when looking at the APK file, making it harder for researchers—and presumably the Play Store—to inspect the app code.
The bad actor(s) behind this threat tried several packers in the apps, which clearly tells us of their sophistication, resources available, and determination.
Our team identified five different packers used in apps related to this threat. One packer was eventually preferred and all apps published since August 2019 used that one. In the image below, the files “0OO00l111l1l“ and “0OO00l111l1l“ are those packed DEX files. Native libraries are used by the packer to unpack the DEXs and load them in the Java context.
Source: White Ops Satori Threat Intelligence and Research Team
Historically, packing binaries is a common technique malware developers use to avoid being detected by security software like antivirus. Packed files in Android are not new and can’t be assumed to be malicious, as some developers use packing to protect their intellectual property and try to avoid piracy.
The below figure shows an APK using another packer, in this case the extra DEX is the file named: ijiami.ajm, which is unpacked by the native library named: libexec.so.
Source: White Ops Satori Threat Intelligence and Research Team
In this case, the entry point to initiate the unpacking process is Java code in the code path “s.h.e.l.l” (at the top of the figure).
The most interesting fact around packers in this threat is the number of them tested by this actor, showing that they are playing the long game, testing and improving iteratively, increasing their sophistication and chances of success with each app release.
The second level of obfuscation is the use of Arabic characters as symbols for classes, methods, and paths. This particular methodology of obfuscation helps threat actors in a few different ways:
Source: White Ops Satori Threat Intelligence and Research Team
In the below figure we link verses from the Quran to a snippet of decompiled code from com.photoeditor.selfie.beautycamera app. Verses from Quran are also used in other apps of this group.
This means the obfuscation logic is not using random Arabic symbols, but pulling symbols chains from Quran to use for its mission.
Source: White Ops Satori Threat Intelligence and Research Team
It’s important to note that the use of Arabic characters should not be taken as an indication that the authors of the apps are native Arabic speakers. In much the same way, there are Chinese strings in the apps too, in literal strings.
Source: White Ops Satori Threat Intelligence and Research Team
The use of character sets that are not in simple ASCII tables is not new for obfuscation. White Ops researchers previously reported on the use of Udmurt characters for obfuscation in our Soraka investigation from December 2019.
The apps in this operation use configuration key/values to control the fraud behaviors. The keys have default values, included in a Settings class. The first time the app is opened (and after that, at different intervals) the app will request configuration updates from a remote server. This application is using a remote configuration management service to distribute configuration updates among the users that install the apps.
A request and a response can be seen in Appendix B below.
Using this remote configuration product provides the threat actor great control of the apps for different users, the service helps return different configurations to different user segments.
This means fraud can be activated or deactivated by any one of several different context factors that will control where, when, and for whom the fraud is launched. Some examples are: Country, language, operating system, app version, date, and time.
Below are a few examples of config keys declared in the code with default values, and the same keys received from the C2 in our lab environment, which overrode the default values:
Config Element |
Local value |
Remote value |
nyyw_dl |
false |
true |
nyyw_enable |
false |
true |
nyyw_max |
45 |
40 |
Table 6 - Config key/values from default class vs. C2 response
Source: White Ops Satori Threat Intelligence and Research Team
Key prefixes are related to each of the fraud services, meaning the values in the config with each prefix will control the execution of fraud originating from a specific service (more on services below).
Config Elements |
Service Related |
Abused Ad Type |
yyw_dl & yyw_enable |
InsService |
InterstitialAds |
nyyw_dl & nyyw_enable |
NInsService |
NativeAds |
Table 7 - Config keys, services reading them, and ad types involved
Source: White Ops Satori Threat Intelligence and Research Team
The developers of these apps are also using a commercial tracking and reporting service to monitor activity from their user base.
Analysis of the app showed that OOC ad fraud is controlled and initiated by two services: InsService and NInsService. The primary difference between them is in what type of OOC ads they show. The InsService service executes interstitial ads, while NInsService executes native ads.
Depending on the app’s implementation and the config received from the C2, the services might attempt to target different ad networks.
The execution of each service is controlled by jobs and alarms, which are started when the device boots up. Both services perform a series of checks every time they are executed to determine if they will attempt a fraudulent ad impression or not.
The checks these services perform are (these vary slightly from app to app):
The config contains specific boolean flags and time intervals for each service.
This service evaluates if conditions are set for launching an OOC interstitial ad every time it’s started by the worker service (every 15 minutes).
Note: green annotations in all code segments below were added by White Ops.
Code 2 - Code snippet from com.catooneditor.beauty.selfie.camera, comments added
Source: White Ops Satori Threat Intelligence and Research Team
If all checks are positive, then the current time is saved as last_display_on in the shared preferences and a handler is run to load and render an OOC ad.
The next class attempts an ad load from one of the ad networks targeted, using a placement id from the config keys. If instead of a placement id a “shutdown” kill switch is found, then the ad is not loaded.
Once the ad network loads an ad, the interstitialAdListener receives a call, which will repeat some of the checks.
If all checks are cleared again, then a method is called, which renders the loaded ad. For example in the code below, method interstitialAd.show is called.
Code 3 - Code snippet from com.catooneditor.beauty.selfie.camera
Source: White Ops Satori Threat Intelligence and Research Team
This service will load an ad from one of the targeted ad networks and launch an activity to render it, when conditions are met. This service is executed every 100 seconds.
Code 4 - Code snippet from com.catooneditor.beauty.selfie.camera, comments added.
Source: White Ops Satori Threat Intelligence and Research Team
Similar to InsService, the NInsService service will check similar configurations to decide if an OOC ad will be rendered or not.
Once the service triggers an ad rendering attempt, there are two paths that the code can follow, either using a pre-cache ad or sending an ad request to the ad server.
Source: White Ops Satori Threat Intelligence and Research Team
The ad request is mediated and can be made to either of the targeted ad networks. Specialized activities are used for rendering ads from the SDKs too.
The Satori Team continues to monitor this threat and will identify any emerging adaptations and new apps. We recommend removal of any apps identified in Appendix A.
As noted above, it’s unclear why the fraudsters removed the fraudulent code from two of their most successful apps, but the reasons potentially boil down to one of four options:
Options 2, 3, and 4 above present a “Chekhov’s App” of sorts. There’s reason to believe fraud will resume from these bad actors, it’s only a question of where, when, and how.
We suggest the following questions to ask about an app to help identify potential threats:
Request for config from com.catooneditor.beauty.selfie.camera
Response from C2 with config
To read more investigations from the Satori Threat Intelligence and Research Team: