In part 1 of this series on PHP malware, we learned what a web shell is and looked at some basic examples. Basic web-shells are not too difficult to find since there are only so many commands that can be used to execute a string as a shell command.
However, most attackers would not include a basic web shell such as the ones discussed in the first video. They know it would be much too easy to find and dwell time would be short. Instead the attacker will encode or encrypt the malware so it is more difficult to find. Also, there is an important difference between encrypting and encoding. Before we look at some more advanced ways to hide malware, let’s understand the difference between these two terms.
What is Encoding?
Encoding refers to the process of converting data from one form to another. Encoding does not normally imply that the encryptor is trying to hide or protect the contents from being discovered. Therefore decoding is usually a simple process once you know how the data has been encoded and some encoding schemes are easy to guess by looking at the data. For example, Mp3 and WAV are both standard audio encoding formats, and similarly JPEG, PNG, and GIF are all image encoding formats.
Another common encoding format is Base64. It’s an effective way to encode binary data that needs to pass through a firewall, web-application firewall (WAF), or other appliance that might not allow special characters because base64 encodes any binary data into only human readable characters. If someone does not know that the data has been encoded, it may look like random letters and numbers.
Base64 can be used to hide text, or code from being easily searched for or read in human readable language, although it doesn’t do a great job of hiding it because the same input will always have the same base64 output, and also because security malware hunters already know to look out for base64 encoded data. So, if you are searching an application’s source code for the string ‘eval(’ in order to hunt down any potential web shells, you can also search for the string ‘ZXZhbCg=’ to include its base64 equivalent.
What is Encrypting?
On the other hand, encryption refers to converting the data into a cipher-code, (also known as cipher-text) which is meant to maintain confidentiality of the data and prevent unauthorized access. This requires a known algorithm or standard process to be used so that the cipher-text can be returned to plain-text by (and hopefully only by) the authorized person.
Other Types of Obfuscation
So, to recap, the main purpose of encoding is not hide the data’s contents, but it can serve that purpose, while the purpose of encryption is always to hide. However, there are other ways to obfuscate some code from being easily discovered. In the next part of this series on PHP malware, we will cover some other types of obfuscation found in documented PHP malware samples.
Samples of Malware Payload Obfuscation
Simple Base64 Encoding of a Malware Payload
This could be accomplished by base64 encoding the malicious code and then using the eval() function to ‘evaluate’ that code. ‘Evaluate’ refers to assigning the PHP code to a string variable, and then using the eval() function to run that variable containing the code as though it was simply inline code. By base64 encoding the code first, then decoding it right before it is run, the function calls in the base64 encoded string cannot be directly searched for in the website’s source code.
Reverse the Base64 Encoded String
Since base64 itself does not scramble or rearrange the code in any way, a malware hunter could search the entire source code for the base64 encoded strings of all the system command functions in PHP mentioned in Part 1 of this series just as easily as searching for the system command functions themselves. So, this isn’t really a bulletproof way to mask your malware payload.
A slightly more advanced way attackers can better hide the payload is to scramble the base64 using another function. Alternatively, we could simply use a function such as PHP’s strrev() which would reverse the order of the base64 encoded string. This is slightly more hidden than using only base64 encoding. But, I’ve got news for you, attackers are more sophisticated than this!
ROT13 the Base64 Encoded Malware String
For example, an attacker can use a very simple encryption algorithm called a ROT13 cipher or Caesar Cipher. Instead of reversing the string, this merely offsets each character in the string by 13 characters. This can be done using the str_rot13() function in PHP. You will probably recognize this device below, which is used to decipher the letters of the alphabet that have been encoded with a ROT cipher.
Translate the Base64 Encoded Malware String
Another way an attacker could scramble the base64 payload string is to use strtr() which would replace certain characters in the base64 encoded string.
Avoid Using eval() Function by Using File Inclusion
To avoid using the eval() function the payload can be dumped into a temporary file, included using the include() or require() function, and then deleted again after it has been included into the inline code. This means the threat hunter cannot find the malware by analyzing all the source code inclusions of the eval() function and instead must consider the use of all include() and require() function statements. By combining this attack strategy with an obfuscated base64 string, the attack is harder to find.
AES Encryption of PHP Malware
Then, when an attacker wants to insert the web-shell source code, it is decrypted, stored into a temporary file, the file Is then included using either the PHP ‘include’, or ‘require’ function. After the code has been run, the file containing the decoded malware is deleted. This is called a staged payload.