Five campaigns, one mechanism: pre-trust
Over 31 days, five campaigns ran on the same primitive — a credential, a workflow, a certificate or an app consent the target had already accepted. Not one of them had to defeat an authentication check.
What happened
The window is 2026-09-23 to 2026-10-23, 31 days. A corpus of roughly 2,550 rows resolved to 1,715 incident-grade news reports, 481 ransomware victim claims across 30 countries, and 33 newly exploited CVEs added to CISA KEV. Multi-outlet coverage of the same event inflates the news count, which is why the survey's own estimate of distinct incidents is 1,000 to 1,300 rather than 1,700.
The outcomes were ordinary: 365 data-breach incidents, 155 ransomware, 111 exploited vulnerabilities, 90 malware, 80 supply chain, 71 phishing or BEC, 69 cloud and identity. The tempo was not — incident headlines went from 141 in ISO week 39 to 523 in week 43.
Two patterns sit outside the cluster and still matter. Exploitation now starts before disclosure: PHP2Shell's two PHP flaws — CVE-2026-109618 and CVE-2026-109619, CVSS 9.2 — were probed four days before publication, and Citrix NetScaler's flaws were exploited weeks before Citrix disclosed them. And 229 of the month's incident headlines mention AI, agents or models.
The five campaigns
Five campaigns ran inside those 31 days and share something more specific than a theme.
LiteLLM 1.107.0 — the release pipeline
GitHub CLI OAuth tokens belonging to three engineers were used to run the project's own release workflow against a lookalike repository, Berri-AI/litellm instead of BerriAI/litellm, so the poisoned artefacts were signed and published by the project's automation. The package carried a .pth startup hook that ran a credential stealer before the library was imported, and a sitecustomize.py daemon polling a GitHub dead drop hourly. PyPI quarantined it in about two hours. Stolen AWS instance-role credentials were validated roughly four and a half hours later and probed for Bedrock model capacity.
GhostAction — the maintainer account
Hijacked maintainer credentials pushed security-audit.yml into 94 repositories in the first wave and more than 340 in the second. The workflow dumped the repositories' named secrets, scanned the working tree and the entire git history for 13 credential patterns, and posted the results to a hard-coded IP address over plain HTTP. 3,325 secrets left, and as of publication none of the publishing tokens had been used.
eMudhra / emSign — the certificate authority
Eight intermediate CA private keys were found recoverable, one of them brute-forceable to the integer 4, after a flaw in an April 2025 key ceremony left weak key material. An intermediate key signs the certificates websites present, so a holder could mint a certificate for any domain that unpatched clients would accept. Mozilla and Chrome blocked all eight within hours (CVE-2026-111943); Go shipped on its URGENT track; Linux and Python trust stores do not process revocation at all, so the blocks had to go into code. The root above them, emSign ECC Root CA - G3, was removed from the Mozilla, Chrome and Go bundles outright — so anything chaining to it stops validating, on each client's own schedule, whether or not it touched a compromised intermediate.
EvilTokens — the device-authorisation flow
A phishing-as-a-service platform, $1,500 to join and $500 a month, launched in February 2026 and taken down in September. Its takeover primitive was the OAuth device-authorisation flow: the attacker started a legitimate device login and phished the code, so the victim authorised the attacker's session. No password was typed into a phishing page, and the session survived password resets. More than 12,000 inboxes across more than 10,000 organisations.
ConnectWise Cloud Backup — the consented application
Stolen application identities for a backup product were used to authenticate into customer Microsoft 365 tenants. Because customers had already granted those applications permissions — Microsoft cited Directory.ReadWrite.All — interactive sign-in and MFA never applied. Microsoft attributed the campaign to Storm-0940 and described agents attempting sign-ins to more than 2,250 tenants at 2,900 attempts per minute, then granting themselves Global Administrator and planting new secrets in other applications for persistence that outlives the original credential.
| Campaign | What was already trusted | The decisive act | Signal |
|---|---|---|---|
| LiteLLM 1.107.0 | The release pipeline and the OAuth tokens driving it | The workflow was run against a lookalike repository, so the project signed and published a poisoned release | SUSPICIOUS_PACKAGE_RELEASE → LLM_JACKING_ACTIVITY |
| GhostAction | A maintainer account, and a workflow job with secrets in context | A security-audit workflow pushed into 94 then 340-plus repositories, dumping secrets and mining full git history | CI_WORKFLOW_TAMPER → SECRET_LEAKED |
| eMudhra / emSign | A public CA intermediate every unpatched client trusted | Eight intermediate keys turned out to be recoverable, one brute-forceable to the integer 4 | CERTIFICATE_TRUST_COMPROMISED |
| EvilTokens | The OAuth device-authorisation flow and the session it issues | The attacker started a legitimate device login and phished the code, so the victim authorised the attacker's session | IDENTITY_ANOMALY + ACCESS_ANOMALY on one identity |
| ConnectWise Cloud Backup | A third-party application customers had already consented to | Stolen app identities authenticated into 2,250-plus tenants; MFA never applied because the app was already trusted | IDENTITY_ANOMALY / BOUNDARY_VIOLATED |
Read that last column as a list of things nobody had to steal. Four of the five campaigns never cracked a password, and none of them exploited a vulnerability in the target's own code.
The mechanism
The shared mechanism is pre-trust: an identity, artefact or permission the target had already accepted, used against it. The publisher token was legitimate. The workflow had secrets in context because it was supposed to. The intermediate key signed real chains. The device code was authorised by the victim. The application was already consented to.
Pre-trust defeats the checks that normally carry the load. Provenance and signatures prove who published an artefact, not that they meant you no harm. A padlock proves a chain is valid, not that the key behind it was ever safe. An MFA prompt never fires when a pre-authorised application authenticates on your behalf. And a workflow that reads every secret in a repository is doing what workflows are for — until you look at where the output went.
That is why the join matters more than any single detection in this class. Each campaign produces events that are individually unremarkable: a package release, a workflow commit, a certificate reissue, a sign-in from a trusted app. The escalation is the join — release and credential use, workflow and secret, session and privilege change — and the join is also what a per-tool scanner cannot do, because the two halves arrive from two different systems.
Two conditions made the month worse. Attack labour got cheaper: an agentic framework drove reconnaissance, password spraying and OAuth abuse at a pace no human team runs, and a separate campaign ran autonomous agents against more than 1,200 websites for about $5,000 of tokens — roughly $50 per successful hack. And the gap between artefact and advisory collapsed: a poisoned package can be quarantined in two hours, while PHP2Shell was under attack four days before its own disclosure.
What we would have seen
Four signal types carry the cluster, and four tier-1 rules turn them into incidents: CI_WORKFLOW_TAMPER (RULE-T1-016), SUSPICIOUS_PACKAGE_RELEASE (RULE-T1-017), LLM_JACKING_ACTIVITY (RULE-T1-018) and CERTIFICATE_TRUST_COMPROMISED (RULE-T1-019). All four sit in the existing architecture: engines emit typed signals, correlation compounds risk, and no model touches the detection or scoring path.
The chains convert them. RULE-T2-014 joins a workflow tamper to a secret that becomes readable or an exfiltration attempt — the GhostAction end state, scoped to the secrets that workflow could reach. RULE-T2-015 joins a suspicious or malicious release to the LLMjacking sequence, which is the difference between a package you should stop using and an incident on your cloud account. Neither rule fires on half a chain, which is what keeps the queue readable: 75 correlation rules across two tiers, over 166 typed signals. For the identity campaigns the join is the entity itself — correlation, not more coverage, is the scarce thing.
What is not covered yet
The survey's coverage map names the gaps, and they belong on the page rather than in a roadmap document.
- Registry policy drift: trusted publishing that binds a package to a repository name rather than an immutable ID can be inherited by claiming an abandoned slug. The npm flaw affected more than 1,500 packages with more than 10 million downloads; the configuration itself is not yet alerted on.
- Device-code grant anomalies, application-credential planting and tenant-wide role grants: the EvilTokens primitive and the ConnectWise persistence step are visible through identity and access anomalies, not as their own signal.
- Supplier-access baselines: bulk lookup volume and off-hours access at a vendor are not modelled. The Danish CPR register was searched 14 million times over ten days before anyone noticed.
- OT device posture: the French supermarket attack manipulated refrigeration controllers to heat units to 50 degrees Celsius, and there is no signal for a temperature setpoint.
What to do
Ordered by what reduces exposure first. The first two are days of work; the rest change how the estate is trusted.
- 01
Inventory what is pre-trusted, before an incident
Applications consented in your tenant and the permissions they hold, publish tokens and OAuth grants for your packages, workflows with secrets in context, certificates chaining to public CAs, device-code grants. This list is the attack surface for the class, and it makes the next step possible.
- 02
Treat exposed credentials as current
Rotate from a clean host, then read what the credential did. The LiteLLM sequence —
sts:GetCallerIdentity, thenbedrock:ListFoundationModels, then inference — is a template: validation, discovery, use. - 03
Query the history you already have
The full git history for the 13 credential patterns the campaign used, sign-in records for first-ever application sign-ins, and certificate transparency logs for issuance against your domains after the eMudhra block.
- 04
Close the two structural gaps in the pipeline
Pin releases by digest and require provenance before publication, and gate workflow changes in the pull request, where the cheap fix still exists. The CI/CD gate runs the same workflow analyser the scheduled scan does.
- 05
Reissue what chains to the compromised hierarchy, then test rejection
A reissue is not the fix on its own. A client that never received the block — a Linux image, a Python application using
certifi— will keep accepting the old chain.
Questions this survey raises
What do the five campaigns actually share?
The news count is inflated by duplicate coverage. Why publish it at all?
Which parts can Hanu detect today, and which can't it?
Is the AI part of this a new detection problem?
Run it in your own account
One Docker Compose stack, your datastores, read-only credentials into your clouds. The Community edition is free to run in production.