Critical 7 Hunt Leads

Microsoft: China’s Storm-0940 Let AI Agents Run the ConnectWise Hack

Microsoft ties the ConnectWise Cloud Backup supply-chain attack to China-aligned Storm-0940, which used ARTEX AI agents to try sign-ins to more than 2,250 Microsoft 365 tenants at up to 2,900 a minute.

Microsoft has put a name on the ConnectWise Cloud Backup supply-chain attack. In a report published Oct. 21, Microsoft Threat Intelligence says the China-state-aligned group it tracks as Storm-0940 was behind it, and that the group ran much of the campaign through ARTEX, an open-source framework whose AI agents carry an intrusion from reconnaissance to data theft with little human input. According to Microsoft, the agents tried to sign in to more than 2,250 Microsoft 365 tenants at up to 2,900 attempts a minute, and in several cases went from first targeting to privileged access in under three hours. Neither Microsoft nor ConnectWise has said how the app credentials were stolen. (Background: our earlier coverage of the breach.)

For defenders

Affected: any Microsoft 365 tenant that authorized ConnectWise’s multi-tenant apps. Microsoft lists three app IDs: Cloud Backup (506e08f9-6e9a-4da4-942b-a099a03644ae), ConnectWise – MS Teams (24205314-2b89-4e07-a2a4-579e898a5640) and ConnectWise – MS Graph (0de14c77-b9b0-4137-9360-34878a929827). Its guidance mentions “all four application IDs” but publishes only three, so take the full list from ConnectWise’s advisory. No CVE: this is stolen app credentials, not a software bug.

Actor and tooling: Microsoft says Storm-0940 has been active since 2021, has no known industry aliases, and goes after data in sectors including aerospace and defense, financial services, government and energy. It has used ARTEX since September 2026. ARTEX is a multi-agent LLM pentest framework with a Go backend and a Next.js frontend, and it works with any AI model. Microsoft says several other threat actors use it too.

What Microsoft saw: from Oct. 10 to 14, a password spray from 144.172.64[.]99 hit 327 accounts at eight organizations with more than 151,000 failed logons and no observed success. After that came app-only sign-ins using the stolen ConnectWise credentials, followed by Microsoft Graph reconnaissance, new application credentials and changes to users, groups and privileged roles. One ConnectWise management app gave itself Global Administrator; Huntress identified it as the Teams app. Microsoft maps the activity to T1195 (Supply Chain Compromise), T1078.004 (Valid Accounts: Cloud Accounts), T1528 (Steal Application Access Token), T1098.001 (Account Manipulation: Additional Cloud Credentials), T1098.003 (Account Manipulation: Additional Cloud Roles), T1087.004 (Account Discovery: Cloud Account), T1580 (Cloud Infrastructure Discovery) and T1595 (Active Scanning). The post also includes Defender XDR and Sentinel hunting queries, which we reproduce in the report below.

Network
144.172.64[.]128 (app sign-ins and Graph activity)
144.172.64[.]60 (app sign-ins and Graph activity)
144.172.64[.]99 (password spray; also in ConnectWise’s advisory)
187.15.88[.]186 (VPN, transient, Oct. 15-16)
187.15.90[.]217 (VPN, transient, Oct. 15-16)
187.15.89[.]186 (VPN, transient, Oct. 15-16)

User agents (low fidelity alone)
Python-urllib/3.12
python-requests/2.31.0
python-requests/2.34.2
curl/7.88.1
azure-toolkit/1.0

What it means for you

If a managed IT provider runs your company’s Microsoft 365, this is about their tools, not anything you did. The intruders signed in as a trusted backup app, so your passwords and two-factor codes never came into play. What’s new is the speed. With AI agents doing the work, an attack that used to take days took a few hours here. Ask your provider whether they used ConnectWise Cloud Backup (formerly SkyKick) and whether they’ve checked your account. If you run Microsoft 365 yourself and never installed it, there’s nothing to do.

Do this now

  1. Keep the ConnectWise apps disabled until ConnectWise publishes restoration instructions, and don’t delete them. Find them by app ID, not display name, in every tenant, including ones where the tool was installed but never used.
  2. Export Entra sign-in and audit logs, Purview audit records and Graph activity logs now. Microsoft’s Defender queries look back 30 days, so activity from Oct. 13 starts aging out around Nov. 12.
  3. Review service principal sign-ins for those apps from at least Oct. 15, and from Oct. 1 where you can. Look at successes and failures separately, and don’t stop at the published IPs.
  4. Check audit logs for credentials added to any app, new role assignments and consent grants. Remove anything you didn’t authorize, but only after the evidence is saved.

