Analysis of compromised websites – hacked PHP scripts

Things have been pretty busy lately as far as web attacks ago. Over the past few weeks we have seen several large spikes of threat detections, corresponding to various waves of mass defacement attacks against legitimate web sites.

Pages on the hacked sites are typically injected with iframes (or scripts that add iframes), which explains the dominance of Mal/Iframe detections in our web threat data.

At the start of last week I happened to notice that a security-related site had been hacked in one of these attacks. Thankfully when I alerted the site owners of the problem, the site was taken offline quickly, and the matter resolved.

I do not believe the organisation was specifically targeted – it just appears to be one of many victims in this aggressive wave of mass-defacement attacks.

The incident raises some interesting questions. Most notably the malicious content being injected into the web pages was changing over time (sometimes a straight iframe, sometimes JavaScript).

This is not what you necessarily expect for hacked sites – ordinarily pages are injected with a fixed string (for example an iframe redirect or a script).

However, in these attacks, we were seeing various Sophos detections being triggered:

Clearly the injected content was dynamic, suggesting a slightly more sophisticated type of hack.

Hacked PHP files

Subsequently we managed to gather a few of the compromised files (PHP scripts) from servers in these attacks. In each case, the PHP scripts had been modified to include malicious code at the start of the file. Several flavours of code have been seen. In the simplest cases, the malicious payload is hidden within a base-64 encoded string:

Sometimes, an additional layer of compression is added as well:

And in several cases, I have seen obfuscation used to try and hide the malicious code (from security scanners and site admins!):

In this latter case, you can see that preg_replace has been used in order to obfuscate the use of eval, gzinflate and base64_decode.

The presence of any of the above strings within PHP scripts on web sites suspected of being hacked, should ring alarm bells for site administrators. Scripts to routinely check the size and last modified date of all PHP files within the site can be useful.

Payload of inserted PHP

And what of the actual payload of the prepended PHP? They are pretty easy to manually decode, and then the actual payload is normal quite straightforward to determine. Obviously the exact payloads vary between attacks but in the case of the sophisticated dynamic injection attacks described above, it is summarised below.

  1. retrieve IP for the user requesting the web page ($_SERVER).
  2. retrieve user-agent string from the page request header ($_SERVER).
  3. check user-agent string against an array of strings the PHP script contains for search-engine bots.
  4. if the request is deemed to be from a search-engine bot, bail. The original web page is delivered with no modifications.
  5. if the request is deemed to NOT be from a bot, check the IP against a local blacklist.
  6. if the IP has requested the page before, bail. The original web page is delivered with no modifications.
  7. otherwise, download a web page from a remote server (using cURL). This page contains the string to inject.
  8. echo the string to inject to the requested page.
  9. add the user IP to the local blacklist.

Note the check for bots – search-engines will never get to see the malicious code. This is done to stop search-engines blacklisting/removing compromised pages from their search results. Also note the use of a local IP blacklist. This is done to only hit each user once, which makes it harder to troubleshoot/investigate the problem!

The following diagram gives an overview of how the drive-by attacks proceed once the web servers are compromised:

From this analysis, what other clues might be present on hacked web servers? The cURL request to the remote server could be logged, or blocked with URL filtering. Use scripts to check the web folders for unexpected files such as those used for storing the local IP blacklist data.