DEV Community

jeffrey
jeffrey

Posted on

From Facebook Ad to Phone Bill: How the Android Toll Fraud Campaign Reached Victims

From Facebook Ad to Phone Bill: How the Android Toll Fraud Campaign Reached Victims

On 14 September 2026, CERT Polska analysts recorded two Facebook advertisements that warned Polish users their PDF application had expired. Both ads pointed to Messenger Pro in Google Play, a messaging app with no relation to PDF files. Installing it started a four-stage chain that ended in a module which charged the user's mobile account.
The campaign behind those two ads was wider than a single listing. CERT Polska eventually retained 1,235 unique Meta ad records shown under 74 identified profile names, promoting 29 Google Play applications. Code and infrastructure evidence linked 17 of those applications to one operation, promoted through 852 ads under 60 profile names.
This article traces how paid advertising, app-store trust and remote code delivery combined, and which parts of that chain defenders can observe from the public internet.

The two ads that started the investigation

Both advertisements used the same false update theme. The captured ad text told the reader that the PDF application had expired, that PDF files would stop opening without an update, and that the user was one step away from losing access.
The ads ran under the profile names Britney Harris and Kenneth Williams and were active in the Meta Ad Library when recorded on 14 September 2026. Their identifiers were 1101937705505412 and 4635863290017072. At the time of recording, the second ad had fewer than 100 impressions, a figure that applies to one ad inside a much larger set.
Clicking either ad redirected straight to the Google Play page for the advertised package:

com.messages.sms.messenger.textmessage.owyo
Enter fullscreen mode Exit fullscreen mode

Google Play presented the package as Messenger Pro version 9.0, published by the developer Noah Isaiah Shortland. The listing screenshots advertised password locking, appearance changes and emoji support. Nothing in the description connected the application to PDF files or to file updates.
CERT Polska reported Messenger Pro to Google on 15 September 2026, and Google removed the application from the store. Removal stopped new installations from the listing page. It did not affect copies already present on user devices, and the C2 infrastructure continued to answer controlled registrations from Poland during the analysis.

How a paid ad becomes an installed payload

The visible application was functional. In the test environment Messenger Pro completed onboarding and displayed a working inbox with message categories, private conversations, spam blocking and an archive. The permission screen carried the message "Your privacy comes first. No unnecessary permissions."
That visible layer produced the permissions the hidden code wanted. When the application was set as the default SMS handler through the ordinary Android interface, the system granted READ_SMS, RECEIVE_SMS, RECEIVE_MMS and SEND_SMS with the GRANTED_BY_ROLE flag. Phone state, call, contact and notification-posting access were granted as well.
Behind that layer, the delivered build carried an encrypted execution chain with four stages:
| Stage | Role | Size |
| --- | --- | --- |
| Base APK | Messenger application and loader | 18,512,332 B |
| Stage 1 | Package and country check | 80,384 B |
| Stage 2 | Payload selection | 21,860 B |
| Default payload | Used by Poland and other allowed MCC values | 174,916 B |
| Selected-country payload | Used for MCC 208 and 460 | 216,724 B |
The loader and the encrypted stage 1 sat inside classes9.dex, which accounted for 0.552% of the base APK's 39,990,208 bytes of DEX code. A single injected call in Application.onCreate() started the loader. The loader rebuilt stage 1 as a byte array and loaded it with InMemoryDexClassLoader; stage 1 decrypted stage 2 the same way; stage 2 downloaded the final DEX from an object-storage bucket and loaded it in memory as well.
Execution began without the user opening the application. On 15 September the Package Manager registered the installation at 12:54:02, and one second later the Android contacts process sent a request to the application's exported Bluetooth Message Access Profile content provider. ActivityManager started the application process to serve that request, which reached Application.onCreate() and the injected loader call.

Why the store listing was the weakest control

