Back to Intelligence

Storm-0940 ConnectWise Supply Chain Compromise: Detecting and Remediating ARTEX-Driven Microsoft 365 Credential Abuse

SA
Security Arsenal Team
October 21, 2026
12 min read

Microsoft's Threat Intelligence team has disclosed a large-scale nation-state campaign in which Storm-0940 leveraged an agentic AI framework — tracked as ARTEX — to dramatically accelerate a supply chain compromise originating in the ConnectWise ecosystem. The endgame: abuse of application credentials across downstream Microsoft 365 environments. If your organization uses ConnectWise tooling (ScreenConnect, Automate, Manage) — or if any of your MSPs or IT vendors do — you are in the blast radius of this campaign whether you know it or not.

This is not a hypothetical supply chain risk scenario. It is a confirmed, active nation-state intrusion set with a force multiplier we have been warning clients about for two years: agentic AI compressing the time between initial access and downstream tenant compromise from weeks to hours. Defenders need to treat any ConnectWise-associated trust relationship as suspect until proven otherwise.

What Happened

Per Microsoft's reporting, Storm-0940 compromised ConnectWise infrastructure/tooling as a supply chain pivot point, then used ARTEX — an agentic AI capability — to automate and accelerate the labor-intensive phases of the operation: reconnaissance of downstream tenants, identification of high-value application registrations and service principals, credential material extraction, and lateral movement into Microsoft 365 environments. Once inside victim tenants, the actor abused application credentials (client secrets and certificates on Entra ID app registrations and service principals) to maintain durable, MFA-independent access to mailboxes, SharePoint data, and Graph API resources.

Why this matters more than a typical intrusion

  1. Supply chain amplification. ConnectWise sits inside thousands of MSPs and enterprise IT operations. One upstream compromise inherits every downstream trust relationship — exactly the SolarWinds/Kaseya pattern, now re-run with AI acceleration.
  2. Agentic AI compression. The traditional defender advantage — dwell time — evaporates when an AI agent performs tenant enumeration, OAuth app review, and credential harvesting at machine speed. Detection windows shrink from days to minutes.
  3. Application credential abuse bypasses your best controls. Rogue client secrets and certificates on app registrations authenticate as the application, not a user. Conditional Access, MFA, and phishing-resistant auth do not apply. This is the quietest persistence mechanism in a Microsoft 365 tenant, and Storm-0940 knows it.

Technical Analysis

Affected platforms and scope

  • Upstream vector: ConnectWise product ecosystem (remote access/management tooling deployed at MSPs and enterprises)
  • Downstream targets: Microsoft 365 / Entra ID tenants of organizations reachable through the compromised ConnectWise estate
  • Persistence/data access mechanism: Abuse of Entra ID application credentials — attacker-added client secrets or certificates on existing or newly created app registrations, followed by Graph API access under the application's identity

No CVE has been published for this activity at time of writing; the campaign is technique-driven (trusted-relationship abuse plus credential manipulation), not dependent on a single patchable bug. Do not wait for a CVE to act.

