The White Ops’ Threat Intelligence team recently identified more than 40 malicious apps using our bot detection platform. As of this writing, none of these apps are available on the Google Play Store. These apps performed a variety of ad fraud techniques all centered on a common code package known under several different names, notably Poseidon.
As we started our analysis, our friends over at NETSCOUT ASERT shared a sample with us that caught our attention. This sample was curiously signed by Tushu; see our previous blog post, Another Day, Another Fraudulent App. We did not see any evidence of the Tushu SDK from our previous report in the apps described below. Of the apps we identified, this was the only one signed by Tushu.
White Ops reported several of the apps to the Google Play Store following our investigation, and all of the apps we reported have been taken down. One of those apps was Jelly Cube Pop 2019: Crush cubes. This app has more than a million downloads since March 2019. If you look through the reviews of the app, you can see many complaints about excessive ads.
Figure 1 - Jelly Cube Pop 2019:Crush cubes on Google Play store
Source: White Ops Threat Intelligence
App Name | Package Name |
Jelly Cube Pop 2019:Crush cubes | com.jelly.bubble.game.pop |
jelly cube crush colors 2019 | com.jelly.cube.crush.colors |
Magic Camera: Make Magical Photos | com.magicvcam.photos.ygy.tool.magic |
Table 1 - App Information
Source: White Ops Threat Intelligence
The app Artistic Effect Filter was an Android photography app posted to the Google Play store in December 2018 by the publisher Mandyli, and has subsequently been taken down. During our analysis, the app makes http requests to the mapi[.]1oceans[.]com subdomain. Additional subdomains are shown in the Indicators of Compromise (IOC) section at the end of this blog. Our research identified many other Android apps related to this subdomain as well as several other subdomains.
In many Android applications, the BootCompleteReceiver class runs services after the boot process has finished. This is a common persistence mechanism in malicious applications. As we analyzed the Artistic Effect Filter app, several similarities in the application packages emerged among the apps we found. The app manifest lists the BootComplete Receiver class as com.jiubang.commerce.daemon.BootCompleteReceiver. This daemon led us to discover the Poseidon package in a number of these apps.
Figure 2 - App manifest section related to Jiubang Daemon
Source: White Ops Threat Intelligence
The Jiubang daemon starts a process by initiating the com.poseidon package, which activates the AppID spoofing. In the image below, the activity com.mirth.campic.CampicActivity configures a new string to create a spoofed APK net.lrstudios.android.tsumego_workshop.
Figure 3 - com.poseidon package
Source: White Ops Threat Intelligence
During analysis of the related applications, five similar packages had comparable functionality as Poseidon, including two variants of Poseidon. The Tawords and Pandora packages were possibly earlier versions of Poseidon, based on a code comparison. The Freeflying package uses a new configuration code and may be the most recent version.
Package Name |
Poseidon v1 |
Poseidon v2 |
Tawords |
Pandora |
Supreme |
Essential |
Freeflying |
Table 2 - Package Names
Source: White Ops Threat Intelligence
Figure 4 - com.poseidon package
Source: White Ops Threat Intelligence
The Poseidon v1 and v2 packages differ in the package content. The v1 variant does not have an AdReceiver method, which may be a sign that it is an earlier variant.
Upon decompilation of the discovered apps, we observed the threat actor(s) behind this campaign using various Greek mythological-related names. The following is a list of the Greek-related Methods, Classes, Activities or packages we observed:
Poseidon | Pandora |
Cronus (ActivityName) | Prometheus |
Tethys | Epimetheus |
Atlas | Iapetus (BootCompleteReceiver) |
Europa |
Figure 5 - Examples of the Greek mythology names in the app
Source: White Ops Threat Intelligence
We found apps that display out-of-app full screen ads and hidden ads. These ads are implemented by a few slightly different execution paths. All of the ad rendering execution paths implement independent counters and time interval controls between ad rendering.
Source | Description |
GameAdService | Out-Of-App ads, based on persistent job, screen must be on. |
AdReceiver | Out-Of-App ads, triggered by USER_PRESENT broadcast. |
EmptyShow | Hidden ads, service based, C2 boolean controlled, cannot fake clicks. |
OtherApp | Hidden ads, Service based (foreground where avail), C2 boolean controlled. Can fake clicks. |
OtherShow | Hidden ads, Multiple services (3), C2 boolean controlled, uses an independent app spoofing data set than the others. Can fake clicks. |
Table 3 - Beauty Selfie Camera ad fraud sources
Source: White Ops Threat Intelligence
Looking at one of the Poseidon variants identified in an app named “Beauty Selfie Camera,” we found the class com.cameraapp.deamad.BootCompleteReceiver in the app manifest. This class executes all of the receivers. Additionally, there is an another Receiver class, AdReceiver, in the app manifest named com.poseidon.AdReceiver. This class received the USER_PRESENT intent, a broadcast receiver used to show that the user screen is unlocked.
Figure 6 - Poseidon AdReceiver
Source: White Ops Threat Intelligence
The onReceive method starts a persistent job from the function InitUtils.startJobService(). It also starts a function named otherTask() discussed in the hidden ad section below. This function executes every time the USER_PRESENT broadcast is received.
Figure 7 - Poseidon AdReceiver onReceive method
Source: White Ops Threat Intelligence
Eventually, it makes a call to InitUtils.isCanShowAd() to determine if an ad will be started.
Figure 8 - Poseidon AdReceiver isCanShowAd()
Source: White Ops Threat Intelligence
This ad initiation routine tied to USER_PRESENT does not seem to be hidden, but is an entry point to executing otherTask() and InitUtils.startJobService(), which each have different execution paths with different conditions to start ads.
Figure 9 - Poseidon AdReceiver startJobService()
Source: White Ops Threat Intelligence
The InitUtils.startJobService() method executes the class com.poseidon.GameAdService and uses a similar approach to com.poseidon.AdReceiver. It does not matter if the originating app is running in the foreground while the screen is unlocked. The execution path uses a scheduled job to display out-of-app ads.
Note the com.poseidon.GameAdService is also listed in the apk manifest.
Figure 10 - Poseidon GameAdService
Source: White Ops Threat Intelligence
The following screenshots are examples of out-of-app ads that displayed on our test phones during analysis.
Figure 11 - Out of context ads
Source: White Ops Threat Intelligence
Researched and written by John Laycock, Inna Vasilyeva, and Nico Agnese.
App Name
Artistic Effect Filter
Package Name
art.eff.filter.photo.editor
MD5
B9D9C9E21CBEA1B50C0EBE8F7345EB9A
SHA-256
5F2248128D0B863E1A1144D95DBCD4CFB9864381D28CFADB2CAFED41FC3828DA
App Name
Beauty Selfie Camera
Package name
com.magicvcam.beauty.yoobao.camera
MD5
2DD69FD9E0D4219EC082C9EEFA74C278
SHA-256
796B1D610734B36B81DEA62239010826F9C95335DE5A2AAE15D99DE56FB69900
Domains:
1oceans[.]com | hikingman[.]net | anncute[.]com | annchic[.]com |
atsbmw[.]com | cubegamemart[.]com | mapi[.]1oceans[.]com | jk[.]hikingman[.]net |
reportus[.]hikingman[.]net | atc[.]anncute[.]com | bmw[.]anncute[.]com | test[.]anncute[.]com |
ba[.]atsbmw[.]com | bb[.]atsbmw[.]com | jk[.]cubegamemart[.]com | aps[.]annchic[.]com |
App Packages Using Poseidon and/or Related SDKs:
Package Name
com.magicvcam.beauty.yoobao.camera | com.onestoke.games.www.puzzlegame | com.time.date.stamp.camera.xixifunction |
art.eff.filter.photo.editor | com.jelly.crush.europam.games | com.tools.blur.master.editor |
com.mirth.cam.pic | com.mobwontools.pixel.blur.editor | com.blurcam.pro.usefultools |
com.magicvcam.tool.beauty.camera | com.mobwontools.pixel.blur.cam | com.camera999.super.photo.editor |
com.jelly.bubble.game.pop | com.pic.photo.editor.eraser | com.music.play.hi.cloud |
com.puzzle.ygyline.onestroke | com.puzzle.lines1.drawstroke | com.video.nin.cut.face |
com.camera.ygysuper.photograph | com.magicvcam.hdmeet.cam008 | com.box.checkers.chess.free |
com.super.photo.ygy.camera | com.magicvcam.meet.photograph | com.funny.camera.top |
com.soon.ygy.photograph.camera | com.video.master.face.fb | com.magicvcam.camera.meet |
com.camera.easy.photo.beauty | com.magicvcam.camera.newmeet | com.magicvcam.ygycronus.camera.magic |
com.cos.ygy.camera.new | com.jelly.cube.crush.colors | com.photoeditor.background.change |
com.connect.dots.maker.drawoneline | com.blur.oceans.flying | com.magicvcam.mine.ygycamera.magic |
com.ygy.find.spot.the.difference | com.candy.crushfunny.toystoys | com.frog.crushtoy.blast |
com.magicvcam.ygycamera.magic.tool | com.toy.blast.cube.crush.toysfun | com.magicvcam.photos.ygy.tool.magic |