The campaign treated the app store as a delivery mechanism rather than a filter. Google Play provided an installation path users consider reviewed, and the default-SMS role provided a system-granted permission set that the hidden code reused for payment abuse.
Applications in the set did not all request the same permissions. Phone Cleaner Master, presented as a utility, did not request READ_SMS, RECEIVE_SMS or SEND_SMS. Its downloaded AqMu payload still contained a general SMS routine, but an application without those permissions would normally be unable to send messages. Browser-based carrier billing, cellular binding and notification handling remained available to it.
The difference matters for defenders who assume a messaging application is the only vehicle. Premium SMS and Direct Carrier Billing are separate paths. The first sends a keyword to a short code and needs SEND_SMS. The second opens a payment page inside a hidden WebView and charges the subscriber through carrier identification, without the application sending an SMS itself. The operator could reuse one payload skeleton and enable only the functions the visible layer supported.

Where ZoomEye fits in this chain

The chain has an internet-facing layer that defenders can inventory: the object storage and rule hosts the loader contacts. The loader download endpoint for Messenger Pro was observed as https://tuonew.oss-me-east-1.aliyuncs.com/aqmu2155, and the rule endpoint as api.tehsnb[.]link/sabd/mckd.
ZoomEye records services, so it can describe the shared storage family the operation rented rather than the operator's private buckets. Queries executed on 24 September 2026 between 05:13 and 05:16 UTC produced the following counts:
| ZoomEye dork | Matching services |
| --- | --- |
| domain="aliyuncs.com" | 1,995 |
| domain="aliyuncs.com" && port="443" | 1,019 |
| domain="aliyuncs.com" && port="80" | 972 |
| domain="oss-me-east-1.aliyuncs.com" | 5 |
| domain="oss-ap-southeast-1.aliyuncs.com" | 44 |
| domain="oss-eu-west-2.aliyuncs.com" | 0 |
Neither number measures victims, installations or confirmed exploitation. The useful reading is architectural: the operation depended on a large commercial storage and rule-hosting layer, and its own endpoints are only reachable through the downloaded code and the C2 that delivers it.
Domain indicators from the campaign are similarly thin on the internet side. Queries for api.appbhwljk.com, ablefee.wiki, tehsnb.link and hsbdbv.link returned 0 matching services, and the addresses used as C2 or fallback returned small counts: 47.84.77.127 returned 2, 47.84.194.202 returned 1, 47.84.193.174 returned 1 and 47.84.57.5 returned 38.

Detection priorities for defenders

The evidence points to a small number of checks that match how this chain actually worked.

  1. Treat the default-SMS role as a privileged grant. Review which applications hold it, and treat a messaging role on a device alongside an unknown signing certificate as a finding.
  2. Look for content providers that start application processes without user interaction. The Bluetooth MAP provider here was the trigger for Application.onCreate().
  3. Review applications that load code with InMemoryDexClassLoader. Remote code loading is the mechanism this campaign used to keep the store-visible portion small.
  4. Inspect outbound traffic from managed devices to cloud object storage and to raw IP addresses over plain HTTP. The C2 here used unencrypted HTTP with a key derived from the URL itself, so transport inspection remains useful.
  5. Verify that the payment paths matter to your population. Premium SMS short codes and carrier billing are regional products; exposure depends on the carrier billing arrangements that exist in the country.

What the evidence does not show

CERT Polska attributes no identity, nationality or location to the operator, and states that reuse of a certificate does not prove that one party controlled every historical server. This article follows that position. The retained ad set is the set the analysts could recover, not the campaign's total output, and profile names are display labels rather than verified identities.
The counts above describe internet-visible services, not affected users, not confirmed victims and not an estimate of installation volume. The task allocation observed during analysis, 41 unique tasks from 50 polls of one controlled profile, describes what the C2 offered to one device and cannot be used to size the victim population.

References

  • CERT Polska, "Fałszywe reklamy i złośliwe aplikacje - analiza operacji toll fraud", published 23 September 2026: https://cert.pl/posts/2026/09/analiza-tollfraud/
  • ZoomEye queries executed 24 September 2026, 05:13-05:16 UTC, against the dorks listed above.

Top comments (0)