Loading...
You are here:  Home  >  ARTEX: An Agentic Pentesting Framework Turned Espionage Tool

ARTEX: An Agentic Pentesting Framework Turned Espionage Tool

ARTEX: An Agentic Pentesting Framework Turned Espionage Tool

The adversary’s use of the ARTEX agent framework, the wider ARTEX threat picture, the activity recorded in our environment, and the defensive outcomes achieved.

Blocked requests were followed within seconds by reworded ones. That rhythm, not any single indicator, is what this post is about.

On 17 October 2026 a China-based intrusion set started using a publicly released, open-source agentic penetration-testing framework called ARTEX against more than 200 organizations in at least 14 countries. ARTEX is not a tool an operator drives by hand. It plans, it writes its own JavaServer Pages web shells, it re-encodes its own commands the moment a web application firewall blocks them, and in one recorded engagement it consumed about 1.4 billion input tokens before anyone noticed it was there.

What follows is the whole case, written from our side of the wire: what the public advisories state, what our own telemetry recorded, where the two agree, where the record is still open, and what was closed and then verified by attempting the action again as the application account.

The interesting part is not that an artificial intelligence framework was used. It is that the framework arrived better documented than the defensive tooling pointed at it, and that it was being improved while it worked.

Section 3 opens the machinery: one turn of the agent loop at a time, the four channels the bots use to hand work to each other, and the minute by minute trace of that loop inside our estate.

Source reporting Our record Adversary infrastructure

Throughout, source reported material and our own recorded material are labelled separately with these marks.

As always, names have been changed, except for our external entity.

A note on naming. Host names, internal domain names, application names, service accounts and case record identifiers in this post have been replaced with role-based labels carrying a single name, cybercrypto. The labels are stable throughout and can be read positionally:

  • cybercrypto-app-dev-01 through cybercrypto-app-dev-05 are the development application servers.
  • cybercrypto-app-prod-01 is the production application server.
  • cybercrypto-app-web-01 is the web server.
  • cybercrypto-cloud-01 is the cloud instance.
  • cybercrypto-grants-gateway, cybercrypto-ci, cybercrypto-scm, cybercrypto-wiki, cybercrypto-dev, cybercrypto-artifacts, cybercrypto-iam and cybercrypto-web are the public-facing and internal service endpoints.
  • cybercrypto-svc-01 through cybercrypto-svc-04 are service accounts.
  • cybercrypto-app-reg-01 and cybercrypto-app-reg-02 are cloud application registrations.

Security products in our environment are described by their role rather than by vendor.

External adversary infrastructure, file hashes, tool names and published advisory identifiers are reproduced exactly as reported, because those are the parts you need in order to defend.

1Bottom line

Nine findings, each marked with where it comes from.

The campaign
Source reporting
The actor used the publicly released agentic framework ARTEX, run mainly on DeepSeek models, against more than 200 organizations in at least 14 countries from 17 October 2026. The source advisory confirms post-exploitation activity at nine. It attributes the campaign to that adversary with moderate confidence.
The controller address is in our record, and we had it first
Our record
Advisory CSA-261253, published 27 October, lists 118.128.151.28 as the ARTEX controller. Our case record had already named that address as the actor’s address on 26 October.
Techniques the advisories report are present in our record
Our record
JavaServer Pages web shells, Base64-encoded echo commands, and queries for Enterprise Admins and Domain Admins. The advisories name no victims, and this post does not identify any.
Shell writes were detected as they happened
Our record
On 27 October, five endpoint web shell alerts on cybercrypto-app-dev-02 each fired within one second of a web shell write. A further alert fired on cybercrypto-app-prod-01 on 29 October at 15:05:22.
The exploit chain is closed where it was proven open
Our record
On cybercrypto-app-prod-01, cybercrypto-app-web-01 and cybercrypto-cloud-01, the web-root write and the root escalation are both closed. Each closure was verified by attempting the action as the application account.
The campaign indicators are enforced
Our record
Every advisory address and domain is covered by kill rules, and the advisory hashes are set to prevent.
No sign-in from the controller succeeded
Our record
All four identity events from 118.128.151.28 are failures.
No campaign malware was found on screened endpoints
Our record
The vendor hashes and file names returned no match across the endpoint telemetry planes over 30 days.
ARTEX is used by more than one actor
Source reporting
The source advisory and Microsoft both report this. A commercial edition went on sale on 16 October 2026.

2Threat overview

What the cited sources state. Confidence language is the source’s own.

Source reporting

2.1 ARTEX

  • ARTEX is an open-source agentic penetration-testing framework developed in China. It was published on GitHub by the developer “Autumn-27” (Zscaler ThreatLabz; CSA-261253) and first released in July 2026 (Korea JoongAng Daily).
  • Zscaler reports that ARTEX shipped a default blocklist restricting the targeting of government entities and universities, and that the blocklist did not extend to financial institutions.
  • Autumn-27 converted the project to closed source on 8 October 2026, and Reuters reported the GitHub page had been taken down. Korea JoongAng Daily notes that previously released source and downloaded copies remain usable.
  • On 16 October 2026 ThreatBook launched RedAgents, a hosted platform of artificial intelligence penetration-testing agents. Its launch roster includes Artex Pro, an enterprise edition built on the open-source Artex. ThreatBook states the open-source edition was a personal project of the RedAgents product lead (ThreatBook announcement, 20 October 2026).