Source article: AI-driven, large-scale nation-state campaign using ARTEX enables supply chain compromise
Publisher: Microsoft Security Blog (authors: Microsoft Security Research and Microsoft Threat Intelligence)
Published: October 21, 2026
URL: https://www.microsoft.com/en-us/security/blog/2026/10/21/storm-0940-uses-artex-agentic-ai-connectwise-supply-chain-compromise/

Executive Summary

Storm-0940 is a China-state-aligned actor that Microsoft Threat Intelligence has tracked since 2021. Microsoft says it has no known industry aliases; Huntress and Truesec reported the same ConnectWise intrusion earlier without attributing it. The group goes after data in sectors including aerospace and defense, financial services, government and energy. It has historically relied on password spraying and exploitation of internet-facing applications, and in cloud environments it added credentials to existing OAuth applications so it could keep reading email through Microsoft Graph. Since at least September 2026 it has automated that tradecraft with ARTEX, an open-source multi-agent LLM penetration testing framework (Go backend, Next.js frontend, works with any AI model). ARTEX agents run an engagement from reconnaissance to exfiltration around the clock, try several breach paths at once and record what they find in a graph of assets and vulnerabilities. Microsoft says multiple actors in several regions use ARTEX, and that public reporting has tied it to personal-data breaches at Korean financial institutions. In this campaign, a spray from 144.172.64[.]99 between October 10 and 14, 2026 hit 327 accounts at eight organizations: more than 151,000 failed logons, a peak of 2,900 failures per minute on October 11, nearly 98% of the activity ending in lockouts, and no observed success. Before October 15 the actor had taken control of the identities of multiple ConnectWise multi-tenant cloud applications; neither Microsoft nor ConnectWise has said how. It then signed in app-only to customer tenants from the same 144.172.64.x range, attempting sign-ins to more than 2,250 tenants at up to 2,900 attempts per minute with no interactive user sign-in. In several environments it went on to Microsoft Graph reconnaissance, added application credentials for persistence and changed identities, groups and privileged roles. One ConnectWise management application assigned itself Global Administrator, and in multiple instances the time from initial targeting to privileged access was under three hours. The objective is data theft. Every tenant that authorized the apps was exposed to an attacker acting with the app’s own permissions, and a stolen app identity bypasses user passwords and MFA. The Hunt Leads below cover detection logic, false-positive expectations, the hunting queries Microsoft published and the published indicators.

ATT&CK chain: Reconnaissance → Credential Access → Initial Access → Discovery → Persistence → Privilege Escalation

Hunt Lead Grid

Hunt Lead Level Hunt Lead Name ATT&CK Risk of False Positives
1 (Junior) ConnectWise App Presence and Permission Inventory T1195 (Supply Chain Compromise) Low. The query matches only the published application IDs, so every hit is a real ConnectWise app instance. The work is deciding whether each one is still needed and whether its permissions fit its job, not filtering out noise.
1 (Junior) Service Principal Sign-ins from Storm-0940 Infrastructure T1078.004 (Valid Accounts: Cloud Accounts) Low. Legitimate ConnectWise sign-ins come from the vendor’s own hosting, so the published app IDs combined with the 144.172.64[.]x addresses leave little room for benign matches. Without the IP filter the query returns every normal backup sign-in, so treat that broader version as a scoping step and expect to review the results.
2 (Pro) Graph Reconnaissance by ConnectWise Apps T1087.004 (Account Discovery: Cloud Account), T1580 (Cloud Infrastructure Discovery) Medium. A backup app legitimately reads mail, files and directory objects in volume, so volume alone is noise. The rule anchors on the published IPs and user agents, directory enumeration a backup tool has no need for, and write requests to directory, application and role endpoints.
2 (Pro) New Credentials Added to Applications and Service Principals T1098.001 (Account Manipulation: Additional Cloud Credentials) Medium. Admins and automation rotate secrets and certificates all the time. The rule anchors on additions initiated by a service principal rather than a named admin, especially by the ConnectWise identities, and on additions with no change record since October 1.
2 (Pro) Application Self-Assigned to Global Administrator T1098.003 (Account Manipulation: Additional Cloud Roles) Low. Legitimate directory-role grants to applications are made by a human admin and logged with that admin as the initiator. An app adding itself to a privileged role has essentially no benign explanation, so the rule anchors on the initiator and the target being the same service principal.
3 (Elite) Machine-Speed Password Spray Across Accounts T1110.003 (Brute Force: Password Spraying) Medium. Misconfigured services, stale saved passwords and lockout storms also produce bursts of failures. The rule needs per-tenant baselines and anchors on one source failing against many distinct accounts per minute, not on many failures against a single account.
3 (Elite) App-Only Activity from an Uncommon ISP Chained to Privilege Changes T1528 (Steal Application Access Token), T1078.004 (Valid Accounts: Cloud Accounts), T1098.003 (Account Manipulation: Additional Cloud Roles) Medium. Vendors move hosting and add regions, so a new ISP for an app is noisy on its own. The chain anchors on a new ISP or hosting ASN followed within hours by a credential addition, role or app-role assignment, or consent grant by the same app.

