Back to Intelligence

ConnectWise Cloud Backup Supply-Chain Attack: Detecting and Remediating Compromised Microsoft 365 Tenants

SA
Security Arsenal Team
October 17, 2026
12 min read

ConnectWise has shut down customer access to its Cloud Backup service (formerly SkyKick Cloud Backup) after confirming that attackers gained access to the application's identities and used them to compromise downstream Microsoft 365 tenants. This is a supply-chain incident in its purest modern form: the victims did nothing wrong inside their own tenants — the compromise flowed through a trusted third-party SaaS application that held delegated, persistent access to their Microsoft 365 data.

If your organization uses (or has ever used) ConnectWise Cloud Backup / SkyKick Cloud Backup for Microsoft 365 mailbox, OneDrive, SharePoint, or Teams backup, you must assume the application's service principal in your tenant is a suspect identity until proven otherwise. The exposure surface is significant: cloud backup applications, by design, hold broad read access to email and files across the entire tenant. An attacker holding the application's credentials effectively holds the keys to your corporate data archive — with no malware dropped, no endpoints touched, and often no traditional alerting triggered.

This is not a vulnerability you patch. It is an identity compromise you must hunt for and contain. This post breaks down the attack mechanics and gives you concrete detection and remediation content you can run today.

Technical Analysis

What was affected

  • Product: ConnectWise Cloud Backup, formerly SkyKick Cloud Backup (acquired by ConnectWise in 2024)
  • Affected platform: Microsoft 365 tenants where the SkyKick/ConnectWise Cloud Backup enterprise application was consented
  • Attack vector: Compromise of the application identity (service principal credentials — secrets and/or certificates) belonging to the multi-tenant backup application registered by the vendor
  • Vendor response: ConnectWise shut down customer access to the Cloud Backup service while investigating
  • Exploitation status: Confirmed active exploitation in the wild. This is not a theoretical risk — ConnectWise has stated hackers accessed application identities and compromised customer Microsoft 365 tenants
  • CVE: None assigned. This is a credential/identity compromise, not a software flaw — and it is not (and will not be) on the CISA KEV catalog as a CVE-driven event. Do not wait for a CVE to act.

