CUTSIGNcutting for sign — daily OSINT threat read
AI-generated draft, unreviewed. Version 2, written by a model from the stored public sources on 2026-11-03; hype score 0. It is regenerated when the evidence changes and is published as a verdict card under /cards/ once it crosses the publish bar. Status: draft. Supersedes version 1.

Storm-0940/UNC7228 ARTEX agentic intrusions: ConnectWise M365 abuse plus wider on-prem and cloud TTPs

Hunt / IR + hardenP1confidence: highre-issue of card connectwise-m365-2026

Stolen ConnectWise Cloud Backup app credentials were used against 2,250+ M365 tenants from Oct 15. GTIG links the same ARTEX tooling to intrusions with confirmed data theft since late August. Today: hunt the ConnectWise app identities and the Entra audit log back to Oct 1, then run the MySQL-webshell and webhook.site egress hunts.

Triage: Microsoft and Huntress confirm privileged access in M365 tenants via a vendor app identity in under three hours [S2][S4]. Any tenant that used ConnectWise Cloud Backup should treat a hit as an active compromise.

Microsoft [S2] and GTIG/Mandiant [S1] are primary sources for the core claims, and Huntress [S4] corroborates from its own telemetry. Two newer reports (CrowdStrike on Vapor Panda; WorkOS) arrived only as truncated change notes and are not folded in.

Changed since version 1

What happened

Timeline

2026-08 (late)Agentic-framework intrusions, including ARTEX, begin per GTIG S1
2026-10-10 to 2026-10-14Password spray against ConnectWise (151,000+ failures) S2
2026-10-15Stolen ConnectWise app identities authenticate to 2,250+ M365 tenants S2
2026-10-15Huntress observes privilege escalation in ~1,000 monitored tenants in under three hours S4
2026-10-21Microsoft publishes Storm-0940 / ARTEX attribution S2
2026-11-02GTIG/Mandiant publish wider ARTEX, PentAGI and CAIRN intrusion TTPs S1

Detect

Entra app credential, role and principal changes · Entra ID directory audit logs

index=* earliest="10/01/2026:00:00:00" operationName IN ("Add service principal credentials","Update application – Certificates and secrets management","Add member to role","Add app role assignment to service principal","Remove service principal","Consent to application") | stats count min(_time) as first max(_time) as last values(operationName) as ops by initiatedBy.app.displayName, initiatedBy.app.servicePrincipalId | sort - count
FROM logs-* | WHERE @timestamp >= "2026-10-01T00:00:00Z" AND event.action IN ("Add service principal credentials", "Update application – Certificates and secrets management", "Add member to role", "Add app role assignment to service principal", "Remove service principal", "Consent to application") | STATS count = COUNT(*), first = MIN(@timestamp), last = MAX(@timestamp), ops = VALUES(event.action) BY azure.auditlogs.properties.initiated_by.app.displayName, azure.auditlogs.properties.initiated_by.app.servicePrincipalId | SORT count DESC

A hit means: A service principal added credentials, granted roles (including to itself) or deleted a principal. A vendor or Teams principal assigning itself Global Administrator matches the pattern in [S2][S4].

Vendor app sign-ins with scripted user agents or listed IPs · Entra service principal sign-in logs; Microsoft Graph activity logs

index=* earliest="10/01/2026:00:00:00" (userAgent="Python-urllib/3.12*" OR userAgent="curl/7.88.1*" OR userAgent="python-requests/2.31*" OR ipAddress="144.172.64.*") | stats count min(_time) as first max(_time) as last values(userAgent) as ua values(ipAddress) as ip by appId, servicePrincipalName
FROM logs-* | WHERE @timestamp >= "2026-10-01T00:00:00Z" AND (user_agent.original LIKE "Python-urllib/3.12*" OR user_agent.original LIKE "curl/7.88.1*" OR user_agent.original LIKE "python-requests/2.31*" OR TO_STRING(source.ip) LIKE "144.172.64.*") | STATS count = COUNT(*), first = MIN(@timestamp), last = MAX(@timestamp), ua = VALUES(user_agent.original), ip = VALUES(source.ip) BY azure.signinlogs.properties.app_id, azure.signinlogs.properties.service_principal_name