2.2 The ARTEX campaign

Adversary and attribution. The advisory identifies a China-based targeted intrusion adversary, first observed in February 2021 using the ProxyLogon exploit chain. The source advisory attributes this campaign to that adversary with moderate confidence (CSA-261253). It describes this as the adversary’s first observed artificial-intelligence-driven intrusion, and states the campaign is separate from the ARTEX activity Microsoft tracks as Storm-0940.

Reach against result

One ARTEX controller, 17 to 27 October 2026. Bar length is to scale. Sources: CSA-261253, CSA-261264.

In one intrusion the planning agents alone consumed about 1.4 billion input tokens (vendor research blog, 29 October 2026). High volume, low conversion.

Scale. The source advisory recorded one ARTEX controller, 118.128.151.28, targeting entities in at least 14 countries from 17 to 27 October 2026 (CSA-261253). At least 20 engagements reached more than 200 distinct organizations; post-exploitation was confirmed at nine (CSA-261253, CSA-261264). In one intrusion, the planning agents consumed about 1.4 billion input tokens (vendor research blog, 29 October 2026).

Models. Worker agents were configured with ARTEX_LLM_BASE_URL set to https://api.deepseek.com/v1, and all 35,159 recorded tool-call identifiers follow DeepSeek’s format. The source assesses that the workers almost certainly used DeepSeek models, with high confidence. Planner agents used a second, subscription-based service that the source has not identified (CSA-261264).

Operator and endpoint sensor. Operator instructions were written in Chinese, labelled 【人类指令】 (human instruction). They directed the agent to write web shells, use Base64-encoded echo commands, extract domain administrator passwords and enumerate sensor coverage (CSA-261253). Rather than disable the sensor, the operator directed the agent to avoid it and look for hosts without it (CSA-261264).

Targeting

  • Foreign ministries in Latin America, Europe, Asia and the Middle East.
  • 19 U.S.-based companies in one engagement, in the pharmaceutical, semiconductor, defense, nuclear and financial sectors.
  • Telecommunications providers in the U.S., Belgium and the Philippines.
  • Think tanks, shipping and critical-minerals entities, and a U.S. newspaper’s advertising platform.

Sources: CSA-261253, CSA-261264.

Tooling

  • BLOODALCHEMY, side-loaded by a legitimate GameHook binary renamed svchost.exe, and a second loader acrobat_compat.dll.
  • Cobalt Strike, loaded by libcef.dll.
  • Stowaway, SoftEther and Chisel.
  • At the Greek government entity GR1, WebLogic CVE-2020-14882 and CVE-2020-14883 were used to deploy web shells.

Sources: CSA-261253, CSA-261264.

2.3 Other reported ARTEX activity

Storm-0940 (Microsoft, 21 October 2026)

  • Microsoft reports that Storm-0940 used ARTEX from September 2026 against hundreds of organizations.
  • On 15 October the group compromised Microsoft 365 environments belonging to ConnectWise Cloud Backup customers, attempting sign-ins to more than 2,250 tenants.
  • ARTEX was used to speed up reconnaissance, password spraying and OAuth application abuse.
  • Microsoft reports that threat actors in other regions have also used ARTEX.

South Korean financial sector, late September to early October 2026

  • The source advisory reported on 7 October that an actor used ARTEX and commercial models against South Korean financial institutions.
  • Zscaler reports personal data of about 67,000 individuals exfiltrated. Recorded Future cites public reporting of at least 68,000 people across at least seven institutions.
  • Recorded Future tracks the actor as TAG-217 and places its infrastructure testing as early as 17 to 22 August 2026. It notes that the evidence does not establish that an artificial intelligence system acted without a human operator.
  • Zscaler reports that the actor used Claude Code sessions to seek advice on selling the stolen data and to locate Korean-language Telegram channels that sell data.

Time from intrusion to detection, as reported by Korean press

Hours. Bar length is to scale.

2.4 Source assessments

Assessment, as statedConfidenceSource
The activity is attributed to a China-based targeted intrusion adversaryModerateCSA-261253
China-nexus adversaries will highly likely continue adopting agentic frameworks such as ARTEX in the short termHighCSA-261253, CSA-261264
ARTEX workers almost certainly used DeepSeek modelsHighCSA-261264
ARTEX use has highly likely given the adversary access at a scale that would previously have required a substantially larger teamHighCSA-261264
Defenders’ responses ended individual engagements rather than the campaignModerateCSA-261264
The adversary’s success with a publicly available framework and a China-based commercial model represents a likely emerging trend in China-nexus targeted intrusion activityModerateCSA-261264
45.116.20.180 is highly likely compromisedHighCSA-261264
It is highly likely that more threat actors will incorporate ARTEX and similar artificial intelligence penetration-testing tools into their operationsHighly likely (as stated)Recorded Future Insikt Group

3Anatomy of the bot

How the ARTEX loop actually works, and where it touched us.

Source reportingOur record

This section exists because the phrase “artificial intelligence agent” hides the mechanism, and the mechanism is the part you can see, measure and interrupt. ARTEX is not a program that does a thing. It is a loop that writes a new program for nearly every step it takes, calls a hosted model to decide what to write next, and hands the result to a tool. Everything below is either published in the source reporting or visible in our own telemetry, and the two are labelled separately.

3.1 The framework is a product, and it has a release history

