WP Malware Analysis: How Backdoors Bypass Security Solutions with Advanced Obfuscation Techniques

Archive

Case Study: How Backdoors Bypass Security Solutions with Advanced Camouflage Techniques

Case Study: How Backdoors Bypass Security Solutions with Advanced Camouflage Techniques

The nature of our business is such that many of our clients come to us only after experiencing a security breach, with their websites already infested by one or more backdoor shells. As a result, a good chunk of our time is spent towards perfecting our backdoor detection and removal mechanisms. But even when you think you’ve seen it all, hackers never cease to surprise.

The following is a case study that delves into the details of a sophisticated backdoor we’ve recently neutralized one that really brought out our inner security geek. We hope that it will provide assistance and guidance to fellow security professionals and help them outsmart similar sneaky perpetrators.

The Challenge

Searching for a website backdoor is like looking for the proverbial needle in a haystack, mainly because it can be installed anywhere on the server under any name or alias or injected into any of the existing files.

Thus, going over an entire website’s code is not a feasible way to stay secure. Typically, a feasible method to detect a backdoor is by searching every directory and sub-directory on the website, attempting to find code that “should not be there”.

This type of search is made even more difficult by the fact that most websites are built on 3rd party frameworks and include 3rd party extensions. The practical result is that website scanners that go over the code usually relay on various heuristic and signature-based rules, which need to be able to handle various obfuscation techniques.

Discovery

In order to preemptively block backdoor injections through our WAF, we’ve set up some heuristic rules that look for suspicious POST requests. These rules have been developed based on our analysis of abnormal traffic patterns from various clients.

A short while ago we started seeing an increase in POST requests containing what seemed to be malicious behavior by unknown clients. These clients were sending POST requests to different PHP files in (seemingly) random locations.

The attackers behind this campaign knew what they were doing; they had backdoors in place ready to execute any given PHP payload on the compromised machines. The following analysis provides an in-depth look at one such example.

Analysis

The perpetrator sends the following URI-encoded POST body to the backdoor via the command and control channel:

Backdoor's URI-encoded

After URI decoding and some clean-up we reveal the following piece of code:

Backdoor's URI-decoded

This code has all the trappings of malware. Passing PHP code inside a POST body is very unusual, while the use of eval and base64 encoding are commonly used in web malware. So while we can see this probably has malicious intent, we still can’t figure out what it does exactly.

It’s also interesting to note that at this point the attackers used a proprietary function for Base64 decoding (b64d), as well as a supposedly random parameter “qdb24bc“.

We’ll elaborate on both of these later. The next step is to replace the eval function with print or echo to see what the base64 value holds. One would expect to get something that’s humanly readable, but instead we get code that looks like this:

Base64 code

This, as we’ll soon find out, is a highly obfuscated malware dropper. Per VirusTotal, this code was not detected by any antivirus or any web scanner.

Moreover, it uses obfuscation techniques that are more advanced than the usual gzip->deflate->base64. Automatic PHP de-obfuscation services such as DDecode and UnPHP couldn’t de-obfuscate it due to the use of the following tactics:

  1. Instead of using “base64_decode” it has a proprietary “b64d” function that serves two purposes:
    • Bypass static keyword based rules.
    • Circumvent automatic PHP de-obfuscation engines.
  2. It uses a string lookup array to avoid keyword-based detection:

String lookup array

Then it creates random strings in the GLOBALS table by concatenating indexes. For example, this code translates to chmod:

Encoded chmod

This is very effective technique (more common in binary malware) in avoiding detection by engines that rely on keywords. Not only that, the string is completely unreadable as it is.

To speed up our analysis, we built some simple scripts to reconstruct the code. The first phase uses the original dictionary to revert back the strings:

Reconstructed code step 1

The second phase replaces the strings using the values in the GLOBALS variables:

Reconstructed code step 2

The result is a somewhat readable version of the code. With a little bit of manual editing, we can translate it into this understandable format:

Reconstructed code step 3

Payloads

Now that the code is readable, it’s fairly easy to see that it tries to download a binary file (depending on OS/CPU architecture):

Payload

The binary file is a malware known as Backdoor.Linux.Snessik, per VirusTotal.

Another type of backdoor payload we spotted was a Facebook account scrubber. While this backdoor uses the same advanced obfuscation techniques and MO as the previous example, the payload is different.

Host Backdoor

We’ve seen that backdoor commands are sent via POST requests. The next step of our analysis is to break down the request structure (after URI-Decode):

Host backdoor

The first parameter “q6ae4d5” serves as the backdoor key. Each backdoor has a unique hard-coded value (key), which correlates to the backdoor filename. When a command is received, the parameter value is checked against the hardcoded one.

We’ve downloaded a few backdoors from infected websites. Here’s one example of the very simple PHP code:

Host backdoor encoded

And de-obfuscated:

Host backdoor de-obfuscated

As you can see, the backdoor checks whether the hard-coded key parameter exists in the POST array, and if so eval()s it.

The key parameter carries the pre-loader code:

Pre-loaded code

This very straightforward code will be run by the hosted backdoor. It saves the request’s POST data as an array in the $p parameter, then executes the second POST parameter value using eval().

The $val’ parameter contains the request’s data parameter value. From this point on, the malware dropper payload we covered in the previous part gets executed.

The initial infiltration vector isn’t covered in the scope of this analysis, but our best educated guess is that attackers used popular known vulnerabilities (in RevSlide / wpDataTables / WP Symposium/ etc.) in order to upload the backdoors.

In some cases, we saw multiple backdoors on the same site.

In our analysis we came across several different types of payloads, from the covered Trojan dropper to a Facebook accounts scrubber.

Clearly, today’s attackers try to use the hosted backdoors for multiple purposes, and it’s quite possible that backdoors are being offered by hackers as an “on-demand” service.

We collected and analyzed the backdoor attack events based on our clients’ websites over a 30-day period.

Summary statistics:

  • Over 500 targeted websites on Incapsula network (these websites are protected from backdoor attacks by our WAF).
  • More than 100 unique hosts (IPs) used to spread and command the backdoors (not protected by Incapsula).
  • Some 17,000 unique attack events originating from these hosts.
  • ~860 unique backdoors keys (one per specific backdoor file name).

Backdoor URLs:

URLs vary from site to site, most of the infected websites were private blogs running WordPress/Joomla/known PHP scripts.

The attackers tried sending commands to backdoors located in various paths, most commonly:

  • WordPress sub directories
    • /wp-content/plugins/{sub-directory}/
    • /wp-content/themes/{sub-directory}/
    • /wp-content/uploads/{sub-directory}/
    • /wp-includes/{sub-directory}/
  • /
  • /{Joomla sub directories}
  • /known_PHP_scripts/{sub-directory}
  • /{static_resource_ dirs}/{sub-directory}
  • /{random}/

Attacks by country

We can see a very wide geographic distribution with respect to the countries from which these attacks originated (i.e., the host IP). This fact corroborates our assumption that these machines were compromised by attackers to spread backdoors in an anonymous manner.

Of a total of some 17,000 unique attack events, the majority came from IPs in France (39.5%) and the United States (18.6%).

Attacks by country