High 6 Hunt Leads

Storm-0940’s AI Agents Move On to Okta, Entra and Cognito

Wiz says ARTEX AI agents tied to Storm-0940 spent October probing IT and software vendors' Okta, Entra ID and Cognito sign-ins. Most attempts failed.

The AI-driven crew behind the ConnectWise breach didn’t stop at ConnectWise. Wiz Research says it watched ARTEX tooling probe multiple IT and software vendors throughout October, using infrastructure that overlaps with what Microsoft tied to the China-aligned group Storm-0940. Where Microsoft’s report focused on stolen ConnectWise app credentials and the Microsoft 365 tenants behind them (our coverage), Wiz shows the same agents going after vendors’ own logins, identity providers and customer-facing apps. Wiz says most attempts failed and names no victims.

For defenders

What’s new: the targets now include Okta, Entra ID and AWS Cognito, plus Microsoft 365 integrations and vendors’ internal web apps. Wiz describes the agents mapping apps by pulling JavaScript bundles, source maps, runtime config files and Swagger/OpenAPI docs to find hidden API routes. They then hammered sign-in flows: forged OAuth callbacks, unsigned JWTs sent to SSO endpoints, self-registration with throwaway email where sign-up was open, and repeated hits on password-reset, username-recovery and activation endpoints. On Cognito that looked like bursts of InitiateAuth, ForgotPassword, ResendConfirmationCode and SignUp events. Throwaway accounts were then used to test whether changing an ID exposed other tenants’ data.

Spray pattern: T1110.003 (Brute Force: Password Spraying) against Okta and Entra, aimed heavily at software engineers. Each burst used its own user agent, ran 20 to 60 minutes at a median one-second gap, and some sessions lasted 24 to 30 hours. When blocked, the agents rotated IPs, user agents and endpoints. Wiz considers ReconProbe/1.0 a more distinctive marker than the generic agents in its table. The app mapping and throwaway sign-ups fit T1594 (Search Victim-Owned Websites) and T1136.003 (Create Account: Cloud Account).

No malware: ARTEX is a planner agent steering worker agents that run nmap, curl and Impacket. Wiz reports no implants, hashes or C2. The framework went closed-source on Oct. 8 after more than 12,000 forks, so copies are everywhere and the IPs below won’t stay current.

Network (Wiz)
104.194.150[.]21
144.172.64[.]60 (Microsoft: Storm-0940)
144.172.64[.]99 (Microsoft: Storm-0940)
144.172.64[.]128 (Microsoft: Storm-0940)
167.88.172[.]97

User agents (noisy alone)
ReconProbe/1.0
norma/0.4
python-requests/2.34.2
Python-urllib/3.12
curl/7.88.1

What it means for you

This is aimed at software companies, but your data may sit in their systems. The attackers tried every door to it: weak passwords, password-reset pages and sloppy separation between customers. Most doors held. It’s a fair moment to ask your key software suppliers whether they require two-factor sign-in for their own staff.

Do this now

  1. Alert on one source failing against many accounts, and on 20-to-60-minute bursts with one user agent each. Rate matters more than IPs here.
  2. Check your Cognito, Okta and Entra logs for spikes in password-reset, sign-up and confirmation-code calls.
  3. Stop shipping source maps and Swagger docs to production, and test whether one customer account can reach another’s records by changing an ID.
  4. Require phishing-resistant MFA for engineers, the accounts this spray chased hardest.

Source article: ARTEX in the Wild: Storm-0940 Expands Targeting of IT and Software Vendors
Publisher: Wiz (Sapir Federovsky, Rami McCarthy)
Published: Oct. 22, 2026
URL: https://www.wiz.io/blog/artex-in-the-wild-storm-0940-expands-targeting-of-it-and-software-vendors

Executive Summary