ARTEX was published as open source on GitHub by the developer known as Autumn-27. At the time of collection the repository carried 2,062 stars and 534 forks, a hosted demonstration site, and this technology stack: a Go back end, an embedded Next.js front end, PostgreSQL for state, and model configuration by application programming interface key (ANTHROPIC_API_KEY or OPENAI_API_KEY) or through its own user interface.

Its own licence text forbids using it against any website, online service or networked system, authorised or not. It shipped with default interception rules that block targeting of .gov and .edu domains, including their Chinese equivalents, and did not extend that blocklist to financial institutions. The blocklist is a configuration file, not a control, and anyone who downloads the framework can edit it.

Two months from publication to a hosted commercial edition

2026. The gaps between entries are shown in days.

  1. 26 JulyARTEX repository created on GitHub, licensed AGPL-3.0
  2. 17 to 22 AugustInfrastructure testing attributed to the South Korean financial actor (Recorded Future)22 days after release
  3. 7 to 8 OctoberARTEX use against South Korean financial institutions is disclosed publiclyabout seven weeks later
  4. 8 to 9 OctoberThe author converts the project to closed source and the repository is taken down
  5. 16 OctoberA commercial successor, ARTEX Pro, goes on sale on a hosted multi-agent platform
  6. 17 OctoberThe ARTEX controller at 118.128.151.28 begins targeting entities in at least 14 countriesone day after the commercial launch
  7. 24 to 30 OctoberActivity recorded in our estate (section 4)

The lesson for defenders sits in the middle of that timeline: pulling a repository does not recall the copies. Forks are already in the wild, a commercial edition needs no download at all, and one vendor reports detectable user agents on hundreds of internet-exposed instances of the framework. Blocking the tool was never available as a strategy. Blocking the endpoint it thinks with, and detecting the shape of the loop, is.

3.2 The cast: an operator, a planner and workers

Three parties sit in the loop, and the source reporting separates them cleanly.

The operator

A human. The only human input.

Goals are written in Chinese, marked 【人类指令】 (human instruction), and timestamped in China Standard Time. That is the only human input in the entire chain, and it is injected in band, into the same task channel the bots use.

The planner agents

The reasoning tier.

They take one goal and break it into ordered tasks. In the published campaign the planners ran on a separate, subscription-based model service, returned quota errors, and exhausted every profile on 25 October. The provider has not been identified.

The worker agents

The execution tier.

Workers were configured with an environment variable, ARTEX_LLM_BASE_URL, pointed at https://api.deepseek.com/v1. All 35,159 recorded tool call identifiers follow the identifier format used by DeepSeek.

The split between those last two tiers is the architectural detail worth keeping. Reasoning ran on a subscription model. Execution ran on a metered application programming interface. That is a cost decision, and it produces two different traffic profiles to hunt: a small volume of high value planning, and a large volume of cheap execution. It also means the adversary is on a budget. When the planner profiles ran dry on 25 October, the loop lost its reasoning tier and the workers were left holding context.

The loop, end to end

Three places the loop lives: the adversary’s infrastructure, the model providers it rents reasoning from, and the target estate where its tool calls land. Steps 1 to 4 are from the source reporting; steps 5 and 6 are what we recorded.

The ARTEX agent loop The operator gives an instruction to the planner agents, which reason on a subscription model and write tasks to a task store on disk. A worker agent picks up the task, reasons through the DeepSeek API, and sends a tool call into the target estate, where it stages a numbered file and acts on a host or application. The result returns into the worker’s context and the worker runs again; results are written back to the task store for the planner. Adversary infrastructure Rented model providers Target estate (ours) 1 Human operator goal written in Chinese, marked 【人类指令】 2 Planner agents turn one goal into ordered tasks 3 Task store on disk /opt/artex/data/tasks/10/ deploy2/ /srv/artex-old/ 4 Worker agent decides the next call, reads the result, repeats result returns into context; step 4 runs again Subscription model (planners) quota limited; every profile exhausted 25 October DeepSeek API (workers) ARTEX_LLM_BASE_URL = https://api.deepseek.com/v1 5 Tool call lands exec, file write, HTTP request, credential read; staging names climb: i25344 to i46077 6 Our host or application file into a served web root, ?c= command parameter, directory query, keytab ticket, credential file read our telemetry lives here in band writes task records task picked up result written back reasoning over HTTPS
The staging number on our hosts climbed by about 20,700 between 25 and 29 October.

3.3 One turn of the loop

Every step the framework takes has the same shape. Read it as a sequence, because each numbered item is something that can be instrumented.

  1. An instruction enters. The operator types a goal into the task console. Goals recorded in the source reporting: write web shells, use Base64-encoded echo commands, extract domain administrator passwords, enumerate endpoint sensor coverage.
  2. The planner decomposes it. The planner model turns one goal into an ordered list of tasks and writes that list to disk. The published paths show a task store rather than a message bus: /opt/artex/data/tasks/10/deploy2/ is task number 10, second deployment, and /srv/artex-old/ is a previous generation kept beside it.
  3. A worker picks up a task and is handed a tool set. The tool set is the framework’s own capability surface: command execution, file transfer, web shell deployment, web application probing, credential reads.
  4. The worker emits a tool call. Every call carries an identifier. In our telemetry a climbing number is visible on disk: staging names are i followed by five or six digits, under /tmp or the application account’s home directory. We recorded i25344 through i26145 on 25 October, and i45844 through i46077 on 29 October, an increase of about 20,700 in four days. We read that number as a per-call counter; the framework’s source would confirm it.
  5. The tool runs and the output returns into the worker’s context. The model reads the result and decides the next call. That is the entire engine, and it explains why the loop changes technique when a technique fails. The failure is just another observation in the context window.
  6. The result is written back to the task record. The planner reads it and issues the next task, or the operator writes a new instruction. The loop continues until the goal is met or the budget runs out.