Attack chain (defender's view)

  1. Upstream compromise: Storm-0940 gains execution within the ConnectWise environment — either on ConnectWise-managed infrastructure or via deployed ConnectWise agents at MSPs.
  2. Agentic acceleration (ARTEX): The ARTEX agent enumerates reachable downstream tenants, identifies privileged sessions, harvests tokens/credentials from ConnectWise-managed endpoints, and prioritizes targets — autonomously.
  3. Tenant ingress: Using harvested session material or legitimate remote-access channels (ScreenConnect sessions look like your own admins), the actor authenticates into victim environments.
  4. Credential forging in Entra ID: With sufficient privilege (Global Admin, Application Admin, Cloud Application Admin, or a compromised service principal with Application.ReadWrite.All), the actor adds a client secret or uploads a certificate to an app registration — often an existing, legitimate-looking app to blend in.
  5. Silent data access: The actor authenticates via client credentials flow (grant_type=client_credentials) from external infrastructure and reads mail, files, and directory data through Microsoft Graph. No user sign-in, no MFA prompt, no Conditional Access evaluation.
  6. AI-driven scale: ARTEX repeats steps 3–5 across dozens or hundreds of downstream tenants — the "large-scale" in Microsoft's headline is the point.

Exploitation status

Confirmed active exploitation at scale, attributed to a nation-state actor by Microsoft Threat Intelligence. This is not a proof-of-concept or theoretical exercise. If you consume ConnectWise software or services directly or through an MSP, assume elevated threat posture now.

Detection & Response

The three highest-fidelity detection surfaces for this campaign are: (1) Entra ID audit events for credential manipulation on applications, (2) endpoint telemetry around ConnectWise components spawning unexpected child processes, and (3) service-principal sign-ins from anomalous infrastructure. The rules below target those surfaces.

Sigma Rules

YAML
---
title: Entra ID Application Credential Added to App Registration or Service Principal
id: 8c2f4a61-3b9d-4e17-a5c2-9f1d7e4b6a03
status: experimental
description: Detects addition of client secrets or certificates to Entra ID applications/service principals, a persistence technique used by Storm-0940 in the ConnectWise supply chain campaign. Triage all hits immediately; correlate actor identity against approved change windows.
references:
  - https://www.microsoft.com/en-us/security/blog/2026/10/21/storm-0940-uses-artex-agentic-ai-connectwise-supply-chain-compromise/
  - https://attack.mitre.org/techniques/T1098/001/
  - https://attack.mitre.org/techniques/T1550/
author: Security Arsenal
date: 2026/10/22
tags:
  - attack.persistence
  - attack.credential_access
  - attack.t1098.001
logsource:
  product: azure
  service: auditlogs
detection:
  selection:
    operationName:
      - 'Add service principal credentials'
      - 'Add application credentials'
      - 'Update application – Certificates and secrets management'
      - 'Consent to application'
    result: 'success'
falsepositives:
  - Legitimate application onboarding or secret rotation by app owners — baseline and alert on deviation
level: high
---
title: ConnectWise ScreenConnect or Automate Spawning Shell or Scripting Child Processes
id: 3e7b9c24-6a1f-4d58-b2e7-8c4a1f9d5e62
status: experimental
description: Detects ConnectWise remote access/management components spawning command shells, PowerShell, or script interpreters. Storm-0940 leveraged ConnectWise channels for downstream execution; legitimate ScreenConnect sessions launching interactive shells outside approved maintenance windows are high-fidelity for hands-on or agentic abuse.
references:
  - https://www.microsoft.com/en-us/security/blog/2026/10/21/storm-0940-uses-artex-agentic-ai-connectwise-supply-chain-compromise/
  - https://attack.mitre.org/techniques/T1219/
author: Security Arsenal
date: 2026/10/22
tags:
  - attack.command_and_control
  - attack.execution
  - attack.t1219
  - attack.t1059
logsource:
  category: process_creation
  product: windows
detection:
  selection_parent:
    ParentImage|contains:
      - '\ScreenConnect'
      - '\ConnectWiseControl'
      - '\ConnectWiseAutomate'
      - 'ScreenConnect.ClientService.exe'
      - 'ScreenConnect.WindowsClient.exe'
      - 'LTAgent.exe'
      - 'ltsvcmon.exe'
  selection_child:
    Image|endswith:
      - '\cmd.exe'
      - '\powershell.exe'
      - '\pwsh.exe'
      - '\wscript.exe'
      - '\cscript.exe'
      - '\mshta.exe'
      - '\rundll32.exe'
      - '\wmic.exe'
  condition: selection_parent and selection_child
falsepositives:
  - MSP technicians running interactive remediation sessions — whitelist by scheduled session metadata, not by parent process alone
level: high
---
title: New Service Principal Created Followed by Privileged Role Assignment
id: 5f1a8d73-2c6e-4b49-9d31-7e5c2a8f4b19
status: experimental
description: Detects creation of a new service principal or app registration followed by directory role or app role assignment, a pattern consistent with Storm-0940 establishing durable application-based persistence in compromised M365 tenants.
references:
  - https://www.microsoft.com/en-us/security/blog/2026/10/21/storm-0940-uses-artex-agentic-ai-connectwise-supply-chain-compromise/
  - https://attack.mitre.org/techniques/T1098/
  - https://attack.mitre.org/techniques/T1136/
author: Security Arsenal
date: 2026/10/22
tags:
  - attack.persistence
  - attack.privilege_escalation
  - attack.t1098
logsource:
  product: azure
  service: auditlogs
detection:
  selection:
    operationName:
      - 'Add service principal'
      - 'Add application'
      - 'Add app role assignment to service principal'
      - 'Add member to role'
    result: 'success'
falsepositives:
  - DevOps pipelines provisioning applications — alert on actor accounts outside known automation identities
level: medium

KQL — Microsoft Sentinel / Defender Hunting

KQL — Microsoft Sentinel / Defender
// Hunt 1: Application credential additions on app registrations / service principals
// Core Storm-0940 persistence. Correlate actor UPN/IP against approved changes.
AuditLog
| where TimeGenerated > ago(30d)
| where OperationName in~ (
    "Add service principal credentials",
    "Update application – Certificates and secrets management",
    "Consent to application")
| where Result == "success"
| mv-expand TargetResources
| extend AppDisplayName = tostring(TargetResources.displayName)
| extend ModifiedProps = TargetResources.modifiedProperties
| mv-expand InitiatedBy__ = InitiatedBy
| extend ActorUpn = tostring(parse_json(tostring(InitiatedBy__.user)).userPrincipalName)
| extend ActorIp = tostring(parse_json(tostring(InitiatedBy__.user)).ipAddress)
| project TimeGenerated, OperationName, AppDisplayName, ActorUpn, ActorIp, CorrelationId, ModifiedProps
| order by TimeGenerated desc
;

// Hunt 2: Service principal sign-ins from anomalous ASNs or first-seen IPs
// Client-credentials abuse authenticates as the app — look here, not just user sign-ins.
AADServicePrincipalSignInLogs
| where TimeGenerated > ago(14d)
| summarize FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated),
            IPs = make_set(IPAddress), Locations = make_set(Location)
    by ServicePrincipalName, AppId