A hit means: An app identity authenticated or called Graph with tooling other than the ConnectWise baseline (kiota-dotnet), or from the reported IP range [S4]. Check the appId against the ConnectWise IDs in [S2].

MySQL general_log webshell and ARTEX artifacts · MySQL general/query log; web server access log; EDR file creation

index=* ("SET GLOBAL general_log_file" OR "cl1217.jsp" OR "f1219a.jsp" OR "z1219.jsp" OR "artex-probe-" OR "ArtexProbe") | stats count min(_time) as first max(_time) as last values(source) as sources by host
FROM logs-* | WHERE message LIKE "*SET GLOBAL general_log_file*" OR message LIKE "*cl1217.jsp*" OR message LIKE "*f1219a.jsp*" OR message LIKE "*z1219.jsp*" OR message LIKE "*artex-probe-*" OR message LIKE "*ArtexProbe*" OR url.path LIKE "*cl1217.jsp*" OR url.path LIKE "*f1219a.jsp*" OR url.path LIKE "*z1219.jsp*" OR file.path LIKE "*cl1217.jsp*" OR file.path LIKE "*f1219a.jsp*" OR file.path LIKE "*z1219.jsp*" OR file.path LIKE "*artex-probe-*" OR process.command_line LIKE "*ArtexProbe*" OR process.command_line LIKE "*artex-probe-*" | STATS count = COUNT(*), first = MIN(@timestamp), last = MAX(@timestamp), sources = VALUES(log.file.path) BY host.name

A hit means: The MySQL log was redirected to a file, a reported webshell name was requested, or ARTEX naming artifacts were created. Any of these warrants host-level investigation [S1].

Server egress to webhook.site · Proxy, DNS, network flow

index=* ("webhook.site" OR query="*webhook.site" OR url="*webhook.site*") | stats count dc(url) as distinct_urls values(http_user_agent) as ua min(_time) as first max(_time) as last by src
FROM logs-* | WHERE message LIKE "*webhook.site*" OR dns.question.name LIKE "*webhook.site" OR url.full LIKE "*webhook.site*" OR url.domain LIKE "*webhook.site" OR destination.domain LIKE "*webhook.site" | STATS count = COUNT(*), distinct_urls = COUNT_DISTINCT(url.full), ua = VALUES(user_agent.original), first = MIN(@timestamp), last = MAX(@timestamp) BY source.ip

A hit means: A host contacted webhook.site. Many distinct URLs from a server, especially with a curl user agent, matches the C2 and exfil pattern in [S1].

Verify

Scope

Affected

Only if

Not affected if

None stated by the sources.

Enumerate

Contain

Eradicate

Recover

Re-enter the loop when

Debrief

Detection coverage — checked automatically