3.4 How the bots communicate

The framework has four communication channels. Only one of them resembles a conversation, and it is not the one that carries the work.

Instructionoperator to planner
MechanismIn-band prompt into the same task channel, Chinese, marked 【人类指令】, China Standard Time timestamps
What is observableNothing on our side. It lives on the adversary’s own console and in the task store.
Task handoffplanner to worker
MechanismShared state on disk. The planner writes the task and its goal, the worker writes results back into the same tree. Task number and deployment generation are the addressing scheme.
What is observableCreation of task directories and deployment subdirectories inside the framework’s task root, for example /opt/artex/data/tasks/10/deploy2/
Reasoningworker to model endpoint
MechanismPlain HTTPS carrying the context and the next decision, authenticated with an application programming interface key
What is observableOutbound HTTPS from a server to a model endpoint with no browser involved. In the published campaign configuration, api.deepseek.com/v1
Actionworker to target
MechanismOrdinary protocols and ordinary tools: HTTP requests carrying a command in a parameter, file writes into a web root, interactive logins, directory queries
What is observableThe application level artifacts in section 4: file manager writes, ?c= command parameters, Lightweight Directory Access Protocol binds, kinit with a host keytab

So the bots do not talk to each other the way a person would recognise. They hand work to each other through persisted state, and the model endpoint is the one participant that belongs neither to the adversary nor to the target. Three consequences follow, and they are the reason this section is here:

  • The task store is the coordination point. Interrupt it and the planner has nothing to hand off to.
  • The model endpoint is the only hard dependency. Cut it and the worker holds cached context and nothing else. It does not have a fallback, because the framework was never designed to run without a model.
  • Volume is measurable. A tool call counter and a token count turn “the agent was active” into a number with a rate attached, which is a far more durable detection primitive than a file hash that dies on the next turn.

3.5 The loop inside our telemetry, minute by minute

Our record

The clearest window we have is the evening of 24 October, against cybercrypto-grants-gateway and then cybercrypto-app-dev-01. Times are UTC. Hollow red markers are requests the edge refused; filled markers are requests the application served.

  1. 18:58 to 19:57WebLogic console and wls-wsat paths requested on cybercrypto-grants-gateway, every one answered 403Probing before the successful path. Failed attempts are kept in context and do not stop the run.
  2. 22:36:27First local login to the file applicationAccess acquired.
  3. 22:50:18Write through the file application’s file managerWeb shell deployed, 13 minutes 51 seconds after the login. The first command request reached it 44 seconds later, at 22:51:02.
  4. 22:51:02 to 22:57:19Command requests blocked by edge rules, then served as split, trimmed and Base64-encoded variants, HTTP 200 at the application. Shells zq7f3k2.jsp and z8k4m2x9.jsp.The re-encode step. A block is an observation. The next turn works around it, repeatedly, without losing the goal.
  5. 22:51:16One served request: ?c=echo Y2F0IC9ldGMvaG9zdHM= | base64 -d | shDecoded, the command is cat /etc/hosts. Reconnaissance through the shell it just built.
# What the served request did, step by step
$ echo Y2F0IC9ldGMvaG9zdHM= | base64 -d
cat /etc/hosts
# ...and the trailing "| sh" then runs that text as a command.

The interval is the interesting measurement. Between the first blocked request and a working replacement form the gap is seconds, and it repeats across several variants in the same window. A person rewriting a blocked command by hand takes minutes and stops after one or two attempts. A loop takes seconds and does not get bored. That difference in tempo is the cheapest machine behaviour signal available to a defender, and it depends on no adversary address at all.

3.6 The loop adapts, so detection must not be anchored

Tool switching inside one primitive class. The privilege step is an interpreter loader hijack. The recorded form is RUBYOPT pointed at a staged file and passed to ohai. The same class covers PERL5OPT, PYTHONPATH, LD_PRELOAD and BASH_ENV. An agent that reads its own error messages will try each of them in turn.

# Recorded: loader hijack through a sudo grant (staged file name abbreviated)
sudo -n RUBYOPT=-r<file>.rb /usr/bin/ohai version

# Recorded: rogue local-mode Chef run with a staged cookbook
sudo -n /usr/bin/chef-client -z -o recipe[probe]

# The class to hunt: any interpreter loader variable carried through sudo
# (regular expression over the process command line)
sudo\s+(-\S+\s+)*(RUBYOPT|PERL5OPT|PYTHONPATH|LD_PRELOAD|BASH_ENV)=

A second, independent execution path. Beside the loader hijack, the same behaviour appeared inside a rogue local-mode Chef run, with the same injection carried in the cookbook. That path is the only one that surfaced two of the six hosts we know about. Had the rule set been anchored to the loader hijack alone, a third of the affected hosts would have stayed invisible.

Which rule saw which host

Recorded event counts per host, 24 to 29 October. A shaded cell is a match. Outlined cells are hosts that only one rule surfaced.

