Lead
Microsoft on October 21 assessed that the ConnectWise Cloud Backup supply-chain compromise was the work of Storm-0940, a China state-aligned threat actor active since 2021 [9][10]. The group stole an API credential (client assertion) belonging to ConnectWise Cloud Backup (formerly SkyKick) and used the open-source Go-based agentic AI framework ARTEX to authenticate against more than 2,250 Microsoft 365 tenants [9][10][11]. Earlier, Storm-0940 conducted password-spray attacks reaching 2,900 sign-in attempts per minute against targeted organizations [9][21]. Huntress confirmed unauthorized sign-ins in approximately 162 partner and customer tenants [3]. In at least one tenant, a secondary ConnectWise application self-escalated to Global Administrator and planted long-lived backdoor credentials on other trusted applications [4].
ConnectWise identified the unauthorized access on October 14, disabled seven application identities on October 17 at 07:00 UTC, and suspended Cloud Backup, SaaS Security, and Cloud Management services[8]. As of the October 22 advisory, phased restoration is underway with no confirmed timeline [5]. The company states that existing backup archives remain encrypted, isolated, and preserved [5][8].
Background: Storm-0940
Storm-0940 was first detailed publicly by Microsoft in October 2024 in connection with the Quad7 botnet (also tracked as CovertNetwork-1658), which the group used for evasive password-spray attacks [10]. Microsoft assesses the group has been active since at least 2021 [9][10]. Prior targeting has focused on think tanks, government entities, legal organizations, and defense-related sectors [9].
The group's operational profile shifted in September 2026 when Microsoft observed Storm-0940 begin using ARTEX to automate attacks across a broad set of industries: aerospace and defense, automotive, chemicals, energy, financial services, government, legal, manufacturing, media, military, semiconductors, software, technology, and think tanks and non-profits [9][10].
Background: ARTEX
ARTEX is an open-source autonomous penetration-testing framework published by a Chinese developer referred to as Autumn-27 on GitHub in July 2026 [12][13]. It reportedly won a Chinese AI red team competition in September 2026 [12]. The framework is written in Go with an embedded Next.js frontend and PostgreSQL data store, and it operates against any OpenAI-compatible LLM backend [13]. It supports English, Korean, Mandarin, Spanish, and Japanese [13].
ARTEX uses a dual-graph multi-agent architecture. A planner agent maintains a shared task list across operational cycles, breaking objectives into sequenced steps. Worker agents run tools such as nmap, curl, and Impacket, feeding results back into a shared graph of assets and findings [12][13]. The developer made the tool closed-source on October 8, but by that point the repository had accumulated thousands of forks [12]. Copies persist in the wild [13].
ARTEX artifacts surfaced in attacks on South Korean and Japanese organizations in September and October before being identified in the ConnectWise campaign [12].
The Credential and Why Customer Defenses Did Not Apply
ConnectWise Cloud Backup authenticates to each customer's Microsoft 365 tenant as a trusted "app-only" identity, the same mechanism that lets the backup service run unattended [4]. The stolen credential was a client assertion, a type of API secret that lives in the vendor's own Entra tenant, not in any customer environment [3]. MFA policies, conditional access rules, and session restrictions apply to user sign-ins. They do not apply to application credentials authenticating machine-to-machine via client assertion [4][14]. Every organization that had granted ConnectWise Cloud Backup consent was exposed regardless of its own security posture [3][4].
The application holds broad Microsoft Graph permissions: read and write access to Exchange mailboxes, OneDrive, SharePoint, Teams chats, and directory data across every tenant where it is installed [3][7][14]. No custom malware or third-party implants were identified. All actions were performed using legitimate administrative tools and credentials [16].
Attack Timeline and Initial Access
Between October 10 and 14, Storm-0940 conducted an automated cross-tenant password-spray campaign from 144.172.64[.]99, targeting Microsoft 365 and Exchange Online accounts across multiple organizations [9][21]. Microsoft observed more than 151,000 failed logon attempts, peaking at 2,900 failures per minute on October 11 [9][21]. The same attacker IP 144.172.64[.]128 engaged in password spraying against four law firm tenants on October 13 and 14, with no successful user sign-ins observed [3].
On October 15, Storm-0940 pivoted to the ConnectWise supply-chain vector, using ARTEX-driven AI agents and the same infrastructure to authenticate as the ConnectWise Cloud Backup service principal (Application ID 506e08f9-6e9a-4da4-942b-a099a03644ae) [3][9]. The actor obtained Microsoft Graph tokens from 144.172.64[.]128 between 06:13 and 08:34 UTC, moving through tenants in sorted GUID order, a few seconds apart, consistent with a script working from a pre-built target list [3]. Observed user agents were Python-urllib/3.12 and python-requests/2.31.
By late Saturday (October 16), Huntress had observed sign-in activity from the malicious infrastructure across almost 1,000 Entra tenants, with more than 300 of those sign-ins appearing to succeed [1]. Huntress confirmed unauthorized sign-ins within approximately 162 tenants [3]. Attackers typically gained persistent access within five minutes of the first sign of their attack unfolding [2].
Privilege Escalation and Persistence
In at least one confirmed tenant, a second ConnectWise application, ConnectWise Cloud Management MS Teams (Application ID 24205314-2b89-4e07-a2a4-579e898a5640), added itself to the Global Administrator role [4][7]. A Python script then added new client secrets, set to expire in 2028, to two other trusted applications [4]. Huntress observed the same pattern in a second tenant [6]. Those backdoor secrets survive even if the original ConnectWise applications are disabled or removed.
Huntress additionally saw suspicious Exchange Administrator role assignments via related ConnectWise Cloud Management applications in approximately 50 tenants it monitors [8][17]. The choice of which applications to backdoor "appeared to be random in the two tenants we reviewed," Huntress noted [6].
Microsoft stated that in some environments, ARTEX-driven agents progressed from initial targeting to privileged cloud access in less than three hours [11][21]. Microsoft described the AI agents as not constrained by factors affecting humans, able to "work around the clock, on weekends, and on holidays and attempt multiple breach paths simultaneously" [21].
Broader ARTEX Targeting Beyond ConnectWise
Wiz Research identified the same actor using ARTEX tooling throughout October 2026 against multiple IT and software vendors, focused on identity providers including Okta and Entra, as well as abuse of Microsoft 365 integrations [12]. Wiz observed repeated attempts to uncover authentication bypasses, enumerate APIs, and access customer data across multiple environments and cloud providers [12]. The same infrastructure, tooling, and attack patterns were identified expanding into additional software supply-chain targets [12].
ConnectWise Response and Service Status
ConnectWise said it identified unauthorized access to application identities on October 14 [2][5]. On October 16 at 17:47 UTC, the company published its first advisory. On October 17 at 07:00 UTC, ConnectWise disabled seven application identities[8]:
- ConnectWise Cloud Backup:
506e08f9-6e9a-4da4-942b-a099a03644ae - ConnectWise Cloud Management:
2399d300-6fca-4e6a-a686-399fefe75b83 - Cloud Management MS Teams:
24205314-2b89-4e07-a2a4-579e898a5640 - Cloud Management Exchange Online:
b78f6a77-d4e5-46fb-87e5-d1648bd02519 - Cloud Management MS Graph:
0de14c77-b9b0-4137-9360-34878a929827
(Two additional application identities were disabled; the source lists five by App ID) [8].
ConnectWise suspended Cloud Backup, SaaS Security, and Cloud Management services. Backups, restores, SaaS Security monitoring, and Cloud Management functions remain unavailable. ConnectWise stated it has not observed successful threat activity since mitigations began on October 17 (initial mitigation efforts started at approximately 05:00 UTC, with application identities fully disabled at 07:00 UTC), but "this observation does not establish whether individual partner or customer Microsoft 365 tenants have been affected" [5][6]. The company engaged a third-party incident response firm [2][6].
As of the October 22 advisory, ConnectWise stated that "based on evidence available to ConnectWise, including threat intelligence shared by Microsoft, it appears that a China state-aligned group was responsible" [5]. Phased restoration is underway, each step subject to security validation, and is expected to take several days [5].
IOC Table
| Type | Value | Context | Source |
|---|---|---|---|
| IP | 144.172.64.128 |
Primary attacker IP for tenant sign-ins, October 15 | [3] |
| IP | 144.172.64.99 |
Password-spray infrastructure, October 10-14 | [21] |
| IP | 144.172.64.60 |
Additional attacker IP shared by ConnectWise | |
| IP | 155.133.5.15 |
ConnectWise-listed threat actor IP | [5] |
| IP | 155.133.5.14 |
ConnectWise-listed threat actor IP | [5] |
| IP | 118.69.65.60 |
ConnectWise-listed threat actor IP (Vietnamese IP space, likely proxy) | [5] |
| IP | 144.172.94.243 |
Huntress-identified IP used for password spray | [17] |
| User Agent | Python-urllib/3.12 |
Observed during automated tenant sign-ins | |
| User Agent | python-requests/2.31 |
Observed during automated tenant sign-ins | |
| Application ID | 506e08f9-6e9a-4da4-942b-a099a03644ae |
ConnectWise Cloud Backup service principal | [3][8] |
| Application ID | 24205314-2b89-4e07-a2a4-579e898a5640 |
Cloud Management MS Teams (used for escalation) | [8] |
| Application ID | 2399d300-6fca-4e6a-a686-399fefe75b83 |
ConnectWise Cloud Management | [8] |
| Application ID | b78f6a77-d4e5-46fb-87e5-d1648bd02519 |
Cloud Management Exchange Online | [8] |
| Application ID | 0de14c77-b9b0-4137-9360-34878a929827 |
Cloud Management MS Graph | [8] |
MITRE ATT&CK Mapping
| Technique ID | Name | Observed Activity | ||||
|---|---|---|---|---|---|---|
| ------------- | ------ | -------------------- | n | T1195.002 | Supply Chain Compromise: Compromise Software Supply Chain | Stolen vendor application credential used to access downstream customer tenants [3][4] |
| T1078.004 | Valid Accounts: Cloud Accounts | Authentication as the ConnectWise service principal using stolen client assertion [3][4] | ||||
| T1098.003 | Account Manipulation: Additional Cloud Roles | ConnectWise Cloud Management app self-assigned Global Administrator [4][7] | ||||
| T1098.001 | Account Manipulation: Additional Cloud Credentials | New client secrets added to other trusted applications with 2028 expiration [4][6] | ||||
| T1087.004 | Account Discovery: Cloud Account | Microsoft Graph directory reads and enumeration of users and accounts [16] | ||||
| T1114.002 | Email Collection: Remote Email Collection | Application permissions enabled read access to Exchange mailboxes [3][14] | ||||
| T1550.001 | Use Alternate Authentication Material: Application Access Token | Attacker obtained Microsoft Graph access tokens using compromised app credential [3][7] |
Entra Service Principal Sign-In Logs
The primary detection surface is the service principal sign-in logs in Entra ID, not the interactive or non-interactive user sign-in logs. Filter on the implicated Application IDs listed in the IOC table above. Legitimate Cloud Backup traffic originates from Azure private IPv6 space. Any sign-in from a public IP, particularly from 144.172.64.0/24, is anomalous[7].
KQL query for Microsoft Sentinel:
AADServicePrincipalSignInLogs
| where AppId in (
"506e08f9-6e9a-4da4-942b-a099a03644ae",
"24205314-2b89-4e07-a2a4-579e898a5640",
"2399d300-6fca-4e6a-a686-399fefe75b83",
"b78f6a77-d4e5-46fb-87e5-d1648bd02519",
"0de14c77-b9b0-4137-9360-34878a929827"
)
| where IPAddress !startswith "fde4:"
| where TimeGenerated >= datetime(2026-10-13)
| project TimeGenerated, AppId, IPAddress, ResourceDisplayName, ResultType
Backdoor Credential Detection
Hunt for new credentials (client secrets or certificates) added to enterprise applications between October 13 and present. Focus on secrets with abnormally long expiration dates (2028+). In Entra audit logs, filter for operations Add service principal credentials and Update application - Certificates and secrets management [6].
AuditLogs
| where OperationName in ("Add service principal credentials", "Update application - Certificates and secrets management")
| where TimeGenerated >= datetime(2026-10-13)
| extend InitiatedByApp = tostring(InitiatedBy.app.displayName)
| where InitiatedByApp contains "ConnectWise" or InitiatedByApp contains "Cloud Management"
| project TimeGenerated, OperationName, InitiatedByApp, TargetResources
Role Assignment Anomalies
Look for any application granting itself a directory role, especially Global Administrator or Exchange Administrator. This is the privilege escalation pattern Storm-0940 used in confirmed compromises [7][8][17].
AuditLogs
| where OperationName == "Add member to role"
| where TimeGenerated >= datetime(2026-10-13)
| extend InitiatedByApp = tostring(InitiatedBy.app.displayName)
| extend RoleName = tostring(TargetResources[0].modifiedProperties[1].newValue)
| where RoleName has_any ("Global Administrator", "Exchange Administrator")
| project TimeGenerated, InitiatedByApp, RoleName, TargetResources
User Agent and IP Alerting
Alert on Python-urllib/3.12 and python-requests/2.31 user agents in service principal sign-in logs. While these user agents are not inherently malicious, their presence in app-only authentication flows for backup applications is abnormal.
Sigma Rule: Suspicious ConnectWise Application Sign-In from Non-Azure IP
title: ConnectWise Cloud Backup Sign-In from Non-Azure IP
id: f8a2c1d0-7e3b-4a19-9c5d-1b2e3f4a5b6c
status: experimental
description: Detects service principal sign-ins for ConnectWise Cloud Backup or Cloud Management applications from non-Azure IP addresses
author: RedSheepSec
date: 2026/10/22
logsource:
product: azure
service: signinlogs
detection:
selection:
AppId|contains:
- '506e08f9-6e9a-4da4-942b-a099a03644ae'
- '24205314-2b89-4e07-a2a4-579e898a5640'
- '2399d300-6fca-4e6a-a686-399fefe75b83'
filter:
IPAddress|startswith: 'fde4:'
condition: selection and not filter
falsepositives:
- Legitimate ConnectWise infrastructure changes
level: high
tags:
- attack.t1078.004
- attack.t1195.002
Analysis
This incident represents a significant operational shift for Storm-0940. The group's historical reliance on the Quad7 botnet for password spraying was a known, relatively slow method [10]. The adoption of ARTEX compressed the attack timeline from days to hours. Microsoft observed the group move from initial targeting to privileged cloud access in under three hours in some environments [11][21]. The 2,900 sign-in attempts per minute throughput demonstrates what agentic AI tooling enables when pointed at application-layer authentication flows that lack rate limiting or anomaly detection [9][10].
The architectural weakness here is structural, not specific to ConnectWise. Any multi-tenant SaaS application that holds broad Microsoft Graph permissions and authenticates via client assertion presents the same risk profile. A single compromised vendor credential fans out to every consenting tenant simultaneously. Customer-side controls (MFA, conditional access) are irrelevant to app-only authentication [4][14].
The apparent restraint in post-compromise activity is notable. Despite access to approximately 162 confirmed tenants and sign-in attempts against over 2,250, Huntress found deep post-compromise persistence (Global Admin escalation, backdoor credentials) in at least two of the tenants it investigated [6]. No evidence of bulk data exfiltration, mailbox manipulation, or user/policy changes was found in those investigated tenants [6][14]. This pattern is consistent with targeted collection rather than opportunistic exploitation.
Reporting from Huntress suggests the second wave on October 15 included tenants in policy, national security, trade, and critical mineral sectors [17]. This targeting aligns with Storm-0940's known collection priorities.
Red Sheep Assessment
Confidence: Moderate
Available evidence suggests that Storm-0940's primary objective was targeted intelligence collection from a small number of high-value tenants, with the mass sign-in wave serving primarily as cover or as an automated enumeration pass to identify which tenants contained relevant data. The evidence: persistence was established in at least two of the tenants Huntress investigated [6], the second wave targeted specific sectors [17], and no signs of bulk data theft appeared in forensically examined tenants [6][14]. The group likely had a priority target list and used ARTEX's speed to move through the full tenant population faster than defenders could respond, while selectively deepening access only where collection requirements warranted it.
An alternative interpretation: the rapid containment by ConnectWise (disabling application identities within roughly 48 hours of the main wave) may have cut short a broader persistence campaign before the actor could complete it. The five-minute average time to persistent access [2] suggests the tooling was ready for mass deployment, and the 2028-dated credentials indicate an intent for long-term access that the actor may have planned to establish more widely.
The ARTEX component warrants distinct analysis. We assess this is likely the first publicly confirmed nation-state use of an agentic AI framework in an active supply-chain operation. The framework's widespread forking before going closed-source [12] means the tooling is widely available. Other threat actors, state-sponsored or otherwise, can replicate Storm-0940's operational tempo. Organizations should expect AI-accelerated OAuth abuse and application-layer attacks to become a recurring pattern rather than an isolated incident.
Microsoft's explicit statement that this activity "did not result from a compromise of, or a vulnerability in, its own corporate systems, products or services" [18] places the defensive burden squarely on SaaS vendors managing multi-tenant application credentials and on the enterprises that consent to those applications.
Defender's Checklist
- ▢[ ] Review Entra service principal sign-in logs for the five ConnectWise Application IDs listed above, filtering for any sign-ins from non-Azure IP addresses, particularly
144.172.64.0/24. Use the KQL queries provided in the Detection section.
- ▢[ ] Audit all application credentials and role assignments in your tenant since October 13. Search Entra audit logs for
Add service principal credentialsandAdd member to roleoperations. Any new client secrets with expiration dates in 2028 or later on applications you did not modify warrant immediate investigation and revocation.
- ▢[ ] Disable, do not delete, the affected ConnectWise applications in your tenant until ConnectWise provides formal reconnection instructions [5]. Deleting the service principal removes the audit trail needed for forensic review.
- ▢[ ] Inventory all multi-tenant SaaS applications with broad Microsoft Graph permissions (Mail.Read, Files.ReadWrite.All, Directory.ReadWrite.All) in your environment. Use the Entra admin center Enterprise Applications blade filtered by application permissions, or run
Get-MgServicePrincipalwithGet-MgServicePrincipalAppRoleAssignmentin Microsoft Graph PowerShell to enumerate high-privilege application permissions. Evaluate whether each application still requires those permissions and whether conditional access for workload identities can restrict their sign-in to expected IP ranges.
- ▢[ ] Implement Microsoft Graph activity logging to gain visibility into what data applications actually access in your tenant, not just whether they authenticated. Graph activity logs capture read operations on mailboxes, files, and directory objects that service principal sign-in logs alone do not reveal.
References
[1] https://cyberscoop.com/connectwise-cloud-backup-supply-chain-attack/
[2] https://www.bankinfosecurity.com/connectwise-suspends-cloud-backup-services-as-probes-hack-a-33142
[3] https://thehackernews.com/2026/10/hackers-use-compromised-connectwise.html
[4] https://techleetsolutions.com/news/posts/2026-10-18-connectwise-skykick-m365-breach
[5] https://www.connectwise.com/company/trust/advisories
[6] https://thehackernews.com/2026/10/connectwise-resets-credentials-as-cloud.html
[7] https://guardz.com/blog/connectwise-skykick-breach-in-microsoft-365/
[8] https://thecybersecguru.com/news/connectwise-cloud-backup-breach/
[9] https://cyberscoop.com/microsoft-attributes-connectwise-supply-chain-attack-china-storm-0940/
[10] https://thehackernews.com/2026/10/china-linked-hackers-use-artex-ai.html
[11] https://www.theregister.com/security/2026/10/22/microsoft-says-connectwise-breach-let-chinese-spies-loose-on-2250-cloud-tenants/5304687
[12] https://www.wiz.io/blog/artex-in-the-wild-storm-0940-expands-targeting-of-it-and-software-vendors
[13] https://www.techtimes.com/articles/329360/20261022/chinas-ai-agent-hacked-2250-microsoft-365-tenants-hours-mfa-didnt-apply.htm
[14] https://dev.to/anoymask/connectwise-cloud-backup-breach-stolen-app-credentials-used-to-compromise-microsoft-365-tenants-pcn
[15] https://www.rescana.com/post/connectwise-cloud-backup-supply-chain-attack-analysis-of-microsoft-365-tenant-compromise-and-mitigation-strategies
[16] https://www.newsbeep.com/au/932475/
[17] https://safeguard.sh/resources/blog/connectwise-microsoft-365-supply-chain-attack
[18] https://brandefense.io/security-news/storm-0940-artex-connectwise-supply-chain-attack/
[19] https://tech-insider.org/connectwise-cloud-backup-breach-173-tenants-2026/
[20] https://www.decryptiondigest.com/blog/connectwise-cloud-backup-supply-chain-attack
[21] https://aiweekly.co/alerts/microsoft-ties-storm-0940-to-artex-driven-connectwise-hack
Event Timeline
Timeline
Entity Relationships
Entity Graph (15 entities, 6 relationships)
Diamond Model
Diamond Model
Hunt Guide: Storm-0940 ConnectWise Cloud Backup Supply-Chain Compromise via ARTEX AI Framework
Attribution: Rules adapted, ported, or quoted from a public source retain that source's author (e.g. SigmaHQ / Florian Roth, Elastic, Emerging Threats, Abuse.ch, or the cited vendor/researcher) and carry an attribution credit. Rules without a credit were authored in-house by RedSheepSec. If you reuse a rule, preserve its stated attribution.
Hypothesis: If Storm-0940 exploited the stolen ConnectWise Cloud Backup client assertion to access our Microsoft 365 tenant, we expect to observe service principal sign-ins from the five implicated ConnectWise Application IDs originating from non-Azure IP addresses (particularly 144.172.64.0/24, 155.133.5.0/24, 118.69.65.60, 144.172.94.243), anomalous application role assignments (Global Administrator, Exchange Administrator), and new client secrets with long-lived expiration dates in Entra audit logs, Azure AD sign-in logs, and cloud-azure event data.
Intelligence Summary: Microsoft assessed on October 21, 2026 that Storm-0940, a China state-aligned threat actor, stole a ConnectWise Cloud Backup client assertion and used the ARTEX agentic AI framework to authenticate against more than 2,250 Microsoft 365 tenants. Huntress confirmed unauthorized sign-ins in approximately 162 tenants, with at least two showing privilege escalation to Global Administrator and backdoor credential implantation on other trusted applications. The attack bypassed all customer-side MFA and conditional access controls because the compromised credential was an app-only client assertion authenticating machine-to-machine.
Confidence: Moderate | Priority: Critical
Scope
- Networks: All Microsoft 365 tenants with ConnectWise Cloud Backup, SaaS Security, or Cloud Management applications consented. All Entra ID environments. All network segments with outbound connectivity to Microsoft Graph API endpoints.
- Timeframe: October 10, 2026 through present. Primary attack window: October 10-17, 2026. Backdoor credentials may persist through 2028; ongoing monitoring required.
- Priority Systems: Entra ID tenant directories, Exchange Online mailboxes, SharePoint/OneDrive file stores, any application with Global Administrator or Exchange Administrator role assignments. Prioritize tenants in policy, national security, trade, critical mineral, defense, and legal sectors.
MITRE ATT&CK Techniques
T1195.002: Supply Chain Compromise: Compromise Software Supply Chain (Initial Access) [P1]
Storm-0940 stole a client assertion belonging to the ConnectWise Cloud Backup vendor application. This single credential provided access to every Microsoft 365 tenant that had granted ConnectWise consent, enabling cross-tenant compromise without exploiting any vulnerability in Microsoft or the customer environments themselves.
Splunk SPL:
index=cloud-azure sourcetype="azure:monitor:aad" OR sourcetype="mscs:azure:audit" OR sourcetype="azure:json"
| eval AppId=coalesce(properties.appId, appId, properties.servicePrincipalId)
| where AppId IN ("506e08f9-6e9a-4da4-942b-a099a03644ae", "24205314-2b89-4e07-a2a4-579e898a5640", "2399d300-6fca-4e6a-a686-399fefe75b83", "b78f6a77-d4e5-46fb-87e5-d1648bd02519", "0de14c77-b9b0-4137-9360-34878a929827")
| eval src_ip=coalesce(properties.ipAddress, callerIpAddress)
| where NOT match(src_ip, "^fde4:")
| table _time, AppId, src_ip, properties.resourceDisplayName, properties.status.errorCode, user
| sort - _time
Elastic KQL:
azure.signinlogs.properties.app_id:("506e08f9-6e9a-4da4-942b-a099a03644ae" OR "24205314-2b89-4e07-a2a4-579e898a5640" OR "2399d300-6fca-4e6a-a686-399fefe75b83" OR "b78f6a77-d4e5-46fb-87e5-d1648bd02519" OR "0de14c77-b9b0-4137-9360-34878a929827") AND NOT source.ip:fde4\:*
Sigma Rule:
title: ConnectWise Cloud Backup Service Principal Sign-In from Non-Azure IP
id: f8a2c1d0-7e3b-4a19-9c5d-1b2e3f4a5b6c
status: experimental
description: Detects service principal sign-ins for ConnectWise Cloud Backup or Cloud Management applications from non-Azure IP addresses, indicative of the Storm-0940 supply-chain compromise using a stolen client assertion.
author: RedSheepSec
date: 2026/10/22
references:
- https://cyberscoop.com/microsoft-attributes-connectwise-supply-chain-attack-china-storm-0940/
- https://thehackernews.com/2026/10/hackers-use-compromised-connectwise.html
logsource:
product: azure
service: signinlogs
detection:
selection:
properties.appId|contains:
- '506e08f9-6e9a-4da4-942b-a099a03644ae'
- '24205314-2b89-4e07-a2a4-579e898a5640'
- '2399d300-6fca-4e6a-a686-399fefe75b83'
- 'b78f6a77-d4e5-46fb-87e5-d1648bd02519'
- '0de14c77-b9b0-4137-9360-34878a929827'
filter:
properties.ipAddress|startswith: 'fde4:'
condition: selection and not filter
falsepositives:
- Legitimate ConnectWise infrastructure IP changes during migration
level: high
tags:
- attack.initial_access
- attack.t1195.002
- attack.t1078.004
Legitimate ConnectWise Cloud Backup traffic originates from Azure private IPv6 space (fde4: prefix). Any sign-in from a public IPv4 address is anomalous. The five Application IDs are the ones ConnectWise disabled on October 17; any sign-in activity after that date is highly suspicious.
T1078.004: Valid Accounts: Cloud Accounts (Defense Evasion) [P1]
Storm-0940 authenticated as the ConnectWise Cloud Backup service principal using the stolen client assertion. The actor obtained Microsoft Graph tokens from attacker infrastructure, moving through tenants in sorted GUID order consistent with automated scripting. User agents Python-urllib/3.12 and python-requests/2.31 were observed.
Splunk SPL:
index=cloud-azure sourcetype="azure:monitor:aad" OR sourcetype="azure:json"
| eval user_agent=coalesce(properties.userAgent, userAgent)
| eval src_ip=coalesce(properties.ipAddress, callerIpAddress)
| where match(user_agent, "(?i)(Python-urllib|python-requests)")
| eval AppId=coalesce(properties.appId, appId)
| stats count by AppId, src_ip, user_agent, _time
| where count > 5
| sort - count
Elastic KQL:
azure.signinlogs.properties.user_agent:("Python-urllib/3.12" OR "python-requests/2.31") AND azure.signinlogs.properties.service_principal_id:*
Sigma Rule:
title: Python User Agent in Azure Service Principal Sign-In
id: a7c3d2e1-5f8b-4c09-b1d4-2e3f5a6b7c8d
status: experimental
description: Detects Python-based user agents in service principal sign-in logs, which is abnormal for legitimate backup application authentication flows and was observed in the Storm-0940 ConnectWise supply-chain attack.
author: RedSheepSec
date: 2026/10/22
references:
- https://thehackernews.com/2026/10/hackers-use-compromised-connectwise.html
logsource:
product: azure
service: signinlogs
detection:
selection:
properties.userAgent|contains:
- 'Python-urllib'
- 'python-requests'
condition: selection
falsepositives:
- Legitimate Python-based automation scripts authenticating as service principals
- Internal DevOps tooling using Python SDKs
level: medium
tags:
- attack.defense_evasion
- attack.t1078.004
Python user agents in service principal sign-in logs may occur with legitimate automation. Correlate with the ConnectWise Application IDs and attacker IP ranges for high-fidelity alerting. Volume and timing patterns (sorted GUID order, seconds apart) are additional discriminators.
T1098.003: Account Manipulation: Additional Cloud Roles (Persistence) [P1]
In at least one confirmed tenant, the ConnectWise Cloud Management MS Teams application (App ID 24205314-2b89-4e07-a2a4-579e898a5640) self-assigned itself to the Global Administrator role. Huntress also observed Exchange Administrator role assignments in approximately 50 tenants.
Splunk SPL:
index=cloud-azure sourcetype="azure:monitor:aad" OR sourcetype="mscs:azure:audit" OR sourcetype="azure:json"
| eval operation=coalesce(operationName, properties.operationName, activityDisplayName)
| where operation="Add member to role"
| eval initiator_app=coalesce(properties.initiatedBy.app.displayName, initiatedBy.app.displayName)
| eval target_role=coalesce(properties.targetResources{}.modifiedProperties{}.newValue, mvindex('properties.targetResources{}.modifiedProperties{}.newValue', 0))
| where match(target_role, "(?i)(Global Administrator|Exchange Administrator|Company Administrator)")
| table _time, operation, initiator_app, target_role, properties.targetResources{}.displayName
| sort - _time
Elastic KQL:
azure.auditlogs.operation_name:"Add member to role" AND azure.auditlogs.properties.target_resources.modified_properties.new_value:("Global Administrator" OR "Exchange Administrator" OR "Company Administrator")
Sigma Rule:
title: Application Self-Assignment to Global or Exchange Administrator Role
id: b8d4e3f2-6a9c-4d18-a2e5-3f4a6b7c8d9e
status: experimental
description: Detects an application adding itself or another application to the Global Administrator or Exchange Administrator directory role, as observed in the Storm-0940 ConnectWise supply-chain compromise.
author: RedSheepSec
date: 2026/10/22
references:
- https://guardz.com/blog/connectwise-skykick-breach-in-microsoft-365/
- https://techleetsolutions.com/news/posts/2026-10-18-connectwise-skykick-m365-breach
logsource:
product: azure
service: auditlogs
detection:
selection_operation:
operationName: 'Add member to role'
selection_role:
properties.targetResources.modifiedProperties.newValue|contains:
- 'Global Administrator'
- 'Exchange Administrator'
- 'Company Administrator'
selection_initiator:
properties.initiatedBy.app.displayName|exists: true
condition: selection_operation and selection_role and selection_initiator
falsepositives:
- Legitimate first-party Microsoft applications performing role assignments during provisioning
level: critical
tags:
- attack.persistence
- attack.t1098.003
Any application self-assigning Global Administrator or Exchange Administrator is critical and warrants immediate investigation. Filter out known first-party Microsoft provisioning events. Cross-reference with the ConnectWise Application IDs for direct attribution.
T1098.001: Account Manipulation: Additional Cloud Credentials (Persistence) [P1]
A Python script added new client secrets with 2028 expiration dates to two other trusted applications in the tenant. These backdoor secrets persist even if the original ConnectWise applications are disabled or removed. Huntress observed this pattern in at least two tenants.
Splunk SPL:
index=cloud-azure sourcetype="azure:monitor:aad" OR sourcetype="mscs:azure:audit" OR sourcetype="azure:json"
| eval operation=coalesce(operationName, properties.operationName, activityDisplayName)
| where operation IN ("Add service principal credentials", "Update application - Certificates and secrets management")
| eval initiator_app=coalesce(properties.initiatedBy.app.displayName, initiatedBy.app.displayName)
| eval target_app=coalesce(properties.targetResources{}.displayName, mvindex('properties.targetResources{}.displayName', 0))
| table _time, operation, initiator_app, target_app, properties.targetResources{}.modifiedProperties{}.newValue
| sort - _time
Elastic KQL:
azure.auditlogs.operation_name:("Add service principal credentials" OR "Update application - Certificates and secrets management")
Sigma Rule:
title: New Client Secret Added to Enterprise Application
id: c9e5f4a3-7b0d-4e29-b3f6-4a5b7c8d9e0f
status: experimental
description: Detects addition of new credentials to enterprise applications, which may indicate backdoor credential implantation as performed by Storm-0940 during the ConnectWise compromise.
author: RedSheepSec
date: 2026/10/22
references:
- https://thehackernews.com/2026/10/connectwise-resets-credentials-as-cloud.html
logsource:
product: azure
service: auditlogs
detection:
selection:
operationName:
- 'Add service principal credentials'
- 'Update application - Certificates and secrets management'
condition: selection
falsepositives:
- Routine credential rotation by IT administrators
- Automated certificate renewal processes
level: high
tags:
- attack.persistence
- attack.t1098.001
Focus on credentials with expiration dates in 2028 or later. Correlate the initiating application with the ConnectWise Application IDs. Any secret addition initiated by an application (rather than a named user) warrants investigation. Secrets added between October 13-17, 2026 are highest priority.
T1087.004: Account Discovery: Cloud Account (Discovery) [P2]
Storm-0940 used the broad Microsoft Graph permissions held by the ConnectWise applications to read directory data, enumerate users, and discover accounts across compromised tenants. All actions were performed using legitimate administrative tools and credentials.
Splunk SPL:
index=cloud-azure sourcetype="azure:monitor:aad" OR sourcetype="azure:json"
| eval operation=coalesce(operationName, activityDisplayName)
| where match(operation, "(?i)(List users|Get user|List members|Read directory data)")
| eval initiator_app=coalesce(properties.initiatedBy.app.displayName, initiatedBy.app.displayName)
| where isnotnull(initiator_app)
| stats count by initiator_app, operation, _time
| where count > 50
| sort - count
Elastic KQL:
azure.auditlogs.operation_name:("List users" OR "Get user" OR "List members" OR "Read directory data") AND azure.auditlogs.properties.initiated_by.app.display_name:*
Microsoft Graph activity logging must be enabled to gain full visibility into directory read operations. Service principal sign-in logs alone do not reveal what data was accessed post-authentication.
T1114.002: Email Collection: Remote Email Collection (Collection) [P2]
The ConnectWise Cloud Backup application holds read and write access to Exchange mailboxes via Microsoft Graph permissions across every tenant where it is installed. Storm-0940 could leverage these permissions for mailbox access without requiring user-level authentication.
Splunk SPL:
index=cloud-azure sourcetype="azure:json" OR sourcetype="azure:monitor:aad"
| eval operation=coalesce(operationName, activityDisplayName)
| where match(operation, "(?i)(MailItemsAccessed|MailboxLogin|mail\.read|messages)")
| eval initiator_app=coalesce(properties.initiatedBy.app.displayName, initiatedBy.app.displayName)
| eval src_ip=coalesce(properties.ipAddress, callerIpAddress)
| where isnotnull(initiator_app)
| table _time, initiator_app, operation, src_ip
| sort - _time
Elastic KQL:
azure.activitylogs.operation_name:("MailItemsAccessed" OR "MailboxLogin") AND source.ip:("144.172.64.128" OR "144.172.64.99" OR "144.172.64.60" OR "155.133.5.15" OR "155.133.5.14" OR "118.69.65.60" OR "144.172.94.243")
Requires Microsoft Purview Audit (Premium) or equivalent for MailItemsAccessed events. Correlate with attacker IPs and ConnectWise Application IDs for high-fidelity detection.
T1550.001: Use Alternate Authentication Material: Application Access Token (Defense Evasion) [P1]
Storm-0940 obtained Microsoft Graph access tokens using the compromised ConnectWise client assertion. Tokens were obtained from 144.172.64.128 between 06:13 and 08:34 UTC on October 15, with the actor moving through tenants in sorted GUID order seconds apart.
Splunk SPL:
index=cloud-azure sourcetype="azure:monitor:aad" OR sourcetype="azure:json"
| eval AppId=coalesce(properties.appId, appId)
| eval src_ip=coalesce(properties.ipAddress, callerIpAddress)
| where src_ip IN ("144.172.64.128", "144.172.64.99", "144.172.64.60", "155.133.5.15", "155.133.5.14", "118.69.65.60", "144.172.94.243", "187.15.88.186", "187.15.90.217", "187.15.89.186")
| eval resource=coalesce(properties.resourceDisplayName, resourceDisplayName)
| table _time, AppId, src_ip, resource, properties.status.errorCode
| sort _time
Elastic KQL:
source.ip:("144.172.64.128" OR "144.172.64.99" OR "144.172.64.60" OR "155.133.5.15" OR "155.133.5.14" OR "118.69.65.60" OR "144.172.94.243" OR "187.15.88.186" OR "187.15.90.217" OR "187.15.89.186") AND azure.signinlogs.properties.service_principal_id:*
Direct IOC match on attacker infrastructure. Any service principal sign-in from these IPs should be treated as confirmed compromise and escalated immediately.
Indicators of Compromise
| Type | Value | Context | |
|---|---|---|---|
| ip | 144.172.64.128 |
Primary attacker IP for tenant sign-ins on October 15; used to obtain Microsoft Graph tokens and authenticate as ConnectWise Cloud Backup service principal \ | AbuseIPDB confidence 21% (5 reports, AU) |
| ip | 144.172.64.99 |
Password-spray infrastructure used October 10-14 against Microsoft 365 and Exchange Online accounts, generating over 151,000 failed logon attempts \ | AbuseIPDB confidence 11% (2 reports, AU) |
| ip | 144.172.64.60 |
Additional attacker IP shared by ConnectWise in advisory \ | AbuseIPDB confidence 1% (1 reports, AU) |
| ip | 155.133.5.15 |
ConnectWise-listed threat actor IP \ | AbuseIPDB confidence 0% (0 reports, US) |
| ip | 155.133.5.14 |
ConnectWise-listed threat actor IP \ | AbuseIPDB confidence 0% (0 reports, US) |
| ip | 118.69.65.60 |
ConnectWise-listed threat actor IP in Vietnamese IP space, likely proxy infrastructure \ | AbuseIPDB confidence 0% (0 reports, VN) |
| ip | 144.172.94.243 |
Huntress-identified IP used for password spray activity \ | AbuseIPDB confidence 43% (115 reports, US) |
| ip | 187.15.88.186 |
VPN IP used to reach Graph API in breach, identified by Brandefense \ | AbuseIPDB confidence 0% (0 reports, US) |
| ip | 187.15.90.217 |
VPN IP used to reach Graph API in breach, identified by Brandefense \ | AbuseIPDB confidence 0% (0 reports, US) |
| ip | 187.15.89.186 |
VPN IP used to reach Graph API in breach, identified by Brandefense \ | AbuseIPDB confidence 0% (1 reports, US) |
IOC Sweep Queries (Splunk):
index=cloud-azure sourcetype="azure:monitor:aad" OR sourcetype="azure:json"
| eval src_ip=coalesce(properties.ipAddress, callerIpAddress)
| where src_ip="144.172.64.128"
| table _time, src_ip, properties.appId, properties.resourceDisplayName, properties.status.errorCode
| sort - _time
index=cloud-azure sourcetype="azure:monitor:aad" OR sourcetype="azure:json"
| eval src_ip=coalesce(properties.ipAddress, callerIpAddress)
| where src_ip="144.172.64.99"
| table _time, src_ip, properties.appId, properties.status.errorCode, properties.userPrincipalName
| sort - _time
index=cloud-azure sourcetype="azure:monitor:aad" OR sourcetype="azure:json"
| eval src_ip=coalesce(properties.ipAddress, callerIpAddress)
| where src_ip="144.172.64.60"
| table _time, src_ip, properties.appId, properties.status.errorCode
| sort - _time
index=cloud-azure sourcetype="azure:monitor:aad" OR sourcetype="azure:json"
| eval src_ip=coalesce(properties.ipAddress, callerIpAddress)
| where src_ip="155.133.5.15"
| table _time, src_ip, properties.appId, properties.status.errorCode
| sort - _time
index=cloud-azure sourcetype="azure:monitor:aad" OR sourcetype="azure:json"
| eval src_ip=coalesce(properties.ipAddress, callerIpAddress)
| where src_ip="155.133.5.14"
| table _time, src_ip, properties.appId, properties.status.errorCode
| sort - _time
index=cloud-azure sourcetype="azure:monitor:aad" OR sourcetype="azure:json"
| eval src_ip=coalesce(properties.ipAddress, callerIpAddress)
| where src_ip="118.69.65.60"
| table _time, src_ip, properties.appId, properties.status.errorCode
| sort - _time
index=cloud-azure sourcetype="azure:monitor:aad" OR sourcetype="azure:json"
| eval src_ip=coalesce(properties.ipAddress, callerIpAddress)
| where src_ip="144.172.94.243"
| table _time, src_ip, properties.appId, properties.status.errorCode
| sort - _time
index=cloud-azure sourcetype="azure:monitor:aad" OR sourcetype="azure:json"
| eval src_ip=coalesce(properties.ipAddress, callerIpAddress)
| where src_ip="187.15.88.186"
| table _time, src_ip, properties.appId, properties.status.errorCode
| sort - _time
index=cloud-azure sourcetype="azure:monitor:aad" OR sourcetype="azure:json"
| eval src_ip=coalesce(properties.ipAddress, callerIpAddress)
| where src_ip="187.15.90.217"
| table _time, src_ip, properties.appId, properties.status.errorCode
| sort - _time
index=cloud-azure sourcetype="azure:monitor:aad" OR sourcetype="azure:json"
| eval src_ip=coalesce(properties.ipAddress, callerIpAddress)
| where src_ip="187.15.89.186"
| table _time, src_ip, properties.appId, properties.status.errorCode
| sort - _time
YARA Rules
ARTEX_Framework_Strings: Detects ARTEX agentic AI penetration-testing framework binaries or artifacts based on string patterns observed in the Go-based tool used by Storm-0940
rule ARTEX_Framework_Strings {
meta:
author = "RedSheepSec"
description = "Detects ARTEX agentic AI framework strings in Go binaries or related artifacts"
date = "2026-10-22"
reference = "https://www.wiz.io/blog/artex-in-the-wild-storm-0940-expands-targeting-of-it-and-software-vendors"
threat_actor = "Storm-0940"
strings:
$s1 = "artex" ascii nocase
$s2 = "Autumn-27" ascii
$s3 = "planner_agent" ascii
$s4 = "worker_agent" ascii
$s5 = "shared_task_list" ascii
$s6 = "dual_graph" ascii
$go1 = "go.mod" ascii
$go2 = "github.com/" ascii
$next1 = "next.js" ascii nocase
$next2 = "_next/static" ascii
$pg1 = "postgresql" ascii nocase
condition:
(3 of ($s*)) or ($s1 and any of ($go*) and any of ($next*, $pg1))
}
Suricata Rules
SID 9000001: Detects outbound connection to Storm-0940 primary attacker IP 144.172.64.128 used for ConnectWise supply-chain attack
alert ip any any -> 144.172.64.128 any (msg:"HUNT Storm-0940 Attacker IP 144.172.64.128 - ConnectWise Supply Chain"; classtype:trojan-activity; sid:9000001; rev:1; reference:url,cyberscoop.com/microsoft-attributes-connectwise-supply-chain-attack-china-storm-0940/; metadata:created_at 2026_10_22;)
SID 9000002: Detects outbound connection to Storm-0940 password-spray IP 144.172.64.99
alert ip any any -> 144.172.64.99 any (msg:"HUNT Storm-0940 Password Spray IP 144.172.64.99 - ConnectWise Supply Chain"; classtype:trojan-activity; sid:9000002; rev:1; reference:url,thehackernews.com/2026/10/hackers-use-compromised-connectwise.html; metadata:created_at 2026_10_22;)
SID 9000003: Detects outbound connection to Storm-0940 attacker IP 144.172.64.60
alert ip any any -> 144.172.64.60 any (msg:"HUNT Storm-0940 Attacker IP 144.172.64.60 - ConnectWise Supply Chain"; classtype:trojan-activity; sid:9000003; rev:1; reference:url,socradar.io/blog/connectwise-cloud-backup-breach/; metadata:created_at 2026_10_22;)
SID 9000004: Detects outbound connection to ConnectWise-listed threat actor IP 155.133.5.15
alert ip any any -> 155.133.5.15 any (msg:"HUNT Storm-0940 Threat Actor IP 155.133.5.15 - ConnectWise Supply Chain"; classtype:trojan-activity; sid:9000004; rev:1; reference:url,connectwise.com/company/trust/advisories; metadata:created_at 2026_10_22;)
SID 9000005: Detects outbound connection to ConnectWise-listed threat actor IP 155.133.5.14
alert ip any any -> 155.133.5.14 any (msg:"HUNT Storm-0940 Threat Actor IP 155.133.5.14 - ConnectWise Supply Chain"; classtype:trojan-activity; sid:9000005; rev:1; reference:url,connectwise.com/company/trust/advisories; metadata:created_at 2026_10_22;)
SID 9000006: Detects outbound connection to ConnectWise-listed threat actor IP 118.69.65.60 (Vietnamese proxy)
alert ip any any -> 118.69.65.60 any (msg:"HUNT Storm-0940 Threat Actor IP 118.69.65.60 - ConnectWise Supply Chain"; classtype:trojan-activity; sid:9000006; rev:1; reference:url,connectwise.com/company/trust/advisories; metadata:created_at 2026_10_22;)
SID 9000007: Detects outbound connection to Huntress-identified password spray IP 144.172.94.243
alert ip any any -> 144.172.94.243 any (msg:"HUNT Storm-0940 Password Spray IP 144.172.94.243 - ConnectWise Supply Chain"; classtype:trojan-activity; sid:9000007; rev:1; reference:url,safeguard.sh/resources/blog/connectwise-microsoft-365-supply-chain-attack; metadata:created_at 2026_10_22;)
SID 9000008: Detects HTTP traffic with Python-urllib/3.12 user agent targeting Microsoft login endpoints, consistent with Storm-0940 automated token acquisition
alert http any any -> any any (msg:"HUNT Storm-0940 Python-urllib User Agent to Microsoft Auth"; flow:established,to_server; content:"Python-urllib/3.12"; http_user_agent; content:"login.microsoftonline.com"; http_host; classtype:trojan-activity; sid:9000008; rev:1; metadata:created_at 2026_10_22;)
SID 9000009: Detects outbound connection to Storm-0940 VPN IP 187.15.88.186 used to reach Graph API
alert ip any any -> 187.15.88.186 any (msg:"HUNT Storm-0940 VPN IP 187.15.88.186 - Graph API Access"; classtype:trojan-activity; sid:9000009; rev:1; reference:url,brandefense.io/security-news/storm-0940-artex-connectwise-supply-chain-attack/; metadata:created_at 2026_10_22;)
SID 9000010: Detects outbound connection to Storm-0940 VPN IP 187.15.90.217 used to reach Graph API
alert ip any any -> 187.15.90.217 any (msg:"HUNT Storm-0940 VPN IP 187.15.90.217 - Graph API Access"; classtype:trojan-activity; sid:9000010; rev:1; reference:url,brandefense.io/security-news/storm-0940-artex-connectwise-supply-chain-attack/; metadata:created_at 2026_10_22;)
SID 9000011: Detects outbound connection to Storm-0940 VPN IP 187.15.89.186 used to reach Graph API
alert ip any any -> 187.15.89.186 any (msg:"HUNT Storm-0940 VPN IP 187.15.89.186 - Graph API Access"; classtype:trojan-activity; sid:9000011; rev:1; reference:url,brandefense.io/security-news/storm-0940-artex-connectwise-supply-chain-attack/; metadata:created_at 2026_10_22;)
Data Source Requirements
| Source | Required For | Notes |
|---|---|---|
| Azure AD Service Principal Sign-In Logs | T1195.002, T1078.004, T1550.001 | Primary detection surface for this attack. Ensure service principal sign-in logs are ingested into index=cloud-azure. These are separate from interactive and non-interactive user sign-in logs. Verify retention covers at least October 10-22, 2026. |
| Entra Audit Logs | T1098.003, T1098.001, T1087.004 | Required for detecting role assignments and credential additions. Must be flowing into index=cloud-azure with sourcetype azure:monitor:aad or mscs:azure:audit. Verify audit log retention and completeness. |
| Microsoft Graph Activity Logs | T1087.004, T1114.002 | Graph activity logs capture read operations on mailboxes, files, and directory objects that sign-in logs do not reveal. This is a significant gap if not enabled. Requires Microsoft Entra workbook or diagnostic settings configured to export Graph activity logs. |
| Unified Audit Log (Exchange Online) | T1114.002 | MailItemsAccessed events require Microsoft Purview Audit (Premium) licensing. Essential for determining whether mailbox data was actually accessed post-authentication. |
| Network Firewall Logs (Palo Alto) | T1195.002, T1550.001 | index=firewall-pan for perimeter IOC sweeps against attacker IP addresses. Useful for identifying any direct infrastructure communication, though most attack traffic routes through Microsoft cloud endpoints. |
| Zeek/Corelight Network Metadata | T1550.001 | index=corelight for DNS and HTTP metadata. Check corelight_dns and corelight_http for connections to attacker IP ranges from internal hosts. |
Recommendations
- Execute all P1 detection queries in Appendix detections immediately across index=cloud-azure to determine whether any of the five ConnectWise Application IDs authenticated from attacker infrastructure against our tenants between October 10-22, 2026.
- Audit all enterprise application credentials and directory role assignments in Entra ID since October 13. Revoke any client secrets with expiration dates in 2028 or later that were not created by authorized administrators. Use Get-MgServicePrincipal with Get-MgServicePrincipalAppRoleAssignment in Microsoft Graph PowerShell to enumerate high-privilege application permissions.
- Disable (do not delete) the five ConnectWise application service principals in our tenant until ConnectWise provides formal reconnection guidance. Deletion removes the audit trail needed for forensic review.
- Deploy Suricata rules SID 9000001-9000011 to perimeter IDS/IPS to alert on connections to the ten attacker IP addresses.
- Enable Microsoft Graph activity logging in Entra diagnostic settings if not already configured. Without this, we lack visibility into what data applications accessed post-authentication.
- Inventory all multi-tenant SaaS applications with broad Microsoft Graph permissions. Implement workload identity conditional access policies to restrict service principal sign-ins to expected IP ranges where supported.
- Block attacker IPs 144.172.64.128, 144.172.64.99, 144.172.64.60, 155.133.5.15, 155.133.5.14, 118.69.65.60, 144.172.94.243, 187.15.88.186, 187.15.90.217, and 187.15.89.186 at the perimeter firewall.
- Establish ongoing monitoring for the T1098.003 Sigma rule (application self-assignment to privileged directory roles) as a permanent detection, as this pattern extends beyond this specific campaign.
Sources
- CyberScoop: ConnectWise Cloud Backup Supply Chain Attack
- BankInfoSecurity: ConnectWise Suspends Cloud Backup Services as Probes Hack
- The Hacker News: Hackers Use Compromised ConnectWise
- TechLeet Solutions: ConnectWise SkyKick M365 Breach
- ConnectWise Trust Advisories
- The Hacker News: ConnectWise Resets Credentials as Cloud
- Guardz: ConnectWise SkyKick Breach in Microsoft 365
- The Cybersec Guru: ConnectWise Cloud Backup Breach
- CyberScoop: Microsoft Attributes ConnectWise Supply Chain Attack to China Storm-0940
- The Hacker News: China-Linked Hackers Use ARTEX AI
- The Register: Microsoft Says ConnectWise Breach Let Chinese Spies Loose on 2,250 Cloud Tenants
- Wiz: ARTEX in the Wild - Storm-0940 Expands Targeting of IT and Software Vendors
- TechTimes: China's AI Agent Hacked 2,250 Microsoft 365 Tenants
- Dev.to: ConnectWise Cloud Backup Breach Analysis
- Rescana: ConnectWise Cloud Backup Supply Chain Attack Analysis
- NewsBeep AU
- Safeguard: ConnectWise Microsoft 365 Supply Chain Attack
- Brandefense: Storm-0940 ARTEX ConnectWise Supply Chain Attack
- Tech Insider: ConnectWise Cloud Backup Breach 173 Tenants
- Decryption Digest: ConnectWise Cloud Backup Supply Chain Attack
- AI Weekly: Microsoft Ties Storm-0940 to ARTEX-Driven ConnectWise Hack