ConnectWise App Presence and Permission Inventory

Microsoft says the actor gained control of the identities of multiple ConnectWise multi-tenant cloud applications, by means neither Microsoft nor ConnectWise has disclosed, and used them to authenticate into customer tenants that had authorized those apps. The first hunt, then, is finding where those identities exist. Microsoft publishes three application IDs: 506e08f9-6e9a-4da4-942b-a099a03644ae (ConnectWise Cloud Backup), 24205314-2b89-4e07-a2a4-579e898a5640 (ConnectWise – MS Teams) and 0de14c77-b9b0-4137-9360-34878a929827 (ConnectWise – MS Graph). Its mitigation text refers to four application IDs, so take the complete list from the ConnectWise advisory. The detection logic is to locate each enterprise application (service principal) by application ID, never by display name, and record its local service principal Object ID, status, admin-consent state, overall privilege level and every permission with its type, privilege level and usage status. Prioritize instances that are still enabled, admin-consented, and hold high-privilege application permissions on Microsoft Graph, Exchange Online or SharePoint, especially permissions shown as in use.

Use Defender for Cloud Apps app governance data, which Microsoft’s first Defender XDR query reads through the OAuthAppInfo table, or filter Enterprise applications by Application ID in the Entra admin center for each tenant. MSPs should run it in every customer tenant, including tenants where the app was authorized but never used, because Microsoft says those are in scope too. This is a point-in-time inventory rather than a lookback; record the results, including each local service principal Object ID that the later leads key on, before anything is changed. Deleting the enterprise application is the wrong control: Microsoft says to disable the connections and leave the apps in place until ConnectWise issues restoration instructions, so that configuration and evidence survive. Searching by display name is also wrong, because names can differ between tenants while the app ID stays the same. Any instance that is still enabled should be disabled immediately, and every tenant where the apps exist becomes the scope for the leads below. The approach generalizes to any multi-tenant SaaS vendor whose app identity is reported compromised.

Published hunting query, reproduced from the source article (Microsoft Defender XDR advanced hunting, query 1):

let ConnectWiseApps = dynamic([
    "506e08f9-6e9a-4da4-942b-a099a03644ae", // ConnectWise Cloud Backup
    "24205314-2b89-4e07-a2a4-579e898a5640", // ConnectWise - MS Teams
    "0de14c77-b9b0-4137-9360-34878a929827" // ConnectWise - MS Graph
]);
OAuthAppInfo
| where OAuthAppId in (ConnectWiseApps)
| mv-expand Permission = Permissions
| extend
    PermissionName = tostring(Permission.PermissionName),
    TargetApp = tostring(Permission.TargetAppDisplayName),
    TargetAppId = tostring(Permission.TargetAppId),
    PermissionType = tostring(Permission.PermissionType),
    PermissionPrivilegeLevel = tostring(Permission.PrivilegeLevel),
    UsageStatus = tostring(Permission.UsageStatus)
| project
    AppName,
    OAuthAppId,
    ServicePrincipalId,
    AppStatus,
    PrivilegeLevel,
    IsAdminConsented,
    PermissionName,
    PermissionType,
    PermissionPrivilegeLevel,
    TargetApp,
    TargetAppId,
    UsageStatus
| order by AppName asc, PermissionPrivilegeLevel desc

Hunt Lead Level: 1 (Junior Analyst)

