AI, Scripts, Operator: Inside the ConnectWise Attack
Huntress analyzes Entra sign-in and audit logs from the ConnectWise Cloud Backup credential abuse of 15 October 2026 to judge whether a script, a person or an LLM agent drove it. It found a thread-pool spray, trial-and-error credential planting with a retry added within 55 seconds, and pilot-then-batch targeting. Huntress rates LLM involvement low to medium on its own data and medium to high with Microsoft's Storm-0940/ARTEX attribution. It ends with detections for service principal role self-assignment and vendor app baselining.
What it is
Huntress analysis of the ConnectWise Cloud Backup credential abuse on 15 October 2026, based on Entra sign-in and directory audit logs. Huntress asks whether a script, a person or an LLM agent drove the activity. Microsoft (21 October report) attributes the activity to Storm-0940 using ARTEX, an open-source multi-agent AI framework. Huntress says its telemetry aligns with Microsoft's findings but does not independently confirm them.
How it works
Huntress saw three behaviors on 15 October, over a little under 14 hours:
- Scripted loops. From about 06:13 to 08:46 UTC the credential hit almost 1,000 tenants in ascending tenant ID order, one to six minutes apart, always with the user agent Python-urllib/3.12. At about 06:04 UTC, about 100 identical failed token requests landed within 10 seconds against the first 100 tenants of that list. Huntress reads this as a thread pool. A second run against 100 tenants used another application's key, at 13 to 21 attempts per second. Both runs used secrets belonging to a single tenant, so they could not work elsewhere.
- Operator adaptation. Between 03:42 and 03:57 UTC the actor added, removed and re-added a secret. A certificate upload failed on a thumbprint mismatch at 03:48:24. The next run, 55 seconds later, retried the same error at 3.5 and 7.1 seconds. The same sequence ran in a second tenant 47 seconds later. When that tenant refused a Global Administrator removal, the actor granted a different role to a sibling principal and deleted the original service principal.
- Pilot then batch. One sweep touched 17 tenants in a hand-ordered sequence between about 09:25 and 12:35 UTC. A second sweep at 13:54 UTC probed six resources per tenant in sorted order, four seconds per tenant. Huntress saw this pilot-then-batch pattern three times across two tools.
First enumeration began about 01:05 UTC, and credential changes in the first tenant were done by 03:50 UTC. Microsoft reports under three hours from targeting to privileged access.
What to do
Huntress lists these detections as useful regardless of the actor:
- Alert when a service principal assigns itself Global Administrator or Privileged Role Administrator, deletes itself, or when one vendor principal grants a role to a sibling.
- Alert on credential additions to high-privilege applications from unexpected sources.
- Baseline each vendor application's user agent (kiota-dotnet for the ConnectWise applications), source ranges and cadence. A vendor app departing from baseline was the clearest early signal.
- Enable Microsoft Graph activity logs where licensing allows. Keep raw user agent strings and sub-second timestamps, because normalization destroys the retry and cadence signals.
- Correlate across tenants, since a trickle in one tenant can be one campaign at thousands of attempts per minute across the estate.
IOCs named in the text: 144.172.64[.]99 (password spray, 10 to 14 October, python-requests/2.34.2), 144.172.64[.]128, and the user agents Python-urllib/3.12 and curl/7.88.1.
Caveats
- Huntress is highly confident that an operator, human or LLM, adapted the tooling between runs. It rates LLM involvement in the escalation tooling low to medium on its own data and medium to high with Microsoft's attribution.
- Logs cannot show who wrote the tooling. A person pasting chatbot output into a terminal looks like a person.
- No known victim had Graph activity logging on, so Graph access scope is invisible. Application-only audit events carry no source IP.
- After the Teams service principal was deleted, requests using it kept failing every four to eight seconds for 22 minutes. This argues against a fully autonomous agent, though a multi-agent framework or an abandoned background loop could explain it.
- The behavioral table for telling scripts, people and agents is Huntress analyst heuristics, not a standard. Huntress expects the retry and cadence signals to be smoothed away by better tools.
- Huntress has not verified how Microsoft linked the earlier spray to Storm-0940 or identified ARTEX. Microsoft counts more than 2,250 tenants, while Huntress sees only those it monitors.
Organisations named here
- ConnectWise Cloud Backup credential abuse
- curl/7.88.1
- Global Administrator role assignment
- Python-urllib/3.12
- service principal credential addition
Technologies named here
- ConnectWise Cloud Backup application credentials
- Microsoft 365 tenants
- Python-urllib/3.12 user agent
- ARTEX
- curl/7.88.1 user agent
- Microsoft Entra ID
- Microsoft Graph
- python-requests/2.31 and python-requests/2.34.2
- Teams service principal
- Thread-pool script
- Entra Sign-in logs and directory audit logs
- Microsoft Graph activity logs
- Microsoft 365
- ConnectWise
- Python
- Huntress
Techniques named here
- Pilot then batch
- Timeline
- MITRE ATT&CK IDs
- Password spraying
Threat actors named here
- Storm-0940
Also named here
- 144.172.64.99
- 144.172.64.128
Related in Threat Intel
Reverse Engineering the Six Stages of MacSync Stealer and RAT
AI-Coded Malware | Analyzing Vibe-Coded AD Enumeration | Huntress
