Why the APK itself can get flagged
Google Play Protect (on install) or a third‑party antivirus app (scanning the file) may warn about this APK. Three real, verifiable properties of the app explain why, independent of anything it's actually doing on your device:
| Property | Why it reads as risky to a heuristic |
|---|---|
| Not on the Play Store | Sideloaded APKs skip Google's app‑review pipeline entirely — Play Protect's baseline warning for any unrecognized installer source, not a detection of this app specifically. |
| Self‑signed release cert | No certificate authority vouches for the signer's identity — standard for internal/lab tooling, but indistinguishable from an unknown or spoofed developer at the manifest level. |
QUERY_ALL_PACKAGES | Lets the app enumerate every installed app on the device — the installed‑app‑inventory collector's actual purpose, and also one of the most common permissions in real stalkerware, since AV heuristics can't tell "inventories apps for a security dashboard" from "inventories apps to report to a stalker" apart from intent. |
BIND_NOTIFICATION_LISTENER_SERVICE | Grants access to every notification the device receives, from every app — needed for the opt‑in notification‑metadata collector, and one of the single most heavily‑weighted permissions in mobile spyware heuristics industry‑wide. |
android.permission.READ_LOGS | Requested for an optional full‑device‑logcat collector, but Android only ever grants this out‑of‑band via adb shell pm grant — a normal install can't activate it. Still visible to any manifest‑scanning tool as a declared "read other apps' logs" permission. |
The bundled YARA ruleset's own literal strings
Distinct from the permission-shape reasoning above, the full build's on‑device YARA scanner ships with a small starter ruleset (assets/yara_rules/android_starter.yar) containing signature strings written to match real offensive‑security tooling — frida-gadget, com.metasploit.stage, and the industry‑standard EICAR-STANDARD-ANTIVIRUS-TEST-FILE test string. A string‑matching antivirus or EDR scanning the APK's own files can flag those literal bytes, independent of every permission this app declares.
This one has an actual fix rather than just an explanation: the lite build on the download page ships without that asset at all — not a disabled feature still sitting in the file, the file itself isn't packaged. Same app otherwise (same permissions, same collectors apart from YARA, same enrollment and transport). If an AV/EDR product is specifically flagging the APK file rather than warning generically about an unsigned sideload, try the lite build before assuming anything else is wrong.
Confirming you installed the real, unmodified build
Rather than overriding a warning on faith, or assuming a flagged file is compromised, check the file itself against what was actually published:
- Compare the SHA‑256 checksum on the download page against the file you have (
sha256sum WazuhMobileAgent-release.apkon desktop, or any file‑hash app on the phone). A mismatch means you don't have the file this project actually published — stop and re‑download from a trusted copy of this link. - Read the source that produced it. Every line is on the source page — there's no closed binary to take on faith; the collectors, the permissions' actual usage, and the network code are all inspectable.
- A checksum match plus matching source is the actual resolution — not "my antivirus said it's fine" (heuristic engines vary and can both over‑ and under‑flag the same file) and not "I'll just tap install anyway" without checking anything (defeats the point of the warning existing).
The app's own YARA scanner can produce alarming‑looking names
Separately from the APK itself, the app's on‑device YARA scanning feature checks other newly installed apps against a small bundled ruleset — and reports matches to Wazuh as yara_match events. Two of those bundled rules are deliberately named after real offensive‑security tools, which can look like a live compromise in a Wazuh dashboard if you don't already know what they check for:
| Rule name | Severity | What actually triggers it |
|---|---|---|
| EICAR_Test_String_Present | info | The industry‑standard antivirus self‑test string. Explicitly not malware — its only purpose is proving the scan → alert pipeline fires end to end. Wazuh rule 100107 deliberately alerts below its parent rule for exactly this reason. |
| Bundles_Frida_Instrumentation_Toolkit | medium | Any APK bundling Frida gadget/agent artifacts — real for reverse‑engineering and dynamic‑instrumentation tooling, and also common in legitimately repackaged debug/test builds of your own apps during development. Only a real compromise indicator on a production app that has no reason to ship Frida. |
| Metasploit_Android_Meterpreter_Stager | high | The literal default package name msfvenom uses for Android Meterpreter payloads. Very low false‑positive rate in practice — but on a phone used for authorized penetration‑testing work, an intentionally installed test payload will also match, correctly. |
| Bundles_Root_Su_Binary_Paths | low | Hardcoded su/Magisk paths — normal and expected for any legitimate root‑management app (Magisk itself, root file managers), not inherently a sign of anything hostile. |
data.package_name in the alert) and whether that app has an obvious legitimate reason to contain the matched string, the same way you'd triage any other YARA/AV hit.What to actually do about a flag
- Play Protect blocked the install: expected for any self‑signed, non‑Play‑Store APK. Verify the checksum first, then choose "Install anyway" if it matches.
- A third‑party antivirus app flags the installed APK: verify the matching checksum on the download page first. If the flag specifically names a string/signature match rather than a generic "unknown app" warning, try the lite build — it removes the bundled YARA ruleset's literal signature strings entirely, the most likely cause of a content‑based (not permission‑based) detection.
- A
yara_matchalert shows up in Wazuh: checkdata.rule_nameagainst the table above anddata.package_namefor which app triggered it — most hits on a device you control will have an obvious benign explanation (your own dev tooling, an intentional pentest payload, the EICAR self‑test). Treat an unexplained hit on an app you don't recognize as the real signal, not the rule firing itself.