HostLoader-hijack ruleChef rule
cybercrypto-app-dev-01150528
cybercrypto-app-dev-021521
cybercrypto-app-dev-03152
cybercrypto-app-dev-04no match181
cybercrypto-app-dev-05no match1
cybercrypto-app-prod-0142no match
Four hosts on one rule, five on the other, six in total. Either rule alone leaves hosts dark.

Sensor inventory instead of sensor evasion. The operator did not instruct the agents to disable the endpoint sensor. It instructed them to find hosts without it, judging by task list and folder listings, and to enumerate sensor coverage. The Chinese term recorded is 猎鹰, a bird-of-prey name the instructions use for the endpoint sensor. The defensive reading matters: endpoint agent tampering is not the adversary’s primary lever, because the cheap answer is to move to a host where there is nothing to tamper with.

A budget, not unlimited capability. Planner profiles exhausted their quota on 25 October, and the planners ran on a different service from the workers. About 1.4 billion input tokens were consumed by the planning agents in one published engagement, while post-exploitation was confirmed at nine of more than 200 organisations approached. High volume, low conversion. The framework scales reach far faster than it scales success, which is exactly why reach is the thing to detect.

3.7 Instrumenting the loop

Map each stage to what is observable and the detection problem becomes a coverage problem. The two highlighted stages are worth more than the rest.

StageObservableWhy it survives the agent changing tools
  1. Goal entryoperator to plannerNot observable. It happens on infrastructure we do not control.State it as a blind spot rather than pretending otherwise.
  2. Reasoningworker to model endpointOutbound HTTPS from a server to a model endpoint, with no browser involved. In the published configuration: api.deepseek.com, and the same hook covers api.anthropic.com, open.bigmodel.cn and api.x.ai.The single highest value hook in this table. The loop cannot reason without it, and it does not depend on any address the adversary rents or rotates.
  3. Task storeplanner to workerCreation of task directories and deployment subdirectories on a host: /opt/artex/data/tasks/<id>/<deploy>/, /srv/artex-old/Structural rather than lexical. The directory shape is the framework’s, not the operator’s preference, so it survives a change of target or technique.
  4. Loop tempothe tool call counterStaging directory names carrying a climbing number, for example /tmp/i followed by five or six digitsIt counts loop turns rather than content. A rate is comparable across hosts and across days, and it does not care what the tool call did.
  5. Privileged executiontool to hostA sudo grant carrying an interpreter loader variable pointed outside trusted pathsIt matches a class of behaviour, so it covers variants the agent has not tried yet.
  6. Target interactiontool to applicationFile creation in a served web root; commands in query parameters; encoded or split re-sends seconds after a block; directory queries for privileged groups; ticket requests using a host keytab; credential file readsApplication and identity level, so it holds even when every file hash has changed. A block followed by a working variant seconds later is a machine, not a person.

Reasoning traffic is the dependency the framework cannot replace, and loop tempo is the behaviour it cannot hide. Neither is a hash, and neither expires when the adversary edits a script. Tempo is measurable on any estate the loop touches. Reasoning traffic is measurable wherever an agent runs on infrastructure you can see; when the engine runs on the adversary’s own servers, as it did here, that hook sits with the network egress point and the model provider rather than with the target.

4Activity recorded in our environment

Facts from Incident Response telemetry and the case record. ATT&CK identifiers classify the recorded behaviour; they do not attribute it.

Our record

4.1 Contact from advisory infrastructure

The controller address, 118.128.151.28 (ARTEX controller, CSA-261253), as it appears in each telemetry plane:

Plane118.128.151.28
Edge web application firewall (rule-match feed)855 rule-matched events on 28 host names, 24 Oct 16:37:13 to 30 Oct 01:11:37. Most carry the block action (cybercrypto-grants-gateway 363; cybercrypto-artifacts 84). The remaining rows were recorded under rules configured with the log or skip action, as the policy specifies.
Perimeter firewall3,088 rows, 24 Oct 16:36:41 to 29 Oct 23:08:40. The action breakdown covers 2,780 of them: Block 2,530 (262 destinations), Allow 156 (26), Trust 94 (16). Allow and Trust are outcomes of the configured policy. As a destination: 0 rows.
Secondary edge network12 deny events on cybercrypto-web, 24 Oct 16:35:18 to 25 Oct 17:25:11
Secure web gateway285 rows, 25 Oct 19:49:12 to 29 Oct 19:48:51
Private access broker17 requests to cybercrypto-iam, 25 Oct 05:48:47 to 14:09:58, every one answered 303. Paths: / (repeated), /identity/connect/token, /api, /swagger, /odata, /help, /.well-known/apple-app-site-association. User agent recorded in the sample row: curl/7.76.1.
Identity sign-in and logon events4 events, all failures (section 4.3)

Perimeter firewall actions on traffic from 118.128.151.28

2,780 rows with an action recorded, 24 to 29 October. Each action is the outcome of the configured policy. Bar length is to scale.

The remaining advisory infrastructure, as it appears in our telemetry:

Advisory addressRecorded in our telemetry
151.236.22.111 (jump host and SOCKS egress)Perimeter firewall: 174 events to 21 destinations, 25 Oct 07:02:08 to 29 Oct 21:21:06
45.74.31.41 (SOCKS5 egress)Perimeter firewall: 2 Block events from an internal address to port 9891, 26 Oct 05:17:53 to 05:20:34
45.116.20.180 (Chisel relay)Secondary edge network: 1 event on cybercrypto-web, 25 Oct 17:25:16
203.32.25.165 (ARTEX console)Secondary edge network: 1 event on cybercrypto-web, 25 Oct 17:25:19
Remaining six advisory addressesNo rows in the screened planes