Wiz Research observed an actor using ARTEX, an open-source autonomous penetration-testing framework released on GitHub in July 2026 by a Chinese developer, probing IT and software vendors’ applications and identity providers throughout October 2026. Its infrastructure overlaps with Storm-0940, the group Microsoft describes as Chinese-state aligned and tied on Oct. 21 to the ConnectWise supply-chain compromise; Wiz gives the cluster no separate name, and notes that other ARTEX users reported by Zscaler are separate actors. ARTEX runs a planner agent that steers worker agents using nmap, curl and Impacket, recording results in a shared graph; the developer took it closed-source on Oct. 8 after more than 12,000 forks, so copies are widespread. Wiz describes a six-stage playbook: map each application by pulling JavaScript bundles, source maps, runtime config files and Swagger/OpenAPI documents, then call the internal API routes they reveal; probe authentication with fabricated OAuth callbacks, malformed state values and an unsigned alg:none JWT sent to dozens of SSO route variants; password-spray Okta and Entra ID accounts of hundreds of users, mostly software engineers, in 20-to-60-minute bursts at a median one-second interval with a unique user agent per burst and some sessions running 24 to 30 hours; hammer password-reset, username-validation, activation and AWS Cognito ForgotPassword, ResendConfirmationCode and SignUp flows; register throwaway accounts with disposable email where sign-up was open and request other tenants’ data by changing predictable identifiers; and rotate IPs, user agents and endpoints within minutes of being blocked. The objective appears to be access to vendor environments for downstream supply-chain compromise; Wiz says most attempts failed and names no victims. There is no malware, so there are no file hashes. Hunt leads, false-positive expectations, the absence of published rule text, and the indicators are detailed below.

ATT&CK chain: Reconnaissance → Credential Access → Persistence → Initial Access

Hunt Lead Grid

Hunt Lead Level Hunt Lead Name ATT&CK Risk of False Positives
1 (Junior) ARTEX Infrastructure and Self-Identifying Client Sweep T1110.003 (Brute Force: Password Spraying), T1595.003 (Active Scanning: Wordlist Scanning) Low for the five IPs, ReconProbe/1.0 and the /zzz-nonexistent-xyz123 probe path; High for the generic browser, curl and Python user agents Wiz also lists, which the sweep only uses alongside an IP or behavior match.
1 (Junior) Unsigned alg:none JWT Sent to SSO Routes T1606 (Forge Web Credentials), T1190 (Exploit Public-Facing Application) Low. Legitimate clients never send a JWT whose header is {"alg":"none"}; the only benign matches are authorized penetration tests and security scanners, which can be allowlisted by source.
2 (Pro) Source Map, Runtime Config and OpenAPI Harvest Followed by Hidden-Route Calls T1594 (Search Victim-Owned Websites) Medium. Developers and browser dev tools fetch source maps and API docs, so the rule anchors on an unauthenticated client fetching several of .map, config.json, env.js and Swagger within minutes of first contact and then calling internal routes it has never browsed to.
2 (Pro) Account-Recovery and Cognito Sign-up Bursts T1589 (Gather Victim Identity Information), T1136.003 (Create Account: Cloud Account) Medium. Real users reset passwords and resend codes, but rarely many times per minute from one source across many usernames; the rule anchors on per-source rate and username diversity.
2 (Pro) One-Second, Single-User-Agent Spray Bursts Against Okta and Entra T1110.003 (Brute Force: Password Spraying) Medium. Misconfigured service accounts and SSO health checks also fail repeatedly, but against one account; the rule anchors on many distinct users, sub-two-second spacing and a burst-specific user agent.
3 (Elite) Disposable-Email Sign-up Followed by Cross-Tenant Identifier Requests T1136.003 (Create Account: Cloud Account), T1190 (Exploit Public-Facing Application) Medium. Trial users sign up with throwaway addresses and sometimes mistype URLs, so the correlation anchors on a brand-new account requesting other tenants’ identifiers or admin roles within minutes of confirming, producing a run of 401 and 403 responses.

ARTEX Infrastructure and Self-Identifying Client Sweep

Wiz lists five source addresses for the activity: 104.194.150[.]21, 144.172.64[.]60, 144.172.64[.]99, 144.172.64[.]128 and 167.88.172[.]97, of which the three 144.172.64[.]x hosts are the ones Microsoft attributes to Storm-0940. It also lists the user agents seen, warning that most are generic and noisy alone: among them curl/7.88.1, Python-urllib/3.12, python-requests/2.34.2, norma/0.4, bare Mozilla/5.0, a dozen truncated or dated Chrome 120 and 124 strings, Boto3 1.43.112 and 1.43.113 SDK strings, and an aws-cli/1.46.1 md/Botocore#1.43.62 string, and it calls out the self-describing ReconProbe/1.0 as more distinctive. Before fuzzing, the agents requested a deliberately missing path, GET /zzz-nonexistent-xyz123, to learn each application’s “not found” response. The detection logic is a retrospective search of every internet-facing log source for the five IPs, for ReconProbe/1.0 and norma/0.4, and for requests to /zzz-nonexistent-xyz123, with the generic user agents used only to widen a hit that already matches an IP or one of those markers.