| where array_length(IPs) > 2 or FirstSeen > ago(3d)
| order by FirstSeen desc
;

// Hunt 3: ConnectWise components spawning shells on endpoints
DeviceProcessEvents
| where TimeGenerated > ago(14d)
| where InitiatingProcessFileName has_any (
    "ScreenConnect", "ConnectWiseControl", "LTAgent", "ltsvcmon")
| where FileName in~ (
    "cmd.exe", "powershell.exe", "pwsh.exe", "mshta.exe",
    "wscript.exe", "cscript.exe", "rundll32.exe", "wmic.exe")
| project TimeGenerated, DeviceName, InitiatingProcessFileName,
          InitiatingProcessCommandLine, FileName, ProcessCommandLine, AccountName
| order by TimeGenerated desc

Velociraptor VQL — Endpoint Hunt

VQL — Velociraptor
-- Hunt for ConnectWise remote access components spawning shells or scripting engines
-- across the fleet. Deploy as a hunt; export results for timeline correlation
-- against Entra ID audit events in the same window.
SELECT Pid,
       Ppid,
       Name,
       Exe,
       CommandLine,
       Username,
       CreateTime
FROM pslist()
WHERE (Exe =~ '(?i)ScreenConnect|ConnectWiseControl|LTAgent|ltsvcmon'
   AND CommandLine =~ '(?i)cmd\.exe|powershell|pwsh|mshta|wscript|cscript|rundll32|wmic')
   OR Name =~ '(?i)^(cmd|powershell|pwsh|mshta|wscript|cscript)\.exe$'
      AND CommandLine =~ '(?i)connectwise|screenconnect'

Remediation & Verification Script

The fastest high-value containment action: enumerate every client secret and certificate across all app registrations and service principals, flag anything created in the last 45 days or by non-approved actors, and produce a revocation worklist. Run this with an account holding at least Application Administrator (read-only Graph scopes Application.Read.All, AuditLog.Read.All, Directory.Read.All for audit):

PowerShell
# Storm-0940 / ARTEX Campaign - M365 Application Credential Audit & Containment
# Requires: Microsoft.Graph PowerShell SDK
# Run as: identity with Application.Read.All, AuditLog.Read.All, Directory.Read.All

Connect-MgGraph -Scopes "Application.Read.All","AuditLog.Read.All","Directory.Read.All" -NoWelcome
$cutoff = (Get-Date).AddDays(-45)
$report = [System.Collections.Generic.List[object]]::new()

# 1) Enumerate all applications and their credential material
$apps = Get-MgApplication -All -Property Id,AppId,DisplayName,KeyCredentials,PasswordCredentials,CreatedDateTime
foreach ($app in $apps) {
    foreach ($kc in $app.KeyCredentials) {
        $report.Add([pscustomobject]@{
            AppName = $app.DisplayName; AppId = $app.AppId
            CredType = "Certificate"; CreatedOn = $kc.StartDateTime
            ExpiresOn = $kc.EndDateTime; KeyId = $kc.KeyId
            RecentCredential = ($kc.StartDateTime -gt $cutoff)
        })
    }
    foreach ($pc in $app.PasswordCredentials) {
        $report.Add([pscustomobject]@{
            AppName = $app.DisplayName; AppId = $app.AppId
            CredType = "ClientSecret"; CreatedOn = $pc.StartDateTime
            ExpiresOn = $pc.EndDateTime; KeyId = $pc.KeyId
            RecentCredential = ($pc.StartDateTime -gt $cutoff)
        })
    }
}

