Attackers ran 1.8 million Android APKs through Claude to strip out hardcoded secrets

Multiple threat groups used Claude to automate credential extraction from 1.8 million Android apps. The capability isn't new, but the cost just collapsed—and everything you deferred because 'nobody would bother' just moved into range.

The secret was already in the app. That’s the part everyone skips past.

Per a disclosure Anthropic published and BleepingComputer wrote up today, multiple threat groups — financially motivated actors plus state-sponsored espionage teams the report links to Russia and China — used Claude to analyze roughly 1.8 million Android APKs and pull out hardcoded credentials at scale. API keys. OAuth tokens. Cloud access keys. The kind of thing that should never ship inside a client binary but does, constantly, because a developer needed the app to talk to a backend and took the shortcut.

So here’s the reframing that matters before you panic: no model handed anyone a capability they didn’t already have. Static secret extraction from APKs is a solved problem. apktool, jadx, truffleHog, gitleaks — pick your poison, they’ve been finding this stuff for years. What changed is cost, throughput, and the fact that the tedious glue between steps got automated by something that doesn’t get bored at APK number 40,000.

I ran this past a colleague who spends his days doing app-sec teardown, and he was not impressed. Fair. Let me give him the floor, because his objections are the right ones.

“You’re telling me this is news? I can grep an APK.”

Him: “Regex over a decompiled APK finds AWS keys and Google API keys in an afternoon. Every red teamer has done it. Why is ‘someone used an LLM to do the thing a shell loop already does’ a headline?”

Me: He’s right about the mechanics and wrong about what to worry about. A regex over an unpacked APK is high recall, high noise. You get a wall of matches: half are real keys, half are truncated JWTs in test fixtures, placeholder strings, and base64 that happens to look like a token. Someone still has to triage that. The value an LLM adds isn’t detection — it’s the triage and the context. Feed it the decompiled class and it’ll tell you whether a string is a live Google Maps key, a Firebase config, an OAuth client secret that pairs with a redirect you can abuse, or just noise. It stitches the “is this exploitable, and against what” step to the “did we find a string that looks like a secret” step. That’s the tedious human part, and it’s the part that scales badly. Now it doesn’t.

Him: “So it’s a triage engine. That’s an efficiency story, not a security story.”

Me: Efficiency is the security story when you’re talking about 1.8 million apps. The threat model for a hardcoded key used to include an implicit assumption — that nobody would bother mining every app in a store to find yours. That assumption is dead. When the marginal cost of analyzing one more APK drops toward zero, the long tail of small apps with sloppy secret handling stops being safe by obscurity. Your niche B2B app with 4,000 installs and an unrotated backend key is now in the same haystack as everyone else, and the needle-finding is automated.

“Fine. But how solid is the Russia-and-China attribution?”

Him: “Every vendor report links everything to Russia and China. What’s the actual evidence here versus what’s marketing?”

Me: This is where I hedge, and you should too. The attribution comes from Anthropic’s own vantage point — account behavior, usage patterns, infrastructure and tradecraft they can see because the activity ran through their platform. That’s a genuinely useful telemetry position; it’s also a single-source position. Anthropic can see what accounts asked Claude to do. They cannot independently confirm who was behind the keyboard the way a full intelligence workup would. Treat “linked to Russia and China” as the vendor’s assessment with the confidence they assigned it, not as courtroom fact. What’s not in dispute and matters more operationally: financially motivated actors were doing this too, and financially motivated actors don’t need a nation-state budget. That’s the population most of us actually defend against.

What was actually harvested

The disclosure describes the loot as hardcoded credentials and tokens embedded in the app binaries — API keys for cloud and third-party services, OAuth tokens, and access credentials that let the holder impersonate the app to its backend. The mechanism is dull and effective:

  1. Acquire APKs in bulk. App stores and mirror sites make this trivial; nobody’s hacking anything to get the binaries.
  2. Decompile to recover strings, resource files, and class definitions.
  3. Use the model to identify and classify embedded secrets, filtering noise and flagging what’s live and what it unlocks.
  4. Take the validated credentials off-platform and use them against the real backends.

None of this required jailbreaking Claude into writing malware. That’s the detail people miss. The offensive step — “look at this code and tell me what these strings are” — reads like legitimate reverse-engineering or security research right up until you see it running against two million apps that don’t belong to you. The abuse lives in the scale and intent, not in any single request. Which is exactly why it’s hard to catch, and exactly how Anthropic caught it: by spotting the pattern of usage across accounts, not by blocking one nasty prompt.

Audit your own exposure first

If you ship an Android app, your first move isn’t monitoring — it’s finding out whether you’re already in that haystack. Pull your own APK and scan it the way an attacker would. Report mode, no changes:

