ConnectWise Cloud Backup compromise: check your Entra ID tenant for a compromised vendor app
Short answer: if the ConnectWise Cloud Backup app (formerly SkyKick) is in your tenant, look up its service principal sign-ins by app ID, not by name, from 1 October 2026. Then check whether any ConnectWise app gave itself a directory role or added a secret to another app. Disable the apps, don’t delete them, and keep them disabled until ConnectWise tells you how to restore. The steps also work for any other vendor app you need to investigate.
This is a developing incident. Figures below are what each source said on its date. Check the sources for updates before you act.
What happened?
Section titled “What happened?”A credential of the ConnectWise Cloud Backup application was used to get Microsoft Graph tokens in customer Microsoft 365 tenants. Because the app has a service principal in every tenant that consented to it, the same credential could be used in any tenant where the app was installed. Huntress says it was a client assertion credential, which lives in the vendor’s own tenant rather than in customer tenants.
| Date (2026) | What the sources report |
|---|---|
| 10–14 Oct | Microsoft: password spraying from 144.172.64.99 against 327 accounts in eight organizations, with no successful authentication. |
| 15 Oct | Huntress: Graph token sign-ins with the Cloud Backup app from 144.172.64[.]128. In one tenant, the ConnectWise Cloud Management app for Teams added itself to Global Administrator and added new client secrets to two other apps. |
| 16 Oct | Huntress: unauthorized sign-ins confirmed in 162 tenants. |
| 17 Oct | Help Net Security: ConnectWise disabled seven application identities, revoked their certificates and invalidated the shared Cloud Backup credentials. |
| 19 Oct | Help Net Security: Cloud Backup, SaaS Security and Cloud Management still suspended, with no restoration date. |
| 21 Oct | Microsoft attributes the activity to Storm-0940 and says the actor attempted sign-ins to more than 2,250 tenants. |
How the credential was stolen is not public. ConnectWise, as quoted by Help Net Security, says the “original credential-exposure mechanism remains under investigation.” Microsoft notes that the presence of an affected app, or even a successful sign-in by the attacker, does not on its own mean customer data was accessed.
Which apps and indicators should I look for?
Section titled “Which apps and indicators should I look for?”App IDs as listed by Huntress. Microsoft’s blog lists the first, second and fifth (its text says “all four application IDs” but the list has three). Older tenants may show the Cloud Management apps as “SkyKick Cloud Manager”, which is why you search by app ID.
| Application | App ID |
|---|---|
| ConnectWise Cloud Backup (formerly SkyKick) | 506e08f9-6e9a-4da4-942b-a099a03644ae |
| ConnectWise Cloud Management - MS Teams | 24205314-2b89-4e07-a2a4-579e898a5640 |
| ConnectWise Cloud Management | 2399d300-6fca-4e6a-a686-399fefe75b83 |
| ConnectWise Cloud Management - Exchange Online | b78f6a77-d4e5-46fb-87e5-d1648bd02519 |
| ConnectWise Cloud Management - MS Graph | 0de14c77-b9b0-4137-9360-34878a929827 |
| ConnectWise Cloud Management - Partner Center | 412dcf96-176d-4b3a-a1b0-4981ad66971e |
| ConnectWise Cloud Management - SharePoint Online | b2b55f5b-7758-4719-8d8f-88ae172e6bdb |
IP addresses named by Huntress and Microsoft: 144.172.64[.]128, 144.172.64[.]99 and 144.172.64[.]60. Huntress also lists 144.172.94[.]243 for a broad failed login spray, and says it doesn’t believe that address or .60 relate to the app sign-ins. Microsoft lists three transient VPN addresses for 15–16 October: 187.15.88[.]186, 187.15.89[.]186 and 187.15.90[.]217.
Don’t treat the IP list as a clean bill of health. Microsoft tells you not to limit the review to published IPs. Huntress says the app’s normal traffic comes from Azure private IPv6 addresses, but also that the access that led to the secret additions came from that same Azure IPv6 space, and that the address alone doesn’t identify who operated the system. A sign-in from outside Microsoft and Azure ranges needs investigating; an address inside them doesn’t clear it.
How do I check my tenant?
Section titled “How do I check my tenant?”None of these queries has been run in a lab tenant yet. Test them in your own workspace. Microsoft suggests starting the review window on 15 October and extending it to 1 October where your logs allow. The queries use 1 October.
Step 1: Is the app in my tenant, and did it sign in?
Section titled “Step 1: Is the app in my tenant, and did it sign in?”In the Microsoft Entra admin center, the default User sign-ins tab doesn’t show these. Use the Service principal sign-ins tab and filter by app ID. In Log Analytics:
let cwApps = dynamic(["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", "412dcf96-176d-4b3a-a1b0-4981ad66971e", "b2b55f5b-7758-4719-8d8f-88ae172e6bdb"]);AADServicePrincipalSignInLogs| where TimeGenerated > datetime(2026-10-01)| where AppId in (cwApps)| summarize Signins = count(), Resources = make_set(ResourceDisplayName, 10), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by ServicePrincipalName, AppId, IPAddress, ResultType| sort by FirstSeen ascRead the result in two halves, successes (ResultType "0") and failures, as Microsoft
suggests. A success from one of the IPs above means a token was issued to the attacker. A success
from any other address outside Microsoft and Azure ranges needs explaining. Microsoft also warns
that an empty result is not confirmation that no access occurred.
Step 2: Did a vendor app give itself a role or add a secret?
Section titled “Step 2: Did a vendor app give itself a role or add a secret?”This is the step that decides whether the attacker can still get in after the vendor fixes their side. The Entra audit activity names are Add member to role, Add service principal credentials and Update application - Certificates and secrets management. Run two checks: what the ConnectWise apps did, and any credential added to any app since 13 October.
let cwApps = dynamic(["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", "412dcf96-176d-4b3a-a1b0-4981ad66971e", "b2b55f5b-7758-4719-8d8f-88ae172e6bdb"]);AuditLogs| where TimeGenerated > datetime(2026-10-01)| where OperationName == "Add member to role" or OperationName == "Add service principal credentials" or OperationName has "Certificates and secrets management"| extend ActorAppId = tostring(InitiatedBy.app.appId), ActorApp = tostring(InitiatedBy.app.displayName), ActorUser = tostring(InitiatedBy.user.userPrincipalName), Target = tostring(TargetResources[0].displayName)| extend ActorSpId = tostring(InitiatedBy.app.servicePrincipalId)| where ActorAppId in (cwApps) or ActorApp has_any ("ConnectWise", "SkyKick")| project TimeGenerated, OperationName, ActorApp, ActorAppId, ActorSpId, Target, Result| sort by TimeGenerated ascThe filter checks the display name as well as the app ID because, in some audit events, the
actor’s appId may be empty while the display name and service principal ID are filled in
(interpretation; check how the rows look in your tenant).
Second check: every secret or certificate added to any app since 13 October, whoever did it.
AuditLogs| where TimeGenerated > datetime(2026-10-13)| where OperationName == "Add service principal credentials" or OperationName has "Certificates and secrets management"| extend Actor = coalesce(tostring(InitiatedBy.user.userPrincipalName), tostring(InitiatedBy.app.displayName)), Target = tostring(TargetResources[0].displayName)| project TimeGenerated, OperationName, Actor, Target, Result| sort by TimeGenerated ascAny row where a ConnectWise app is the actor is serious. In the second query, look at the targets: in the Huntress case the actor was a ConnectWise app, but the secrets went to an MSP management app and a security vendor’s app. Confirm every addition with whoever owns that app. Also list the directory roles the ConnectWise service principals hold now, and remove any you didn’t grant on purpose.
Step 3: What did the tokens do?
Section titled “Step 3: What did the tokens do?”Sign-in logs show the token request, not what the token was used for. Huntress notes that directory reads through Microsoft Graph leave no audit trail. If you had Microsoft Graph activity logs switched on before 15 October, they show each request:
MicrosoftGraphActivityLogs| where TimeGenerated > datetime(2026-10-01)| 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", "412dcf96-176d-4b3a-a1b0-4981ad66971e", "b2b55f5b-7758-4719-8d8f-88ae172e6bdb")| summarize Requests = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by AppId, IPAddress, RequestMethod| sort by Requests descGraph activity logs need Entra ID P1 or P2 and a diagnostic setting. If you didn’t have them on,
there is no Graph-level record of what was read. Microsoft’s blog has ready-made queries for
Defender XDR and Key Vault tables (OAuthAppInfo, EntraIdSpnSignInEvents,
GraphAPIAuditEvents, CloudKeyVaultEvents) and also tells you to review Purview audit records.
What should I do?
Section titled “What should I do?”- Preserve evidence, but don’t wait for it. Microsoft’s advice: don’t delete enterprise apps as a first step, and export the sign-in and audit logs for the window above. Microsoft also says not to delay urgent containment while waiting for exports.
- Disable, don’t delete. In the Entra admin center, open the enterprise application, then
Properties, and set Enabled for users to sign-in? to No. Microsoft documents that this
sets the service principal’s
accountEnabledtofalseand prevents tokens being issued for the app in your tenant. Deleting moves it to the recycle bin for 30 days, and Huntress warns that it removes the consent you’d need to restore the service later. - Keep it disabled until ConnectWise provides formal restoration instructions (Microsoft) and confirms all credentials have been reset (Huntress). ConnectWise, via Help Net Security, warns that tokens issued before the shutdown may stay usable until they expire, and that disabling its apps doesn’t undo changes already made in your tenant.
- Remove what the attacker added. Any client secret or certificate added since 13 October that you didn’t create (Huntress’s cut-off), any unexpected directory role, and any Conditional Access exclusion for these apps.
- Expect the backup gap. Huntress: while the app is disabled, automated backups pause, but email, files, Teams and user sign-ins keep working.
Does this apply to other vendor apps?
Section titled “Does this apply to other vendor apps?”Yes. Any multitenant app you consent to holds a service principal in your tenant, and whoever holds that vendor’s credential can get tokens for it. Two points to plan for:
- Conditional Access for workload identities doesn’t cover it. Microsoft says it applies to single-tenant service principals registered in your tenant, not multitenant apps. Your levers are the permissions you grant, monitoring, and disabling the app.
- Know your high-privilege vendor apps before an incident. For each one, record its app ID, what it can do and what breaks when you disable it. Step 2’s query, run weekly, catches an app that changes roles or credentials.
For the related case of an attacker’s own app getting consent, see investigating consent phishing. For app secrets stolen from a breached server, see hunting credential reuse after a web-server breach.
What can’t this guide tell me?
Section titled “What can’t this guide tell me?”- Whether data was taken. Without Graph activity logs from before the incident, directory reads aren’t recorded.
- Whether the vendor’s side is clean. That depends on ConnectWise’s investigation.
- Whether the numbers are final. The tenant counts come from Huntress’s and Microsoft’s own visibility on the dates shown.
The queries are based on Microsoft’s schema documentation and the incident write-ups, and have not been reproduced in a lab tenant yet. Until they have, the page is marked as lab test pending.
Sources
- Huntress: vendor credential enables unauthorized access (updated 19 Oct 2026)
- Microsoft Security blog: Storm-0940 uses ARTEX agentic AI in ConnectWise supply chain compromise (21 Oct 2026)
- Help Net Security: ConnectWise suspends Cloud Backup service (19 Oct 2026)
- Disable user sign-in for an application (Microsoft Entra)
- Delete an enterprise application (Microsoft Entra)
- AADServicePrincipalSignInLogs table reference (Azure Monitor)
- Microsoft Entra audit log activities
- Microsoft Graph activity logs overview
- Conditional Access for workload identities