How this class of attack works (defender's view of the kill chain)

Understanding the mechanics matters because it tells you exactly where to hunt:

  1. Trust establishment (historical). At some point, a Global Administrator in the victim tenant granted admin consent to the SkyKick/ConnectWise Cloud Backup application. Multi-tenant backup apps typically request application-level Microsoft Graph permissions such as Mail.Read, Mail.ReadWrite, Sites.Read.All, Files.Read.All, Directory.Read.All, and full_access_as_app for Exchange — permissions that apply tenant-wide with no user interaction required.

  2. Identity compromise (vendor side). The attacker obtained the application's authentication material — client secret and/or certificate — from the vendor's environment. With a multi-tenant app registration, one set of compromised credentials works against every customer tenant where the app was consented. That is the supply-chain multiplier.

  3. Authentication as the application. Using the stolen secret/certificate, the attacker requests OAuth tokens directly from Microsoft's token endpoint (login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token) using the client_credentials flow. Critically, this happens from attacker-controlled infrastructure, not from the vendor's known egress IP ranges. In Microsoft Entra logs, this appears as a service principal sign-in, not a user sign-in — a blind spot in many SOCs.

  4. Data access. With a valid token carrying application permissions, the attacker calls Microsoft Graph and/or Exchange Web Services to enumerate and exfiltrate mailbox content, OneDrive files, and SharePoint data — traffic that looks, at the API layer, like legitimate backup activity.

  5. Potential persistence. Sophisticated actors frequently convert initial application access into durable access: adding their own credentials to the compromised service principal, consenting new malicious OAuth apps, or modifying existing app role assignments.

Why traditional defenses missed it

  • The sign-in is non-interactive service principal authentication — excluded from many identity detections tuned for user logons.
  • Conditional Access policies, by default, do not apply to client credential flows unless you have explicitly configured workload identity CA policies (a premium Entra feature many tenants lack).
  • The Graph API calls come from an application with legitimate, admin-consented permissions — DLP and CASB policies that trust the backup vendor will wave the traffic through.
  • There is no endpoint telemetry — no process execution, no file writes, no EDR footprint. The entire attack lives in cloud control-plane and API logs.

Detection & Response

The hunt has three lanes: (1) anomalous authentication by the SkyKick/ConnectWise app identity, (2) persistence modifications to service principals and consents, and (3) anomalous Graph API data access volume. Every rule below is tuned against behaviors observed in this exact attack class — validate thresholds against your own baseline before production deployment.

YAML
---
title: Credential Added to Existing Service Principal or Application
description: Detects the addition of new secrets or certificates to an existing app registration or service principal, a common persistence technique after application identity compromise as seen in the ConnectWise/SkyKick supply-chain attack.
references:
  - https://www.bleepingcomputer.com/news/security/hackers-breach-microsoft-365-tenants-via-connectwise-supply-chain-attack/
  - https://attack.mitre.org/techniques/T1098/001/
author: Security Arsenal
date: 2026/02/12
tags:
  - attack.persistence
  - attack.t1098.001
logsource:
  product: azure
  service: auditlogs
detection:
  selection:
    operationName:
      - 'Add service principal credentials'
      - 'Update application - Certificates and secrets management'
      - 'Add key credentials to application'
      - 'Add password to application'
  condition: selection
falsepositives:
  - Legitimate secret rotation performed by application owners; verify against change tickets and vendor advisories
level: high
---
title: Admin Consent Granted to Application with High-Risk M365 Data Permissions
id: 4b8f2e71-3c6a-4d5e-9a12-7f0c3b8e2d41
description: Detects new application consent grants carrying broad Microsoft Graph data-access scopes such as Mail.Read or Files.Read.All, the permission class abused in third-party backup application compromises.
references:
  - https://www.bleepingcomputer.com/news/security/hackers-breach-microsoft-365-tenants-via-connectwise-supply-chain-attack/
  - https://attack.mitre.org/techniques/T1550/001/
author: Security Arsenal
date: 2026/02/12
tags:
  - attack.persistence
  - attack.t1098
  - attack.t1550.001
logsource:
  product: azure
  service: auditlogs
detection:
  selection:
    operationName: 'Consent to application'
  filter_scope:
    targetResources|contains:
      - 'Mail.Read'
      - 'Mail.ReadWrite'
      - 'Files.Read.All'
      - 'Files.ReadWrite.All'
      - 'Sites.Read.All'
      - 'full_access_as_app'
      - 'Directory.Read.All'
  condition: selection and filter_scope
falsepositives:
  - Onboarding of legitimate backup, eDiscovery, or journaling applications; all such consents should be rare, ticketed, and reviewed
level: medium
---
title: Service Principal Sign-In from Anomalous Source for Backup Application
id: 9c1d4a62-5e8b-4f7a-b3c9-2e6d1a8f4c73
description: Detects non-interactive client-credential sign-ins by third-party backup application identities, including SkyKick/ConnectWise Cloud Backup. Authentication for these apps should originate only from the vendor's published infrastructure.
references:
  - https://www.bleepingcomputer.com/news/security/hackers-breach-microsoft-365-tenants-via-connectwise-supply-chain-attack/
  - https://attack.mitre.org/techniques/T1550/001/
author: Security Arsenal
date: 2026/02/12
tags:
  - attack.initial_access
  - attack.t1078.004
  - attack.t1550.001
logsource:
  product: azure
  service: signinlogs
detection:
  selection:
    AppDisplayName|contains:
      - 'SkyKick'
      - 'ConnectWise'
      - 'Cloud Backup'
  condition: selection
falsepositives:
  - Legitimate vendor backup operations; alert volume should be low and all hits must be validated against vendor-published egress IP ranges and incident timelines
level: high
KQL — Microsoft Sentinel / Defender
// Hunt: Anomalous service principal sign-ins for SkyKick/ConnectWise Cloud Backup app identities
// Scope: 90 days back. Validate all IPs against ConnectWise's published egress ranges and the vendor's disclosed incident window.
let BackupApps = dynamic(["SkyKick", "ConnectWise", "Cloud Backup"]);
AADServicePrincipalSignInLogs
| where TimeGenerated > ago(90d)
| where AppDisplayName has_any (BackupApps)
| summarize SignInCount = count(),
            DistinctIPs = dcount(IPAddress),
            SourceIPs = make_set(IPAddress, 20),
            Locations = make_set(Location, 20),
            FirstSeen = min(TimeGenerated),
            LastSeen = max(TimeGenerated)
    by AppDisplayName, ServicePrincipalId, TenantId
| order by SignInCount desc;

// Hunt: Credentials added to ANY service principal (persistence after app identity compromise)
AuditLog
| where TimeGenerated > ago(30d)
| where OperationName in ("Add service principal credentials",
                          "Update application – Certificates and secrets management",
                          "Add key credentials to application",
                          "Add password to application")
| mv-expand TargetResources
| extend AppName = tostring(TargetResources.displayName),
         AppId = tostring(TargetResources.id)
| project TimeGenerated, OperationName, AppName, AppId,
          InitiatedBy = tostring(parse_json(InitiatedBy).user.userPrincipalName),
          InitiatorIP = tostring(parse_json(InitiatedBy).user.ipAddress),
          Result
| order by TimeGenerated desc;

// Hunt: Abnormal Microsoft Graph data access volume by any service principal (bulk exfiltration pattern)
MicrosoftGraphActivityLogs
| where TimeGenerated > ago(14d)
| where isnotempty(ServicePrincipalId)
| where RequestUri has_any ("/messages", "/drive", "/mailFolders", "/sites")
| summarize ApiCalls = count(),
            DistinctResources = dcount(RequestUri),
            ResponseBytes = sum(ResponseSizeBytes),
            SourceIPs = make_set(IPAddress, 20)
    by ServicePrincipalId, AppId, bin(TimeGenerated, 1h)
| where ApiCalls > 5000   // tune against your backup vendor's normal API cadence
| order by ApiCalls desc;
VQL — Velociraptor
-- Hunt: Inventory hosts running SkyKick/ConnectWise Cloud Backup agents
-- Establishes exposure scope: which endpoints and servers have the compromised vendor's backup tooling installed.
-- Review the results against asset inventory and flag any unexpected installations for IR triage.
SELECT Pid, Name, Exe, CommandLine, Username, CreateTime
FROM pslist()
WHERE Name =~ '(?i)skykick|connectwise|cloud.?backup'
   OR Exe =~ '(?i)skykick|connectwise'
   OR CommandLine =~ '(?i)skykick'

-- Companion hunt: installed services registered by the backup vendor (persistence surface review)
SELECT Name, DisplayName, Path, State, StartMode, ServiceDll
FROM services()
WHERE DisplayName =~ '(?i)skykick|connectwise'
   OR Path =~ '(?i)skykick|connectwise'
PowerShell
# ConnectWise/SkyKick Cloud Backup exposure audit for a Microsoft 365 tenant
# Run as a user with Global Reader or higher. Requires Microsoft.Graph PowerShell SDK.
# Produces a triage report: does the app exist, what can it access, were credentials recently added?

Connect-MgGraph -Scopes "Application.Read.All","AuditLog.Read.All","Directory.Read.All" -NoWelcome

$report = @()

# 1. Locate the vendor's enterprise application(s) in the tenant
$apps = Get-MgServicePrincipal -All -Filter "startswith(displayName,'SkyKick')" 
$apps += Get-MgServicePrincipal -All | Where-Object { $_.DisplayName -match 'ConnectWise|Cloud Backup' }

foreach ($sp in ($apps | Sort-Object Id -Unique)) {
    # 2. Enumerate delegated app role assignments (effective Graph permissions)
    $roles = Get-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $sp.Id -All |
        ForEach-Object {
            $resource = Get-MgServicePrincipal -ServicePrincipalId $_.ResourceId
            "[$($resource.DisplayName)] $($_.AppRoleId)"
        }

    # 3. Check credential age and recent secret/cert additions
    $pwCreds  = $sp.PasswordCredentials | ForEach-Object { "$($_.DisplayName) | start: $($_.StartDateTime) | end: $($_.EndDateTime)" }
    $keyCreds = $sp.KeyCredentials      | ForEach-Object { "$($_.DisplayName) | start: $($_.StartDateTime) | end: $($_.EndDateTime)" }

    $report += [pscustomobject]@{
        AppDisplayName      = $sp.DisplayName
        ServicePrincipalId  = $sp.Id
        AppId               = $sp.AppId
        AccountEnabled      = $sp.AccountEnabled
        CreatedDateTime     = $sp.AdditionalProperties['createdDateTime']
        AppRoles            = ($roles -join '; ')
        PasswordCredentials = ($pwCreds -join '; ')
        KeyCredentials      = ($keyCreds -join '; ')
    }
}

$report | Format-List
$report | Export-Csv -Path ".\SkyKick_ConnectWise_AppAudit_$(Get-Date -Format 'yyyyMMdd').csv" -NoTypeInformation

# 4. If confirmed compromised or directed by ConnectWise: disable the service principal immediately
# Get-MgServicePrincipal -All | Where-Object {$_.DisplayName -match 'SkyKick|ConnectWise Cloud Backup'} |
#     ForEach-Object { Update-MgServicePrincipal -ServicePrincipalId $_.Id -AccountEnabled:$false }

# 5. For full removal after vendor guidance and forensic preservation:
# Remove-MgServicePrincipal -ServicePrincipalId <ServicePrincipalId>

Remediation

There is no patch for a stolen identity. Remediation is containment, credential invalidation, and scope reduction — in that order.

Immediate actions (today)

  1. Confirm exposure. Determine whether your tenant ever consented to SkyKick Cloud Backup or ConnectWise Cloud Backup. Run the PowerShell audit above, or navigate to Entra ID > Enterprise applications and search for both names. Do not forget tenants you manage as an MSP — this attack disproportionately impacts MSP-managed environments where backup tooling is deployed broadly.

  2. Follow ConnectWise's advisory and engagement process. ConnectWise has shut down customer access to the Cloud Backup service and is communicating with affected customers. Register with the vendor's incident notification channel and obtain their published egress IP ranges and the known compromise window — you need both to scope your log review. Vendor advisory: https://www.connectwise.com/company/trust-center (monitor for the Cloud Backup incident bulletin).

  3. Disable the service principal for the backup application in every tenant where it exists, pending vendor guidance. This severs the attacker's token path immediately. Because ConnectWise has already halted the service, operational impact of disabling the app should be minimal.

  4. Rotate what you control. Remove any secrets or certificates on the service principal that were added outside known change windows. Revoke active refresh tokens and sessions: revoke sign-in sessions for the service principal object and force re-evaluation of its consents.

  5. Scope the breach forensically. Using the KQL hunts above, reconstruct: (a) all service principal sign-ins for the app, filtered to non-vendor IPs; (b) all Graph API calls made by the app identity during the vendor's disclosed window; (c) any directory modifications (new consents, new credentials, new app role assignments) made by that identity. Preserve raw logs before making changes — you will need them for regulatory notification analysis.

Hardening actions (this week)

  1. Deploy Conditional Access for workload identities (requires Entra ID P2 / Workload Identities Premium): restrict the backup application's token requests to ConnectWise's published egress IP ranges. This single control would have neutralized the stolen credentials from foreign infrastructure.

  2. Adopt least-privilege app consent. Audit every enterprise application holding Mail.Read, Files.Read.All, Sites.Read.All, or full_access_as_app. For any third-party app you retain, verify the permission set against documented business need. Backup vendors are increasingly offering granular/scope-limited access models — demand them.

  3. Enable admin consent workflows so no new application consent is granted without security review, and alert on every "Consent to application" and "Add service principal credentials" event — the Sigma rules above are your starting point.

  4. Extend monitoring to service principal sign-in logs. If your SIEM ingestion covers only interactive user sign-ins, you are blind to this entire attack class. Ingest AADServicePrincipalSignInLogs and MicrosoftGraphActivityLogs into Sentinel or your SIEM of record.

  5. Update your third-party risk register. This incident is a textbook case for tabletop exercises: "a trusted SaaS provider's application identity is compromised — what is our 4-hour response?" If the answer is "we don't know what apps have tenant-wide data access," that gap is now your top remediation item.

Notification considerations

If scoping confirms data access by the attacker, engage counsel early. Mailbox and OneDrive content accessed via Graph almost certainly triggers breach-notification analysis under state privacy laws, and potentially HIPAA or contractual PCI obligations depending on the data exposed. The Graph activity logs are your evidentiary basis for determining exactly which mailboxes and files were touched — another reason step 5's log preservation is non-negotiable.

The Bigger Lesson

Supply-chain risk in 2026 is increasingly identity-mediated. Attackers have learned that compromising one SaaS vendor's app registration yields authenticated, permission-rich access into thousands of tenants simultaneously — with zero malware and minimal logging footprints. The defensive response is not to abandon third-party tooling; it is to treat every consented enterprise application as a privileged identity with the same rigor you apply to Domain Admins: known source IPs, monitored authentication, least privilege, and a rehearsed revocation playbook.

Related Resources

Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub

Is your security operations ready?

Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.