On October 21, 2026, a compromised LiteLLM 1.107.0 release was published to the Python Package Index (PyPI) and distributed through official container images. The malicious package added files that Python could execute during normal interpreter initialization. An application did not need to import LiteLLM for the payload to run: starting Python in an affected environment could be enough.
Microsoft analyzed two execution paths in the affected wheels: a credential collector launched through a path extension, and a Unix-oriented loader persisted through site-specific configuration. The collector targeted authentication material across developer tools, AI applications, cloud environments, browsers, and infrastructure. A separate database module attempted to read selected credential and model-configuration records from the LiteLLM proxy.
Endpoint observations on Windows and macOS matched the recovered collectorβs discovery, encryption, and outbound-connection behavior. In one Windows example, a routine Python invocation to install an unrelated dependency activated the collector. This distinction matters for response: investigators should not start Python or pip inside a suspect environment to determine whether the malicious package is present.
This blog explains the startup mechanisms, the credentials the payload could reach, and the evidence defenders can use to investigate exposure. It also provides Microsoft Defender detection information, advanced hunting queries, and recovery guidance. Removing the package or a release tag is not sufficient recovery. Organizations must address the affected Python environment, any surviving processes, and credentials accessible to the compromised identity.
Attack overview
LiteLLM is commonly deployed as a gateway between applications and model providers. In that position it may have access to model-provider API keys, database connection strings, workload identities, routing configuration, and tenant policy data. The same package is also used on developer workstations, build agents, test systems, and containers, which widened the set of environments that could be exposed by the compromised release.
According to LiteLLM maintainers, stolen developer GitHub credentials were used to alter the release workflow and redirect it to the lookalike repository Berri-AI/litellm rather than the legitimate BerriAI/litellm repository. A credential associated with another developer account was then used to satisfy a production approval step. Microsoft has not independently determined how the attacker first accessed the upstream environment or obtained those credentials.
The compromised package used Python startup mechanisms to execute malicious code automatically, meaning exposure was not limited to systems actively using a LiteLLM gateway. Developer workstations, continuous integration and continuous delivery/deployment (CI/CD) agents, test environments, containers, and other systems that started Python with the affected package installed could also execute the payload. The malicious code supported credential collection and, on Unix-based systems, retrieval and execution of additional Python code.
The compromised LiteLLM 1.107.0 release delivered malicious Python startup files to environments where the package was installed.
2. Automatic payload execution
Python startup processing launched the credential collector without requiring the application to actively use LiteLLM gateway functionality.
3. Credential and sensitive-data collection
The collector targeted developer credentials, cloud credentials, browser data, SSH material, environment variables, and LiteLLM database data accessible to the affected process.
4. Encryption and exfiltration
Collected data was encrypted and transmitted to an attacker-controlled endpoint.
5. Conditional retrieval and execution of additional code
On Unix-based systems, the payload supported retrieving and executing additional Python code, although this activity was not confirmed.
Technical details
Compromised package distribution and automatic payload execution
The compromised wheel packaged cook.pth, cook.py, and sitecustomize.py under litellm-1.107.0.data/purelib/. During installation, these files were relocated into the Python environmentβs library directory, outside the normal litellm application directory. This placement enabled execution through Pythonβs normal site initialization, which processes executable import statements in .pth files and later attempts to import the sitecustomize module.
The first execution path began with the single executable line in cook.pth: βimport cookβ. This loaded cook.py, whose wrapper Base64-decoded and zlib-decompressed an embedded Python program before executing the recovered source. The program identified itself as PRIVCOLLECT and performed credential collection in a daemon thread.
Figure 2. The executable .pth line imports cook, and the recovered collector starts a daemon thread after checking its inherited environment flag.
Before starting the thread, the collector checked the inherited PRIVCOLLECT_ACTIVE environment variable. A nonempty value caused it to return; otherwise, it set the flag, limiting duplicate collection in descendant processes. After an upload returned HTTP 200, it attempted to write /tmp/.pc_once_72129118c59f5636c0bb. These duplicate-suppression gates were not containment controls: startup alone did not prove collection or upload completed, because a short-lived process could exit before the thread finished, while write failures or temporary-storage changes could leave the marker absent.
A second startup mechanism used sitecustomize.py, providing a separate Unix-oriented execution path with an embedded collector and functionality to retrieve and execute additional Python code from a remote host. Remote retrieval and execution through this path were not confirmed.
Together, these mechanisms extended potential exposure beyond active LiteLLM deployments: simply starting Python in an affected environment could activate the malicious code, even when LiteLLM itself was never imported. Because the startup files resided outside the litellm application directory, removing only the application files could leave the malicious startup components behind.
Credential and sensitive-data collection
The recovered collector was designed to gather sensitive authentication material across developer tools, AI applications, cloud environments, browsers, and infrastructure. It runs multiple collection modules sequentially with independent error handling, allowing collection to continue even when individual targets are unavailable or inaccessible.
Target
Recovered collection behavior
Developer and AI tools
Reads selected authentication and configuration files for AI assistants, integrated development environments (IDEs) , GitHub Copilot, VS Code, and MCP integrations. Collects fixed paths and top-level JSON files in selected tool directories under a collection budget.
Source control and package ecosystems
Searches Git credentials, package-manager configuration, selected dotenv files, and private-key extensions. Shallow directory walks and file-size limits constrain these searches.
Cloud and workload credentials
Reads AWS, Azure CLI, and Google Cloud configuration or credential caches; Kubernetes service-account files; Docker configuration; and mounted secrets. It also attempts AWS and GCP metadata credential retrieval.
Browsers and user histories
Accesses Chromium-family and Firefox credential-related data and browsing history, plus shell, database-client, and interactive-tool histories. Password decryption is platform- and format-dependent.
Process environments
Collects its own environment and, on Linux, other process environments readable through procfs. This can expose secrets beyond variables explicitly configured for the LiteLLM process.
Private keys and infrastructure
Targets readable Secure Shell (SSH) material and selected GNU Privacy Guard (GPG), Transport Layor Security (TLS), CI/CD, Vault, and infrastructure-tool configuration. A target appearing in the code does not establish successful access.
LiteLLM proxy data
When its prerequisites are satisfied, starts a Python child using Prisma to read selected fields from two proxy database tables, with a 500-row limit for each query
Encryption and exfiltration
After collection, the payload serializes module results and host metadata as JSON. Each run generates a 32-byte AES key and a 16-byte initialization vector. AES-256-CBC encrypts the collection document; an embedded 4,096-bit RSA public key wraps the AES key using OAEP. The OpenSSL path tries SHA-256 and then SHA-1 for OAEP, and the resulting metadata records the selected digest.
Figure 4. The collector generates a fresh AES key and IV, wraps the key with RSA, and packages the encrypted collection in a gzip tar archive before attempting upload. Selected code excerpts are wrapped for readability.
The collector places three members in a gzip-compressed tar archive: data.bin, containing the initialization vector (IV) and encrypted collection; key.bin, containing the wrapped AES key; and hdr.json, containing plaintext envelope metadata. It then attempts an HTTP POST to hxxp://www[.]litellm[.]dev/healthcheck, using application/octet-stream, a fixed browser-like User-Agent, and a body checksum in an X-SHA256 header. The upload routine retries and treats only HTTP 200 as success.
The OpenSSL backend creates temporary directories beginning with .pc_e_, stages input and output files and removes them after use.
Conditional retrieval and execution of additional code
In addition to the credential collector, the compromised package contained a separate Unix-oriented loader in sitecustomize.py, designed to retrieve and execute additional Python code. When Python starts, the loader takes an exclusive lock on /tmp/remote_code_loader.lock so that only one instance runs per host and detaches into the background. Each cycle reads a GitHub-hosted domain.txt file, which acts as a mutable pointer to an attacker-controlled server.
Figure 5. The remote-loader path checks the pointer and DNS before retrieving code, then compiles and executes the response without a content-signature check.
If a valid server address is returned and successfully resolved, the loader is designed to request /codepy from that server, compile the returned content, and execute it as Python code within the affected environment. This gives the attacker a mechanism to change the second-stage payload without publishing another compromised LiteLLM package. This loader is separate from the credential collector delivered directly in the compromised package.
At the time the cited researchers examined domain.txt, it was empty and no second-stage retrieval or execution was confirmed. Because the file could be changed, the loader remained a re-armable remote-code execution mechanism.
Mitigation and protection guidance
Microsoft recommends the following actions for organizations that installed, mirrored, or built images with LiteLLM 1.107.0:
Find and contain every affected copy. Identify LiteLLM 1.107.0 across installed environments, uv and pip caches, internal package mirrors, lock files, build outputs, and container images. Scope mutable container tags and the relevant exposure windows once validated and compare artifacts with the customer-ready hashes in the indicators of compromise section. For background, see secure software supply chain practices and Docker image digests. Digests are preferable to mutable tags because they identify immutable image content.
Prevent Python execution and investigate from outside the environment. Isolate affected developer workstations, build agents, test systems, containers, and AI gateway hosts. Where operationally safe, stop running Python processes and prevent automation from restarting them. Do not run python, pip, or other commands that invoke the affected interpreter during evidence collection; inspect the environment with trusted tools from a known-clean system. Python normally processes site configuration, including executable import lines in .pth files, during initialization.
Rebuild from verified artifacts. Confirm that cook.pth, cook.py, and sitecustomize.py were removed from the environment library path. Rebuilding is more reliable than assuming that deleting the litellm directory cleaned the top-level startup files.
Rotate reachable credentials from a known-clean machine. Include model-provider keys, cloud and workload credentials, CI/CD secrets, source-control and registry tokens, SSH and GPG keys, AI coding-tool tokens, and browser sessions available to the affected identity. On proxy hosts, include stored provider credentials and DATABASE_URL. Revoke affected identity sessions rather than assuming password or key rotation immediately invalidates every active token or application session. See revoke user access in Microsoft Entra ID.
Correlate before declaring compromise. Combine file hashes, Python process ancestry, .pc_e_ cryptographic staging, network destination, workload identity, and subsequent cloud or identity use. Do not use package presence or a generic filename as the sole verdict.
Restrict outbound access. Developer workstations, build agents, test systems, containers, and AI gateway hosts should not have unrestricted outbound HTTP access unless required. Route outbound traffic through managed egress controls, deny unnecessary destinations, and allowlist required services. See control outbound internet access from Azure.
Enable Microsoft Defender for Endpoint protections. Onboard supported developer workstations, build agents, and AI gateway servers to Microsoft Defender for Endpoint, and enable Microsoft Defender Antivirus real-time and cloud-delivered protection where supported. See configure always-on protection and configure cloud protection.
Microsoft Defender XDR detections
As of October 22, 2026, the following Microsoft Defender Antivirus signatures and Microsoft Defender for Endpoint alerts were available for activity associated with the compromised LiteLLM 1.107.0 release. Detection names and availability may change as protection is updated.
Tactic
Observed activity
Microsoft Defender coverage
Initial Access / Execution
Malicious components associated with the compromised package are detected and blocked; related suspicious script and network activity is identified across endpoints and cloud workloads.
Microsoft Defender for Endpoint β Suspicious script launched β Suspicious network connection observed
Command and Control / Credential Access
Credential-like data is staged by Python and followed by network activity to a public destination, including malicious-domain lookups and OpenSSL activity associated with the compromise.
Microsoft Defender for Endpoint β Possible theft of passwords and other sensitive web browser information β Suspicious OpenSSL command launch
Microsoft Defender for Cloud Microsoft Defender for Cloud triggers below detections for related activity in Azure App Service and Kubernetes workloads:
β OpenSSL activity associated with possible LiteLLM compromise detected β DNS lookup of a known malicious domain
Vulnerability Management
Devices vulnerable to this security issue are surfaced for remediation.
Microsoft Defender Vulnerability Management β Endpoints exposure tab in the Microsoft Defender portal: TVM-2026-0003
Threat intelligence reports
Microsoft customers can use the following reports in Microsoft products to get the most up-to-date information about the threat actor, malicious activity, and techniques discussed in this blog. This report provides intelligence, protection information, and recommended actions to prevent, mitigate, or respond to associated threats found in customer environments.
These queries support investigation of the stages discussed above. Select the appropriate lookback in Defender XDR and correlate results with environment, process and identity evidence. They are investigation leads, not standalone verdicts.
Connections to the collector domain
Normalize URL/hostname observations before matching the campaign domain. The query rejects suffix lookalikes such as www[.]litellm[.]dev[.]example; a match still needs process and workload context.
Look for the sensitive table/field pair together with the query API, serialization and complete output-suppression pattern. Legitimate exports may overlap. The recovered parentβs /proc prerequisite limits its applicability; raw arguments are omitted because they can contain a database secret.
DeviceProcessEvents
| where FileName startswith "python" or FileName startswith "platform-python"
| where strlen(ProcessCommandLine)
Collector-like encryption staging
The staging prefix plus encryption operation identifies a behavioral lead, not an upload or a uniquely malicious OpenSSL invocation. Alternate backends are outside this query, and key-bearing arguments are not projected.
Vulnerability/Posture Check | Is the device potentially exposed to the affected Litellm?
Use this query to identify devices potentially exposed to TVM-2026-0003. A match indicates potential exposure, not confirmed exploitation or compromise.
DeviceTvmSoftwareVulnerabilities
| where CveId == "TVM-2026-0003"
CloudProcessEvents query to detect encryption before exfiltration
Identifies OpenSSL public-key encryption using /tmp/.pc_ staging paths, consistent with key wrapping before potential exfiltration.
CloudProcessEvents
| where ProcessName == 'openssl' and ProcessCurrentWorkingDirectory has_any ('/runner/','/app','/tmp/')
and ProcessCommandLine has_all ('pkeyutl','-encrypt','-pubin') and ProcessCommandLine contains '/tmp/.pc_'
MITRE ATT&CK techniques observed
Microsoft mapped the following techniques based on observed activity and analysis of the recovered malicious components; individual entries note where behavior was not confirmed. For standard industry documentation, refer to the MITRE ATT&CK framework.
To hear stories and insights from the Microsoft Threat Intelligence community about the ever-evolving threat landscape, listen to the Microsoft Threat Intelligence podcast.
Reviewβ―ourβ―documentationβ―to learnβ―more about our real-time protection capabilities and see howβ―toβ―enable them within yourβ―organization.β―β―
As early as September 2026, Storm-0940, a China-state aligned actor, used the agentic AI penetration testing framework ARTEX to automate attacks targeting hundreds of organizations globally across a broad range of industries. Several of these Storm-0940 ARTEX-driven attacks have resulted in the actor obtaining privileged access to an organizationβs cloud infrastructure β including multiple instances where the time from initial targeting to privileged access was less than 3 hours. Microsoft assesses that Storm-0940 was responsible for the recently disclosed ConnectWise supply chain compromise of a multi-tenant application.
This activity demonstrates how threat actors are integrating agentic AI into existing offensive security workflows and allows them to scale their operations exponentially. Agents are not constrained by factors affecting humans β they can work around the clock, on weekends, and on holidays and attempt multiple breach paths simultaneously enabling significantly reduced time from selecting a target to achieving objectives, increasing the speed and impact of complex attacks like supply chain compromises.
Storm-0940βs use of ARTEX accelerated the speed of compromised application abuse to authenticate to Microsoft 365 customer environments through applications that had already been granted access. This allowed the threat actor to operate without requiring an interactive user sign-in. In multiple affected environments, Microsoft observed AI-accelerated follow-on activity through Microsoft Graph, including reconnaissance, application credential changes, and attempts to modify privileges that could enable expanded or persistent access. The activity conducted by the threat actor through the usage of ARTEX framework did not result from a compromise of or a vulnerability in Microsoft corporate systems, products, or services.
Although Microsoft identified Storm-0940-initiated authentication and follow-on activity in multiple customer environments, the presence of an affected application or successful threat actor authentication does not necessarily indicate that customer data was accessed or exfiltrated. Microsoft Defender XDR provides detections and hunting queries for suspicious Microsoft Graph activity and activity associated with known threat infrastructure. Customers should review service principal sign-ins, investigate unexpected application credential or privilege changes, and follow ConnectWiseβs published containment guidance while preserving relevant evidence for investigation. For a full list of detections please see the detections section.
Whatβs happening
Storm-0940 is a China-state aligned actor (with no known industry aliases) that has been active since 2021 and targets organizations across multiple industries for data theft. The actor has historically gained initial access using password spraying and exploitation of internet-facing applications, before using compromised accounts to move through targeted environments. In cloud environments, the actor has also established persistence by adding credentials to existing OAuth applications, allowing continued access to Microsoft 365 resources. The actor has used these applications to access and exfiltrate email and other data through Microsoft Graph.
As early as September 2026, Storm-0940 used the agentic AI penetration testing framework ARTEX to automate attacks targeting hundreds of organizations globally across a broad range of industries. These include aerospace and defense, automotive, chemicals, energy, financial services, government, legal, manufacturing, media, military, semiconductor, software, technology, and think tanks and non-profits. During the ConnectWise supply chain compromise, Storm-0940 used ARTEX to accelerate scanning and reconnaissance, password spraying, and OAuth application abuse at downstream victims.
Several of these Storm-0940 ARTEX-driven attacks have resulted in the actor obtaining privileged access to an organizationβs cloud infrastructure β including multiple instances where the time from initial targeting to privileged access was less than 3 hours. When automated with AI, these activities generate a large volume of traffic and log data that may generate alerts. However, the speed of the activity allows very little time for Defenders to respond to those alerts and remediate the actorβs access in a coordinated fashion. Storm-0940βs activity illustrates how a threat actor with a broad target set can use an agentic AI tool and privileged authentication material to quickly attempt to compromise many organizations. While the majority of the targeting wasnβt successful, Storm-0940 achieved privileged cloud persistence at many organizations in a brief time.
What is ARTEX?
ARTEX is an open-source penetration testing framework that can use any AI model to automate a variety of offensive security workflows. The ARTEX framework is a multi-agent LLM system written in GO with a Next.js frontend. While the UI and generated output default to English, the framework can be switched to Korean, Mandarin, Spanish, or Japanese. ARTEX is a system of LLM-driven agents that run an autonomous penetration test from reconnaissance through data exfiltration with little needed human interaction. The agents then accumulate the discovered assets and vulnerabilities into a graph during the penetration test. In October 2026, public reporting noted that the ARTEX framework was being used by threat actors, such as the personal data breaches targeting Korean financial institutions. Microsoft Threat Intelligence has identified threat actors across multiple geographic regions leveraging the ARTEX framework.
ConnectWise published an initial advisory on October 16, 2026, and subsequently expanded its disclosures and containment guidance. The advisory details ConnectWiseβs investigation of attempted unauthorized access associated with Cloud Backup. Following the unauthorized access, Storm-0940 used ARTEX to attempt to sign-in to more than 2,250 tenants. While OAuth application abuse is a typical part of Storm-0940βs toolset, in this case the actor used ARTEX to accelerate the activity to machine speed.
Figure 1. Scale and speed of a subset of Storm-0940βs automated ARTEX campaign on downstream tenants, including tenant reach and rapid sign-ins.
Password Spraying
Between October 10 and 14, 2026, Storm-0940 infrastructure at 144.172.64[.]99 conducted an automated cross-tenant password-spray campaign targeting 327 accounts across eight organizations to gain access to Microsoft 365 and Exchange Online. During this large campaign, Microsoft telemetry captured 151,000+ failed logon events, with activity peaking on October 11 at 2,900 failures per minute and concentrating more than 111,000 failures into a single day. The campaign blended broad, low-rate account spraying with sustained, high-volume authentication attempts against selected identities; 48 accounts received more than 1,000 failures, and lockout responses represented nearly 98% of all activity. Despite the scale, no successful authentication, token issuance, Graph call, or directory change was observed.
Downstream customer access
On October 15, immediately after this notable activity, public reports of the compromise of the popular cloud backup application ConnectWise started to surface with direct references to indicators of compromise matching the same network range observed for the earlier password-spray campaign (144.172.64.x). An advisory from the affected cloud backup vendor posted on October 16 shared later additional indicators with one IP address matching exactly the 144.172.64[.]99 infrastructure responsible for the earlier password-spray campaign.
Additionally, after acquiring control of the identities of multiple ConnectWise cloud applications, the AI agents operating on behalf of the threat actor continued to use the same IP range to authenticate to customer environments using the illicit access acquired through these stolen app credentials, effectively taking advantage of the already established trust by these apps within a tenant. In some of these environments, the AI agents (on behalf of the threat actor) progressed beyond authentication to Microsoft Graph and directory operations, including reconnaissance, application credential modifications to establish persistence, and changes involving identities, groups, and privileged roles. Microsoft identified multiple customer environments with evidence of follow-on activity, highlighting how a compromised third-party application with high privileges could provide access beyond its originally intended purpose.
The application credential modification made by Storm-0940βs associated agents in the targeted victimsβ environments can lead to persistence through other identities, credentials, and cloud services. These changes can remain active as a backdoor even after the original compromised application is mediated. Organizations should examine service principal sign-ins alongside subsequent Microsoft Graph activity, directory changes, and resource access, correlating suspicious events with authorized administrative activity. The presence of an affected application, or even successful authentication, does not necessarily indicate unauthorized data access or data exfiltration.
Mitigation and protection guidance
Microsoft recommends the following mitigations to reduce the impact of this threat. Check the recommendations card for the deployment status of monitored mitigations.
Do not delete enterprise applications as the first response. Preserve configuration and evidence before making irreversible changes.
Inventory all four application IDs listed in this profile and record the local service-principal Object ID in each tenant.
Review every Microsoft 365 tenant where the affected applications are currently or were previously installed or authorized, even if the integration is no longer in use. Search by application ID rather than display name.
Preserve available Microsoft Entra sign-in and audit records, Microsoft Purview Audit records, SIEM data, and previously configured Microsoft Graph telemetry. Do not delay urgent containment while waiting for exports.
Review activity starting from at least October 15, 2026. Where records are available, extend service-principal sign-in review to October 1 and investigate earlier related activity, including failed authentications and volume anomalies.
Review successful and failed service-principal sign-ins separately. Investigate unfamiliar sources and activity outside expected vendor infrastructure; do not limit review to the published IPs.
Review Microsoft Entra audit records for application or service-principal credential additions; new applications, service principals, or owners; app-role assignments and consent grants; privileged role assignments; and changes to users, groups, authentication methods, or Conditional Access. On confirmed suspicious activity, revoke unnecessary permissions and rotate credentials.
Review Microsoft 365 audit records to look for reconnaissance activities like listing directories, permissions, and approvals coming from unusual IPs.
Review Microsoft 365 audit records for unusual mail or file access, downloads, forwarding, inbox or transport rules, delegated mailbox permissions, and related resource activity.
Preserve evidence, then have an appropriately authorized responder remove confirmed unauthorized credentials, grants, owners, assignments, and identities.
Additional recommendations
Threat actor misuse of AI accelerates risk across enterprise environments by amplifying existing threats such as exploitation of vulnerabilities, phishing, malware threats, and insider activity. To help organizations stay ahead of AI-enabled threat activity, Microsoft has introduced the Security Dashboard for AI. The dashboard provides users with a unified view of AI security posture by aggregating security, identity, and data risk across Microsoft Defender, Microsoft Entra, and Microsoft Purview. This allows organizations to understand what AI assets exist in their environment, recognize emerging risk patterns, and prioritize governance and security across AI agents, applications, and platforms. To learn more about the Microsoft Security Dashboard for AI see: Assess your organizationβs AI risk with Microsoft Security Dashboard for AI (Preview).
Apply least privilege to multi-tenant application permissions and consent grants.
Monitor credential additions, privilege assignments, and anomalous app-only activity, especially to applications with high privileged permissions and scopes.
Verify that vendor credential rotation and any tenant-level remediation eliminated remaining unauthorized access.
Assess the operational effect on backup and restore workflows and follow current ConnectWise restoration guidance.
Microsoft Defender XDR detections
Microsoft Defender XDR customers can refer to the list of applicable detections below. Microsoft Defender XDR coordinates detection, prevention, investigation, and response across endpoints, identities, email, and apps to provide integrated protection against attacks like the threat discussed in this blog.
Customers with provisioned access can also use Microsoft Security Copilot in Microsoft Defender to investigate and respond to incidents, hunt for threats, and protect their organization with relevant threat intelligence.
Tactic
Observed activity
Microsoft Defender coverage (Alert title)
Discovery
Unusual behavior attributes were observed from Graph API activity originating from associated ConnectWise Application.
Unusual Microsoft Graph activity associated with Compromised ConnectWise Application
Privilege Escalation Persistence
Initial Access/Valid Accounts
An application assigned itself to a high privilege role through an Add member to a roles operation. No prior self-assignment to that role was observed for the same application in the preceding seven days.
Application self-assigned Global Administrator role
Discovery
Graph API activity for the user originated from an active, production Microsoft Threat Intelligence Center IP indicator.
Graph API activity from a Microsoft threat intelligence IP address
Valid Accounts
A user sign-in from a nation-state threat actor infrastructure has been detected from this account. A threat actor might have compromised the user account to gain unauthorized access and conducted other malicious activities in your system. Investigate promptly to mitigate security risks.
Suspicious sign-in from verified nation-state threat actor infrastructure
Steal Application Access Token
A sign-in was observed from a known threat actor IP address. We recommend promptly investigating this alert, as a threat actor might already be using the stolen credentials to move laterally in the network.
Malicious sign-in from known threat actor IP address
Microsoft Defender for Cloud Apps detections
Tactic
Observed activity
Microsoft Defender coverage (Alert title)
Persistence
An application or service principal was granted a highly privileged app role.
Suspicious addition of app role assignments to service principal
Collection
High-volume mailbox access by an OAuth app after a suspicious role grant.
Suspicious mail access activity by OAuth application following role assignment
Collection
A suspicious OAuth app that was added recently started accessing the Teams Messages folder using an email client.
Newly added OAuth application accessing Teams Messages folder via email client
Credential Access
An OAuth application activity from an uncommonly visited ISP has been observed, indicating potential suspicious behavior.
OAuth application activity from an uncommonly visited ISP
Exfiltration
OAuth applications seen performing extensive Microsoft Graph SharePoint enumeration activities shortly after application creation or modification events
Suspicious OAuth application created from a risky user context performing graph SharePoint enumeration
Privilege Escalation
Risky permissions that enable user to act as other entities or escalate to Global Admin provided to Service Principal
High-privilege application roles assigned to a service principal
Persistence
A service principal added an application role assignment to itself
Suspicious addition of application role assignments by service principal to itself
Microsoft Defender for Cloud (Microsoft Defender for Key Vault)
Tactic
Observed activity
Microsoft Defender coverage (Alert title)
Persistence
The threat actor compromised a multi-tenant application that Azure customers had granted access to their environments. Using that applicationβs trusted access and existing permissions, the actor reached downstream customer environments. There, they enumerated cloud resources and read secrets at scale across multiple Azure Key Vaults. Key enumeration and a key-unwrapping operation were also observed.
KV_AccountVolumeAccessDeniedAnomaly
Microsoft Security Copilot
Security Copilot customers can use the standalone experience to create their own prompts or run the following prebuilt promptbooks to automate incident response or investigation tasks related to this threat:
Incident investigation
Threat actor profile
Threat Intelligence 360 report based on MDTI article
Note that some promptbooks require access to plugins for Microsoft products such as Microsoft Defender XDR or Microsoft Sentinel.
Threat intelligence reports
Microsoft customers can use the following reports in Microsoft products to get the most up-to-date information about the threat actor, malicious activity, and techniques discussed in this blog. These reports provide intelligence, protection information, and recommended actions to prevent, mitigate, or respond to associated threats found in customer environments.
These IPs were seen performing Sign-ins and Graph API activity in customer environments of ConnectWise apps.
144.172.64[.]99
IP
144.172.64[.]60
IP
187.15.88[.]186187.15.90[.]217187.15.89[.]186
IP
These IPs were seen accessing the Graph API via the compromised apps. However, since they are VPN IPs, it is transient and relevant for investigation on October 15 and 16 in context with compromised applications.
Python-urllib/3.12
User Agent
These user agents were seen performing Sign-ins and Graph API activity on customer environments using ConnectWise apps.
python-requests/2.31.0
User Agent
python-requests/2.34.2
User Agent
curl/7.88.1
User Agent
azure-toolkit/1.0
User Agent
Advanced hunting
NOTE: The following sample queries let you search for a weekβs worth of events. To explore up to 30 daysβ worth of raw data to inspect events in your network and locate potential indicators related to this campaign for more than a week, go to the Advanced Hunting page > Query tab, select the calendar dropdown menu to update your query to hunt for the Last 30 days.
Microsoft Defender XDR advanced hunting
1- OAuthAppInfo β Is the affected app present, enabled, and what permissions does it hold?
Start with OAuthAppInfo to determine whether any of the affected ConnectWise applications are present in the tenant and understand the access they have been granted. The query identifies the application and its tenant-specific service principal, whether it is enabled, its privilege level, consent information, and the individual permissions assigned to it.
This establishes the customerβs potential exposure and gives investigators the ServicePrincipalId needed for further hunting. A match does not mean the application was abused, only that it is present and potentially had access, so the next step is to determine whether the service principal was actually used. Run query
let ConnectWiseApps = dynamic([
"506e08f9-6e9a-4da4-942b-a099a03644ae", // ConnectWise Cloud Backup
"24205314-2b89-4e07-a2a4-579e898a5640", // ConnectWise - MS Teams
"0de14c77-b9b0-4137-9360-34878a929827" // ConnectWise - MS Graph
]);
OAuthAppInfo
| where OAuthAppId in (ConnectWiseApps)
| mv-expand Permission = Permissions
| extend
PermissionName = tostring(Permission.PermissionName),
TargetApp = tostring(Permission.TargetAppDisplayName),
TargetAppId = tostring(Permission.TargetAppId),
PermissionType = tostring(Permission.PermissionType),
PermissionPrivilegeLevel = tostring(Permission.PrivilegeLevel),
UsageStatus = tostring(Permission.UsageStatus)
| project
AppName,
OAuthAppId,
ServicePrincipalId,
AppStatus,
PrivilegeLevel,
IsAdminConsented,
PermissionName,
PermissionType,
PermissionPrivilegeLevel,
TargetApp,
TargetAppId,
UsageStatus
| order by AppName asc, PermissionPrivilegeLevel desc
2 β EntraIdSpnSignInEvents + GraphAPIAuditEvents β Did the service principal authenticate, and what Microsoft Graph activity followed?
Use this query to investigate service-principal sign-ins and Microsoft Graph API activity associated with the identified ConnectWise applications and suspicious IP addresses, starting October 13, 2026.
The query combines both event types into a chronological view, helping defenders identify suspicious authentication and related Graph operations, including potential credential changes, privilege modifications, and unusual resource access. Remove the IP filter for broader hunting. Results require further correlation, as authentication alone does not establish compromise. Run query
let Apps = dynamic([
"506e08f9-6e9a-4da4-942b-a099a03644ae",
"24205314-2b89-4e07-a2a4-579e898a5640",
"0de14c77-b9b0-4137-9360-34878a929827"
]);
let IPs = dynamic(["144.172.64.60", "144.172.64.99", "144.172.64.128"]);
union kind=outer
(EntraIdSpnSignInEvents
| extend EventType = "Sign-in"),
(GraphAPIAuditEvents
| extend EventType = "Graph API", IPAddress = IpAddress)
| where Timestamp >= datetime(2026-10-13)
| where ApplicationId in (Apps)
| where IPAddress in (IPs) // Comment out for broader hunting
| project-away IpAddress
| order by Timestamp asc
3 β Bulk Key Vault secret reads by a single identity across multiple vaults
let IPs = dynamic(["144.172.64.128","144.172.64.60","144.172.64.99"]);
union
(CloudKeyVaultEvents | where IPAddress in (IPs) | extend Source = "KeyVault", Operation = ActivityName),
(CloudStorageAggregatedEvents | where IPAddress in (IPs) | extend Source = "Storage", Operation = tostring(OperationNamesList)),
(CloudAuditEvents | where IPAddress in (IPs) | extend Source = "ARM", Operation = OperationName)
| where Timestamp > ago(30d)
| project Timestamp, Source, IPAddress, Operation, AzureResourceId
| order by Timestamp asc
Sentinel hunting queries
1-SigninLogs β Did a service principal authenticate, from where, and against what resource?
Use SigninLogs to determine whether an affected application identity actually authenticated. This moves the investigation from potential exposure to observed authentication, allowing defenders to examine the application and service principal alongside the source IP address, geographic information, authentication result, and resource being accessed. Investigators should evaluate these sign-ins against the applicationβs expected activity and look for unusual source infrastructure, resources, or authentication patterns before pivoting into subsequent Graph activity. Run query
let IPIndicators = dynamic([
"144.172.64.60", // IP Indicator
"144.172.64.99", // IP Indicator
"144.172.64.128" // IP Indicator
]);
let ConnectWiseApps = dynamic([
"506e08f9-6e9a-4da4-942b-a099a03644ae", // ConnectWise Cloud Backup
"24205314-2b89-4e07-a2a4-579e898a5640", // ConnectWise - MS Teams
"0de14c77-b9b0-4137-9360-34878a929827" // ConnectWise - MS Graph
]);
SigninLogs
| where TimeGenerated >= datetime(2026-10-13)
| where AppId in (ConnectWiseApps)
//| where IPAddress in (IPIndicators) // Comment out to review all activity from these applications
| project
TimeGenerated,
AppId,
ServicePrincipalName,
ResourceDisplayName,
ResourceId,
IPAddress,
CorrelationId
| order by TimeGenerated asc
2 β MicrosoftGraphActivityLogs β What observable Graph API activity followed?
Use MicrosoftGraphActivityLogs to investigate observable Microsoft Graph activity following authentication. This query allows defenders to pivot on the affected ApplicationId or tenant-specific ServicePrincipalId and examine details such as the request URI, HTTP method, response status, scopes, source IP address, and target workload. This helps establish what Graph activity occurred after the service principal authenticated and provides additional context around the resources the application attempted to access.
Importantly, the absence of results should not be treated as confirmation that no access occurred; Graph API telemetry should be considered alongside the application permissions and service principal authentication activity identified in the previous hunting steps. Run query
let IPIndicators = dynamic([
"144.172.64.60", // IP Indicator
"144.172.64.99", // IP Indicator
"144.172.64.128" // IP Indicator
]);
let ConnectWiseApps = dynamic([
"506e08f9-6e9a-4da4-942b-a099a03644ae", // ConnectWise Cloud Backup
"24205314-2b89-4e07-a2a4-579e898a5640", // ConnectWise - MS Teams
"0de14c77-b9b0-4137-9360-34878a929827" // ConnectWise - MS Graph
]);
MicrosoftGraphActivityLogs
| where TimeGenerated >= datetime(2026-10-13)
| where AppId in (ConnectWiseApps)
| where IPAddress in (IPIndicators) // Comment out to review all Graph activity from these applications
| project
TimeGenerated,
AppId,
IPAddress,
RequestMethod,
RequestUri,
ResponseStatusCode,
Scopes,
ClientRequestId,
OperationId,
RequestId
| order by TimeGenerated asc
MITRE ATT&CK Techniques observed
This threat has exhibited use of the following attack techniques. For standard industry documentation about these techniques, refer to the MITRE ATT&CK framework.
Reconnaissance
T1595 Active Scanning | Scanning cloud resources to identify targets for compromise.
To hear stories and insights from the Microsoft Threat Intelligence community about the ever-evolving threat landscape, listen to the Microsoft Threat Intelligence podcast.