I've read, I think, my favorite WordPress security post ever. I admit, I do get excited when something is teased to me as a trilogy, but Netanel Rubin follows through with flying colors.
Now, this post is long. And when you click on it, you're going to say, “Dang, this post is long.” But read it. And don't just read it. Read it. Try and follow along not just with what the author is saying, but how he's thinking.
It's amazing to see the process Netanel took — taking advantage of several minor and inconspicuous WordPress bugs, and piecing them together like an obscure puzzle — to lay the groundwork for a critical WordPress exploit.
WordPress got high praise for the core project's security management:
In contrast to these frequent findings in 3rd party plug-ins’ code, barebones WordPress issues are rare, as WordPress core developers are well-trained to hold high security awareness for all released code. We can confirm that during our audit of the source code, we witnessed the developers ‘leaving nothing to chance’, and implementing multiple layers of security protecting most attack vectors we could think of.
WordPress developers deserve praise for their efforts to maintain such complex software in this level of security, specifically considering the presence of the notoriously trigger-happy foot-gun called PHP.
Though WordPress security is often mischaracterized by the larger programming world, it's nice to see someone (who obviously knows what they are doing) give the project and its maintainers the credit that's deserved.
It is worth noting, unfortunately, that this elaborate scheme is due to the fact that the author took on the challenge of creating an exploit from core; exploiting an install via any number of plugins is much more trivial.
Now, back to the post. One thing that stuck out to me was what is at stake if the author (or more importantly, a black hat hacker) is able to successfully navigate exploiting WordPress core.
After a good bit of creative navigation deep into WordPress's internals, Netanel had a breakthrough and realized he was getting close, but also knew he still had a way to go:
This now grants us a deterministic, extremely powerful leverage to exploit our race condition with, yet, our job is not over and we still have a couple of things to do before fully exploiting this vulnerability in a deterministic manor on every WordPress install in the world.
The last part hit me, that, “we still have a couple of things to do before fully exploiting this vulnerability in a deterministic manor on every WordPress install in the world.”
This all seemed, up to this point, like a fun challenge and proof of concept. But realistically, much is at stake in regard to nearly a quarter of the web's security, and that is a huge burden on the WordPress project.
In the end, Netanel was successful (and he walks through the code for each of these components: read it!):
Finally, after passing the token validation, the privileges validation, the basic admin validation, and the post ID validation, changing the post status to ‘trash’ is as simple as sending an HTTP parameter. Thank God.
Combining all of these bypasses together, we use a chain of around a dozen different bugs, a faulty privilege system, and about every false assumption in the system to achieve partial editor privileges. The road to a critical vulnerability is still long, but at its end we found both a SQLi and an XSS, to be described in the next posts.
Thankfully, he's one of the good ones. I look forward to the next two posts that will cover the rest of this experience, but the result was that his extensive research and responsible reporting led to more than one fix in WordPress 4.2.3, which was auto-updated back to 3.7, and millions of websites are safer for it.