4.2 Host activity by tactic

Tactic (ATT&CK)Recorded activityHost, time
Web shell (T1505.003)Write through the file application’s file manager after the first local login to that application at 22:36:27. The entry path into the application is not established.cybercrypto-app-dev-01, 24 Oct 22:50:18
Obfuscation (T1027)Command requests blocked by edge firewall rules were followed within seconds by split, trimmed or Base64-encoded forms that returned 200 at the application, for example ?c=echo Y2F0IC9ldGMvaG9zdHM= | base64 -d | sh at 22:51:16. Shells: zq7f3k2.jsp, z8k4m2x9.jsp.cybercrypto-app-dev-01, 24 Oct 22:51:02 to 22:57:19
Privilege escalation (T1548.003, T1574)Loader hijack through a sudo grant: sudo -n RUBYOPT=-r<file>.rb /usr/bin/ohai version. Events: cybercrypto-app-dev-01 150 (25 Oct 02:53:51 to 05:53:49); cybercrypto-app-dev-03 15 (25 Oct 02:14:39 to 02:32:40); cybercrypto-app-dev-02 15 (27 Oct 16:59:18 to 17:50:42); cybercrypto-app-prod-01 42 (29 Oct 17:13:41 to 18:18:40). Staging directories: /tmp/iNNNNN, the application account’s home directory (~/iNNNNN), and on cybercrypto-app-prod-01 /data/staging (26 of the 42 events).Four hosts, 25 to 29 Oct
Privilege escalation (T1548.003)Local-mode Chef runs: sudo -n /usr/bin/chef-client -z -o recipe[probe] with a staged cookbook path. Events: cybercrypto-app-dev-01 528; cybercrypto-app-dev-04 181; cybercrypto-app-dev-02 21; cybercrypto-app-dev-03 2; cybercrypto-app-dev-05 1. The first Chef payload on cybercrypto-app-dev-02 returned uid=0(root). Whether the escalation on cybercrypto-app-dev-03 succeeded is open in the record.Five hosts, 24 Oct 23:08:05 to 25 Oct 04:59:04
Credential access (T1003.008, T1552.004)On cybercrypto-app-dev-03: /etc/shadow reads, kinit with the host keytab, and a simple bind as the application service account with the password in the request parameter. On cybercrypto-app-prod-01: sudo -n /bin/cat through /var/scm/cache/../../../ against /etc/shadow, the .ssh/id_rsa files of three service accounts (cybercrypto-svc-01, cybercrypto-svc-02, cybercrypto-svc-03), one user’s .bash_history, and /var/scm/cache/core.key.cybercrypto-app-dev-03, 25 Oct 01:43 to 03:51; cybercrypto-app-prod-01, 29 Oct 17:49:29 to 17:53:19
Discovery (T1087.002, T1069.002)ldapsearch for Enterprise Admins and Domain Admins; Lightweight Directory Access Protocol reads of security descriptors over GSSAPIcybercrypto-app-dev-03, 25 Oct
Internal proxy (T1090.001)Python TCP relay mapping local ports 41445, 42445 and 43445 to 445, and 41985 to 5985, on three development application serverscybercrypto-app-dev-03, 25 Oct 03:02
Web shell (T1505.003)Five 428-byte JavaServer Pages shells, SHA256 757a5ca1b9490f3e3f84df969fe312ea5ace2401c865d9dfbdb96ae6901005a0. Only 2kt0lguw.jsp served requests (200 from 16:37:26 to 18:10:06).cybercrypto-app-dev-02, 27 Oct 16:28:58 to 16:37:26
Web shell (T1505.003)pzk8m31x.jsp copied into the file application’s WAR rootscybercrypto-app-prod-01, 29 Oct 15:05:22

4.3 Identity

TimePlaneAccount / applicationResult
25 Oct 16:33:08Directory logon eventsMicrosoft 365✕ Failed
25 Oct 16:36:07Identity provider sign-in logscybercrypto-svc-04 / cybercrypto-app-reg-01✕ Failed (invalid credentials)
29 Oct 23:55:06Directory logon eventsMicrosoft 365✕ Failed
29 Oct 23:56:34Identity provider sign-in logsthe application service account / cybercrypto-app-reg-02✕ Failed (invalid credentials)

No successful sign-in from 118.128.151.28 is recorded in the identity provider sign-in logs.

4.4 Advisory reporting set against our record

