In early June 2026, an intruder Microsoft tracks as Storm-3168 — the same cluster Sysdig documented as the agentic ransomware operation JADEPUFFER — used two Azure service-principal credentials that an employee had leaked in a public GitHub issue to enumerate and then destroy cloud resources inside a customer's tenant. Over roughly 18 hours the first identity ran 300+ read operations; a second identity attempted 150+ destructive or credential-collection actions, including over 100 Storage Account deletions, in a 35-minute burst.
What makes this campaign notable is not a new CVE but the tradecraft: the operator behaved like an autonomous agent, self-narrating its decisions in code comments and correcting failed steps within 31 seconds. The initial JADEPUFFER intrusions reached victims through CVE-2025-3248, an unauthenticated RCE in Langflow. This brief maps the full kill chain, the Entra sign-in and Azure activity-log artifacts, and copy-pasteable KQL and SPL hunts.
◈ Table of Contents
01 · Threat Actor Profile
AttributionStorm-3168 is a Microsoft designation for an emerging, not-yet-fully-attributed activity cluster. Microsoft links the Azure destruction activity to JADEPUFFER, the actor Sysdig first documented in July 2026 running fully automated, LLM-driven ransomware against internet-exposed applications. The profile below consolidates what both vendors have published.
| Attribute | Detail |
|---|---|
| Microsoft designation | Storm-3168 (temporary "Storm" cluster ID — attribution not finalized) |
| Vendor aliases | JADEPUFFER (Sysdig) |
| First observed | July 2026 (Sysdig — Langflow database-extortion campaign) |
| Azure incident | Early June 2026 — ~18-hour destructive operation |
| Motivation | Financially motivated; destruction/extortion aligned |
| Signature tradecraft | Agentic / LLM-driven automation; self-narrating payloads; sub-minute error correction |
| Targeting | Internet-facing AI/dev tooling (Langflow, Nacos); cloud tenants reachable via leaked identities |
| Observed toolset | ENCFORGE (Go ransomware); Base64 Python payloads; python-requests ARM client |
A "Storm-####" label is Microsoft's marker for a cluster in development — treat attribution as provisional. Pivot your hunting on the observed behaviours and IOCs, not on any assumed nation-state or crime-group identity.
02 · Intrusion Timeline
Sequence- 1Pre-incident: An employee of the impacted organization pastes a service principal's client ID, client secret and tenant ID in plaintext into a public GitHub issue. The values are later edited out but remain in the issue's edit history.
- 2Hour 0: The first service principal authenticates and begins reconnaissance — 300+ successful read operations across virtual machines, subscriptions and resource groups over roughly 15.5 hours.
- 3~Hour 16: A second service principal in the same tenant enumerates VMs and resource groups across two subscriptions in about 5 seconds, then reads App Service configuration stores hunting for further credentials.
- 4Destruction window: Within a 35-minute window the second identity attempts 150+ destructive or credential-collection actions — including 100+ Storage Account deletion attempts concentrated into roughly 7 minutes.
- 5Post-destruction: 30+ successful
ListKeysrequests against remaining storage accounts, focused on Azure Site Recovery-related storage. - 6After: Microsoft observed repeated probing of Azure App Service configuration endpoints across multiple customers, indicating the operator continued scanning for exposed secrets.
03 · Initial Access
Two vectorsThe campaign has two distinct entry stories. The Azure destruction relied on leaked identity material; the earlier JADEPUFFER ransomware intrusions relied on an unauthenticated RCE. Both are worth understanding because they represent the same operator adapting to whatever door is open.
| CVE | Product | Type | CVSS | Fixed in |
|---|---|---|---|---|
| CVE-2025-3248 | Langflow | Missing-auth code injection (/api/v1/validate/code) | 9.8 | 1.3.0 |
| CVE-2021-29441 | Alibaba Nacos | Auth bypass via User-Agent backdoor | 9.8 | 1.4.1 |
No exploit was needed for the Azure tenant. The operator authenticated with a service principal whose secret was published to a public GitHub issue. Editing the secret out of the issue body did not revoke it — the credential stayed valid and remained visible in the issue's edit history until it was actually rotated.
Deleting a secret from a GitHub comment, commit, or issue does NOT invalidate it. Git and issue edit history retain the value. Any credential that ever touched a public surface must be rotated, not just removed.
Langflow before 1.3.0 exposes /api/v1/validate/code without authentication, allowing any remote attacker to execute arbitrary Python (CVSS 9.8; on the CISA KEV catalog since May 2025). JADEPUFFER delivered every stage as Base64-encoded Python through this endpoint, then pivoted to the victim's back-end services.
04 · Technical Deep Dive — Agentic Tradecraft
How it worksThis is the part that separates JADEPUFFER from a commodity smash-and-grab. The intrusion behaved like a language model executing a goal, not a human at a keyboard or a static script. Three behaviours evidence that.
The decoded Python delivered through Langflow was saturated with natural-language commentary explaining why each action was taken — the kind of running rationale a model emits, not the terse output of a hand-written tool. That commentary is itself a hunting signal: legitimate automation rarely explains its own intent inline.
In the Nacos backdoor sequence a login failed at 19:34:36 UTC. A corrective payload — diagnosing two possible causes in parallel — was issued at 19:35:07 UTC, and the login succeeded at 19:35:18 UTC. A 31-second diagnose-and-retry loop across a novel error is characteristic of an agent reasoning over live output rather than replaying a fixed playbook.
| UTC | Action |
|---|---|
| 19:34:24 | Nacos backdoor admin inserted (bcrypt hash) |
| 19:34:36 | Initial login attempt fails |
| 19:35:07 | Corrective payload issued (parallel hypotheses) |
| 19:35:18 | Login succeeds |
Against a Nacos configuration service (reached with CVE-2021-29441 and a forged JWT signed with Nacos's well-known default key), the operator encrypted all 1,342 configuration items using MySQL's native AES_ENCRYPT() and wrote a README_RANSOM table. The key was generated as base64(uuid4().bytes + uuid4().bytes), printed to stdout, and never persisted or transmitted — so even paying the ransom could not recover the data. Captured payloads show escalation from row-level deletes to dropping entire schemas.
Because the encryption key is discarded, this is effectively a wiper wearing a ransom note. Treat any JADEPUFFER-style database encryption as unrecoverable and prioritise restore-from-backup over negotiation.
ENCFORGE is a compiled Go ransomware built to encrypt model weights, vector indexes, training datasets and other AI-infrastructure files. It scans roughly 180 file extensions and exposes an --include flag so operators can append campaign-specific extensions; its own help text names LoRA fine-tune adapters and legacy GGML weights as examples — a purpose-built attack on the AI supply chain, not generic office files.
In the tenant compromise, the two leaked principals held potent roles: Storage Account Contributor (via a group), plus directly assigned Contributor and SQL DB Contributor. That combination allowed enumeration, ListKeys credential theft and mass deletion. The operator issued five OAuth tokens for the destruction principal, and at one point ran two tokens in parallel for ~70 seconds — driving concurrent delete operations to move faster than a human could.
Two access tokens for one service principal active simultaneously is abnormal for most workloads. Alert on overlapping token lifetimes per app-id — it is a cheap, high-signal indicator of scripted/parallel abuse.
05 · Post-Exploitation & Destruction
ImpactThe destructive phase was fast and noisy, but its outcomes were uneven — Azure guardrails blocked several actions. The table below is a practical map of what worked and what saved data.
| Target | Action | Outcome |
|---|---|---|
| Storage Accounts | 100+ deletion attempts | Mostly successful; some blocked by resource locks / deletion protection |
| Azure SQL databases | Deletion attempts | Failed — unsupported API version in the request |
| Key Vault | Delete | One deleted (same resource group) |
| Function App | Delete | Deleted |
| App Service plan | Delete | Deleted |
| Site Recovery / Backup locks | Multiple removal attempts | Unsuccessful — protection locks held |
| Storage account keys | 30+ ListKeys reads | Successful — credential harvesting, focused on Site Recovery storage |
Locks Worked
Resource locks and account-level deletion protection stopped a subset of Storage Account deletes. The controls that were in place demonstrably reduced blast radius.
Backups Were Targeted
The operator went after Site Recovery and Backup protection locks specifically — recovery infrastructure is a first-class target, not an afterthought.
Keys Over Data
Post-destruction ListKeys calls show intent to pivot with harvested storage keys, extending reach beyond the initial principals.
06 · C2 & Infrastructure
FingerprintThe same IP surfaces in both the Sysdig ransomware analysis and Microsoft's Azure incident, tying the two campaigns together. All Azure Resource Manager calls carried a single, distinctive client user-agent.
| Indicator | Role | Notes |
|---|---|---|
| 45.131.66.106 | C2 / ARM client | Sysdig: C2 beacon http://45.131.66[.]106:4444/beacon; Microsoft: ARM requests & App Service probing |
| 64.20.53.230 | Staging / probing | Sysdig: exfil/staging (InterServer, AS19318); Microsoft: App Service probing |
| 34.153.223.102 | Probing | App Service configuration probing (Microsoft) |
| python-requests/2.34.2 | User-agent | ARM/token client string across the destructive activity |
07 · DFIR Investigation Steps
Responder runbook- 1Scope the identity: In Entra, pull the app registration / enterprise application for the suspect service principal and list all role assignments (directory + Azure RBAC across every subscription).
- 2Pull sign-ins: Filter
AADServicePrincipalSignInLogsfor the app-id. Note source IPs, and flag thepython-requestsuser-agent and any overlapping token issuance. - 3Reconstruct activity: Query
AzureActivity/ Resource Manager logs for the caller — separate read (Discovery) from write/delete (Impact) operations and build a timeline. - 4Contain: Revoke the principal's credentials (rotate secret/cert), remove excess role assignments, and revoke active refresh/access tokens. Do not merely "delete" a leaked secret — rotate it.
- 5Assess destruction: Enumerate deleted resources, check soft-delete/recycle windows (Storage, Key Vault soft-delete, Recovery Services vault) and begin restores from locked backups.
- 6Hunt for spread: Review
ListKeys/listKeyscalls and any secrets read from App Service config; rotate every key/secret the principal could reach.
- All role assignments for the principal are enumerated and excess removed
- Every credential the principal could read has been rotated
- Deleted resources are inventoried and restore status is tracked
- Source IPs and user-agent are blocked / alerted on tenant-wide
08 · Indicators of Compromise
IOC tables| Type | Value | Context |
|---|---|---|
| IPv4 | 45.131.66.106 | C2 beacon :4444 / ARM client |
| IPv4 | 64.20.53.230 | Staging / App Service probing (InterServer AS19318) |
| IPv4 | 34.153.223.102 | App Service probing |
| User-Agent | python-requests/2.34.2 | Azure Resource Manager calls |
| URL | http://45.131.66[.]106:4444/beacon | Langflow-host crontab beacon |
| Type | Value |
|---|---|
| SHA-256 (packed) | 8cb0c223b018cecef1d990ec81c67b826eb3c30d54f06193cf69969e9a8baea2 |
| SHA-256 (unpacked) | ea7822eac6cecef7746c606b862b4d3034856caf754c4cf69533662637905328 |
| BTC (ransom) | 3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy |
| Contact | e78393397[@]proton[.]me |
Sysdig publishes the full IOC set — source, additional C2, the embedded RSA-2048 key fingerprint and a YARA rule — in its report. Pull those directly for detection engineering; do not rely on this summary alone.
09 · Detection & Hunt Queries
KQL + SPLField names vary by connector — UniqueTokenIdentifier, CallerIpAddress and the storage listKeys operation string differ between Sentinel schema versions and third-party forwarders. Confirm the exact column in your workspace before promoting any of these to an alert rule.
10 · MITRE ATT&CK Mapping
Techniques| Tactic | Technique | ID | In this campaign |
|---|---|---|---|
| Initial Access | Exploit Public-Facing Application | T1190 | Langflow CVE-2025-3248 / Nacos CVE-2021-29441 |
| Initial Access / Defense Evasion | Valid Accounts: Cloud Accounts | T1078.004 | Leaked service-principal secret |
| Discovery | Cloud Service Discovery | T1526 | 300+ read ops across VMs, subs, RGs |
| Credential Access | Unsecured Credentials | T1552 | App Service config & storage ListKeys |
| Impact | Data Destruction | T1485 | Storage / Key Vault / Function App deletion |
| Impact | Inhibit System Recovery | T1490 | Attempts against Site Recovery / Backup locks |
| Impact | Data Encrypted for Impact | T1486 | Nacos config encrypted (key discarded); ENCFORGE |
11 · Mitigation & Hardening
Do this now- 1Rotate anything ever exposed: Treat any secret that appeared in a repo, issue, log or ticket as burned. Removal ≠ revocation — rotate the credential and invalidate issued tokens.
- 2Least privilege for service principals: Strip standing
Contributor/Owner; scope to specific resource groups; prefer managed identities and short-lived, workload-federated credentials over long-lived secrets. - 3Protect recovery infrastructure: Apply resource locks, Storage & Key Vault soft-delete + purge protection, and immutable/locked Recovery Services vaults so a single identity cannot both destroy and un-protect.
- 4Secret scanning at the edge: Enforce push-protection secret scanning on all repos and block plaintext credentials in issues/PRs; monitor public paste and code surfaces for tenant identifiers.
- 5Patch the entry points: Upgrade Langflow to 1.3.0+ (CVE-2025-3248) and Nacos to 1.4.1+ (CVE-2021-29441); keep both off the public internet where possible.
- 6Enable cloud detection plans: Turn on Microsoft Defender for Cloud coverage for Resource Manager, Storage, Key Vault, App Service and Databases so mass-delete and ListKeys anomalies raise alerts.
12 · Sources & References
PrimaryHunting leaked cloud identities in your own tenant?
Run the observed IPs and hashes through the CyberHawk IOC Scanner, then browse our SOP library for the service-principal and cloud-data-destruction response playbooks. More cloud threat intel on the CyberHawk blog.
◈ Stay Connected
Follow CyberHawk Threat Intel for threat intelligence, deployment guides and hands-on SOC tooling content.
"They can't exploit you if you are the Exploit."