Prevent PHP Malware Execution on Windows Server / IIS

Posted on Saturday, November 14, 2015 by Sam

At work I am in the process of migrating a series of legacy Wordpress sites from one Windows server to another.  During the course of this I discovered that some of the sites had become infected over the years with malware.  Wonderful!  I was able to remove the malicious code through a bunch of search and replace operations and with the help of my local system's malware and virus scanner software.

During the clean up process I did some research and found that the attacker was able to upload malicious code by taking advantage of a vulnerability in the Gravity Forms plugin that had been installed on the site.  Read more on that in the original article.  This allowed the attacker to upload arbitrary PHP code to the uploads folder.  Once that happened all bets were off since the attacker could then simply make an HTTP request to the location of the PHP file and run whatever code they had placed in there.  In this case, the offending file copied a small snippet of code around which was encoded to obscure the operations it was performing.

The vulnerability has been fixed in the plugin but since this site was still using an older version that didn't help me here.  Even if the site was using the most up to date version at the time it still could have been a time before this vulnerability was discovered and fixed.

In this case the issue is that the attacker was able to upload code and run it.  PHP files shouldn't be able to be uploaded to the uploads folder (or any other folder for that matter) but in this case of a loophole in a plugin there wasn't a way to prevent that from happening.  However, it is possible to prevent the PHP file from executing if it makes it's way into the uploads folder.  That would stop an attackers code from doing any damage.

I Googled around for methods to accomplish this and came up with adding a web.config file to the uploads folder which prevents files with the extension of ".php" from being allowed.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webserver>
        <security>
            <requestfiltering>
                <fileextensions>
                    <add fileextension=".php" allowed="false"></add>
                </fileextensions>
            </requestfiltering>
        </security>
    </system.webserver>
</configuration>

If this is present and a php file ends up being added to the ~/wp-content/uploads folder and a request is issued for that path instead of the code executing you will see this message instead:

PHP execution prevented in the WP uploads folder

Problem solved! This effectively prevents this sort of attack from occuring and gives me time to keep up to date with plugin bug fixes without worrying about an attack occurring in the meantime.