Search web server, load balancer, WAF and CDN access logs, Okta System Log, Entra sign-in logs, AWS CloudTrail (including Cognito user pool events) and VPN or firewall logs. Sweep back to Sept. 1, 2026, since ARTEX activity against other targets was reported from late September, and keep the IPs on a watchlist. Wiz says new IPs appeared within minutes of blocks and the framework has thousands of forks, so the IPs will go stale quickly and blocking them is not a complete control; blocking the generic user agents would break legitimate tools and SDKs. Any match on the IPs or distinctive markers is a confirmed visit by this tooling: review what the source reached, and especially any successful sign-in, password reset or account creation it produced, then hand off to the behavioral leads below.

Hunt Lead Level: 1 (Junior Analyst)

ATT&CK: Credential Access → T1110.003 (Brute Force: Password Spraying) (our mapping; Wiz publishes no ATT&CK mapping); Reconnaissance → T1595.003 (Active Scanning: Wordlist Scanning) (our mapping)

Sources: “ARTEX in the Wild: Storm-0940 Expands Targeting of IT and Software Vendors”, Wiz, Oct. 22, 2026, https://www.wiz.io/blog/artex-in-the-wild-storm-0940-expands-targeting-of-it-and-software-vendors (source article)

Unsigned alg:none JWT Sent to SSO Routes