ATT&CK: Initial Access → T1195 (Supply Chain Compromise), mapping per source article (Microsoft uses it for reaching downstream tenants through the multi-tenant app). The ATT&CK detection strategy for this technique, DET0537 Behavioral detection for Supply Chain Compromise (package/update tamper → install → first-run), is written for software package tampering and fits a compromised OAuth app only loosely.

Sources: “AI-driven, large-scale nation-state campaign using ARTEX enables supply chain compromise”, Microsoft Threat Intelligence, Oct. 21, 2026, https://www.microsoft.com/en-us/security/blog/2026/10/21/storm-0940-uses-artex-agentic-ai-connectwise-supply-chain-compromise/ (source article)

Service Principal Sign-ins from Storm-0940 Infrastructure

With the ConnectWise app credentials in hand, the actor authenticated to customer tenants as the applications themselves. There was no interactive user sign-in, so user passwords and MFA never came into play. It did this from the same 144.172.64.x range as the earlier spray, attempting sign-ins to more than 2,250 tenants at up to 2,900 attempts per minute. Microsoft ties 144.172.64[.]128 and 144.172.64[.]60 to sign-ins and Graph activity in customer environments. It ties 144.172.64[.]99 to the spray, and that address also appears in ConnectWise’s advisory. Microsoft also lists 187.15.88[.]186, 187.15.90[.]217 and 187.15.89[.]186 as VPN addresses used to reach Graph through the compromised apps on October 15 and 16, and calls them transient. The user agents seen in these sign-ins and in Graph activity were Python-urllib/3.12, python-requests/2.31.0, python-requests/2.34.2, curl/7.88.1 and azure-toolkit/1.0. The detection logic is to pull every service principal sign-in for the ConnectWise app IDs and review successes and failures separately. Any sign-in from the published addresses or with those user agents counts as a hit. After that, list every source IP the apps signed in from and flag anything outside ConnectWise’s normal hosting.

Use Entra service principal sign-in logs. In the Entra admin center they sit under Sign-in logs on the Service principal sign-ins tab. Defender XDR exposes them as EntraIdSpnSignInEvents, and Microsoft’s second Defender query unions that table with GraphAPIAuditEvents so the sign-in and the Graph activity that followed appear on one timeline. Microsoft’s Sentinel query reads SigninLogs. In Sentinel, app-only sign-ins are normally written to the separate AADServicePrincipalSignInLogs table when that diagnostic category is collected, so confirm that table exists and apply the same app ID filter there if SigninLogs returns nothing. Microsoft says to review from October 15 at a minimum and from October 1 where records exist; its queries start on October 13, and Defender advanced hunting covers only 30 days, so export now. Don’t limit the review to the published IPs. Also don’t turn the VPN addresses into a standing block or a long-lived indicator, because Microsoft calls them transient and they may later belong to someone else. The user agents are common scripting libraries and are low fidelity on their own; use them only to raise confidence alongside the app ID. Any successful sign-in from the published addresses is a confirmed compromise of that tenant: escalate to incident response and run the Graph, credential and role leads below for the same service principal. The broader pattern, a multi-tenant app signing in app-only from an ASN it has never used before, generalizes to any vendor app compromise.

Published hunting queries, reproduced from the source article (Microsoft Defender XDR query 2 and Microsoft Sentinel query 1). IP strings are de-fanged for publication; restore the dots before running.

let Apps = dynamic([
    "506e08f9-6e9a-4da4-942b-a099a03644ae",
    "24205314-2b89-4e07-a2a4-579e898a5640",
    "0de14c77-b9b0-4137-9360-34878a929827"
]);
let IPs = dynamic(["144.172.64[.]60", "144.172.64[.]99", "144.172.64[.]128"]);
union kind=outer
    (EntraIdSpnSignInEvents
     | extend EventType = "Sign-in"),
    (GraphAPIAuditEvents
     | extend EventType = "Graph API", IPAddress = IpAddress)