Source reportingOur record
Advisory reporting ●Our record ●See
118.128.151.28: ARTEX controller (CSA-261253)Edge, firewall, proxy and identity events, 24 to 30 OctoberSection 4.1
Operator instruction to write web shells; JavaServer Pages web shells listed (CSA-261253, CSA-261264)JavaServer Pages shells on cybercrypto-app-dev-01, cybercrypto-app-dev-03, cybercrypto-app-dev-02 and cybercrypto-app-prod-01; 23 web shell SHA256 values heldSection 4.2
Operator instruction to use Base64-encoded echo commands (CSA-261253)?c=echo Y2F0IC9ldGMvaG9zdHM= | base64 -d | sh served by the file application, 24 Oct 22:51:16Section 4.2
Operator instruction to extract domain administrator passwords (CSA-261253)ldapsearch for Enterprise Admins and Domain Admins on cybercrypto-app-dev-03Section 4.2
Web shells avoiding command literals through reflection and string concatenation (CSA-261264)Command strings split, trimmed and Base64-encoded after edge firewall blocks, 24 OctSection 4.2
WebLogic CVE-2020-14882 and CVE-2020-14883 at GR1 (CSA-261253)WebLogic console and wls-wsat paths requested on cybercrypto-grants-gateway, 24 Oct 18:58 to 19:57, all answered 403Section 3.5
BLOODALCHEMY, Cobalt Strike, Stowaway, SoftEther (CSA-261253, CSA-261264)No match in the endpoint telemetry planes, 30 daysSection 5

5Defensive outcomes

What was closed, how it was verified, and what is now watching.

Our record
  • Controller identified before vendor reportingThe case record named 118.128.151.28 as the actor’s address on 26 October 2026. CSA-261253, which lists the address as the ARTEX controller, was published on 27 October. 26 OctoberOur case record names the address27 OctoberCSA-261253 lists it as the controller
  • Shell writes detected as they happened27 Oct: five endpoint web shell alerts on cybercrypto-app-dev-02, each within one second of a shell write, 16:28:58 to 16:37:26. 29 Oct: an endpoint web shell alert on cybercrypto-app-prod-01 at 15:05:22.
  • Exploit chain closed, verified by attemptBoth halves of the chain are closed on cybercrypto-app-prod-01, cybercrypto-app-web-01 (34 roots) and cybercrypto-cloud-01 (7 roots): the application account can no longer write into a served web root, and can no longer run code as root through the sudo loader. Each closure was verified by attempting the action as the application account. A two-minute guard re-applies both closures. cybercrypto-app-dev-01 and cybercrypto-app-dev-03 are contained at the endpoint agent.
  • Campaign indicators enforcedCustom indicator groups for Windows, Linux and Mac carry process-kill rules on the advisory addresses and domains. 11 SHA256 values are set to prevent. 11 addresses and 6 domains are set to detect. On cybercrypto-app-prod-01 a host firewall drop set holds the 11 advisory addresses; it had matched 0 packets as of 29 Oct 23:05.
  • Web shell detection specific to the applicationA custom indicator group for the file application is enabled. It detects file creation in the file application’s WAR roots, kills the Java process spawning a shell on the file application’s managed servers, and kills sudo environment injection. The application on cybercrypto-app-prod-01 shuts down automatically on any qualifying endpoint alert on that host (60-second check, live from 29 Oct 23:43:41).
  • Behavioural detection content measured against live dataOur behavioural detection pack was run against live data. The loader-hijack rule matches four hosts. The Chef rule matches five, two of which (cybercrypto-app-dev-04, cybercrypto-app-dev-05) the loader rule does not surface.
  • Application defect fixed at sourceThe file application’s file manager was fixed in the application archive and submitted for test on 29 October 2026 at 22:46 EDT. The result was successful.
  • Identity plane heldNo successful sign-in from 118.128.151.28. All four attempts failed (section 4.3).
  • No campaign malware on screened endpointsThe vendor hashes and file names returned 0 rows across the endpoint telemetry planes over 30 days.
    PlaneEvents screenedHostsMatches
    DNS978,168,28140,7990
    File8,928,426,22251,3090
    Process8,514,413,06751,3380
    Connection8,166,669,33749,4010

6Collection coverage and limits

What this record can and cannot show.

  • The edge web application firewall feed records only requests that match a rule. Requests that match no rule are absent from that feed by design.
  • Some telemetry sources returned query errors or held no current data for the window. Those sources are not counted as negatives.
  • The internal device behind the two blocked connections to 45.74.31.41 on 26 October is not identified.
  • The entry path into the file application is not established. Whether the Chef escalation on cybercrypto-app-dev-03 succeeded is open in the record.
  • The advisories name no victim organizations. This post does not map any described entity to our environment.
  • A negative result means no match in the plane and window queried. It does not cover planes or hosts that were not queried.

7Indicators

Behaviour first, then infrastructure, then hashes. The behavioural rows are the ones that outlive the campaign.

7.1 Behavioural indicators from our record

Our record
IndicatorTypeBasis
sudo with RUBYOPT, PERL5OPT, PYTHONPATH, LD_PRELOAD or BASH_ENV pointing at a staged fileBehaviourRUBYOPT=-r<file>.rb /usr/bin/ohai version recorded on four hosts
sudo -n /usr/bin/chef-client -z -o recipe[...] with a cookbook path under /tmpBehaviourRecorded on five hosts, 24 to 25 Oct
Staging under /tmp/iNNNNN, ~/iNNNNN in the application account’s home directory, /data/staging/iNNNNN*.rbPathLoader file locations recorded on cybercrypto-app-dev-01, cybercrypto-app-dev-02 and cybercrypto-app-prod-01
sudo -n /bin/cat with a /var/scm/cache/../../../ traversalBehaviourRecorded on cybercrypto-app-prod-01, 29 Oct 17:49 to 17:53
Relay listeners on 41445, 42445, 43445 forwarding to 445, and 41985 to 5985BehaviourRecorded on cybercrypto-app-dev-03, 25 Oct
ROOTOK / ROOT_OK_<n> marker stringsStringRecorded in Chef payloads on cybercrypto-app-dev-03 and cybercrypto-app-dev-02
Web shells zq7f3k2.jsp, z8k4m2x9.jsp, 2kt0lguw.jsp, pzk8m31x.jspFile nameCase record, 24 to 29 Oct
SHA256 757a5ca1b9490f3e3f84df969fe312ea5ace2401c865d9dfbdb96ae6901005a0Hash428-byte JavaServer Pages shell, cybercrypto-app-dev-02, 27 Oct

