Leveraging LFI To Get Full Compromise On WordPress Sites

In this post I will discuss how a serious but mostly ignored vulnerability can lead to a full compromise of a WordPress site. The key in this attack is how WordPress handles authentication allowing a brute force attack if the secret salt and key values stored in wp-config.php are exposed. IF an innocuous LFI (local file inclusion) or accidental leak of this data by a backup or copy of wp-config.php is successful, then an attacker could generate their own valid auth tokens and gain full access to the site's admin pages without being detected.

This is a followup to a previous blog post (Jamming with WordPress Sessions) where I discussed an attack against WordPress authentication tokens. At that time I only wrote about a post-compromise scenario where an attacker could generate undetectable authentication tokens that effectively never expire. I restrained myself then from divulging how this flaw could chain with other attacks to allow attackers to compromise WordPress sites. With the release of WordPress 4.0, the vulnerability that this attack exploits (CVE-2012-5868) has finally been patched (yes, after 2 years).

To summarize and get you up to speed, up until WordPress 4.0 the way the site handled creating and validating authentication tokens was by making a hash of three values: 1. the site's secret key/salt pair, 2. four characters of the user's hashed password, and 3. the expiration time stamp.

On a valid login, the three values are passed through a series of hashing algorithms (HMACs) and the resulting md5 hash is given to the user's browser as a cookie. Verification of the authentication cookie is handled by the website running the hashing algorithm again using the expiration time stamp and its known secret values to validate that the cookie's stored authentication token is valid.

This flaw was patched in the 4.0 release by tying the authentication tokens sent to the user to session identifiers managed in the database. I encourage everyone to upgrade to WordPress version 4.0 as soon as possible because it addresses this flaw. Doubly so because there is evidence that shows an increase in LFI (Local File Inclusion) attacks against WordPress sites our Web Server Security team posted about recently.

Getting back to the attack. The three values are key. The timestamp is arbitrary and supplied by the user. The secret salt is by far the least likely to be guessed or brute forced. The four characters of a user's password hash can be brute-forced over a period of time. So, how would we get the unknown and impossible-to-guess secret salt? That's where LFI or information leakage attacks come in.

The attack would play out like this:

1) Use an existing attack to get access to the wp-config.php file's secret key values:

Or, alternatively, use one of the many Local File Inclusion attacks, which target common themes and plugins.

2) Pull out the secret keys and plug their values into the proof of concept code:

Here is the Proof of Concept attack code in full:

3) The PoC will use the key values to generate brute force auth tokens on the fly:

4) Then it uses the generated auth tokens to hit the site looking for a valid authentication cookie (in this case, looking for http header response code that denotes we sent a valid authentication cookie):

This step may take a while as there are 64^4 possible iterations of the four character combination we're bruting. However, from the web server perspective it will not look like a brute force in the access logs, the authentication takes place based via the sending of the cookie to the server. So, the attack could appear in the site's logs like regular traffic to the site.

5) When a valid auth token is found, the code will output the value of the cookie:

6) You can then automate the attack to use the authentication cookie to take immediate actions (such as adding users via the WordPress admin page, upload a backdoor, etc..) or if you prefer the hands on approach, copy the cookie's value into your browser and get access as the brute-forced user's admin pages. The PoC above uses an expiration timestamp that expires in about 100 years, so you have plenty of time on your hands to take action after forging the authentication cookie.

There we have it, anyone who leaks the secret key and salt values of their site is a stone's throw away from a site being seriously compromised.

This post has shown how dangerous leaking secret key values can be and clarified what additional risks have been associated with CVE-2012-5868. Furthermore, using this vulnerability as a example, we see how long a publicly reported vulnerability might take to be patched even by a major vendor. Two years is a surprising length of time to "push back" a vulnerability's public patch, but should serve as a striking example on why implementing a web application firewall (WAF) and using it for virtual patching can help protect against vulnerabilities when a vendor can not be relied upon for timely patches.