UAT-10608 used React2Shell to steal credentials from 766 Next.js hosts
Contents
The React Server Components vulnerability CVE-2025-55182, disclosed in December 2025 and nicknamed React2Shell, was being used in real attacks from the start. Four months later, Cisco Talos has now laid out the full picture of a large-scale credential-harvesting campaign.
At least 766 Next.js hosts were compromised, and the stolen data included DB connection details, SSH private keys, AWS/Azure/GCP secrets, Stripe API keys, GitHub tokens, and even OpenAI and Anthropic keys.
UAT-10608’s Attack Chain
Cisco Talos tracks the group as UAT-10608. The exact attribution is still unconfirmed, but the group was operating a fully automated, multi-stage credential collection framework.
The flow is simple:
graph TD
A[Auto-enumerate public Next.js apps] --> B[Send a crafted POST request<br/>using CVE-2025-55182]
B --> C[Dropper deploys<br/>the harvesting script]
C --> D[Auto-collect credentials<br/>in multiple phases]
D --> E[Send results to<br/>NEXUS Listener C2 over HTTP]
- Automatically enumerate exposed Next.js applications
- Exploit them with a crafted HTTP POST request using CVE-2025-55182
- Fetch and run the main harvesting script via a dropper (
nohup, random dotted filenames under/tmp/) - Collect system-wide credentials in multiple phases
- Send the data back to the NEXUS Listener C2 server over HTTP
CVE-2025-55182 is caused by unsafe deserialization in the React Server Components “Flight” protocol. A single malicious POST request is enough for RCE, with no authentication required. The weak default posture of Next.js deployments is what made the blast radius so large.
I covered the vulnerability itself in the initial December 2025 post, but that article was mainly about patching. This campaign report shows what happened to unpatched hosts in the wild.
How the Harvesting Script Is Structured
The script runs the following phases in sequence:
| Phase | What it collects |
|---|---|
| environ / jsenv | Environment variables, including .env files |
| ssh | SSH private keys and authorized_keys |
| tokens | Pattern-matched tokens |
| history | Shell command history |
| cloud_meta | AWS/GCP/Azure metadata endpoints |
| k8s | Kubernetes service account tokens |
| docker | Container config files |
| cmdline / proc_all | Command lines of running processes |
The data is sent to the C2 using HTTP requests of the form:
http://<C2_IP>:8080/h=<HOSTNAME>&l=<PHASE>&id=<ID>
The phase name is embedded in the query string, so the attacker can track harvesting progress in real time.
The NEXUS Listener C2
The attacker infrastructure was centered on a web-based admin interface called NEXUS Listener (version 3 was observed).
- Password-protected GUI
- Dashboard of compromised hosts
- Database search across stolen data by host and phase
One NEXUS Listener instance Cisco found had no authentication at all, and its /stats endpoint was fully exposed. That endpoint showed 91,505 scanned systems, a 64.6% success rate, and 59,128 confirmed compromised servers.
The “766 hosts” figure is only what Cisco directly confirmed. The total operation could have been nearly 80 times larger.
What Was Stolen From the 766 Hosts
Even the confirmed 766-host sample tells a clear story.
| Item | Compromised hosts | Share |
|---|---|---|
| DB credentials | about 701 hosts | 91.5% |
| SSH private keys | about 599 hosts | 78.2% |
| AWS credentials | about 196 hosts | 25.6% |
| Stripe API keys | about 87 hosts | 11.4% |
| GitHub tokens | about 66 hosts | 8.6% |
| Total files collected | 10,120 | — |
The SSH keys included both ED25519 and RSA PEM private keys, often paired with authorized_keys entries. That is enough for lateral movement inside internal networks. Stripe live keys enable fraudulent charges and refunds, while AWS keys can take over the infrastructure if the IAM permissions are broad enough.
The campaign also collected keys for AI platforms such as OpenAI and Anthropic, plus notification and webhook secrets from services like SendGrid, Brevo, and Telegram Bot tokens.
Indicators of Compromise
The report lists the following signs of UAT-10608 activity.
Network IOCs
144.172.102.88172.86.127.128144.172.112.136144.172.117.112
Outbound connections to those IPs on port 8080 are a strong sign that the harvesting script is or was running.
Host Artifacts
- Random dotted filenames under
/tmp/ - Unexpected
nohupusage - Unusual outbound HTTP/HTTPS connections from the application container
Snort rule ID 65554 has been published for CVE-2025-55182.
Response and Credential Rotation
If you suspect compromise, here is the response list.
Patch first. If your Next.js version is still affected, update it now. See the original React2Shell post for affected and fixed versions.
More important than the patch, though, is credential rotation. The affected window is any Next.js app that was public on the internet on or after December 4, 2025.
- Change every database password and username
- Rotate SSH key pairs and remove old public keys from
authorized_keys - Invalidate and reissue AWS, Azure, and GCP access keys
- Rotate all external service keys, including Stripe and SendGrid
- Invalidate GitHub personal access tokens
- Audit
.envfiles and hard-coded secrets in the codebase
On AWS, if IMDSv2 is disabled on an EC2 instance, the cloud_meta phase can retrieve IAM temporary credentials. Enforcing IMDSv2 should be treated as mandatory.
Also check that you are not accidentally prefixing secrets with NEXT_PUBLIC_. Anything with that prefix is bundled into the client by design and must never contain sensitive values.
CVE-2025-55182 Is Still an Active Threat
Four months after disclosure, with patches already available, more than 59,000 compromised hosts is a serious number. The attackers are clearly automating against patch lag, so “patch immediately” is the only real answer.
Unit 42 estimates more than 968,000 Next.js/React instances worldwide, which means the campaign will continue as long as any vulnerable systems remain exposed.
The important part of this report is that the attackers had a complete post-compromise harvesting framework ready almost at the same time as the PoC became public. This was not just an RCE; it was a full credential extraction pipeline. If SSH keys were stolen, fixing the Next.js app alone is not enough. You need to review the infrastructure too.
Timeline Since Disclosure
| Date | Event |
|---|---|
| December 4, 2025 | CVE-2025-55182 (React2Shell) disclosed, with attacks already observed the same day |
| December 5, 2025 | CISA added it to the KEV catalog and set the remediation deadline to December 12 |
| December 9, 2025 | CISA recommended checking for signs of compromise |
| December 10, 2025 | I published the initial post |
| December 11, 2025 | Additional DoS and source-code exposure bugs were disclosed, requiring a second patch |
| December 22, 2025 | The initial post was updated with Dify impact |
| March-April 2026 | Cisco Talos published the full UAT-10608 campaign analysis |
The remediation deadline CISA set for December 12 was missed by a lot of hosts. If you handled it at the time, you were spared a major incident. If not, DB passwords, SSH keys, and cloud secrets were already gone by the time this campaign landed.
Related Reading
- React2Shell response notes for Next.js / React - the original December 2025 post, with the affected versions, checks, and patch targets
- Mintlify’s vulnerability is not React2Shell: framework responsibility vs implementation responsibility - how the Mintlify bug differs from React2Shell