We usually write a lot about obfuscation methods on Sucuri Labs and here on the blog. Sometimes we write about free tools to obfuscate your code that aren’t that free and we also have an online tool to help decoding the malware you find. But sometimes the malware is not clearly encoded using base64, gzinflate, hex concatenation, string rotation or any of those common functions. That’s the case we are seeing today, a Joomla backdoor hidden inside fake core files being used to manage database input.
Our tools triggered an anomaly on the client’s site structure: /includes/joomla/database/database.php – which contained a hex-encoded string that translated to preg_replace.
Why is that an anomaly? Let me explain:
- /includes/joomla/database/database.php is not part of Joomla 2.5.8 (outdated version that was running on the client site)
- Joomla core files don’t use this encoding method.
What if this is a valid file, created by the client to manage his Joomla database? It’s possible. I’ve seen so many CMS core files modified to attend client’s needs that it’s always good to check first.
The first few lines are like any Joomla core file. Nice comments, getInstance function… Then it gets weird. What are all those variables badly indented that are storing other vars?… functions? Something is smelling bad here.
Form of the Functions
Scrolling around I found some other functions, variables, hex encoded strings, then a very strange concatenation:
First thing on my mind was to check the output of it. Maybe the malware is in there somehow and – based on the content of the variables – it’ll store a lot of things in the database? But…
Concatenated results is just a diversion to keep an analyst occupied trying to understand what it all means. But not now – I have better things to do than read this crazy db code. Maybe later. It depends if it’s going to be used anywhere else. So, keep it and move on.
Investigated a little deeper and found this:
Deobfuscated At Last
Here we can see that $new_stats is being called by a function which is stored in another variable. You know what? Let’s make things easier to read:
First we see a new variable: $_state. I moved it from another part of the code to give you a clearer picture of what is happening.
Remember all the functions that I said are commonly used to obfuscate malware? Yep, the malware author used almost all of them in one line!
The code is getting the content of HTTP_SCHEME server variable (which is not logged by default, unless you use a module… and have infinite storage space… or want to keep only recent logs, who knows?) and processing it to use later.
Next it gets the array created from $_validate and perform a translation of $new_stats using strtr function. Since we don’t have the array sent through HTTP_SCHEME, it’s hard to tell if the content of $new_stats is the malicious code being executed later in that preg_replace or if it is completely overwriting the variable content with a new one. I hope it is stored in the variable. It’s prettier that way.
The last line of code, as I mentioned before is executing the base64 decoded content of that translation.
A Note on Preg_replace with e
This regex modifier e used in the preg_replace regex will be removed on PHP 7.0.0 (THANK YOU!) – In case you are wondering what it does, here is the reference from the php.net manual:
If this deprecated modifier is set, preg_replace() does normal substitution of backreferences in the replacement string, evaluates it as PHP code, and uses the result for replacing the search string. Single quotes, double quotes, backslashes (\) and NULL chars will be escaped by backslashes in substituted backreferences.
You see the problem, right? This is a function that our remediation team looks for every day while cleaning hacked websites.
Everyday malware is becoming harder and harder to spot. Attackers are storing malware inside the database, encrypting it, or even coding it like it is a core file. Do a health check on your site now and then check what files were added or modified and be paranoid, just a little bit.