run.shbash — zsh
#!/usr/bin/env bash
# Dry-run: decompile an APK and scan for hardcoded secrets.
# Requires: apktool, gitleaks (or trufflehog). Read-only.
set -euo pipefail
​
APK="${1:?usage: scan-apk.sh path/to/app.apk}"
WORKDIR="$(mktemp -d)"
echo "[*] Decompiling $APK -> $WORKDIR"
​
apktool d -f -o "$WORKDIR/src" "$APK" >/dev/null
​
echo "[*] Scanning decompiled sources for secrets (report only)"
gitleaks detect \
  --source "$WORKDIR/src" \
  --no-git \
  --report-format json \
  --report-path "./$(basename "$APK").secrets.json" \
  --verbose || true
​
echo "[*] Quick grep for common key formats as a sanity check"
grep -rInE \
  'AIza[0-9A-Za-z_-]{35}|AKIA[0-9A-Z]{16}|ya29\.[0-9A-Za-z_-]+|eyJ[A-Za-z0-9_-]+\.' \
  "$WORKDIR/src" | head -n 50 || true
​
echo "[*] Findings written. Nothing was modified or transmitted."
echo "[*] Cleanup: rm -rf $WORKDIR"

If that returns anything real, the key is already compromised. Assume it. Rotate before you do anything else — the extracted-secret population is presumably already circulating.

On the identity side, any long-lived credential that could have leaked in a client needs an owner and a rotation clock. If you use Entra ID app registrations for backend auth, enumerate the ones with client secrets and how old they are:

audit.ps1PowerShell
# Report-only: list app registration secrets and their age.
# Rotate anything that could have shipped in a client binary.
Connect-MgGraph -Scopes "Application.Read.All" -NoWelcome
​
Get-MgApplication -All |
    ForEach-Object {
        $app = $_
        foreach ($cred in $app.PasswordCredentials) {
            [pscustomobject]@{
                AppName       = $app.DisplayName
                AppId         = $app.AppId
                KeyId         = $cred.KeyId
                Created       = $cred.StartDateTime
                Expires       = $cred.EndDateTime
                AgeDays       = [int]((Get-Date) - $cred.StartDateTime).TotalDays
                RotateNow     = ((Get-Date) - $cred.StartDateTime).TotalDays -gt 180
            }
        }
    } |
    Sort-Object AgeDays -Descending |
    Format-Table -AutoSize

The developer fix is boring and non-negotiable

Stop shipping secrets in the binary. There’s no clever obfuscation that survives contact with a decompiler and a patient model — string encryption, ProGuard, native .so stashing all buy you minutes, not safety. The actual controls:

  • Move the secret server-side. The app authenticates the user; a backend you control holds the third-party keys and proxies the call. The client never sees the credential.
  • Short-lived, scoped tokens minted per session, not static keys with a five-year life.
  • Secret scanning in CI — gitleaks or trufflehog as a build gate, plus a scan of the assembled APK, so nothing merges with a key baked in.
  • Restrict the keys you can’t fully hide. Maps and similar client keys should carry API restrictions, package-name and signing-cert allowlists, and quotas — so an extracted key is far less useful off your app.

What the SOC can actually watch for

You won’t catch this by blocking prompts. The tell is bulk, automated model use paired with data movement — decompiled code going up, structured findings coming back, repeatedly. On managed endpoints, hunt for programmatic egress to AI API endpoints that isn’t tied to a sanctioned integration:

query.sqlSQL
// Defender Advanced Hunting: non-browser processes talking to LLM APIs.
// Tune the domain list and baseline your approved automation first.
DeviceNetworkEvents
| where Timestamp > ago(7d)
| where RemoteUrl has_any (
    "api.anthropic.com", "api.openai.com", "generativelanguage.googleapis.com")
| where InitiatingProcessFileName !in~ ("chrome.exe","msedge.exe","firefox.exe")
| summarize Connections = count(),
            Endpoints = make_set(RemoteUrl, 10),
            FirstSeen = min(Timestamp), LastSeen = max(Timestamp)
        by DeviceName, InitiatingProcessFileName, InitiatingProcessAccountName
| where Connections > 100
| order by Connections desc

Pair that with DLP on outbound prompt content and a policy in Defender for Cloud Apps that flags unsanctioned generative-AI use. The goal isn’t to ban the tools — half your engineers are already using them. It’s to know when a workstation or service account is pushing thousands of code payloads to a model on a schedule, because that’s not someone asking for help with a bug.

What to do this week versus what can wait

Immediate, if you ship Android apps: scan your own binaries and rotate anything you find. Extracted keys don’t wait for your patch cycle. There’s no CVE and no vendor patch here — the fix is your own hygiene, which means the clock is entirely yours to start.

This cycle, for the SOC: baseline sanctioned AI usage and stand up detection for bulk, programmatic access. You want the visibility in place before the next crew industrializes something you haven’t thought of.

The lesson isn’t that AI made attackers powerful. It’s that AI made the boring, expensive, manual work of mass exploitation cheap — and everything you deferred because “nobody would bother” just moved into range.