
AWS Organization-wide detection toolkit for CVE-2025-55182 & CVE-2025-66478 (React Server Components / Next.js RCE vulnerabilities)
AWS Organization-Wide Detection Toolkit for CVE-2025-55182 & CVE-2025-66478
⚠️ IMPORTANT DISCLAIMER - PLEASE READ BEFORE USE
This toolkit has NOT been tested in a production AWS environment.
Due to infrastructure constraints, this project was developed and validated through code review, static analysis, and documentation verification only. It has not been deployed to or tested against a live AWS environment with active GuardDuty, WAF, EventBridge, or CloudTrail services.
What This Means For You:
Component Status Python Scanner Logic ✅ Code reviewed, Snyk validated Terraform Syntax ✅ Validated, not applied IAM Policies ⚠️ May require adjustment for your environment EventBridge Rules ⚠️ Finding patterns based on AWS documentation WAF Rules ⚠️ Regex patterns untested against live traffic Athena Queries ⚠️ Schema assumptions may need modification Recommendations:
- Deploy to a non-production account first - Test all components in a sandbox environment
- Review IAM policies carefully - Adjust permissions to match your organization's requirements
- Validate Terraform plans - Run
terraform planand review before applying- Test EventBridge patterns - Verify finding type strings match your GuardDuty output
- Monitor CloudWatch logs - Check for errors after deployment
Liability:
This software is provided "AS IS" without warranty of any kind. The authors assume no responsibility for any damage, security incidents, or AWS costs incurred through the use of this toolkit. Use at your own risk.
If you successfully deploy and test this toolkit, please consider contributing your findings back to improve it for the community.
A comprehensive security toolkit for detecting React2Shell exploitation attempts across AWS environments. This toolkit provides real-time detection, threat hunting capabilities, and automated response for the critical React Server Components RCE vulnerability.
__proto__:then manipulation enables arbitrary code execution via process.mainModule.require('child_process').execSync()1. INITIAL ACCESS → WAF detects Next-Action header + prototype pollution payloads
2. EXECUTION → GuardDuty ThreatIntelSet detects C2 IP connections
3. CREDENTIAL THEFT → CloudTrail detects GetCallerIdentity from EC2 roles
4. LATERAL MOVEMENT → EventBridge rules detect SSM SendCommand/StartSession
5. EXFILTRATION → DNS exfiltration to ceye.io/dnslog.cn detected
6. CRYPTOMINING → GuardDuty detects cryptocurrency mining activity
# Minimum IAM permissions for the detection script
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"cloudtrail:LookupEvents",
"logs:StartQuery",
"logs:GetQueryResults",
"guardduty:ListDetectors",
"guardduty:ListFindings",
"guardduty:GetFindings",
"guardduty:CreateThreatIntelSet",
"guardduty:UpdateThreatIntelSet",
"guardduty:ListThreatIntelSets",
"guardduty:GetThreatIntelSet",
"s3:PutObject",
"s3:GetObject",
"sts:GetCallerIdentity",
"sts:AssumeRole"
],
"Resource": "*"
}
]
}
# For Security Hub integration, add:
"securityhub:BatchImportFindings"
# For SNS alerting, add:
"sns:Publish"
# For organization-wide scanning, add:
"organizations:ListAccounts"
# Navigate to project
cd React2Shell_Hunter
# Create virtual environment (RECOMMENDED)
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
# Option A: Use AWS CLI profile
aws configure --profile security-scanner
# Option B: Export environment variables
export AWS_ACCESS_KEY_ID="your-access-key"
export AWS_SECRET_ACCESS_KEY="your-secret-key"
export AWS_DEFAULT_REGION="us-east-1"
# Option C: Use IAM role (recommended for EC2/Lambda)
# Attach appropriate IAM role to your compute resource
# Test AWS connectivity
aws sts get-caller-identity
# Test Python dependencies
python -c "import boto3, yaml; print('Dependencies OK')"
# Test IOC loading
python -c "
import yaml
with open('config/iocs.yaml') as f:
iocs = yaml.safe_load(f)
print(f'Loaded {len(iocs[\"network_iocs\"][\"malicious_ips\"])} malicious IPs')
"
python src/react2shell_detector.py --hours 24
Expected Output:
2025-12-06 10:00:00 - React2ShellDetector - INFO - ============================================================
2025-12-06 10:00:00 - React2ShellDetector - INFO - React2Shell IOC Detection Script
2025-12-06 10:00:00 - React2ShellDetector - INFO - CVE-2025-55182 & CVE-2025-66478
2025-12-06 10:00:00 - React2ShellDetector - INFO - ============================================================
2025-12-06 10:00:00 - React2ShellDetector - INFO - Starting single account scan...
2025-12-06 10:00:00 - React2ShellDetector - INFO - Analyzing CloudTrail logs...
2025-12-06 10:00:05 - React2ShellDetector - INFO - Checking GuardDuty findings...
Total findings: 0
CRITICAL: 0
HIGH: 0
MEDIUM: 0
python src/react2shell_detector.py \
--organization \
--role-name SecurityAuditRole \
--security-hub \
--guardduty-bucket my-threat-intel-bucket-12345 \
--vpc-log-group /aws/vpc/flowlogs \
--waf-log-group aws-waf-logs-react2shell \
--sns-topic arn:aws:sns:us-east-1:123456789012:security-alerts \
--output json \
--output-file findings-$(date +%Y%m%d).json \
--hours 72
YOU CANNOT CREATE CUSTOM DETECTION RULES IN GUARDDUTY.
GuardDuty uses ML models and threat intelligence to generate findings. To detect React2Shell:
MaliciousIPCaller.Custom findings┌─────────────────────────────────────────────────────────────────────────────┐
│ DETECTION ARCHITECTURE │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ DATA SOURCES DETECTION ENGINE RESPONSE │
│ ════════════ ════════════════ ════════ │
│ │
│ ┌──────────┐ ┌─────────────────┐ ┌───────────┐ │
│ │CloudTrail│────────────>│ GuardDuty │───────>│EventBridge│ │
│ │ Logs │ │ Detector │ │ Rules │ │
│ └──────────┘ │ │ └─────┬─────┘ │
│ │ ┌─────────────┐ │ │ │
│ ┌──────────┐ │ │ThreatIntel │ │ ▼ │
│ │VPC Flow │────────────>│ │Set (C2 IPs) │ │ ┌───────────┐ │
│ │ Logs │ │ └─────────────┘ │ │ SNS │ │
│ └──────────┘ └─────────────────┘ │ Topic │ │
│ └─────┬─────┘ │
│ ┌──────────┐ ┌─────────────────┐ │ │
│ │DNS Query │────────────>│ Route 53 │ ▼ │
│ │ Logs │ │ Resolver │ ┌───────────┐ │
│ └──────────┘ └─────────────────┘ │ Lambda │ │
│ │ (Enrich) │ │
│ ┌──────────┐ ┌─────────────────┐ └─────┬─────┘ │
│ │ WAF │────────────>│ WAF WebACL │ │ │
│ │ Logs │ │ (HTTP Rules) │ ▼ │
│ └──────────┘ └─────────────────┘ ┌───────────┐ │
│ │ Security │ │
│ │ Hub │ │
│ └───────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
The Terraform creates 7 specific EventBridge rules:
The WAF WebACL implements 9 rules in priority order:
Note: Rules 2 & 3 use
or_statementwith multiplebyte_match_statementchecks to detect malicious header VALUES (not just header presence). AWS WAF does not support regex in header matching, so each pattern requires a separate statement. Header names are lowercase as required by WAF.
React2Shell_Hunter/
├── config/
│ └── iocs.yaml # IOC database (IPs, domains, patterns) - 452 lines
├── src/
│ └── react2shell_detector.py # Main detection script - 1141 lines
├── terraform/
│ ├── guardduty.tf # GuardDuty + ThreatIntelSet + S3 - 405 lines
│ ├── eventbridge_rules.tf # 7 EventBridge rules - 533 lines
│ └── waf_rules.tf # WAF WebACL with 9 rules - 681 lines
├── lambda/
│ └── ioc_scanner/
│ └── handler.py # Real-time Lambda scanner - 381 lines
├── athena_queries/
│ └── detection_queries.sql # 18 threat hunting queries - 483 lines
├── tests/
│ ├── __init__.py # Test package init
│ ├── conftest.py # Pytest fixtures (project_root, ioc_config, etc.)
│ ├── test_ioc_matching.py # IOC pattern validation tests
│ ├── test_terraform.py # Terraform configuration validation
│ └── test_waf_patterns.py # WAF regex pattern tests
├── docs/
│ ├── THREAT_INTELLIGENCE_REPORT.md
│ └── GUARDDUTY_EVENTBRIDGE_SETUP_GUIDE.md
├── requirements.txt # Python dependencies (boto3, pyyaml, pytest, python-hcl2)
├── README.md
└── CLAUDE.md
cd terraform
# Initialize Terraform
terraform init
# Preview changes (ALWAYS DO THIS FIRST)
terraform plan \
-var="threat_intel_bucket=react2shell-threat-intel-$(aws sts get-caller-identity --query Account --output text)" \
-var="enable_guardduty=true" \
-var="enable_waf=true" \
-var="waf_scope=REGIONAL"
# Apply changes
terraform apply \
-var="threat_intel_bucket=react2shell-threat-intel-$(aws sts get-caller-identity --query Account --output text)"
Terraform Variables:
The WAF WebACL must be associated with your resources:
# Associate with ALB
aws wafv2 associate-web-acl \
--web-acl-arn $(terraform output -raw web_acl_arn) \
--resource-arn arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/app/my-alb/1234567890
# Associate with API Gateway
aws wafv2 associate-web-acl \
--web-acl-arn $(terraform output -raw web_acl_arn) \
--resource-arn arn:aws:apigateway:us-east-1::/restapis/abc123/stages/prod
# Get SNS topic ARN
SNS_TOPIC=$(terraform output -raw sns_topic_arn)
# Subscribe email
aws sns subscribe \
--topic-arn $SNS_TOPIC \
--protocol email \
--notification-endpoint [email protected]
# Subscribe Slack webhook (via Lambda)
aws sns subscribe \
--topic-arn $SNS_TOPIC \
--protocol lambda \
--notification-endpoint arn:aws:lambda:us-east-1:123456789012:function:slack-notifier
# Open Athena console or use AWS CLI
# Run the CREATE TABLE statements from athena_queries/detection_queries.sql
# CloudTrail table
aws athena start-query-execution \
--query-string "CREATE EXTERNAL TABLE cloudtrail_logs ..." \
--work-group primary \
--query-execution-context Database=default
| Port | Usage |
|---|---|
| 652 | PowerShell stager |
| 2045 | Custom C2 |
| 8000, 8080 | Alternative HTTP C2 |
| 12000, 45178 | Custom C2 |
# Check if GuardDuty is enabled
aws guardduty list-detectors
# If empty, enable GuardDuty
aws guardduty create-detector --enable
# Or use Terraform
terraform apply -var="enable_guardduty=true"
# Verify role exists in target account
aws iam get-role --role-name SecurityAuditRole
# Verify trust policy allows your account
aws iam get-role --role-name SecurityAuditRole --query 'Role.AssumeRolePolicyDocument'
# Test role assumption
aws sts assume-role \
--role-arn arn:aws:iam::TARGET_ACCOUNT:role/SecurityAuditRole \
--role-session-name test
# Check ThreatIntelSet status
DETECTOR_ID=$(aws guardduty list-detectors --query 'DetectorIds[0]' --output text)
aws guardduty list-threat-intel-sets --detector-id $DETECTOR_ID
# Verify S3 bucket permissions
aws s3api get-bucket-policy --bucket your-threat-intel-bucket
# Verify IP list format (one IP per line, no CIDR)
aws s3 cp s3://your-bucket/threat-intel/react2shell-ips.txt -
# Check if WebACL is associated
aws wafv2 list-resources-for-web-acl \
--web-acl-arn $(terraform output -raw web_acl_arn)
# Check sampled requests
aws wafv2 get-sampled-requests \
--web-acl-arn $(terraform output -raw web_acl_arn) \
--rule-metric-name React2Shell-Malicious-IP-Blocked \
--scope REGIONAL \
--time-window StartTime=2025-12-06T00:00:00Z,EndTime=2025-12-06T23:59:59Z \
--max-items 10
# Generate sample findings to test pipeline
DETECTOR_ID=$(aws guardduty list-detectors --query 'DetectorIds[0]' --output text)
aws guardduty create-sample-findings \
--detector-id $DETECTOR_ID \
--finding-types "UnauthorizedAccess:IAMUser/MaliciousIPCaller.Custom"
# Check EventBridge rule invocations
aws cloudwatch get-metric-statistics \
--namespace AWS/Events \
--metric-name Invocations \
--dimensions Name=RuleName,Value=react2shell-malicious-ip-caller \
--start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZ) \
--end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \
--period 300 \
--statistics Sum
NO. This is a detection toolkit, not a prevention solution. You MUST patch:
No detection is 100%. This toolkit detects:
Recommended schedule:
--hours 1Edit config/iocs.yaml and add to appropriate sections:
network_iocs:
malicious_ips:
- ip: "NEW.IP.ADDRESS.HERE"
port: 8080
context: "Description"
confidence: high
source: "Your source"
Then update ThreatIntelSet:
python src/react2shell_detector.py --guardduty-bucket your-bucket
# Install test dependencies
pip install -r requirements.txt
# Run all tests
pytest tests/ -v
# Run specific test categories
pytest tests/test_terraform.py -v # Terraform validation
pytest tests/test_ioc_matching.py -v # IOC pattern tests
pytest tests/test_waf_patterns.py -v # WAF regex tests
# Run with coverage
pytest tests/ --cov=src --cov-report=html
Disclaimer: This toolkit is for defensive security purposes only. Ensure you have proper authorization before scanning systems.
| Software | Version | Purpose |
|---|
| Python | 3.9+ | Detection script runtime |
| Terraform | 1.0+ | Infrastructure deployment |
| AWS CLI | 2.x | AWS authentication |
| boto3 | 1.34+ | AWS SDK for Python |
| Rule | Finding Type Pattern | Severity |
|---|
react2shell-malicious-ip-caller | MaliciousIPCaller.Custom | CRITICAL |
react2shell-credential-exfiltration | InstanceCredentialExfiltration.* | CRITICAL |
react2shell-dns-exfiltration | DNSDataExfiltration | HIGH |
react2shell-cryptocurrency-mining | CryptoCurrency:* | HIGH |
react2shell-unusual-network-ports | NetworkPortUnusual | MEDIUM |
react2shell-malicious-domain | MaliciousDomainRequest.* | HIGH |
react2shell-high-severity-catchall | Severity >= 7 | VARIES |
| Priority | Rule | Action | What It Detects |
|---|
| 1 | Block Malicious IPs | BLOCK | Connections from 9 known C2 IPs |
| 2 | Next-Action Header Values | BLOCK | next-action header containing $ACTION OR __proto__ patterns |
| 3 | RSC-Action-ID Header Values | BLOCK | rsc-action-id header containing $ACTION OR __proto__ patterns |
| 4 | Prototype Pollution | BLOCK | __proto__ or constructor.prototype in body |
| 5 | RCE Patterns | BLOCK | process.mainModule.require, child_process, execSync |
| 6 | ACTION Parameter | BLOCK | $ACTION_0:0 or $ACTION_REF in POST body |
| 7 | Suspicious User-Agents | COUNT | Go-http-client, Assetnote, python-requests |
| 8 | AWS Known Bad Inputs | INHERIT | AWS managed rule group |
| 9 | AWS Common Rule Set | INHERIT | AWS managed rule group |
| Class | Purpose | Key Methods |
|---|
IOCLoader | Load IOCs from YAML | get_malicious_ips(), get_suspicious_ports(), get_malicious_domains() |
CloudTrailAnalyzer | Detect API-based IOCs | analyze_recent_events(hours) |
VPCFlowLogAnalyzer | Detect network IOCs | analyze_flow_logs(log_group, hours) |
GuardDutyManager | Manage threat intel | create_threat_intel_set(bucket), get_relevant_findings(hours) |
WAFLogAnalyzer | Detect HTTP IOCs | analyze_waf_logs(log_group, hours) |
OrganizationScanner | Cross-account scanning | scan_organization(hours, role_name) |
SecurityHubReporter | Import findings | import_findings(findings) |
SNSAlerter | Send alerts | send_alert(findings) |
| Argument | Type | Default | Description |
|---|
--config | string | config/iocs.yaml | Path to IOC configuration file |
--hours | int | 24 | Hours of logs to analyze |
--organization | flag | false | Scan entire AWS Organization |
--role-name | string | OrganizationAccountAccessRole | Role to assume in member accounts |
--sns-topic | string | none | SNS topic ARN for alerts |
--security-hub | flag | false | Import findings to Security Hub |
--guardduty-bucket | string | none | S3 bucket for GuardDuty threat intel |
--vpc-log-group | string | none | VPC Flow Logs CloudWatch log group |
--waf-log-group | string | none | WAF logs CloudWatch log group |
--output | enum | text | Output format: json, text, csv |
--output-file | string | none | Output file path |
--debug | flag | false | Enable debug logging |
| Variable | Required | Default | Description |
|---|
threat_intel_bucket | YES | - | S3 bucket name for threat intel files |
enable_guardduty | no | true | Enable GuardDuty detector |
enable_waf | no | true | Create WAF WebACL |
waf_scope | no | REGIONAL | REGIONAL or CLOUDFRONT |
block_mode | no | BLOCK | BLOCK or COUNT |
enable_lambda_automation | no | false | Enable Lambda for automated response |
| IP Address | Port | Confidence | Context | Source |
|---|
| 93.123.109.247 | 8000 | HIGH | Primary C2 Server | Datadog |
| 45.77.33.136 | 8080 | HIGH | Primary C2 Server | Datadog |
| 194.246.84.13 | 2045 | HIGH | Primary C2 Server | Datadog |
| 141.11.240.103 | 45178 | HIGH | Primary C2 Server | Datadog |
| 23.235.188.3 | 652 | HIGH | PowerShell Stager | GreyNoise |
| 46.36.37.85 | 12000 | HIGH | Payload Staging | GreyNoise |
| 144.202.115.234 | 80 | MEDIUM | Payload Hosting | Datadog |
| 162.215.170.26 | 3000 | MEDIUM | Secondary Payload | GreyNoise |
| 45.32.158.54 | - | MEDIUM | Scanner | GreyNoise |
| Domain | Category | Confidence |
|---|
| ceye.io | DNS Exfiltration | HIGH |
| dnslog.cn | DNS Exfiltration | HIGH |
| *.oastify.com | Burp Collaborator | MEDIUM |
| sapo.shk0x.net | C2 | HIGH |
| xwpoogfunv.zaza.eu.org | C2 | HIGH |
| *.c3pool.com | Cryptomining | HIGH |
| 3333, 5555, 14433, 14444 | Cryptomining |
| Pattern | Severity | Description |
|---|
next-action: * | CRITICAL | RSC exploitation header (lowercase in WAF) |
rsc-action-id: * | CRITICAL | RSC action identifier (lowercase in WAF) |
$ACTION_0:0 | CRITICAL | RSC action parameter |
__proto__:then | CRITICAL | Prototype pollution |
process.mainModule.require | CRITICAL | Node.js RCE |
child_process | CRITICAL | Command execution |
Go-http-client/1.1 | MEDIUM | Scanner user agent |