A backdoor is a method for bypassing the normal authentication or encryption of a system. Sometimes developers construct backdoors to their own programs for various reasons. For example, to provide easy maintenance, developers introduce a backdoor that enables them to restore the manufacturer’s default password.
On the other side, very often attackers inject backdoors into vulnerable servers to take over the server, execute attacks and upload malicious payloads. A backdoor paves the way for hackers to launch further attacks. For example, attackers may inject backdoors that allow them to execute code on the infected server, or upload files. This code and files will contain the actual attack, which may contain different kinds of payloads like stealing data from an internal database or run cryptomining malware.
In this blog, we’ll discuss some of the attackers’ methods to inject backdoors while evading detection. We’ll show examples of real backdoors found in our data, and how they use different evasion and obfuscation techniques, some of them quite complex.
Types of Backdoors
There are several kinds of backdoors, written in different programming languages. For example, a backdoor written in PHP is designed to work on servers running on PHP, contrary to backdoors written in ASP that are designed to run on .net servers.
The purpose of the backdoor may vary, from a web shell which allows the attacker to run operating system commands on the infected machine to specially crafted backdoors which allow the attacker to upload and execute files.
There are many open source backdoors publicly available on sites like GitHub. Hackers can choose to inject a known backdoor, but then they risk being easily detected. More sophisticated hackers create their own backdoors or obfuscate the known backdoor they inject using different evasion techniques.
Common Security Controls
Security controls may try to block backdoors using a couple of different methods. One of them is to block the initial injection of the backdoor during an HTTP request, which is usually injected to a server using a known vulnerability. Another method is to analyze the content of the backdoor during the HTTP response, to find whether it contains code that is considered malicious.
This should come as no surprise, as attackers work hard to hide their real intentions when injecting these backdoors. Hackers usually make use of several evasion techniques, including obfuscating known functions and parameter names and using the encoding of the malicious code. In the next sections, we’ll show backdoors written in PHP where attackers used different techniques in order to avoid detection by security controls.
PHP evasion techniques
There are many methods that can be used in order for attackers to evade detection. The overall motivation, however, is to mask known functions or PHP keywords. Some of the known functions and keywords include:
In this example, the visual output of this page is the well-known “404 Not Found” message (line 2), which may suggest an error. However, there is an embedded backdoor code (lines 3-13) in this page. The keyword “_POST” is written in plain site; however, the attacker used a simple method to hide it:
In line 1, the backdoor code turns off all error reporting to avoid detection in case of an error. In line 3, the “default” parameter is defined as what seems to be like a random combination of characters. In line 4, the “about” parameter is defined when the code reorders these characters and turns them to upper case to build the keyword “_POST”. This keyword is used in lines 5-12 to check if the HTTP request to this page was done via the POST method and whether it contained the “lequ” parameter.
If so, the backdoor uses the “eval” function to run the code that was sent in the parameter “lequ”. Thus, the backdoor reads the value from a parameter in a post request without ever using the keyword “$_POST”.
Another popular method used by attackers to obfuscate known keywords, is string concatenation, as in the following example:
Contrary to the previous backdoor, where known functions were written into backdoor itself without obfuscation, the only visible command in this code snippet is the “chr” function (line 1). This function takes a number between 0 and 255 and returns the correlated ascii character.
Adding a dot at the end of a character or a string is the PHP way to concatenate it to the next string. Using this functionality, attackers can concatenate several characters or strings to create a keyword that represents a known function, thus hiding it from detection.
Finally, this function is executed with the “@” sign at the beginning, that surpasses the printing of error notices. The purpose of this backdoor is to create a function that evaluates the code that is given in the first parameter of a post request. Using this backdoor, an attacker can trick detection systems and send the arbitrary code to the infected server using POST requests, where the code will be executed.
Although some functions or functionality have been deprecated in previous versions of PHP, we still see attacks trying to abuse this functionality in current backdoors, as in this example:
This one-line code snippet might seem simple, but it actually uses a couple of evasion techniques and can cause a lot of damage as a backdoor. First, the “str_rot13” function takes a string and shifts every letter 13 places in the alphabet. The output of this function on ‘riny’ is the well-known function ‘eval’. Next, the “preg_replace” function takes a regular expression, a replacement string, and subject string. It then searches for every occurrence of the regular expression in the subject and replaces it with the replacement string. The output string in the above example will be:
Meaning, evaluate the expression in the parameter ‘rose’ from the post request.
Notice the ‘/e’ tag inside the ‘preg_replace’. This is a deprecated tag that tells the program to execute output of the ‘preg_replace’ function. The PHP manual states the following warning about this modifier: “Caution Use of this modifier is discouraged, as it can easily introduce security vulnerabilities“. This modifier was deprecated in PHP 5.5.0 and removed as of PHP 7.0.0. So why worry about a deprecated functionality which was removed since the new version of PHP? Look at the following survey taken from W3Techs:
According to this survey, more than 80% of the websites written in PHP use a version in which the deprecated ‘e’ modifier of the ‘preg_replace’ function is used. Thus the vast majority of websites written in PHP are vulnerable to attacks using this deprecated modifier.
As another mean to evade detection, the code will be evaluated with the ‘@’ sign as seen in the previous example, which surpasses error messages.
Multi-Step PHP evasion techniques
There are evasion methods where attackers obfuscated their code using a combination of multiple techniques.
Reverse string, concatenation, compression, and encoding
In this example, the attacker used a combination of methods to hide the code. First, the attacker used the aforementioned “preg_replace” function with the “/e” modifier that evaluates the code. In the second argument, we can see the attack payload being split to several strings and concatenated with the “.” operator. We can also see the attacker used the “strrev” function to reverse the order of the concatenated string “lave”, which turns into “eval”. After concatenation, we get the following payload:
Here, the code isn’t only encoded with base64 encoding, it is also compressed with the “deflate” data format. After decoding and decompression we get the following payload:
Which means evaluate the code that is sent in the “error” parameter, either in GET or POST requests.
String replacement, concatenation, and encoding
In this example, the attackers hid function names inside variables and obfuscated the backdoor itself using base64 encoding. The only visible known keyword is “str_replace”, in line 2, and it is used only once.
Let’s go over the code to see how it works. First, in line 2, the parameter “tsdg” is given the value “str_replace”, by taking the string “bsbtbrb_rbebpblacbe” and removing all the letters ‘b’ using the str_replace function. Here the attacker obfuscated a known PHP function by creating a string that includes the designated function including additional letters. Then, these letters are removed using the str_replace function.
Next, using this same method, in lines 6 and 7, the parameters “zjzy” is given the value “base64_decode” and the parameter “liiy” is given the value “create_function”. Notice how instead of using the str_replace function directly, the parameter “tsdg” is used in order to evade detection.
Next, there are four other parameters in lines 1, 3, 4, 5 that contain a base64 encoded text. In line 8, the values of these four parameters are concatenated in a specific order to form a long string encoded in base64. The parameter “iuwt” in line 8 will contain the following line of code:
This code will create a function that removes all the “hd” from the base64 encoded text and then decode it. In line 9, this function is executed and the base64 encoded text is decoded to:
This is the backdoor itself. This backdoor will execute code sent to the compromised server through the cookie. In line 6, the value sent through the cookie is changed using the preg_replace function and two regular expressions. The altered text is then base64 decoded and is executed, running an arbitrary code that the attacker sent.
The evasion techniques in this backdoor are more complex than what we saw in the previous section. Here, on top of using parameters instead of PHP functions, the backdoor itself is decoded in base64. Additionally, to avoid a simple base64 decoding mechanism, the base64 text is split into four parts, and the characters “hd” are added at random places to prevent the text from being decoded as is.
The O and 0 Catch
In the next backdoor the evasion techniques are even more sophisticated, requiring more steps to be made in order to find the actual backdoor:
Again, the only two visible known functions are “urldecode”, which is used in line 1 to decode a URL, and “eval” which is used in line 7. The decoded URL is just gibberish but used in later steps for character concatenation as seen in previous evasion methods.
All the parameter names are made of a combination of zeroes and capital O’s. Since these two characters are visually similar, it makes it extremely hard to read and understand the code. Each such parameter is assigned with a string using character concatenation from the previously decoded URL. The parameter values are:
Line 3 – ‘strtr’
Line 4 – ‘substr’
Line 5 – ‘52’
Line 2+6 – concatenated together to form ‘base64_decode’
Finally, in line 7, a long text encoded in base64 is being decoded and then executed using the previously defined ‘base64_decode’ parameter. The decoded text is:
This is not the backdoor itself but just another step of evasion. Here, the previously defined parameters of the O’s and 0’s are being used once more.
Line 1 contains another long text encoded in base64, but this time the decoding is more complex and cannot just be decoded as is. Replacing the parameters in line 2 with their values gives the following line of code:
Where the remaining O’s and 0’s parameter is the encoded base64 text from line 1. This command takes the portion of the encoded text with the offset of 104, it then creates a map to the first 52 characters from the second 52 characters of the encoded text and replaces them character to character using the strtr function. Then, the manipulated text is being base64 decoded and executed using the eval function. It is impossible to decode the text without using the above-mentioned map. Finally, the text is decoded to the actual backdoor:
Now the attacker’s real intentions are revealed. The purpose of this backdoor is to create a new HTML form containing an “input” tag which enables the attacker to upload a file. Then, the attacker can upload a file of his choice and the backdoor moves it to a directory specified by the attacker inside the compromised server. The backdoor also indicated whether the file was move successfully to the desired folder by printing an appropriate message.
Summary of evasion techniques
As seen in the examples above, attackers are doing their best to hide their malicious code and evade detection. Some of the techniques we saw in our data that attackers are using are:
- Hiding known PHP function using string manipulations (replacement, concatenation, reverse, shift and split)
- Using obscure parameter names, like random characters or combinations of the characters O and 0 which are visually similar
- Encoding the backdoor, or part of its code with base64 encoding
- Using compression as a mean to hide the backdoor code
- Obfuscating base64 encoded text by manipulating the text in order to avoid simple decoding
- Obfuscating requests sent to the backdoor after it was uploaded by using the “preg_replace” function on the input
Suggestions for Mitigation
There are a couple of infection points where a backdoor attack can be mitigated.
First, at the upload point of the backdoor. This is the best spot to stop the backdoor as it happens before it is even uploaded to the compromised server. Usually, the upload of a backdoor is done using a known vulnerability, most of the times by exploiting a or an unauthorized file upload. Organizations using servers vulnerable to RCE vulnerabilities are advised to use the latest vendor patch. An alternative to manual patching is virtual patching. Virtual patching actively protects web applications from attacks, reducing the window of exposure and decreasing the cost of emergency patches and fix cycles.
Second, while uploading the backdoor, the uploaded code itself can be checked for malicious content. Checking the code can be complicated as attackers obfuscate their code so it could not be understood, and usually, there is not much clear code when looking at the code as is. Using static security rules and signatures may result in limited success. Instead, Other dynamic rules include profiling the normal behavior of the application and alerting any deviations from the profiled behavior.
Third, if the backdoor was already uploaded on an infected server, it is possible to block the communication between the attacker and the backdoor. This method stops the backdoor from working and alerts the server admin, so the backdoor can be removed.