| where Timestamp >= datetime(2026-10-13)
| where ApplicationId in (Apps)
| where IPAddress in (IPs) // Comment out for broader hunting
| project-away IpAddress
| order by Timestamp asc
let IPIndicators = dynamic([
    "144.172.64[.]60",  // IP Indicator
    "144.172.64[.]99",  // IP Indicator
    "144.172.64[.]128"  // IP Indicator
]);
let ConnectWiseApps = dynamic([
    "506e08f9-6e9a-4da4-942b-a099a03644ae", // ConnectWise Cloud Backup
    "24205314-2b89-4e07-a2a4-579e898a5640", // ConnectWise - MS Teams
    "0de14c77-b9b0-4137-9360-34878a929827" // ConnectWise - MS Graph
]);
SigninLogs
| where TimeGenerated >= datetime(2026-10-13)
| where AppId in (ConnectWiseApps)
//| where IPAddress in (IPIndicators) // Comment out to review all activity from these applications
| project
    TimeGenerated,
    AppId,
    ServicePrincipalName,
    ResourceDisplayName,
    ResourceId,
    IPAddress,
    CorrelationId
| order by TimeGenerated asc

Hunt Lead Level: 1 (Junior Analyst)

ATT&CK: Initial Access → T1078.004 (Valid Accounts: Cloud Accounts), mapping per source article; detection strategy DET0546 Detection of Abused or Compromised Cloud Accounts for Access and Persistence

Sources: “AI-driven, large-scale nation-state campaign using ARTEX enables supply chain compromise”, Microsoft Threat Intelligence, Oct. 21, 2026, https://www.microsoft.com/en-us/security/blog/2026/10/21/storm-0940-uses-artex-agentic-ai-connectwise-supply-chain-compromise/ (source article)

Graph Reconnaissance by ConnectWise Apps

After authenticating, Microsoft says, the agents moved in several environments to Microsoft Graph and directory operations: reconnaissance, application credential changes and modifications to identities, groups and privileged roles. Microsoft does not publish the specific Graph endpoints. Its Defender for Cloud Apps detections for this activity describe SharePoint enumeration through Graph, mail access by an OAuth application following a role assignment, and an OAuth app reaching the Teams Messages folder through an email client, but the post does not confirm which of these occurred in this campaign. The detection logic is to pull every Graph request made by the ConnectWise app IDs and flag requests from the published addresses or user agents, enumeration of users, groups, directory roles, applications and service principals (which a backup or Teams management function has little reason to sweep), and any POST, PATCH or DELETE against directory, application, role or policy resources. Then look for a jump in mail or SharePoint reads by the same app that follows a role or credential change.

Use Microsoft Graph activity logs (MicrosoftGraphActivityLogs in Sentinel or Log Analytics, GraphAPIAuditEvents in Defender XDR) together with Purview audit records for mail and file access. Graph activity logs have to be enabled through Entra diagnostic settings and are not retroactive. Huntress notes that Graph directory reads leave no audit record, so a tenant that wasn’t collecting Graph activity logs before October 13 may never be able to reconstruct what was read; record that gap in the incident rather than treating silence as clean. Sweep from October 1 forward. Tune by baselining each app’s normal endpoints and methods over the weeks before October 10, since a backup app’s routine read pattern is stable. The wrong approach is to close a hit because the backup app reads mail anyway: the requests that matter are the ones from new infrastructure, in new categories, or that write. Any Graph request from the published addresses is a confirmed hostile session. Escalate it to incident response and scope which mailboxes, sites and directory objects it touched. The same baselining works for any high-privilege OAuth app.

Published hunting query, reproduced from the source article (Microsoft Sentinel query 2). IP strings are de-fanged for publication; restore the dots before running.

let IPIndicators = dynamic([
    "144.172.64[.]60",  // IP Indicator
    "144.172.64[.]99",  // IP Indicator
    "144.172.64[.]128"  // IP Indicator
]);
let ConnectWiseApps = dynamic([
    "506e08f9-6e9a-4da4-942b-a099a03644ae", // ConnectWise Cloud Backup
    "24205314-2b89-4e07-a2a4-579e898a5640", // ConnectWise - MS Teams
    "0de14c77-b9b0-4137-9360-34878a929827" // ConnectWise - MS Graph
]);
MicrosoftGraphActivityLogs
| where TimeGenerated >= datetime(2026-10-13)
| where AppId in (ConnectWiseApps)
| where IPAddress in (IPIndicators) // Comment out to review all Graph activity from these applications
| project
    TimeGenerated,
    AppId,
    IPAddress,
    RequestMethod,
    RequestUri,
    ResponseStatusCode,
    Scopes,
    ClientRequestId,
    OperationId,
    RequestId
| order by TimeGenerated asc

Hunt Lead Level: 2 (Pro)