7.2 Network indicators from our record

Our recordAdversary infrastructure
IndicatorBasis
118.128.151.28Case actor address from 24 Oct; ARTEX controller per CSA-261253; recorded as MOACK.Co.LTD in our edge data
118.128.151.10, .40, .41, .42, .51, .52, .57, .58, .62, .82Supplied to the case on 29 Oct; same /24 as the controller
209.50.255.91, 45.61.188.134, 2605:6404:18a:6838:b5a1:939d:de90:4c45Actor network values from case analysis, 28 Oct

7.3 Indicators from the advisories

Source reportingAdversary infrastructure
AddressDescription (as published)Advisory
118.128.151.28ARTEX controller and open-directory IP addressCSA-261253
65.20.92.170ARTEX engine egress IP addressCSA-261253
151.236.22.111Jump host and SOCKS egress IP addressCSA-261253
148.113.46.187Proxy egress IP addressCSA-261253
45.74.31.41SOCKS5 egress IP addressCSA-261253
45.153.126.223Resolution of nginxmysql.comCSA-261253
89.46.234.50Resolution of sqlserver-sqlite.comCSA-261253
192.121.47.20Resolution of www.ddduuuppp.comCSA-261253
203.32.25.165ARTEX console and Secure Shell dynamic-forwarding exit IP addressCSA-261264
104.233.154.148Open-directory and Secure Shell dynamic-forwarding upstream IP address (port 20068; open directory on port 8080)CSA-261264
45.116.20.180Compromised server used as Chisel relay, port 8443CSA-261264
DomainDescription (as published)Advisory
nginxmysql.comBLOODALCHEMY command-and-control domainCSA-261253
sqlserver-sqlite.comBLOODALCHEMY command-and-control domainCSA-261253
www.ddduuuppp.comBLOODALCHEMY command-and-control domainCSA-261253
www.developgram.onlineCobalt Strike command-and-control domainCSA-261264
SHA256Description (as published)Advisory
3fb5a9fb3e2cb1d6208966bd4e55d10282d19c7250d827efa560463d60a12ee4BLOODALCHEMY loader DLL graphics-hook-filter64.dllCSA-261253
364251838edfcf5ef1107fa692da3c5bd9a540482449f645992830134bf807abBLOODALCHEMY payload file graphics-hook_config.binCSA-261253
55ddd6bbe962a260dba426d33f26bfb0925c18d85ca49a3183a9dcdaf3df0bbeStowaway binary llllCSA-261253
fa10f23220ab85fecc7f351f97fb6f56f3be3db587f5e0ba9a4069697279c774SoftEther binary renamed MStrmanager.exeCSA-261253
49fe70419fd19b81ca8d730a6ef7c1ec71b681d60b390761070d42686c7d2068Legitimate GameHook binary named svchost.exe, used for side-loadingCSA-261253
2efc820d9fd40a382a595e8953f382e1291bcb145c7d83b7def8f5b6fe1ae2fbCobalt Strike loader DLL libcef.dllCSA-261264
2748a0a10a86a81be7e2ab813e7a85885d1b259b38057438e48a67e44803bd45Encrypted Cobalt Strike payload file cache.datCSA-261264
5ec24779c24bcbf02fbd32acfbb98cb1d6ffa9cc719a2a4c4dfaf5f6faf781fbDecrypted Cobalt Strike BeaconCSA-261264
3b65d3675f9108060c1bbd5ddceeddbc249f765a5081cf4a3f30707c8f3fc6d5BLOODALCHEMY loader DLL acrobat_compat.dllCSA-261264
d62619b54f75eeb491a963dd637bb88898855e2b73e97606c37bab117ad1c259Encrypted BLOODALCHEMY payload file 99cd33a02d60e2a3.datCSA-261264
0beb5aca4ba62671580558661c8bc1b3881c1d749789cbd2f2279ab87dac77e4Decrypted BLOODALCHEMY backdoorCSA-261264
Fingerprint or markerDescription (as published)Advisory
134f28f7cd6c67ade04d7ca1166b175bc4751a837b6b6ac02eae02cf85a42f6eTLS certificate on all three BLOODALCHEMY command-and-control addressesCSA-261253
21d14d00021d21d21c42d43d0000007abc6200da92c2a1b69c0a56366cbe21JARM hash shown with that certificateCSA-261253
ad0778dcefab688f3734a14d07946e9fb300776b773846265922e0eb1a4855a3Self-signed TLS certificate on the ARTEX console at 203.32.25.165CSA-261264
artx or artex in command lines; artx-prefixed AWS roles; art18- Systems Manager comments; C:\ProgramData\artx5v\ARTEX markersCSA-261253
itop_hookDaily scheduled task for BLOODALCHEMY persistenceCSA-261264
/opt/artex/data/tasks/10/deploy2/; /srv/artex-old/Paths recorded in ARTEX infrastructureCSA-261264