Turn WordPress into a Honeypot
About half a year ago, my WordPress based blog got hacked. Let's take this as an idea for an infosec project!
Disclaimer
I am talking here about an idea in combination with a proof of work. Most of this are ideas and not meant to be taken for granted. Some aspects might need *a lot* improvement, but I still think it's interesting to talk about.
What to track?
First of all it must be considered what actions or activities the honeypot should monitor.
For this project, I will take especially an look into these activities:
- Activities in the dashboard (requires login)
- Calls on the xmlrpc.php interface (requires login)
- Directory traversal (e. g. with dirbuster or gobuster)
- Dropped and modified files (e. g. from an vulnerability)
- Uploads in wp-content (requires login)
How to track?
Option A: Rebuild a WordPress fake
..aka the "high effort route". Takes a lot of time to archieve and needs continuous adaption to new updates.
Not really an option.
Option B: Use WordPress
This route requires additional measurements to prevent attackers from permanently turning the instance. On the other hand, the hooks and filters allow to inject a lot of logic into WordPress to make sure the attackers can be monitored properly.
Anyways: This is the way to go for this project.
Let's build a honeypot!
Taking precautions
The Honeypot will run on an dedicated machine, deploying WordPress inside Docker. The container won't have any mailing configured. A cronjob will be killing the containers by a schedule.
An extension to this is to route the traffic throught a proxy for further monitoring. But I think that is not something to include in this post.
Where to start
WordPress has plenty of hooks and filters to work with. For this project, we will especially use following hooks.
Hook/ filter | Purpose |
---|---|
template_redirect |
Tracking of 404's |
wp_head |
Manipulate the generator tag |
wp_handle_upload_prefilter |
Tracking of files uploaded inside /wp-admin/ |
comment_post |
Tracking of comments |
admin_init |
Tracking of navigation inside /wp-admin/ |
wp_logout |
Tracking of logouts from the admin menu |
wp_login_failed |
Tracking of logins (to create new accounts) |
Collecting data and artefacts
We need to talk here about to three types of files being uploaded:
- Files uploaded in wp-admin, which are allowed
- Files attempted to be uploaded in wp-admin, which are not allowed
- Files uploaded in the filesystem by an exploit
To monitor files uploaded somewhere in the webroot, the honeypot will create a file list including the files CRC32 checksum with hash_file(). Why CRC32? It's the quickest one to use for large file iterations. On each request, the file list will be verified. If something changed, the change will be logged.
For (attempted) file uploads, the hook wp_handle_upload_prefilter will be used to catch the file and store it outside the wp-content/ folder tree.
Hello, user!
My current idea here is do follow two paths. Use of prepared, existing users or to allow the attacker to create new users after login. Last one uses an defined list of credentials to make the login not "too easy" (such as admin:admin or user:user). I am not talking about registering new users here using the WordPress onboarding process. The "register" process will be done in the background.
To create users on the fly, I will be using the wp_login_failed hook. If the login fails internally, the user will be created and a session will be opened using wp_set_current_user. This basically simulates an regular user login, even as the user was not existing at the start. The user will be flagged in it's meta data to keep track for users created this way. Capabilities and roles will be controlled by the defined WordPress settings.
Setting a limit
An initial infection only might take some seconds until the instance will be abused for really malicious actions later. To prevent (or to be realistic: limit) actual abuse, the instance will need some resets, especially on the user side. For this, the honeypot utilizes wp_schedule_single_event, which deletes the user after a given time. The artefacts uploaded by the user will be logged and collected outside of WordPress, so the user will be deleted, including all of it's contents. So from this point, the instance will be "fresh", even as the files are still logged. If the user logs out by itself, the user will be also deleted, including all of it's content.
Avoiding exposure, wear a mask
At the point where the attacker will infiltrate the WordPress, the Honeypot will most likely be unmasked. To increase the time to this point, the Honeypot will hide behind a given plugin, such as "Hello Dolly" (which is installed per default). An alternative could be to include the file in a (child)-theme. For this, the Honeypot will be deployed as an plugin.
An improvement of this is to obfuscate the code, hiding the function signatures. Same goes for files, but this is out of scope for now.
At some point it might be interesting what action an attacker does without actually having the vulnerability anymore. For this, I will be using the wp_head action, adding a fake generator meta tag. Of course there might be the need for other faking actions, but for this point this is okay. If an attacker checks the generator tag to apply exploits build against a certain version, this can be still tracked without actually having the issue anymore.
Cleaning up the mess
As we are working with a real WordPress instance at this point, is it important to reset the whole environment at some point, and not only the users.
For my use-case, I will be using a Docker environment to spawn and reset the instances on a schedule.
Wrapping up
The API of WordPress offers a lot of hooks and filters to track malicous actions. Quite a challenge remains to restore the instance to a really clean point to prevent it's abuse. But other options, such as "faking" an WordPress using a different stack ist just not worth the effort.
With the hooks for file uploads and administrative actions it is possible to keep track attackers attempting to do something with the dashboard while dropped files can be monitored from a global perspective as well, if the file is dropped using an exploit, for example.
So for the theory, this should cover quite a range of possible attacks. But to be realistic, some thing will not be properly monitored. So this will be a learning-and-adapt process.
I will be continue working now and then on this project with the goal to deploy it and to see if malicious actions can be tracked in the wild. I will do updates on this project.
The code for this proof of work is available on GitHub: https://github.com/cmllr/honeypress (expect spaghetti code!). Please keep in mind that this is just playing around and to make this "field ready" it still needs improvements.
Photo by Benyamin Bohlouli on Unsplash
https://giphy.com/gifs/floor-wet-caution-KccoHFiEXjWZW
https://giphy.com/gifs/star-trek-mess-tribbles-108KUzjTMEp2gw