CategorySourceStatus
VendorImpacted vendor / CERT advisorypublished — primary source among the thread's sources: https://www.microsoft.com/en-us/security/blog/2026/10/21/storm-0940-uses-artex-agentic-ai-connectwise-supply-chain-compromise/
GovernmentCISA KEVnot checkable — no CVE: the catalog is keyed by CVE
EDR / endpoint VMCrowdStrike blognothing found — no post names it among the feed's 10 newest items
EDR / endpoint VMMicrosoft Security blogpublished — ARTEX abuse expands as cybercriminals target financial sector · Threat actors use agentic AI tooling to find and abuse exposed secrets (names ARTEX in the title; the feed text carries no CVE id)
EDR / endpoint VMSentinelOne blogpublished — The Good, the Bad and the Ugly in Cybersecurity - Week 43 (2026) (names the campaign in the title; the feed text carries no CVE id)
EDR / endpoint VMSentinelOne Labsnothing found — no post names it among the feed's 10 newest items
WAF / edgeAkamai blogpublished — What ARTEX Reveals About Overlooked Attack Surfaces (names ARTEX in the title; the feed text carries no CVE id)
WAF / edgeCloudflare WAF managed-ruleset changelognothing found — no post names it among the feed's 139 newest items
Cloud / containerWiz blogpublished — ARTEX in the Wild: Storm-0940 Expands Targeting of IT and Software Vendors (names ARTEX / Storm-0940 in the title; the feed text carries no CVE id)
IDS / researchCisco Talos blogpublished — Appraisal by AI: Model-driven victim prioritization in the VOLTA infostealer · NIK C2: The new AI-enabled command-and-control framework (names the campaign in the title; the feed text carries no CVE id)
Detection contentElastic detection rulespublished — 22 files name ARTEX / ConnectWise: rules/integrations/azure/discovery_graph_application_directory_reconnaissance.toml, rules/integrations/azure/credential_access_key_vault_secret_burst_by_application.toml, rules/_deprecated/exfiltration_rds_snapshot_export.toml, rules/integrations/aws/exfiltration_rds_snapshot_export.toml
Detection contentElastic Security Labsnothing found — no post names it among the feed's 102 newest items
Detection contentSigmaHQ rulespublished — 18 files name ARTEX / ConnectWise: rules-compliance/other/netflow_cleartext_protocols.yml, rules/network/firewall/net_firewall_cleartext_protocols.yml, deprecated/windows/file_event_win_access_susp_teams.yml, rules/windows/file/file_event/file_event_win_hktl_nppspy.yml
Detection contentSplunk ESCUpublished — 15 files name ARTEX / ConnectWise: stories/use_of_cleartext_protocols.yml, detections/network/protocols_passing_authentication_in_cleartext.yml, removed/investigations/get_notable_history.yml, removed/investigations/get_process_information_for_port_activity.yml
MSSP / IR firmsArctic Wolf blognothing found — no post names it among the feed's 10 newest items
MSSP / IR firmsHuntress blogpublished — AI, Scripts, Operator: Inside the ConnectWise Attack · ConnectWise (SkyKick) Vendor Credentials Abused in M365 Attacks · Inside an AhsayCBS Intrusion: Hidden Webshells, a CryptoMiner, and a C2 Implant (names ConnectWise in the title; the feed text carries no CVE id)
MSSP / IR firmsRapid7 blogpublished — Rapid7 Analysis: NetScaler intrusions chaining CVE-2026-88771 and CVE-2026-88779 (names the campaign in the title; the feed text carries no CVE id)
MSSP / IR firmsSophos threat researchpublished — ConnectWise Cloud Backup application abused in cross-tenant token sweep (names ConnectWise in the title; the feed text carries no CVE id)
ResearchUnit 42nothing found — no post names it among the feed's 15 newest items

Checked automatically 2026-11-10 18:12Z from public sources: 12 published, 6 nothing found, 1 not machine-checkable, 0 failed. "Nothing found" means the public source answered and had nothing, as of that moment; a feed covers only its newest posts. Re-checked daily.

What a person would still look up (6)
Identity / cloud (Entra, M365)Whether the identity product alerts on service principal self-assignment of privileged roles and on credential additions to third-party apps.
EDR / endpointWhether the vendor has published detections for ARTEX artifacts, JSP webshells spawned by a Java servlet container, and curl download cradles on database servers.
Cloud / containerWhether CSPM/CDR content covers AWS DryRun permission-probe bursts, Kudu command execution and unexpected key pair or EIP creation.
WAF / edgeWhether managed rules flag requests to newly created .jsp files and high-volume directory fuzzing.
Proxy / DNSWhether webhook.site and OAST domains are categorised and blockable for server segments.
Detection content (Sigma, Splunk ESCU, Elastic)Read the matched rules themselves; keyword hits on ARTEX or ConnectWise may be unrelated.

Exposure queries — generated automatically

No CVE in this campaign: nothing an internet scanner keys on. Scope by product in your own tool.

Banner spellings: a model read 2 from the NVD names and this card's text (former and marketing names, console titles); 0 matched something on Shodan and are shown above, the rest were dropped.

Scope every query in your own tool, never in a shared document: Shodan `net:<your_ranges>`, `org:"<your_org>"` or `hostname:<your_domain>` (or a Shodan Monitor network alert, which applies the scope for you); Censys `host.ip: <your_ranges>` or `host.dns.names: <your_domain>`. Then compare the banner version with the affected range. Generated automatically 2026-11-10 18:12Z from the CVE ids and NVD's CPE configurations, each Shodan query counted against Shodan itself; re-built daily with the coverage check.

Open questions

Sources

Public OSINT only. AI-generated by the pipeline; structure follows the DAIR model from Dynamic Incident Response (Joshua Wright). Published automatically once it crosses the publish bar.