ATT&CK: Discovery → T1087.004 (Account Discovery: Cloud Account), detection strategy DET0386 Cloud Account Enumeration via API, CLI, and Scripting Interfaces; Discovery → T1580 (Cloud Infrastructure Discovery), detection strategy DET0169 Detection Strategy for Cloud Infrastructure Discovery. Mapping per source article.

Sources: “AI-driven, large-scale nation-state campaign using ARTEX enables supply chain compromise”, Microsoft Threat Intelligence, Oct. 21, 2026, https://www.microsoft.com/en-us/security/blog/2026/10/21/storm-0940-uses-artex-agentic-ai-connectwise-supply-chain-compromise/ (source article); “ConnectWise (SkyKick) Vendor Credentials Abused in M365 Attacks”, Huntress (Jonathan Semon), Oct. 16, 2026, https://www.huntress.com/blog/vendor-credential-enables-unauthorized-access (additional source, same campaign; Graph directory reads leave no audit record)

New Credentials Added to Applications and Service Principals

Microsoft says the actor added application credentials in affected tenants for persistence, a habit that predates ARTEX: Storm-0940 has historically added credentials to existing OAuth applications and used them to keep reading email through Graph. Huntress, reporting on the same campaign, saw the compromised ConnectWise Teams app make nine changes to two other applications in one tenant (an MSP management app and Huntress’s own app); some failed, but the client secrets it added afterwards succeeded. Those secrets survive the ConnectWise apps being disabled. The detection logic is to search Entra audit logs for credential additions to applications and service principals (“Add service principal credentials” and “Update application – Certificates and secrets management” in Entra’s audit naming), new application owners, new app-role assignments and consent grants. Flag any where the initiator is a service principal rather than a named user, especially the ConnectWise identities or any session from the published addresses. Then check whether each new credential has since been used to sign in, and from where.

Use Entra audit logs (AuditLogs in Sentinel, or Entra audit data in Defender XDR) joined to service principal sign-in logs to see whether a new credential was used. Sweep from October 1, the earliest date Microsoft asks for. Because this actor has used app credentials as long-term persistence before, a 90-day lookback on every app holding mail or directory permissions is reasonable. Allowlist by the initiating identity and a matching change record, not by application, because the apps that received the new secrets are legitimate apps. Disabling only the ConnectWise apps is the wrong fix on its own, and so is rotating ConnectWise’s secret: credentials planted on other applications keep working until someone removes them. Following Microsoft’s order, preserve the audit evidence first, then have an authorized responder remove confirmed unauthorized credentials, owners, grants and assignments and rotate anything confirmed suspicious. A service principal adding credentials to a different application is an escalation to incident response, not a tuning candidate, and the rule generalizes to any OAuth-app persistence.

Hunt Lead Level: 2 (Pro)

ATT&CK: Persistence → T1098.001 (Account Manipulation: Additional Cloud Credentials), mapping per source article; detection strategy DET0531 Detection Strategy for Additional Cloud Credentials in IaaS/IdP/SaaS

Sources: “AI-driven, large-scale nation-state campaign using ARTEX enables supply chain compromise”, Microsoft Threat Intelligence, Oct. 21, 2026, https://www.microsoft.com/en-us/security/blog/2026/10/21/storm-0940-uses-artex-agentic-ai-connectwise-supply-chain-compromise/ (source article); “ConnectWise (SkyKick) Vendor Credentials Abused in M365 Attacks”, Huntress (Jonathan Semon), Oct. 16, 2026, https://www.huntress.com/blog/vendor-credential-enables-unauthorized-access (additional source, same campaign; secrets added to two other applications)

Application Self-Assigned to Global Administrator

Microsoft says one ConnectWise management application added itself to the Global Administrator role through an “Add member to role” operation, and that the same app had not assigned itself to that role in the preceding seven days. Microsoft doesn’t say which app; Huntress identified it as the ConnectWise Cloud Management app for Microsoft Teams (24205314-2b89-4e07-a2a4-579e898a5640) in one customer tenant. Microsoft’s coverage for this step includes the Defender XDR alert “Application self-assigned Global Administrator role” and the Defender for Cloud Apps alerts “Suspicious addition of application role assignments by service principal to itself”, “Suspicious addition of app role assignments to service principal” and “High-privilege application roles assigned to a service principal”. The detection logic is any “Add member to role” event for a directory role where the initiator is a service principal and the target is that same service principal. Add any privileged directory role or high-privilege Graph app-role assigned to a service principal by another service principal, and any such assignment by a ConnectWise app ID.

