Skip to content

Build1 publisher2 min readPublished

Messenger Pro built its real payload in four stages after it cleared Google Play review

CERT Polska found that Messenger Pro cleared Google Play review as a 40MB base APK whose malicious loader was 0.552% of its code. Its real payload never shipped to the store; stage two pulled it from an Alibaba Cloud bucket only after install.

The Engineer · Build desk

Drafted by a language model from the sources cited here and checked against its claim ledger before publication. How we use AISend a correction

Illustration accompanying Messenger Pro built its real payload in four stages after it cleared Google Play review
Generated illustration

What happened

  • Google Play pulled the reference sample, an app called Messenger Pro, after CERT Polska reported it on 15 September 2026.
  • On CERT Polska's test phone the chain killed itself under the default country code 310 and only proceeded once the profile was set to Poland's 260.
  • Stage two downloaded the chosen payload, cached it in the app's private folder so later launches skip the fetch, and loaded the final DEX pointed at a command server at 47.84.77.127.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • constraint Store review inspects the shipped binary, but the capability is decrypted and downloaded only on a targeted device, so passing review is not evidence the install is safe.
  • exposure An analyst running the sample on a device outside the targeted country codes sees it self-terminate, so a sandbox in the wrong region returns a false negative while real victims are served the payload.
  • precedent Because a rule server, not the APK, sets targeting and branch, removing Messenger Pro from Google Play does not stop the operator re-pointing the chain at fresh victims.
  • decision Detection has to move to runtime behaviour, remote class loading and post-install downloads, because none of that exists in the package the store approved.

Start with the loader, because it is almost nothing. One call sits inside the base APK's large Application.onCreate(): OePZg.zbM9Zl8(this), which spawns a background thread and returns. [6] That thread rebuilds an 80,433-byte array from 73 generated methods, producing an authenticated container with a 12-byte nonce, 80,384 bytes of ciphertext and a 32-byte HMAC. [7] Two SHA-256 derivations give an auth key and a stream key, and each ciphertext block is XORed against SHA256(stream_key + nonce + counter). [8] The verified plaintext begins dex\n038\0, a valid DEX, where 038 is the format version and not an app version. [9] All of it lives in classes9.dex, which CERT Polska measured at 0.552% of the base package's 39,990,208 bytes of DEX code. [4][5] That is about 220 KB of loader inside roughly 40 MB of plausible messenger app. [1] CERT Polska's 23 September 2026 report describes four execution stages, and this is only the first. [1]

The decrypted DEX is the first stage that does anything hostile, and the first thing it does is read where the phone is. It continues only when the SIM's mobile country code is on an allow list of 15 countries, among them Thailand, Indonesia, Poland, Germany and China. [10][2]

Then it asks a server what to do. Stage one requests a rule endpoint and receives a plain-text control string, cbhedbgegevddgwv_GUOJIA=460_FR208. [12] CERT Polska is explicit that this is a control string, not executable code and not a decryption key. [13] The tag tells the stage to continue, and the suffix names the country codes routed to the more targeted branch, China 460 and France 208; Poland's 260 is absent, so the Polish run took the default branch. [14]

Stage two picks one of two remote payloads by matching the first three digits of the SIM operator against that list, then downloads a Base64 blob; on the Polish run it was 123,388 bytes and gzip-inflated to a 174,916-byte DEX, which it loaded in memory with an InMemoryDexClassLoader. [15][16][17] The two payload URLs point at Alibaba Cloud OSS buckets in the me-east-1 and eu-west-2 regions. [15] Before handing over control, stage two registers a JobScheduler job for persistence, initialises AppsFlyer and reads the install referrer. [18]

So the reviewed artifact and the harmful one barely overlap. The base package scans as a messenger app; the capability only exists once the DEX is decrypted on a phone in an allowed country and the rule server replies. [9][10][13] CERT Polska reconstructed the full chain from static analysis, captured network traffic and a controlled run on Android 15 with a Polish carrier profile. [19]

What to watch

  • Whether the Alibaba Cloud buckets in me-east-1 and eu-west-2 and the 47.84.77.127 server are taken down now that the store listing is gone.
  • Whether Google Play review begins flagging apps that load remote DEX in memory after install.
  • What the stage-three payload actually does once com.jk.MainEntry.init runs, which this chain analysis does not reach.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories