Back to Blog

AI Malware Analysis: Reasoning Through the Glitch SPY Android RAT

We pointed BackBox AI at a live Android RAT and asked for a full analysis. It unpacked a dropper, decoded an XOR-obfuscated C2 URL straight from smali bytecode, confirmed that the C2 infrastructure was still responding by speaking the malware's own protocol, and attributed the operation. This is what evidence-driven analytical reasoning looks like when it reaches past red teaming.

AI Malware Analysis: Reasoning Through the Glitch SPY Android RAT

Most of what we have published about BackBox AI so far lives on the offensive side: autonomous exploitation, CVE chaining, red team scenarios. Those are the capabilities people expect from an agentic security platform. This write-up is about a different discipline, one that rewards patience and inference rather than a working exploit: malware analysis.

We handed BackBox AI a single Android APK and a broad objective. Perform static and dynamic analysis, extract indicators of compromise, recover the command-and-control (C2) infrastructure, determine whether the command-and-control infrastructure was still operational, and, if the infrastructure was reachable, probe it for attribution evidence. No hints about what the sample was. The interesting part is not the verdict it reached, but how it got there: the hypotheses it formed, the evidence it correlated across very different sources, the moments it changed strategy when a tool failed it, and the way every conclusion was tied back to something it had actually observed.

Starting Cold

The engagement began exactly as an experienced malware analyst would. BackBox AI hashed the sample (SHA256 d439475b..., a 7.1 MB Android package), provisioned its own toolchain (apktool, jadx, apksigner, androguard, and a handful of supporting utilities), created a workspace, and laid out a task plan before touching the code.

Decompilation surfaced the first meaningful signal. The application package was com.brkwl.apkstore, labelled TutajDom, and it was signed with an Android debug certificate (CN=Android Debug). A production app signed with a debug key is already a contradiction worth noting. Reading the code, the agent found a BuildConfig.IMPLANT_PACKAGE reference and a MainActivity built around a PackageInstaller, a notification-driven install handoff, and a routine that repeatedly nudges the user toward the "install from unknown sources" setting.

That was enough to form a hypothesis and act on it:

This is a dropper. The visible application is a shell. The real payload is embedded and installed at runtime.

The agent went looking for the payload and found it in the raw resources, alongside a small but telling artifact: an empty placeholder file named put_your_implant_file_in_this_directory.txt. That file is a fingerprint of a builder, a template where an operator drops in the implant of their choice. The embedded implant.apk (SHA256 80af5e92..., 1.5 MB) was extracted and became the real object of study.

Two APKs, One Purpose

The implant told a very different story from the innocuous shell that carried it. Its package was com.p22d75ef3.pcd6ba814, a machine-generated name, and it was signed with a genuine certificate: CN=Kooooo Release, O=Kooooo. The manifest requested a permission set that reads like a surveillance shopping list: camera, microphone, fine and background location, contacts, call logs, full SMS access including SEND_SMS, and media projection for screen capture.

The component layout confirmed the intent. A persistent C2Service, an accessibility service (A11yService), dedicated capture services for camera, microphone, screen, and location, a notification listener, an SMS receiver registered at priority 999 (the maximum, so it sees messages first), a device-admin receiver, and a BootReceiver for persistence across reboots. A RemoteBrowserActivity stood out in particular, since it lets an operator browse the web from the victim's device and IP address.

A configuration file bundled with the implant, builder_features.json, spelled out the campaign's enabled capabilities directly:

{
  "accounts": true, "apps": true, "audio": true, "browser": true,
  "calllog": true, "camera": true, "clipboard": true, "clipper": true,
  "contacts": true, "crypto": true, "files": true, "keylog": true,
  "location": true, "mic": true, "screen": true, "sms": true,
  "decoy_url": "https://tutaj-dompl.com/", "device_admin_activation": false
}

The decoy_url was the first concrete piece of infrastructure: a Polish-themed rental property site shown to the victim as a distraction while the implant works in the background. With more than 70 remote commands mapped from the Dalvik layer, the agent's classification was unambiguous. This was a full-featured Android remote access trojan, not a piece of adware or a simple stealer.

The C2 That Would Not Decompile

Up to this point, every key finding had come from straightforward decompilation. The C2 address did not. When BackBox AI tried to read the implant's connect() routine, jadx failed to reconstruct it, a common outcome when bytecode is deliberately structured to resist decompilation. A brittle workflow stops here. Instead, the agent treated the failure as information and changed approach.

It first pulled at a thread it already had. The network_security_config.xml embedded in the implant listed two hosts with cleartext traffic explicitly permitted:

<domain includeSubdomains="false">sportypointsrewards.com</domain>
<domain includeSubdomains="false">87.237.53.199</domain>

That was a strong lead, but a lead is not proof, and a static allow-list is not the same as the URL the malware actually dials at runtime. To recover that, the agent abandoned the high-level Java view and dropped down to the smali representation from apktool, where it located a small static initializer in a class named f2. The routine decrypts a character array at load time using a rolling XOR keyed by an integer state:

const v3, -0x3f0011ee      # seed, 0xC0FFEE12 as an unsigned 32-bit value
const v5, -0x61c88647      # 0x9E3779B9, the golden-ratio / TEA constant
shl-int/lit8 v6, v3, 0xd
xor-int/2addr v6, v3
ushr-int/lit8 v3, v3, 0x7
xor-int/2addr v3, v6
xor-int/2addr v3, v5
and-int/lit16 v5, v3, 0x7fff

This is the clearest example in the whole engagement of the agent forming a hypothesis, testing it, and correcting it against the data. It reimplemented the algorithm in Python and ran it. The first attempt produced garbage, a run of CJK characters, because the shift-and-XOR arithmetic had overflowed beyond 32 bits. Rather than discard the model, the agent reasoned about why it had failed. It recognized 0x9E3779B9 as the well-known golden-ratio constant used in the TEA family of ciphers, kept the structure, and constrained every operation to 32-bit wrapping. On the next run the array resolved to clean ASCII:

sportypointsrewards.com

The static allow-list and the decrypted string now agreed with each other, one piece of evidence corroborating the other. The agent then applied the exact same routine, with different parameters, to two more obfuscated arrays elsewhere in the code (M3.m(...)) and recovered the remaining components: the path /ws/agent and the scheme wss. Reassembled, the live C2 endpoint was:

wss://sportypointsrewards[.]com/ws/agent

A WebSocket URL that no decompiler would show, rebuilt from bytecode by understanding the cipher rather than by running the sample.

Is Anyone Home?

Extracting a C2 URL answers what. The objective also asked whether the campaign was still live, and here the agent had a real constraint: the environment had adb but no Android emulator, so a full device detonation was off the table. Instead of reporting that as a dead end, it substituted a more direct test, and was careful to label it as such.

First it characterized the infrastructure. DNS placed sportypointsrewards[.]com behind Cloudflare (chad/dora nameservers, anycast addresses 188.114.96.7 and 188.114.97.7). The origin IP from the network config, 87.237.53[.]199, refused to answer: a full TCP scan of ports 1 to 1000 timed out with nothing open. The agent did not simply record "host down." It reasoned about the two competing explanations, a decommissioned server versus an origin firewalled to accept traffic only from Cloudflare, and leaned toward the latter, which is exactly how a defended C2 origin behaves.

The front door, on the other hand, was very much open. Fetching the site returned an HTTP 200 response exposing a web panel branded Glitch SPY, with sections for Agents, Viewer, Builder, Cryptor, Dropper, and Payloads. More usefully, the panel's client-side JavaScript (panel.js, roughly 377 KB) was served without authentication, so the agent mapped the entire back-end API surface from it: the /api/agents/ roster, APK build and download endpoints, a multi-step MFA flow, a Telegram notification hook, a dual /c2/ routing prefix, and both the /ws/agent and /ws/admin sockets.

Then came the decisive move. To confirm the campaign was truly operational, the agent did not need the panel; it implemented the malware's registration protocol. It opened a WebSocket to the agent endpoint, unauthenticated, and sent the same registration handshake the implant sends:

-> {"kind":"hello","agent_id":"ANDROID_PROBE001","payload":{"os":"Android","model":"TestDevice","version":"13"}}
<- {"agent_id":"ANDROID_PROBE001","kind":"hello_ack"}

The server acknowledged and registered the fabricated agent. That single exchange confirmed that the C2 endpoint was operational and responding as of the analysis date. The agent then listened for 30 seconds, received no tasking, and drew a measured inference rather than an overreach. Commands are operator-initiated, not automatically pushed, which is why a planted agent sits idle. It had, in effect, performed the one piece of dynamic behavior that mattered, without ever running the malware.

Probing Without Breaking In

With the scope allowing analysis of reachable infrastructure, the agent turned to the panel itself. This is where an offensive reflex could have wasted the entire engagement, and where restraint was the smarter play. It catalogued four real weaknesses: the unauthenticated agent WebSocket, the fully exposed panel source, a wildcard CORS policy on the API (Access-Control-Allow-Origin: *), and no rate limiting on the login endpoint.

It also tried the obvious authentication guesses. Every one returned 401, and the login flow was gated behind multi-factor authentication. Instead of grinding on a brute-force path with no realistic prospect of success, the agent stopped, recorded that the panel was not breachable with the available evidence, and drew a distinction that matters for severity: the exposed endpoints and the fake-agent registration affect the operator's console, not the devices of existing victims, whose data stayed behind the authenticated API. That separation of victim impact from operator impact shaped the risk ratings that followed.

Connecting the Dots

Attribution is where evidence from unrelated sources has to be woven together, and it is the part of the analysis most prone to overconfidence. The agent had one strong internal signal, the implant's signing certificate, CN=Kooooo Release, O=Kooooo. It corroborated it against the outside world.

Open-source threat intelligence independently identified the same malware family and the infrastructure independently: a published Cyble report described Glitch SPY as a RAT distributed through fake Polish rental apps, named sportypointsrewards[.]com as the C2, and even documented a second operator panel at gich.etherraffleexchange[.]us. The agent checked that second panel directly and found it returning HTTP 530, a Cloudflare error indicating the origin was offline, consistent with a rotated or abandoned node. It also located a GitHub account, github.com/kooooo, whose handle matched the signing identity, although this alone should not be considered attribution.

Crucially, the agent did not inflate this into a confident unmasking. It settled on medium confidence, and justified the ceiling with specific reasoning: the signing certificate is direct, artifact-level evidence, but the sample is builder-generated (the builder version string 4.20260607_170032 suggests a semi-commercial product), which means the same certificate and the "Kooooo" identity could be shared across multiple operators. The evidence tied the build artifacts to the "Kooooo" signing identity; it could not, on its own, separate the developer of the tool from whoever was running this particular campaign. Explicitly acknowledging that uncertainty is a hallmark of sound analytical reasoning.

Calibrated by an Expert, Not Just Asserted

Before finalizing, the agent submitted its findings to a malware-analysis expert review to filter false positives and calibrate severity, and then it acted on the feedback rather than defending its first draft.

The core finding held: the Glitch SPY RAT was assessed to pose a Critical threat, its impact anchored to the accessibility-service abuse that lets the implant reach beyond its own sandbox and take over the whole device. We describe that severity deliberately in qualitative, capability terms rather than as a CVSS score. CVSS is defined by its own specification to rate the characteristics of a vulnerability, a weakness in a system, and a piece of malware is not a vulnerability; it is a threat that abuses one, or abuses the user. The natural home for a numeric vector here is the operator-side weaknesses of the C2 panel, not the trojan itself, and the family is better characterized by its capabilities and its mapped ATT&CK techniques than by a single number. Elsewhere the agent revised downward. The unauthenticated WebSocket was reduced from medium toward low, on the reasoning that a fake agent cannot read victim data or command other agents; its value is reconnaissance and nuisance, not compromise. Two candidate indicators were discarded as noise rather than clung to: the shared Cloudflare anycast IPs and the site's Let's Encrypt certificate. The firewalled origin IP was retained, but annotated for what it most likely is. And the agent recorded, plainly, what it had not covered: the native agent_core library, any Telegram bot token, and full device-based detonation remain open work.

That willingness to downgrade its own findings and enumerate its own blind spots is, for a malware report, as important as anything it discovered.

The Evidence, Collected

Analysis summary

Field Detail
Malware family Glitch SPY (Android RAT)
Delivery Dropper (com.brkwl.apkstore, TutajDom) installing an embedded implant
Implant package com.p22d75ef3.pcd6ba814
Capabilities Screen, camera, mic, location, SMS, contacts, call logs, keylog, clipper, remote browser (more than 70 commands)
Live C2 wss://sportypointsrewards[.]com/ws/agent (confirmed responsive)
Decoy Polish rental-property site at tutaj-dompl[.]com
Attribution Signing identity "Kooooo" (medium confidence)
Threat level Critical: capable of full device compromise
Analysis date 8 July 2026

Key indicators of compromise

Type Value
C2 URL wss://sportypointsrewards[.]com/ws/agent
C2 domain sportypointsrewards[.]com
C2 origin IP 87.237.53[.]199 (firewalled behind Cloudflare)
Second panel gich.etherraffleexchange[.]us (offline, HTTP 530)
Decoy URL https://tutaj-dompl[.]com/
Dropper SHA256 d439475bf09af7b474cdba2c19e136a1dd38e62b088537445ac3c8e4c2d3a8b1
Implant SHA256 80af5e921cf8a3052fe4483bb2eb15953590e72ed003ac61c0b9135575c32075
Implant cert SHA256 8e680f86bbca985104039dad318456f974aaff3667a3e805d23e492eaed7545a

Two artifacts from the analysis also make durable detection signatures: the deobfuscation constants in the f2 class (the seed 0xC0FFEE12 combined with the TEA constant 0x9E3779B9) and the structure of the builder_features.json file. Both survive a change of C2 domain or package name, which is what makes them worth writing rules against.

The Reasoning That Made the Difference

Strip away the specifics and the shape of this analysis is the point. Four behaviors recur throughout, and they are the same four we care about most.

  • It formed hypotheses and verified them. "This is a dropper" led to extracting the payload. A guessed cipher model produced garbage, was diagnosed as a 32-bit overflow, and was corrected into a clean decode. "The campaign is live" was proven by an actual protocol handshake, not assumed.
  • It correlated evidence across sources. A static network-config allow-list, an XOR-encrypted bytecode string, two more obfuscated arrays, a live server response, a signing certificate, a public threat report, and a GitHub handle were pulled from entirely different places and made to agree before anything was concluded.
  • It adapted when a strategy failed. A decompiler that choked sent it to smali. A missing emulator sent it to direct protocol emulation. A locked panel sent it from breaking in to mapping the API from exposed source. Each dead end became a detour, not a stop.
  • It justified its conclusions with data, and bounded them. Live because of hello_ack. The malware was assessed as Critical because its observed capability set, screen, microphone, SMS, and full accessibility takeover, adds up to complete device compromise. Attribution capped at medium because a shared builder certificate cannot, by itself, tell the developer from the operator.

Red teaming asks a system to find a way in. Malware analysis asks it to reconstruct intent from fragments, to hold competing explanations open until the evidence closes them, and to say clearly where the evidence runs out. This engagement did all of that end to end, and left behind a report whose conclusions are supported by directly observed evidence. That traceable chain of reasoning, not any single indicator, is the capability we set out to demonstrate.

If you work in threat intelligence or incident response and want a second analyst that reasons in the open, get in touch.