The agents sent GET /sso?jwt=eyJhbGciOiJub25lIn0.eyJlbWFpbCI6InRlc3RAdGVzdC5jb20ifQ., a token whose header decodes to {"alg":"none"} and whose payload is {"email":"test@test.com"} with an empty signature, an attempt to get an SSO endpoint to accept an unsigned identity assertion. More than 60 SSO route variants received this payload within two minutes, including /sso, /sso/, /sso/login, /sso/jwt and /jwt/sso…, with and without the token, at about one request per second. In the same stage the agents fabricated OAuth callbacks such as GET /sign_in/oauth/microsoft/callback?code=AAAA&state=notvalidb64!!. The detection logic is a match in web, WAF or API gateway logs on any request carrying a JWT that begins eyJhbGciOiJub25lI (the base64url encoding of {"alg":"none" in any form), on the exact token above, and on OAuth callback requests with the placeholder code AAAA or a state value that is not valid base64.

Use web server and reverse-proxy access logs with full query strings, WAF logs, and API gateway logs; if query strings are not logged, this lead depends on enabling that for authentication routes. Sweep back to Sept. 1, 2026 and run continuously. Scope to every route that accepts tokens, including legacy and internal SSO handlers. False positives are limited to authorized testing and commercial scanners, which should be allowlisted by source rather than by pattern. A hit with a 2xx response is the priority: it means the endpoint may accept unsigned tokens, which is a vulnerability to fix immediately regardless of who sent it, and the session that followed should be investigated as a possible account takeover. The lead generalizes to any tooling that tests JWT validation.

Hunt Lead Level: 1 (Junior Analyst)

ATT&CK: Credential Access → T1606 (Forge Web Credentials) (our mapping; Wiz publishes no ATT&CK mapping); Initial Access → T1190 (Exploit Public-Facing Application) (our mapping)

Sources: “ARTEX in the Wild: Storm-0940 Expands Targeting of IT and Software Vendors”, Wiz, Oct. 22, 2026, https://www.wiz.io/blog/artex-in-the-wild-storm-0940-expands-targeting-of-it-and-software-vendors (source article)

Source Map, Runtime Config and OpenAPI Harvest Followed by Hidden-Route Calls

Within minutes of first contact, the agents pulled files that describe an application’s internals, such as GET /packs/js/main-3a9f...js.map, GET /assets/config.json, GET /env.js and GET /swagger/?format=openapi, then called internal API routes by name, taken from the downloaded source maps. The detection logic is a per-source correlation in web access logs: an unauthenticated client that requests two or more of a .js.map file, a runtime config file (config.json, env.js or similar), and an OpenAPI or Swagger document within a short window such as ten minutes, and then requests API routes that no page it loaded links to, with higher severity when those routes are administrative or account-related.

Use web, CDN and WAF access logs with per-client session reconstruction by IP and user agent. Back-test 60 days and run continuously. Developers and QA staff fetch source maps and API docs routinely, so exclude corporate egress ranges and authenticated staff sessions, and baseline which routes your own front end calls so that “never linked” is meaningful. The better control is to stop shipping source maps, runtime secrets and Swagger documents to production; blocking the requesting IP is a weak control given how fast the agents rotate. Any hit from an external, unauthenticated source should be correlated with the authentication and recovery leads, since mapping preceded those stages within minutes. The pattern generalizes to most agentic and automated reconnaissance tools.

Hunt Lead Level: 2 (Pro)

ATT&CK: Reconnaissance → T1594 (Search Victim-Owned Websites) (our mapping; Wiz publishes no ATT&CK mapping)

Sources: “ARTEX in the Wild: Storm-0940 Expands Targeting of IT and Software Vendors”, Wiz, Oct. 22, 2026, https://www.wiz.io/blog/artex-in-the-wild-storm-0940-expands-targeting-of-it-and-software-vendors (source article)

Account-Recovery and Cognito Sign-up Bursts

The agents repeatedly hit account-recovery and enumeration endpoints, for example GET /Account/ValidateUserName?UserName=admin, POST /api/v1/Users/GeneratePasswordResetToken (which returned 204) and POST /forgot_password, along with activation and reset-token endpoints, and on AWS Cognito generated bursts of InitiateAuth, ForgotPassword, ResendConfirmationCode and SignUp events, the last used to create new identities. The detection logic is a per-source rate rule on recovery and sign-up endpoints and Cognito events: one IP or user agent calling username validation, password reset, resend-confirmation or sign-up many times per minute, or across many distinct usernames, with extra weight when the validated usernames are generic administrative names such as admin.

Use application access logs for custom recovery routes and CloudTrail for Cognito user pool API calls (unauthenticated user pool calls such as ForgotPassword and SignUp are logged as management events), plus Okta and Entra self-service password reset logs. Back-test 60 days and run continuously. Normal users reset passwords occasionally and from residential networks, so set thresholds per source and per username diversity rather than raw volume, and exclude load tests from known ranges. Rate limiting and identical responses for valid and invalid usernames are the preventive controls; captchas alone are a weak fit against agents that switch endpoints when one is throttled, as Wiz observed. A hit that produced reset tokens or confirmed sign-ups should be followed through to the tenant isolation lead below. The lead generalizes to credential-stuffing and enumeration tooling.

Hunt Lead Level: 2 (Pro)

ATT&CK: Reconnaissance → T1589 (Gather Victim Identity Information) (our mapping for username validation); Persistence → T1136.003 (Create Account: Cloud Account) (our mapping for Cognito SignUp; Wiz publishes no ATT&CK mapping)

Sources: “ARTEX in the Wild: Storm-0940 Expands Targeting of IT and Software Vendors”, Wiz, Oct. 22, 2026, https://www.wiz.io/blog/artex-in-the-wild-storm-0940-expands-targeting-of-it-and-software-vendors (source article)

One-Second, Single-User-Agent Spray Bursts Against Okta and Entra

The spraying hit hundreds of users across both Okta and Entra ID, mostly software engineers, with some users receiving more than a dozen attempts. Each burst used its own user-agent string, ran 20 to 60 minutes with a median gap of one second between attempts, and some sessions lasted 24 to 30 hours; when a login page rate-limited, the agent moved to another endpoint on the same host, and new IPs appeared within minutes of a block. Wiz says its existing rules covered this, naming “Potential Password Spray Attack From Single IP”, “Okta Users Password Spray” and “Numerous Failed Login Attempts To Multiple Users Followed By A Successful Login To Admin User”, but publishes no query logic. The detection logic is a windowed rule on IdP authentication failures grouped by source IP and user agent: many distinct target users (for example 20 or more) within 30 minutes, a median inter-attempt gap under two seconds, and a single user agent for the whole burst, escalating if any targeted user then signs in successfully from the same source or ASN.

Use the Okta System Log (authentication failure events) and Entra interactive and non-interactive sign-in logs exported to a SIEM, with ASN enrichment. Back-test from Sept. 1, 2026 and run continuously. Service accounts with stale passwords and health checks fail repeatedly but against one account, and single-sign-on outages cause broad failures from corporate ranges, so require user diversity and an external source. Grouping by user agent alone is the wrong design, since the agents change it every burst; group by burst timing and source, then use the user agent to delimit bursts. Any spray followed by a success is a likely compromise: revoke that user’s sessions, reset the password and review MFA changes; engineers are the priority because they hold source and pipeline access. This generalizes to any automated password spray.

Hunt Lead Level: 2 (Pro)

ATT&CK: Credential Access → T1110.003 (Brute Force: Password Spraying) (our mapping; Wiz publishes no ATT&CK mapping)

Sources: “ARTEX in the Wild: Storm-0940 Expands Targeting of IT and Software Vendors”, Wiz, Oct. 22, 2026, https://www.wiz.io/blog/artex-in-the-wild-storm-0940-expands-targeting-of-it-and-software-vendors (source article)

Disposable-Email Sign-up Followed by Cross-Tenant Identifier Requests

Where an application allowed self-registration, the agents signed up with addresses from free temporary-email services, confirmed the account, and immediately requested another company’s data by changing predictable identifiers and role parameters, for example POST /v2/register_user (201), POST /confirm (200), then GET /company/1/logins (403) and GET /api/users/generate_redirect_link?role=admin (401). The detection logic is a per-account sequence correlation: a newly created account whose email domain is on a disposable-email list, confirmed within minutes, that then requests resources keyed to tenant or company identifiers other than its own, or passes elevated role parameters, producing several 401 or 403 responses in a row; any 2xx response to such a request is the critical case.

This needs application logs that record the authenticated account and tenant for each request, sign-up and confirmation events, a disposable-email domain list, and the HTTP status codes, joined per account in a SIEM; Wiz’s “Unusual Mass Access Denied Activity” rule name points to the same denial pattern, though its logic is not published. Back-test 60 days and run continuously. Genuine trial users also use throwaway addresses and occasionally hit forbidden pages, so require the cross-tenant identifier or role parameter and a run of denials, not either alone. The wrong response is to treat 403s as proof the controls worked and stop; each denied identifier should be retested by the application team for broken access control, because one route that returns data is enough. A 2xx response for another tenant’s identifier is a data exposure: preserve logs, disable the account and fix the authorization check. The lead generalizes to IDOR testing by any automated tool.

Hunt Lead Level: 3 (Elite)

ATT&CK: Persistence → T1136.003 (Create Account: Cloud Account) (our mapping); Initial Access → T1190 (Exploit Public-Facing Application) (our mapping for broken-access-control testing; Wiz publishes no ATT&CK mapping)

Sources: “ARTEX in the Wild: Storm-0940 Expands Targeting of IT and Software Vendors”, Wiz, Oct. 22, 2026, https://www.wiz.io/blog/artex-in-the-wild-storm-0940-expands-targeting-of-it-and-software-vendors (source article)

Hash Appendix

No file hashes: Wiz reports no malware, implants or command-and-control for this activity, and lists no domains. ARTEX worker agents use standard tools (nmap, curl, Impacket), whose hashes should not be blocked. Wiz names its detection rules but publishes no query, Sigma or YARA text. Network indicators and user agents are listed in the infrastructure lead above.

References Appendix

  • “ARTEX in the Wild: Storm-0940 Expands Targeting of IT and Software Vendors”, Wiz (Sapir Federovsky, Rami McCarthy), Oct. 22, 2026, https://www.wiz.io/blog/artex-in-the-wild-storm-0940-expands-targeting-of-it-and-software-vendors (source article; ARTEX background, Storm-0940 overlap, six-stage playbook, logged requests and responses, Cognito events, spray characteristics, IP and user-agent indicators, rule names)
  • MITRE ATT&CK Enterprise technique pages linked above, MITRE, https://attack.mitre.org/

More from the Roundup