# 2) Pull audit events for credential manipulation in the window
$events = Get-MgAuditLogDirectoryAudit -All -Filter "activityDateTime ge $($cutoff.ToString('o'))" |
  Where-Object { $_.ActivityDisplayName -match 'credentials|Certificates and secrets|Consent to application' } |
  Select-Object ActivityDateTime, ActivityDisplayName,
    @{n='Actor';e={ $_.InitiatedBy.user.userPrincipalName }},
    @{n='ActorIp';e={ $_.InitiatedBy.user.ipAddress }},
    @{n='Target';e={ ($_.TargetResources | Select-Object -First 1).displayName }}

# 3) Export findings - review EVERY RecentCredential=$true row and every audit actor
$report | Sort-Object RecentCredential -Descending | Export-Csv .\M365_AppCred_Audit.csv -NoTypeInformation
$events | Export-Csv .\M365_AppCred_AuditEvents.csv -NoTypeInformation
Write-Host "[+] $($report.Count) credentials enumerated across $($apps.Count) apps." -ForegroundColor Cyan
Write-Host "[!] REVIEW REQUIRED: $(($report | Where-Object RecentCredential).Count) credentials created since $($cutoff.ToShortDateString())." -ForegroundColor Yellow
Write-Host "[i] Cross-reference .\M365_AppCred_AuditEvents.csv actors against approved change records." -ForegroundColor Cyan

# 4) CONTAINMENT (uncomment ONLY after IR approval - removes a confirmed rogue secret):
# $badApp = Get-MgApplicationByAppId -AppId "<CONFIRMED-MALICIOUS-APP-ID>"
# Remove-MgApplicationPassword -ApplicationId $badApp.Id -KeyId "<ROGUE-KEY-ID>"
# For rogue certificates: Remove-MgApplicationKey -ApplicationId $badApp.Id -KeyId "<ROGUE-KEY-ID>" -BodyParameter @{Proof="<jwt>"}

Disconnect-MgGraph

Remediation & Hardening — Prioritized

Immediate (0–24 hours):

  1. Run the credential audit above across every tenant you operate or manage. Any client secret or certificate created outside an approved change window in the last 45 days is presumptively rogue — revoke it and open an IR case.
  2. Inventory your ConnectWise exposure. Identify every endpoint running ScreenConnect/Automate agents, every ConnectWise integration in your identity stack, and — critically — every MSP with ConnectWise-based access into your environment. Contact each MSP and demand their Storm-0940/ConnectWise exposure assessment in writing.
  3. Force service-principal sign-in review. Client-credentials abuse leaves no MFA trail; your only telemetry is the service principal sign-in log. Baseline expected ASNs/locations per application and alert on deviation.
  4. Rotate credentials on any application administered from a ConnectWise-managed endpoint during the exposure window, including Graph-integrated automation apps.

Short term (24–96 hours):

  1. Lock down who can add application credentials. Remove standing Application Administrator / Cloud Application Administrator / Global Admin assignments; move to PIM with just-in-time elevation and approval gates. Audit for any service principal holding Application.ReadWrite.All or Directory.ReadWrite.All — these are self-perpetuating keys to the kingdom.
  2. Enable and alert on Entra ID Protection for service principals (workload identity risk detections) if licensed; this catches anomalous client-credentials usage patterns.
  3. Deploy the Sigma and KQL detections above, tuned against your automation identities. In an agentic-AI-accelerated campaign, alerting latency is the entire game.
  4. Constrain ConnectWise execution paths. Application control (WDAC/AppLocker) policy: ConnectWise agents must not spawn interactive shells outside scheduled session identifiers. EDR network baselining on ScreenConnect listener traffic.

Structural (this quarter):

  1. Adopt managed identity and federated credentials in place of long-lived client secrets wherever the workload supports it. Secrets you don't have can't be abused.
  2. Contract for supply chain visibility. MSP agreements must include 24-hour incident notification, agent inventory attestation, and the right to audit their RMM estate. Storm-0940's campaign demonstrates — again — that your perimeter includes your vendors' tooling.
  3. Rehearse the tenant-compromise scenario. Your IR runbook needs a specific annex for rogue application credentials: revoke, re-consent review, Graph activity scoping, mailbox audit (non-owner access), and downstream notification.

The Bottom Line

Storm-0940's use of ARTEX is a preview of the next decade of nation-state tradecraft: AI agents absorbing the human bottlenecks in multi-tenant operations. The defensive counter is not panic — it is shrinking your own detection and revocation cycle below the attacker's automation cycle. Application credential hygiene in Entra ID, ruthless auditing of who can mint credentials, and visibility into your RMM supply chain are no longer best practices. They are the perimeter.

If your team lacks the bandwidth to execute the credential audit, MSP exposure review, or detection deployment described above, Security Arsenal's IR and SOC teams are running this exact playbook for clients right now.

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.