Use Entra audit logs plus the Defender alerts above, sweeping from October 1. Pair it with a point-in-time check of current role membership: list every service principal holding Global Administrator or another privileged directory role in each tenant. That catches the assignment even if audit retention has lapsed or the event was missed. Microsoft’s seven-day condition works as a simple suppression (no prior self-assignment of the same role by the same principal in seven days), but in practice an app adding itself to Global Administrator should alert every time. Removing the role assignment alone is the wrong response, because an app with Global Administrator could have done anything in the tenant, including adding the credentials covered in the previous lead. Treat a hit as full tenant compromise: escalate to incident response, chain it with the credential and Graph leads for the same service principal, and review changes to users, groups, authentication methods and Conditional Access, as Microsoft advises. The rule applies to any multi-tenant app, not just ConnectWise’s.

Hunt Lead Level: 2 (Pro)

ATT&CK: Privilege Escalation → T1098.003 (Account Manipulation: Additional Cloud Roles), mapping per source article; detection strategy DET0277 Detection Strategy for Role Addition to Cloud Accounts

Sources: “AI-driven, large-scale nation-state campaign using ARTEX enables supply chain compromise”, Microsoft Threat Intelligence, Oct. 21, 2026, https://www.microsoft.com/en-us/security/blog/2026/10/21/storm-0940-uses-artex-agentic-ai-connectwise-supply-chain-compromise/ (source article); “ConnectWise (SkyKick) Vendor Credentials Abused in M365 Attacks”, Huntress (Jonathan Semon), Oct. 16, 2026, https://www.huntress.com/blog/vendor-credential-enables-unauthorized-access (additional source, same campaign; identifies the Teams app)

Machine-Speed Password Spray Across Accounts

Between October 10 and 14, 2026, a cross-tenant password spray from 144.172.64[.]99 targeted 327 accounts across eight organizations. Microsoft counted more than 151,000 failed logons, with a peak of 2,900 failures per minute on October 11 and more than 111,000 failures in that single day. Forty-eight accounts each took more than 1,000 failures, nearly 98% of the activity ended in account lockouts, and Microsoft observed no successful authentication in this phase. Microsoft attributes the speed to ARTEX: its agents work around the clock, try several breach paths at once and operate at rates no human operator would. The detection logic is stateful counting per source IP and ASN of failed sign-ins and distinct target accounts per minute, across tenants where you can see them. Alert when one source fails against many distinct accounts at a rate well above the tenant’s baseline, raise severity when the failures turn into lockouts, and treat any later success from the same IP or ASN as the event that matters.

Use Entra interactive and non-interactive user sign-in logs, in Defender XDR or Sentinel. MSPs should aggregate across customer tenants, because the campaign was cross-tenant and any one tenant may see only a slice of it. Sweep from September 1, 2026, the earliest ARTEX-driven activity Microsoft reports, and keep the rate rule running as a standing analytic. Build the baseline per tenant and allowlist known internal scanners and legacy application hosts by IP rather than raising thresholds globally. Blocking 144.172.64[.]99 is a reasonable addition but the wrong primary control, because the actor also used transient VPN addresses and can rotate infrastructure, and smart lockout on its own will lock out real users, which accounts for most of the 98% lockout figure. A spray with no success is a hunting finding: confirm MFA coverage and reset passwords for the most-targeted accounts. A success from the same source is an escalation to incident response. Rate is a durable signal against agent-driven attacks, since whatever the infrastructure, these tools run faster than people.

Hunt Lead Level: 3 (Elite)

ATT&CK: Credential Access → T1110.003 (Brute Force: Password Spraying); detection strategy DET0487 Distributed Password Spraying via Authentication Failures Across Multiple Accounts. The source article describes the spray but does not list a technique for it in its ATT&CK section; this mapping is ours, based on the described behavior.

Sources: “AI-driven, large-scale nation-state campaign using ARTEX enables supply chain compromise”, Microsoft Threat Intelligence, Oct. 21, 2026, https://www.microsoft.com/en-us/security/blog/2026/10/21/storm-0940-uses-artex-agentic-ai-connectwise-supply-chain-compromise/ (source article)

App-Only Activity from an Uncommon ISP Chained to Privilege Changes

