Cyber News / Article / Inside a multi stage toll fraud operation targeting Poland

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 forMessenger 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 Prosent Polish MCC260to its default fraud payload.Phone Cleaner Master, another confirmed build of the same operation, later explicitly selectedPL260for the newerAqMupayload branch. This article usesMessenger Proas 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 ofJokerdescribed 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.
Figure 1. Typical premium SMS and carrier billing paths used in toll fraud.
In theMessenger Propolicy 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 ansms:link without a user gesture and passed its destination and keyword to the native SMS bridge. The values92505,92512and92513were 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 associated92513with a one time charge of 30.75 PLN. A further job reached a Teleaudio page advertising 17 PLN every seven days.
The three short codes returned by theMessenger ProC2 were checked against theUKE Rejestr Premium, the Polish regulator's public register of premium rate numbers. All three -92505,92512and92513- 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).92505is operated by GoMobee LTD (Malta),92512by Telefuture Nederland B.V. (Netherlands) and92513by RedLeads B.V. (Netherlands). The registered service name for92505includesLoovafitandLoovaplay, matching the keywords the malware sent; for92513it isUsluga ALL na numerze 92513, matching theALL 64913keyword 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 throughepayment.teleaudio.pldirect carrier billing rather than a premium SMS short code, so it does not appear as an entry in this register.
Our investigation began with two Polish ads in Meta's Ad Library. They were displayed under the namesBritney HarrisandKenneth Williamsand 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.
Both advertisements were active in Meta's Ad Library when we captured them on 14 September 2026. Their Ad Library IDs were1101937705505412and4635863290017072. 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 theMessenger Prolisting on Google Play. The advertised package was:
Google Play presented the package asMessenger Pro, version9.0, under the developer nameNoah 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.
CERT Polska reportedMessenger Proto 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.
The investigation started with a narrow scope: two advertisements leading to a single application. After characterizingMessenger 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 Proprovided 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.
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 forQuick ShowandBlushTooncame 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.
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 Messagereused 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 Messagesand five newly identified removed packages remain supporting evidence because their APKs were unavailable.Easy Messages ProandComic Readerwere 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:
Britney Harrisalso displayed 12 advertisements forEasy Messages, andKenneth Williamsdisplayed 21 forLight 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-25690b87d8b4dda273ef64853a9997bba0844f0bc02071ae5101d1be2693be1b861, appeared in 55 new advertisements across 20 packages and 39 identified profiles, in addition to one earlier record. The previously leading file, SHA-2567299f7de6acf366fc7f32f7c3873a09e11a08d9493aaa508cd2b2ee816c5d284, 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 ourMarch 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 Affairspublished its correspondence with Meta, Deputy Prime Minister Krzysztof Gawkowskiannounced that he had formally asked the European Commissionto impose a penalty of at least 250 million euro over Meta's handling of fraudulent advertising in Poland.
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 Wallpaperimplemented part of this chain in native code.Max Messengerused 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 MessagesandInstant Messagespassed a validated or transformed server response into an obfuscated native library.Quick Chat Messagedecrypted the server response and loaded it directly throughInMemoryDexClassLoader. Six applications recovered during the investigation followed the same two designs.PDF Scanner Pro,Text Magic Messages,Go Cleaner ProandText Message Prohanded validated policy responses to native code.Quick Message ProandLite PDF Scannerreconstructed 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.
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 16apihosts to distinct Aliyun US East load balancers. The four new parent domains followed the same AWS name server template and theirapihosts 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 theaqmuprefix and identifiers from2115to2155.
The four newly recovered parent domains shared the exact historical WHOIS hashes for registrant organization, telephone number and street address withpiaagt.click,tehsnb.linkandhsbdbv.link. This provides a more specific connection than common registrar or cloud provider use.PDF Scanner Prosupplied another direct bridge: its primary endpoint reusedapi.piaagt.click, which was already present inColorful MessageandShort 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 Mastersupplied the clearest later comparison with theMessenger Probaseline. On 16 September, its policy endpoint returned:
The marker activated its embedded routing stage, while the suffix selected MCC260,621and232for the newer AqMu branch. Polish devices therefore downloadedaqmu2150and loadedcom.dzyna.mytsx.AqMu.land(). The resulting DEX contained 112 classes, the same class count and obfuscated package size distribution as the AqMu payload recovered fromMessenger Pro.
The two AqMu builds used separate C2 configurations. TheMessenger Probuild used47.84.194.202/asnvoycswith passwordu18r3ze2, while thePhone Cleaner Masterbuild used47.84.193.174/j26j8vf7with passwordtrd6rgu5. Both retained fallback address129.226.172.250, event endpointapi.appbhwljk.com/api/v3/wkevand the same embedded event token. These code and configuration matches link the payloads more specifically than common cloud hosting.
Messenger Proprovided a direct pivot from the sample to the network infrastructure: its final payload communicated with47.84.77.127over 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 forablefee.wiki:
This passive TLS observation is howablefee.wikientered the investigation. The domain does not appear in theMessenger Procode or its network requests, and passive DNS does not connect it to47.84.77.127. Its value is the exact certificate hash, which VirusTotal also observed on five IP addresses independently recovered from related loader samples:
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.
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. TheMessenger ProC2 supplied live premium SMS and recurring carrier billing jobs, while the laterPhone Cleaner Masterpolicy explicitly selected Polish MCC260for 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.
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,observeddescribes behavior captured during execution, whilecapabilitydescribes implemented code that was not activated in our tests.
Unless stated otherwise, the execution details below describe theMessenger Probaseline. Related builds preserved the same general delivery design but changed cover applications, policy markers, routing implementations, payload objects and C2 configuration.
Messenger Prois 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.
After we selected it as the default SMS handler through the normal android interface, android grantedREAD_SMS,RECEIVE_SMS,RECEIVE_MMSandSEND_SMSwith theGRANTED_BY_ROLEflag. 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 Masterused a utility cover and did not requestREAD_SMS,RECEIVE_SMSorSEND_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 requiresSEND_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 deliveredMessenger Proas 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.
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 thisMessenger Probuild, Polish MCC260received the default branch. The following execution flow summarizes this chain.
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 inclasses9.dex, which represented 0.552% of those bytes. One injected call blended into a largeApplication.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 withInMemoryDexClassLoader. 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 withInMemoryDexClassLoader.
Execution did not require the user to open the application. Package Manager recorded installation at12:54:02. At12: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:
The provider itself is a stub. Its importance is that the request started the application process without opening the interface. Android initializes content providers beforeApplication.onCreate(). Startup then reachedMyApplication.onCreate(), where one injected call launched the loader before normal messenger initialization. Reduced to the relevant statements, the code is:
The manifest also declares host components used by later stages: a disabled launcher alias, theWorkJobServicejob service, a transparent activity labelled6002, 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:
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:
The verified plaintext began withdex\n038\0, confirming that decryption had recovered a valid android DEX file. Here,038identifies the DEX format version, not the application or malware version. The loader passed the recovered stage 1 bytes directly toInMemoryDexClassLoader:
The reflective call toGate.a(context)marks the end of the base APK loader and the beginning of stage 1.
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:
The decoded allowlist covers Thailand, Indonesia, Malaysia, Turkey, Saudi Arabia, the United Arab Emirates,Poland, Austria, Greece, Germany, Nigeria, France, Romania, Switzerland and China:
The test environment initially exposed its default MCC310, 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 MCC260and followed the route intended for Polish devices. Stage 1 accepted this value and requested the fixed policy endpoint athxxps://api.tehsnb[.]link/sabd/mckd. On 15 September 2026, it returned the following shared activation and routing response:
The response did not classify the test device as French. It was a shared policy and supplied no executable code or decryption key. The markercbhedbgegevddinstructed stage 1 to continue. The suffix_GUOJIA=460_FR208listed the MCC values assigned to the targeted route:460for China and208for France. Polish MCC260was 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 throughInMemoryDexClassLoader.
Stage 1 then invokedpaint.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 Masterused markerpoirjfirenhrhfgand the same_GUOJIAconvention. Its response selectedPL260,NG621andAT232, 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 receives the complete policy response inOsmanthus.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:
Each configuration contains the payload URL, cache filename, telemetry prefix, entry class, entry method and a branch flag. The47.84.77.127argument becomes the C2 address only for the default payload. For the targeted branch, stage 2 replaces the two entry arguments with the names ofLpMsdqActivityandNotificationTool; that payload contains its own C2 address,47.84.194.202.
Internal diagnostics call the routesnewandold, but those labels do not describe their operational status. We usetargetedanddefaultaccording to their selection logic.
TheMessenger Prodefault payload was not specific to Poland. Stage 2 selected it for every allowed MCC except208and460. 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/MNC26001was classified asPLand received Polish premium SMS and carrier billing tasks.
This routing decision was not fixed across the operation. InPhone Cleaner Master, the live policy includedPL260, so the same MCC selected the newer AqMu branch instead. That build downloadedaqmu2150, invokedcom.dzyna.mytsx.AqMu.land()and used47.84.193.174/j26j8vf7as 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 persistedJobSchedulerjob forWorkJobService, initializes AppsFlyer and reads the Google Play install referrer. It also starts the transparentLpMsdqActivitythrough an indirect activity launch chain. On Android 10 and later, it wraps the activity intent inside a broadcastPendingIntent, sets that pending intent as the media button receiver of a temporaryMediaSessionand dispatches a media button event. A registered receiver extracts the original intent and starts the activity. The accompanying virtual display andPresentationbelong 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:
Stage 2 stores the encoded HTTP body asoyoangonfor the default route ordewqq_rspfor 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 anotherInMemoryDexClassLoader:
For Polish MCC260, stage 2 invokedcom.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:
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.
The default payload searches the host manifest for an activity with an entirely numeric label. In this sample, label6002resolves toLpMsdqActivity, which stage 2 had already opened through the launch mechanism described above. During controlled execution with a Polish operator profile, this activity hosted the nativeRegisterform later used to collect a Polish telephone number.
com.jk.MainEntry.init(host, referrer)receives the C2 address47.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 byHttpsURLConnectionwith 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 operationi, it chooses a random integerrbetween 0 and 998 and calculates:
It places one random ASCII letter before or after every decimal digit ofn, 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:
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 usedContent-Encoding: gzipon 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:
The first 16ASCII hex charactersform 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.
Figure 3. How Messenger Pro encrypts C2 traffic.
During controlled execution, the application generated path/A2W80jUc. Its digits form280, and280 mod 31 = 1, identifying a registration request. The captured URL and derived key were:
Decryption of the 176 byte request body produced:
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:
The backend assigned remote ID60727718and countryPL. 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 ID60723698. Its operation 2 poll used a different URL and therefore a different key:
Decrypted request:
Operation 2 is more than a heartbeat. It tells the backend which fraud routes the device can support.eymbmwreports cellular connectivity,rktfhtreports the inbound SMS capability andsegdipreports 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:
The response reused several field names with different meanings. In the request,eymbmwreported that a cellular route was available. Inside the returned job,eymbmw: truerequired the payload to obtain and bind to that route. If this failed, the job ended with result 203. Similarly,hyszxccarried the country codePLduring registration, buthyszxc: truein the job selected a mode in which the payload retrieved page content through its native HTTP client before loading it into WebView.
lybftacontained the browser task. Although represented as an array, the payload read only its first element.ejqgpkwas job ID863176325, which the client later included in its result.gooycfsupplied the initial affiliate URL.gkreilcontained seven URL matching rules and their JavaScript bodies, allowing the C2 to define how the payload should respond as redirects reached different billing pages.inbzrzselected execution mode 200. Values of 300 or higher enable additional tracing and page capture paths.
The outerjxdkqbobject was processed independently and before the browser task. Itssegdipvalue used the formatdestination---body, instructing the native SMS helper to sendrch59419069to+447752070662. Elsewhere in the payload, an incoming message beginning withrchtriggers a request to/op/paircontaining 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.
The decrypted operation 2 response shown above contained the browser job inlybfta. Itsgkreilarray 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:
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 athxxps://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:
The C2 suppliedNNNNBBBBas a placeholder for the telephone number associated through operation 4. It remained unresolved in our jobs because we supplied no usable number. The omittednextThings()helper schedules result302for 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 wordkod.
The C2 scripts use the stable expressionwindow.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 andmoixxtmethod name are exact:
The C2 can therefore use the stableJBridge.callsyntax, while each WebView instance exposes its native interface under a different name.
The two arguments tomoixxtare a command and its value. The dispatcher logs every invocation asjs-><command>:<value>before calling the native implementation:
headers,data,url,mainFrame,b64andfinalUrlare fields accepted by therequestcommand, 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 tonotify.clfldcbprotect.com,notify.dcbprotect.comandnotify.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 campaigns10371,10372,10374and10375. 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:
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.
In one controlled run, the payload registered MCC/MNC26001, received countryPLand obtained job864515147. The job followed this chain:
The remote rule passed both forms of the short code toSmsManager. The calls were intercepted in the analysis environment and did not reach a mobile network:
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 attemptedLOOVAPLAY F4Jto 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.
Figure 4. Observed C2, WebView and premium SMS sequence for job 864515147.
The C2 registration response storedhyszxc: "PL"in a global country field. Once the host hadRECEIVE_SMS, the payload opened a noncancelableDialogFragment. It constructed the entire screen in Java and selected validation rules from a country table:
For Poland, the dialog displays prefix+48and accepts any nine digits without checking whether the number is allocated. The deliberately impossible value000000000therefore enabled its button.
Pcap decryption recovered the exact exchange:
The dialog then closed, but later jobs still containedNNNNBBBB. The capture therefore does not show that the backend accepted the impossible value as subscriber data.
The left image shows the malware's native+48form. The right image comes from the earlier device run and shows android identifying the actual risk:Messenger Prowanted to send to92505, and the message could cause charges.
A later 240 second run captured three complete Polish premium SMS jobs. The third, job865090137, followed campaign10372through an affiliate chain to a live All4You page. Its DOM identified Poland, shortcode92513, display keywordALL 64913and providerRedLeads 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:
The matching C2 rule contained one statement:
Chrome DevTools Protocol recorded what happened next:
The navigation did not come from a tap. After the remote statement clicked the link, the payload's JavaScript bridge parsed thesms:URL and called the native SMS API for both forms of the short code:
No matchingDA ALLreply 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.
The default payload registers anSMS_RECEIVEDreceiver, parses incoming messages and adds their bodies to the active job queue. The bridge commandpopMsgsearches this queue with a regular expression supplied by the C2. A message beginning withrchalso 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 containscom.jk.NoteListener, which can extract notification text and callcancelAllNotifications(). 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 withTRANSPORT_CELLULARandNET_CAPABILITY_INTERNET, stores the resultingNetwork, and can bind the application process to it:
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 visibleMessenger Proactivity. 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.
The live C2 supplied browser automation fordcb.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 thepl_protocolmarker and navigation began withhttps://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:
The two JSON bodies reconstruct to:
The transaction lookup and subsequent API calls setAuthorization: Bearer <sid>; the POSTs also setContent-Type: application/json. The state machine reports code 901 when it cannot recover an MSISDN, 902 when the proceed response containsERROR, 305 when no PIN arrives, and 903 when the final status page lacksTransakcja 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 job865195912for campaign10371. The C2 rule matchedconsulate.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:
The finalDirect Billing AoCpage contained an empty telephone field, a disabledDalejbutton and this Polish text:
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.
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 aGETto thewifi_nmdtransaction 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 attemptedGRAM 23844to92512and+92512, while an independent command requestedrch59424826to+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.
ThisMessenger Probranch was not selected for Poland during our observation because its policy listed only MCC208and460. The laterPhone Cleaner Masterpolicy demonstrates that the operator could assign Polish devices to the same AqMu payload family in another build.
For MCC208and460in the observedMessenger Propolicy, stage 2 selects a different DEX and C2 protocol. The payload uses the fixed endpointhttp://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 passwordu18r3ze2:
Recognized actions includerrssregistration,dkcopolling/job result, and the reporting actionsgxns,yktyandhchs. 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/MNC20801, subscription ID, android versions and install referrer. The response assigned ID245651and returned anFRlanding page:
The following poll reported SMS access and the selected subscription. Its response assigned a billing URL, remote JavaScript and an independent SMS command:
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.
ThePhone Cleaner MasterAqMu 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 thePhone Cleaner MasterC2, so the French tasking below is evidence from theMessenger ProAqMu backend only.
The targeted job referencedmain.v2.js. We retrieved it as inert evidence: 33,663 bytes, 1,045 lines, SHA-256a2f292da1eb6da3bcd1b2bf2340478c2f02a4844bfaa85f00d6e4820bbbe597a.
The script contains 43 dispatch rules and explicit handlers for 10 French premium SMS short codes:
One helper function sends both forms of a short code:
The handlers parsesms:URLs, send their body and callpopMsgup to 12 times while waiting forOKor a reply containing 3 to 6 digits. They then transmit a confirmation such asDA,DA KROX,DA GBT,OK, or the original body. A generic fallback handles previously unknownsms: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.
The targeted DEX contains three significant capabilities which were not activated during our tests:
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.
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.
TheMessenger Probaseline 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 to92505,92512and92513.
Phone Cleaner Mastershowed that the country assignment could change between builds. Its policy explicitly selectedPL260for a newer AqMu payload configured with another C2 endpoint. Poland was therefore not permanently tied to theMessenger Prodefault 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 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.
Colorful Messageis connected through exact advertising file reuse and the sharedapi.piaagt[.]clickhost, 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:
We also identified the following advertised packages after their APKs had become unavailable, so no file hash could be recovered:
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:
ablefee[.]wikiis a passive certificate pivot. It was not contacted byMessenger Proand does not appear in its code.
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.
