WordPress Unattended Install Hack Demonstration
These are the supporting files to demonstrate how someone can overtake/hack a WordPress installation waiting to be installed without the owner realizing it.
Run the Docker Compose functionality to launch the proper containers:
Add the following line to your
/etc/hosts file to make it easier to demonstrate:
Steps to Attack
- Using Bad Guy's browser, load up the WordPress site at http://goodguy.com:9080 to demonstrate it requires installation
- Progress through and put in
badguy.comas the MySQL host,
hacked_wordpressas the database, username
- Finish install
- Login with
badguywith password of
- Go to plugins and upload plugin from
- Activate plugin
- Note how the site is back to being installed
- Using Good Guy's browser, run the installation process. (database
rootpassword is blank, host is
- As Bad Guy, request a URL like the first page and add
n4v4ac=bHMgLWxhto the GET parameter - show that the result of
ls -lawas on the bottom of the page
- WordPress is waiting for you to install - you'll use a local database server to configure it.
- Bad guy finds the hosting, points it to his own database which already has an install. He configured a super basic MySQL dump with his known username and password.
- WordPress recognizes it has already been installed (it doesn't want to blow away your old site if you had to 'reinstall')
- Bad Guy now authenticates against his remote mysql database but on the local server.
- Uploads a malicious plugin - activates it - it delivers its payload - then it deletes itself. It also deletes
- The payload appended a special check for a
GETrequest - and since its on any page at all, he can choose which page to use to process his code.
wp-config.phpwas deleted, the WordPress instance is back to square one - ready to be installed - looks "fresh" and untouched.
- That special code executes whatever he base-64 encoded and sent as a
GETparameter - in our case, we're using
passthruso that it's easier to demonstrate.
Ways to Make it Harder to Stop
I didn't want to make this too cut & paste, but I still wanted to demonstrate enough to show how easy/important it was. Because of this, here are a list of ways that we could make it harder to detect, but I haven't implemented.
- Don't use
passthru- use something like
- When the plugin deletes itself, it could delete the folder, too.
- Don't append to
index.phpbecause a WordPress update could change it. Write to
wp-config.phpinstead because that's less likely to be changed I think.
- Or pick a set of random file names that look official, and write the code there. Then, you would have to go to just that special URL but it'd wouldn't be deleted.
- File could change it's filename every time it was requested - sending back it's new filename in a header of the request
complicated-standalone.phpto show how we could make the get parameter pretty random looking
obfuscateto show how we could obfuscate the code that was written to the file
- To stop things that scan for checksums and crc's, the payload code and/or the actual zip file itself can have extra random information added to them to make it easier to just point and scan
I've assisted a number of people cleaning up hacked website files, so I was familiar with some of the ways to obfuscate and confuse. The idea to attack WordPress in this manner was directly inspired by this Defcon 2016 talk.