Microsoft says that in multiple instances the time from initial targeting to privileged access was under three hours. The agents signed in with the stolen ConnectWise app material from attacker infrastructure, ran Graph reconnaissance, then added credentials and changed roles. Its Defender for Cloud Apps alert “OAuth application activity from an uncommonly visited ISP” and the Defender XDR alerts “Unusual Microsoft Graph activity associated with Compromised ConnectWise Application”, “Graph API activity from a Microsoft threat intelligence IP address”, “Suspicious sign-in from verified nation-state threat actor infrastructure” and “Malicious sign-in from known threat actor IP address” each cover a single step. This lead joins those steps into one sequence. Build a per-application baseline of the ISPs and ASNs its service principal signs in from. When an app signs in from one it has never used, open a window of a few hours and join that service principal’s Graph activity and Entra audit events. Score the sequence high when the window contains a credential addition, a directory-role or app-role assignment, a consent grant, or a change to users, groups, authentication methods or Conditional Access.

This needs service principal sign-in logs, Graph activity logs and Entra audit logs joined on service principal or application ID, in Sentinel or Defender XDR. It also needs an ASN baseline of 30 days or more, plus an allowlist of each vendor’s published egress ranges that someone keeps up to date. Run it retrospectively from October 1 for the ConnectWise apps, then keep it as a standing analytic for every multi-tenant app holding high-privilege Graph or Exchange permissions. Alerting only on the published IPs is the wrong design: the next vendor compromise will come from different infrastructure, and the generalizable signal is an app using new infrastructure and then changing privileges within hours. Expect benign new-ASN events when vendors migrate hosting, and close them only when no privilege change follows and the vendor confirms the move. A completed chain is an escalation to incident response. The ConnectWise case is a template for any compromised vendor app identity.

Hunt Lead Level: 3 (Elite)

ATT&CK: Credential Access → T1528 (Steal Application Access Token), detection strategy DET0515 Detection Strategy for T1528 – Steal Application Access Token; Initial Access → T1078.004 (Valid Accounts: Cloud Accounts), detection strategy DET0546 Detection of Abused or Compromised Cloud Accounts for Access and Persistence; Privilege Escalation → T1098.003 (Account Manipulation: Additional Cloud Roles), detection strategy DET0277 Detection Strategy for Role Addition to Cloud Accounts. Mapping per source article.

Sources: “AI-driven, large-scale nation-state campaign using ARTEX enables supply chain compromise”, Microsoft Threat Intelligence, Oct. 21, 2026, https://www.microsoft.com/en-us/security/blog/2026/10/21/storm-0940-uses-artex-agentic-ai-connectwise-supply-chain-compromise/ (source article)

Hash Appendix

Storm-0940 ARTEX campaign tooling

The source article publishes no file hashes of any type. ARTEX is an open-source framework and Microsoft gives no sample hashes for it, and the intrusion described was carried out through cloud identities and Microsoft Graph with no files reported on victim systems. With no hash to pivot from, OTX AlienVault and VirusTotal were not queried.

MD5s

(not available)  # ARTEX multi-agent LLM penetration testing framework (no sample hash published)

SHA1s

(not available)  # ARTEX multi-agent LLM penetration testing framework (no sample hash published)

SHA256s

(not available)  # ARTEX multi-agent LLM penetration testing framework (no sample hash published)

References Appendix

  • “AI-driven, large-scale nation-state campaign using ARTEX enables supply chain compromise”, Microsoft Security Research and Microsoft Threat Intelligence (Microsoft Security Blog), Oct. 21, 2026, https://www.microsoft.com/en-us/security/blog/2026/10/21/storm-0940-uses-artex-agentic-ai-connectwise-supply-chain-compromise/ (source article; actor, ARTEX, timeline, indicators, hunting queries, alert names, mitigation guidance)
  • “ConnectWise (SkyKick) Vendor Credentials Abused in M365 Attacks”, Huntress (Jonathan Semon), Oct. 16, 2026, updated Oct. 19, 2026, https://www.huntress.com/blog/vendor-credential-enables-unauthorized-access (additional source, same campaign; Teams app Global Administrator self-assignment, secrets added to other applications, Graph directory reads unaudited)
  • ConnectWise Trust Center advisories, ConnectWise, https://www.connectwise.com/company/trust/advisories (linked from the source article; full list of affected application IDs)
  • MITRE ATT&CK Enterprise technique and detection-strategy pages linked above, MITRE, https://attack.mitre.org/

More from the Roundup