What is Detectify?

How-to Tutorial: PHP Webshell De-Obfuscation

May 24, 2019

I would like to introduce you to some obfuscated malicious PHP files that I had recently found on a WordPress website. I’ve written a detailed report on the research and analysis process for the PHP Web Shell Hexedglobals.3793 variants, while this post is a how-to tutorial on the de-obfuscation. 

In this article I will be covering the following:

  1. DeObfuscation Tutorial for the $GLOBALS family of malware.
  2. Automated tool for Deobfuscation

DE-OBFUSCATION TUTORIAL

This tutorial will cover the malware know as: hexedglobals.3793 | Kidslug | php.obfuscated! | php.malware.GLOBALS.003 | php.malware.GLOBALS.004

I have uploaded a sample to my Github repository where you can use to follow along.

1. Un-minify the code

First, we need to try and make the code more understandable, well at least so it was readable to a degree, it was horrendous in its current form. We can do this via Php Beautifier

Before and after code beautification.

Initial Analysis:
As you can see in the picture the structure of the code is now quite prominent. As well as some other pieces of key information I will get to later.

We can see that $GLOBALS [‘tf7ebf’]  is an Array () on the next line tf7ebf is defined as a global variable, then it states $GLOBALS being the value of $tf7ebf.

GLOBALS is used within PHP for specific reasons. If you would like to know more about GLOBALS you can find out more information in this video here Different superglobals in PHP

Basically, it is being used so it can interact with a predefined variable which is defined outside of the scope of the function. It’s normally only used in special circumstances so if you do see it appear in code it might warrant further investigation. $GLOBALS is used more than once within the malware.
<?php
$u9eee3f = 896;
$GLOBALS['tf7ebf'] = Array();
global $tf7ebf;
$tf7ebf = $GLOBALS;
{
"\x47\x4c\x4fB\x41\x4c\x53"
}

2. De-obfuscation part 1 – Converting the Hex

My next step was to convert the hex strings to find its value.  You can convert the hex string in an online decoder or echo out the value using php as shown below. This confirmed that it was another GLOBALS.

3. De-obfuscation part 2 – Translating its alphabet

Moving down into the main block, we can see in the code the l94b537e is repeated as well as tf7ebf.

What I initially saw was the pattern of variables being repeatedly used. In addition to this, the use of numbers.

We have the long string of hex being assign to l94b537e. Taking this into account, my initial thoughts were that the numbers must represent some value in the long hex string (like a key or alphabet to be used) and that each value would be called into the code and included.

So we will need to convert the long hex to ASCII to see what was being represented by the numbers:

['l94b537e'] = "\x5e\x71\x7c\x43\x7a\x6a\x23\x6d\x26\x2d\x44\x3c\x34\x27\x66\x52\x38\x4
a\x29\x6f\x63\x35\x59\xa\x51\x7e\x22\x3f\x6b\x2c\x65\x68\x61\x37\x4e\x9\
x73\x3b\x76\x4d\x42\x7d\x7b\x55\x79\x4b\x56\x39\x2f\x77\x6c\x75\x6e\x2b\
x78\x3d\x49\x4c\x24\x62\x21\x46\x31\x3a\x2a\x54\x70\x74\x45\x4f\x47\x64\
x28\x5c\x2e\x30\x5d\x5b\x5f\x60\x3e\x67\x53\x32\x36\x69\x40\x5a\x20\x41\
x57\x25\x58\x48\xd\x50\x33\x72";
$tf7ebf[$tf7ebf['l94b537e'][81] . $tf7ebf['l94b537e'][96] . $tf7ebf['l94b537e'][62] . $tf7ebf['l94b537e'][62] .
continues ...

Once again we can echo this out.

This then gives us a long line of characters.

An alternative is to use a site such as UnPHP which will  give us the same output.

Alphabet Obfuscation breakdown:
Our alphabet is completely random, but I assumed that once called in the right order they would become readable variables.

['l94b537e'] = "^q|Czj#m&-D<4'fR8J)oc5Y\xaQ~" ? k, eha7N\x9s;vMB} {    UyKV9 / wlun + x = IL $b!F1 : *TptEOGd(\.0][_`>gS26i@Z AW%XH\xdP3r";

I would need to do a string replace, so for every number it would look up the corresponding character.  

I wrote a very basic PHP script which just printed out the values of each hex value given in the array as ASCII values and give it an index. Sidenote – I had to do some basic tinkering adding quotation marks for it to work.


<?php $array = array ("\x5e","\x71","\x7c","\x43","\x7a","\x6a","\x23","\x6d","\x26","\x2d","
\x44"
,"\x3c","\x34","\x27","\x66","\x52","\x38","\x4a","\x29","\x6f","\x
63"
,"\x35","\x59","\xa","\x51","\x7e","\x22","\x3f","\x6b","\x2c","\x65"
,"\x68","\x61","\x37","\x4e","\x9","\x73","\x3b","\x76","\x4d","\x42","\
x7d"
,"\x7b","\x55","\x79","\x4b","\x56","\x39","\x2f","\x77","\x6c","\x7
5"
,"\x6e","\x2b","\x78","\x3d","\x49","\x4c","\x24","\x62","\x21","\x46"
,"\x31","\x3a","\x2a","\x54","\x70","\x74","\x45","\x4f","\x47","\x64","
\x28"
,"\x5c","\x2e","\x30","\x5d","\x5b","\x5f","\x60","\x3e","\x67","\x
53"
,"\x32","\x36","\x69","\x40","\x5a","\x20","\x41","\x57","\x25","\x58
"
,"\x48","\xd","\x50","\x33","\x72");
print_r($array);

?>

This gave me the result:
Array
(
   [0] => ^
   [1] => q
   [2] => |
   [3] => C
   [4] => z
   [5] => j
   [6] => #
   [7] => m
   [8] => &
   [9] => -
   [10] => D
   [11] => <
   [12] => 4   continues to ...    [97] => r

We now have our alphabet coming together and corresponding number.

So, what you can do now is manually go through the script and update each number with its corresponding letter or you can write a script to help! Manually de-obfuscating is a simple process but can be a time intensive. To help aid you through to de-obfuscation process and save you time I have created a script which automates for this malware family.

Automated Method – Variable Names Alphabet Soup Script! – Python
The fantastic @iamrasting helped me put together a python script which takes the hex and replaces our alphabet correctly to the right numbered variable. This takes a lot of pain away from the process. It’s called Alphabet Key and will print to console the numbers replaced by letters.

I have then built upon this to create Alphabet Soup to take in a webshell PHP file, de-obfuscates and outputs a text file where everything has been de-obfuscated and ready for viewing in its altered state.   Depending on what version you use you may need to still do an iteration of find and replace with the now viewable variables defined at the start of the code.

The script can be found on Github here.

For the purpose of the tutorial and so you can understand what is happening under the hood I will show how to progress manually with the find and the replace. This shows you how to do it without the tool. If you use the above tool it will help cut down the time spent by creating the list of variables required to be further used for find and replace iteration.  You may want to take a look at the Sample-GLOBALS which has the Sample file with all the variables converted to $GLOBALS required in order to run the script alphabet key script.

Manual Method – Variable names
With the use of the alphabet created from the array we need to look at the first section of code and repeat with each section.  

 

 

$tf7ebf[$GLOBALS[‘l94b537e’][81] . $GLOBALS[$GLOBALS[‘alph’][g]
$tf7ebf[‘l94b537e’][96] . . $GLOBALS[‘alph ‘][3]
$tf7ebf[‘l94b537e’][62] . . $GLOBALS[‘alph’][1]
$tf7ebf[‘l94b537e’][62] . . $GLOBALS[‘alph’][1]
$tf7ebf[‘l94b537e’][20] . . $GLOBALS[‘alph’][c]
$tf7ebf[‘l94b537e’][12]] . $GLOBALS[‘alph’][4]]
= =
$tf7ebf[‘l94b537e’][20] . $GLOBALS[‘alph’][c]
$tf7ebf[‘l94b537e’][31] . . $GLOBALS[‘alph’][h]
$tf7ebf[‘l94b537e’][97]; . $GLOBALS[‘alph’][r];

We know that $GLOBALS = $GLOBALS so I have replaced all instances of this in the table also.

We know that ‘l94b537e’ is refers to the alphabet so I have replaced that with alph.

Now looking at this code it now starting to make a bit more sense. The next iteration of changes is to remove the references of $GLOBALS and alpha that are not required. Because from looking at the code, it has become apparent that these were only needed to reference the alphabet, look up the value and append. Now we know the value we can remove.

 

 

$GLOBALS[$GLOBALS[‘alph’][g] $GLOBALS[g]
. $GLOBALS[‘alph ‘][3] [3]
. $GLOBALS[‘alph’][1] [1]
. $GLOBALS[‘alph’][1] [1]
. $GLOBALS[‘alph’][c] [c]
. $GLOBALS[‘alph’][4]] [4]]
= =
$GLOBALS[‘alph’][c] [c]
. $GLOBALS[‘alph’][h] [h]
. $GLOBALS[‘alph’][r] [r]

It should start looking a little bit like this below. We will need to continue stripping the spaces and the “[‘  ‘]” characters away. It will start to come together as you start removing the characters not required.

Once we have done this our first line converts to:

$GLOBALS g311c4=chr;

4. De-obfuscation part 3 – Find and Replace

There are many replacements to make throughout the file.

I would suggest doing the next part in sections to save you removing or replacing code that could be needed. Best way I have found to do this is in notepadd++ and select the code that needs to be edited and then go through removing all the unneeded such as the ‘ and brackets [ ] .

You will then be able to do a find and replace with the deobfuscated variable names defined at the top of the code.

So where we had $GLOBALS g311c4 = chr; We can now search through the code for g311c4 and replace with “chr”. There will still be some variables with odd names, but you can replace with meaningful names to help you read the code better.

You should then start to see what the code is doing and being able to make sense of the behaviour.

Conclusion

What has been covered in the tutorial section should give you some understanding towards manual de-obfuscation and give you a good grounding on the steps to take the next time you come up against some obfuscated malware which you may need to manually de-obfuscate.  A tool has been created to help with this process and to check your obfuscated code against.

The analysis of this code and it’s overall behaviour is covered in the Investigation of the $GLOBALS PHP Malware.  (link to next article)

If you are reading this because you have found similar on your server here are some handy links to help remove and prevent in the future

https://codex.wordpress.org/FAQ_My_site_was_hacked
https://codex.wordpress.org/Hardening_WordPress

Shoutouts:

Tall Panda, @timmehwhimmey @duniel_pls @bufferofStyx for giving thoughts and suggestions during early stages.

@iamrasting – For reviewing original script created and contributing to the  script that can be used to assist in de-obfuscating this type of malware Alphabet Key.  


 

Written by:
5w0rdFish
Security Researcher
Visit her blog