SHA1 hashes:
- 3b9338986f0f7fc50d77a783f4245bc1625343f0 (com.yippo.ai version 1.3.5 «Creation Magic World»)
- c8466dd1f57bb38a984b3adb7a7e6a7c9f20fba3 (com.yippo.ai version 1.3.6 «Creation Magic World»)
Description
Someone on behalf of the developer SHENZHEN RUIREN NETWORK CO., LTD, released several applications. In terms of gameplay, they all are clones of popular mobile games.
- Creation Magic World — a sandbox game that resembles Minecraft. It is an unmistakable cubic world with similar mechanics;
- Cute Pet House — a game that operates on the principle of the Tamagotchi game, where one needs to take care of a cartoon pet;
- Amazing Unicorn Party — a game that also operates on the principle of the Tamagotchi game, with unicorn pets;
- SAKURA School Simulator — an anime-style school simulator game;
- Theft Auto Mafia — a GTA-style imitation; an SLG with criminal elements;
- Open World Gangsters — like the above example, it is a sandbox game involving criminals of all stripes.
The first versions of these games did not contain malware. On September 28/29, Android.Phantom.2.origin origin was embedded in games. On October 15/16, after updates for these games had been released, Android.Phantom.5 appeared. Here is an example of a typical inject for the applications, using Creation Magic World as an example:
Android.Phantom.2.origin is activated when the application launches, at the moment the device owner clicks on the icon. First, Android.Phantom.2.origin creates the task java.util.TimerTask in order to implement regular requests to the control server hxxps[:]//playstations[.]click. This task is executed simultaneously with the application; at all other times, it is inactive.
The data-transfer process between the trojan and the server is additionally protected by AES encryption in the ECB mode. The encryption key in the base64 mode looks like this: ZDgyNjEhKDk1RjBjYzExZUVAODE5XzUyNDA4QmEyNWI=.
After that, Android.Phantom.2.origin checks whether WebRTC can be used. The trojan can use two scenarios: signalling and phantom. This check will show how the trojan will act next. The trojan checks whether the smartphone’s characteristics meet the system requirements:
- at least 4-core CPU;
- Android 13 and later;
- the org.webrtc.PeerConnectionFactory class is available:
-
one of the following conditions is performed:
- the org.webrtc.EglBase class; the “create” method is available;
- the org.webrtc.EglBase$-CC class; the “create” method is available;
- the org.webrtc.EglBase$CC class; the “create” method is available.
The above-mentioned classes are not among the standard set of tools and libraries included in Android SDK. Games available at GetApps do not have such classes. That’s why the trojan needs to download the missing library differently in order to work with WebRTC. For example, with the help of Android.Phantom.5, which can be built into the application we are examining.
If a device meets these requirements, Android.Phantom.2.origin submits a POST request to hxxps[:]//dllpgd[.]click/api/signaling/check-plugin-start. Parameters for requesting a server:
the JSON object; the atom parameter:
| Parameter | Type | Description |
|---|---|---|
| deviceId | String | Device ID |
| deviceInfo | DeviceInfo | Device information |
| version | long | Version |
| appPackageName | String | Application package name |
| appVersion | String | Application package name |
| gaId | String | Google Analytics ID |
| sessionId | String | ID sessions |
| appChannel | String | Application channel |
| pluginInfos | Array | Plugin information list |
| isGeneratedBySubProcess | Boolean | Flag indicating generation by a subprocess |
DeviceInfo:
| Parameter | Type | Description |
|---|---|---|
| timezone | String | Device time zone |
| locale | String | Device locale |
| phoneTimestamp | long | Phone timestamp |
| phoneModel | String | Phone model |
| androidVersion | String | Android version |
The server's response determines the scenarios for further infection.
- SDK signalling will be applied if the trojan receives a response with the run: true parameter in the JSON object.
- SDK phantom is used if a device technically does not meet the signalling option or a positive response is not received from the server.
Both SDKs operate on the same principle. They download websites specified by cybercriminals to WebView together with JavaScript code to simulate user actions. In addition, the trojan adds the JavaScriptInterface “apicmob”. It gives the following capabilities to the code running in WebView:
- screenshot()— the website screenshot in base64; it uses a virtual screen;
- scroll(px, py, p2x, p2y, duration) — to scroll at a specified speed;
- setConfig(s, s1) — to save the JSON string s in the memory;
- getConfig()— to get the saved JSON;
- getGAID()— to get the advertising ID;
- isSignaling()— whether the signalling sdk is being used;
- setTime(t) — to save the timestamp;
- touch(x, y) — the simulation of clicks on the screen;
- updateSignalStatus(s) — task completion status;
- upload_event(s) — to download information about an event to the server;
- upload_log(s) — to send the log to the server.
Signaling way
Android.Phantom.2.origin receives the tasks for this operating scenario from hxxps[:]//playstations[.]click/h5/get_job_by_offer. The signalling SDK connects to the WebRTC alarm server via the WebSockets protocol wss[:]//dllpgd[.]click/signaling_ws. To establish a connection between the nodes, WebRTC uses data from the ICE server:
- turn:101.36.120[.]3:3478 user:wumitech pass:wumitech.com@123
- turn:106.75.153[.]105:3478 user:wumitech pass:wumitech.com@123
After that, Android.Phantom.2.origin broadcasts the video to the cybercriminals from the virtual screen, which displays a WebView with the downloaded website. Together with the target website, JavaScript is downloaded to WebView from hxxps[:]//playstations[.]click/h5/js_file_for_signaling. To remotely manage the content downloaded to WebView, commands in the JSON format are received via DataChannel WebRTC:
- "click" — to click,
- "close" — to disable the broadcast,
- "drag" — to drag from point 1 to point 2,
- "dragEnd" — to drag from point 1,
- "dragStart" — to drag to point 2,
- "goBack" — to go back to WebView,
- "keyInput" — to use the keyboard,
- "paste" — to paste text into the input field, using JS.
If any of these commands fails, the trojan sends an error report to DataChannel WebRTC. This makes it possible to track errors and respond to arising problems.
As a result, a person or an automated system remotely and covertly, via a video call, exploits the browser built into an application.
Phantom way
If the smartphone does not meet the verification requirements, or an application does not have the required library for connecting under the WebRTC standard, or the server does not give the command to operate in the signalling mode, Android.Phantom.2.origin uses the phantom SDK operating mode by default. The trojan receives tasks from the hxxps[:]//playstations[.]click/phantom/task server. The trojan downloads the model for the TensorFlowJS framework, using the following links:
- hxxps[:]//app-download[.]cn-wlcb[.]ufileos[.]com/dllpgd_plugin/ai_model/js_v3/model[.]json,
- hxxps[:]//app-download[.]cn-wlcb[.]ufileos[.]com/dllpgd_plugin/ai_model/js_v3/group1-shard1of2[.]bin,
- hxxps[:]//app-download[.]cn-wlcb[.]ufileos[.]com/dllpgd_plugin/ai_model/js_v3/group1-shard2of2[.]bin,
to the jv3 directory in the application files.
The trojan contains a special WebViewClient which lets the JavaScript code download files from the application's jv3 directory. An example of a link for downloading a model that can be used in the JavaScript code: /apicmob_tf_model/model.json.
After that, Android.Phantom.2.origin refers to hxxps[:]//playstations[.]click/phantom/file. From there, it downloads the JavaScript file that contains all of the functions needed for the model to operate and for interacting with the webpage: the TensorFlowJS framework, the logic for loading the model files, and the logic for performing clicks and other actions on the website. SHA-1 of the decrypted file: sha1:654b3dd6f39cfd1bd7bcd34dc41bfa6e4b55a696. This JavaScript file is downloaded together with other content from the target website, which lets JS perform actions on the webpages. The apicmob interface provides the means for taking screenshots, which are analyzed by the script via TensorFlowJS in scenarios when the button that closes Vignette Ad pop-up ads needs to be found. For example, the trojan launches this analyzing process when it cannot find the object to be clicked using other methods.
A piece of code that includes a call for a feature that uses TensorFlowJS
An example of an intercepted task for phantom way:
task Expand source
{ad_page_bounce_rate: 0.211,
anchor_close_ctr: 0.0897,
content_type: "game",
cookie_confirm_xpaths: ["//div[text()='Privacy Information']/following-sibling::div/*",
"//button[contains(translate(text,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz'),'accept all cookies')]",
"//*[contains(translate(@aria-label,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz'),'cookie')]//*[contains(translate(@aria-label,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz'),'close')]",
"//div[contains(@class,'ecomsend__Modal__CloseButton')]",
"//div[@class='fc-consent-root']//button[contains(@class, 'fc-button') and (contains(@class, 'fc-cta-do-not-consent') or contains(@class, 'fc-cta-consent'))]",
"//*[@id='userAgree']",
"//*[contains(@class,'cookie-notification-bar__accept') or contains(@id,'banner-accept')]",
"//div[contains(@class,'needsclick')]//button[@aria-label='Close dialog']",
"//*[contains(@aria-labelledby,'cookie')]//*[contains(text(),'Agree')]",
"//*[@data-cookie-set='accept']",
"//button[contains(translate(text(),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz'),'allow all cookies')]",
"//*[contains(@class,'cookie') or contains(@class,'consent') or contains(@id,'cookie') or contains(@id,'consent')]//*[contains(@class,'accept') or contains(@id,'accept')]",
"//*[contains(@*,'acceptCookies')]",
"//div[@id='questions-interstitial']//span[@data-bs-dismiss='modal']",
"//*[contains(text(),'cookie')]/..//*[text()='OK']",
"//*[text()='We Value Your Privacy']/..//*[text()='Accept']",
"//*[contains(@class, 'cookie-confirm')]//*[contains(@id, 'confirm')] | //*[@aria-label='Aceptar']",
"//*[@id='onetrust-accept-btn-handler']",
"//div[@aria-label='privacy banner']//button[@aria-label='Accept All']",
"//div[@id='CookieDialog']//span[text()='Got it']",
"//*[contains(@id,'Cookie')]//*[text()='Allow all']",
"//*[contains(@id,'cookies')]//*[contains(@class,'accept')]",
"//*[contains(text(),'cookie')]/..//*[@id='truste-consent-button']",
"//button[@id='accept-cookies']",
"//div[@id='hcpModal']//a[text()='YES']",
"//*[@class='cky-consent-bar']//*[translate(@aria-label,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='close']",
"//button[@data-cookiedays]",
"//div[@class='bx-wrap']//button[@data-click='close']",
"//button[contains(text(),'Accept') or contains(text(),'Aceptar')]",
"//div[contains(@id,'newsletter-popup')]//div[@class='modal__centered']//button[contains(@class,'modal__close')]",
"//*[@id='onetrust-close-btn-container']",
"//div[@id='entryModal']//*[text()='OK']/..",
"//*[contains(@class,'tm-cookie-banner')]//*[contains(@class,'js-accept')]",
"//*[translate(@*,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='close cookie policy']"
],
fast_bounce: false,
offer: {job_id: "XXXXXXXXXX",
offer_id: "apico[.]top",
site_url: hxxps://www[.]apico[.]top
},
pages: [{ads: [{ctr: 0.035,
format: "interstitial",
name: "top_inter"
}
],
pattern: "^hxxps://(www.)?apico[.]top.*#google_vignette"
},
{ads: [{ctr: 0.035,
name: "top_top"
},
{ctr: 0.024,
format: "lazy_banner",
name: "top_sidebar"
},
{ctr: 0.02,
format: "lazy_banner",
name: "top_bottom"
},
{ctr: 0.034,
format: "anchor_banner",
name: "top_anchor"
}
],
pattern: "^hxxps://(www.)?apico[.]top/(game|category)",
xpath: "//a[contains(@href, '/category/')] | //div[contains(@class, 'item-grid')]//a"
},
{ads: [{ctr: 0.035,
name: "top_top"
},
{ctr: 0.024,
format: "lazy_banner",
name: "top_sidebar"
},
{ctr: 0.02,
format: "lazy_banner",
name: "top_bottom"
},
{ctr: 0.034,
format: "anchor_banner",
name: "top_anchor"
}
],
pattern: "^hxxps://(www.)?apico[.]top",
xpath: "//a[contains(@href, '/game/')]"
}
],
pv: 2,
random_swipe: true,
random_swipe_level: "high",
region: "RU",
type: "web_adx"
}
The goal of this task is to increase the number of targeted clicks on the ads at hxxps[:]//www[.]apico[.]top. From another task, we found the similar website hxxps[:]//qaz[.]baouy[.]top. These websites contain different browser games containing numerous ads.
In addition, we discovered that Android.Phantom.2.origin is distributed via:
-
websites with spotify mods:
- hxxps[:]//spotipro[.]top/
- hxxps[:]//spotipro[.]top/
- hxxps[:]//spotiplus[.]xyz/
-
websites with the mods:
- hxxps[:]//apkmody[.]mobi
- hxxps[:]//moddroid[.]com
-
Telegram channels:
- hxxps[:]//t[.]me/spoti_pro/
- hxxps[:]//t[.]me/moddroid_co_OF
- hxxps[:]//t[.]me/spotify_premium_channel
- hxxps[:]//t[.]me/apkmodyOF
-
Discord servers:
- hxxps[:]//discord[.]com/invite/aybQHENK4B
- hxxps[:]//discord[.]gg/TXxc5cqQ6a
- hxxps[:]//discord[.]gg/6Um7CV8nPg
MITRE matrix
| Stage | Technique |
|---|---|
| Initial Access | Managing application versions (T1661) |
| Execution | Command and Scripting Interpreter (T1623) |
| Defense Evasion |
Managing application versions (T1661) Download New Code at Runtime (T1407) Input Injection (T1516) Obfuscated files or information (T1406) Virtualization/Sandbox Evasion (T1633) System Checks (T1633.001) |
| Discovery |
System Information Discovery (T1426) System Network Configuration Discovery (T1422) |
| Data Collection | Screen Capture (T1513) |
| Command and Control |
Application Layer Protocol (T1437) Encrypted Channel (T1521) Symmetric Encryption (T1521.001) Ingress Tool Transfer (T1544) Remote Access Software (T1663) |
| Destructive impact |
Generate Traffic from Victim (T1643) Input Injection (T1516) |