Hacking WordPress 4.7.4

Have I mentioned that I love WordPress?  I do, as long as I’m not maintaining it.  When I’m maintaining it, I hate it.  My kneejerk reaction is to call it junk.  It’s not junk but it’s what happens when designers cut out developers.  I get it – you’re a designer, you want to move quickly and here’s this product which is easier to learn than coding.  If you want a fancy slider, you install a plugin.  If you want to embed a YouTube video, you install a plugin.  From that point of view, it’s amazing.  From my point of view, every time you bolt on a new widget, there’s a potential for an opening.  Heck, without plugins, you can still get owned which is what we’re going to explore in a moment.

As I’m sitting here typing this, I’m looking at two public facing WordPress sites running versions 4.6.1 and 4.7.4 which are both vulnerable to this exploit.  These servers do exist in the wild, likely unmaintained as there are a significant number of web projects that are one and done.  

CVE-2017-8295

WordPress through 4.7.4 relies on the Host HTTP header for a password-reset e-mail message, which makes it easier for remote attackers to reset arbitrary passwords by making a crafted wp-login.php?action=lostpassword request and then arranging for this message to bounce or be resent, leading to transmission of the reset key to a mailbox on an attacker-controlled SMTP server.

Basically, we’re crafting a POST request and we should be able to redirect the Lost Password email to our account.  Certain conditions apply with the most obvious being that a site hosted on a shared IP wouldn’t technically be vulnerable but only because the site needs to be accessible by IP. 

I wanted to see this vulnerability in action in a controlled environment so I setup WordPress 4.7.4 in my new test lab (more on that later...).

Here we have our basic WordPress site running version 4.7.4:





We browse to the lost password page:




Prior to hitting the "Get New Password" button, we need to capture the POST request with Burpsuite:




With Intercept on, we capture the POST.  Now we're going to send it to the Repeater:




In Repeater, we have our unaltered POST request. 




I'm going to setup a simple SMTP server to capture the email transaction and dump it into the file system.  The code you see below came from:

SMTP sink server





We're going to change the HOST to our server:




When we hit "Go", we should see a response like what you see below.  If you see the Render tab appear, you're probably getting an error.  If your SMTP server has an issue, you're going to see a message stating as such.




Since my transaction was successful, my SMTP request gets dumped into the filesystem:




When I cat the file, I see the entire email with the password reset link:




Prior to hitting the link with the web browser, we need to turn off Intercept:




We're accessing the password reset link and WordPress is kind enough to give us a new password.  I'd tell you to write it down but why does it matter, you can do this same hack again.  




Upon selecting the Reset Password link, we get a confirmation message:




Heading back the login page with our newly created password:




Logging in for the win:



Game over!