How to decode obfuscated PHP files
If you've ever had a website or server hacked, that was serving up PHP files, then you might have come across a file like this:
This is a real life example that reddit user /u/narcissus921 posted about here. Even an experienced programmer can have a hard time discerning what exactly a program like this does. Hackers often obfuscate their code so that you can't decipher how it works. Today I'm going to walk you through how to break this code down so that you can understand what it does and use that knowledge to decipher similarly obfuscated programs.
The first step in this whole process is to format the code to make it more readable. You can use an online PHP formatter or use an IDE, such as phpstorm, to autoformat your code for you. Once the code has been formatted it should look something like this:
It's still not exactly readable, but it's a step in the right direction.
Now, some of you may have noticed there's actually a lot of code in this file that doesn't do anything. Code where operations are performed but no values are assigned, strings without assignment and so on. This is another trick hackers use to throw you off; by adding in random code that doesn't actually do anything.
Our next step is going to be removing that kind of code. It can be a little tricky figuring out whether the code is doing something or not, but an easy guideline to follow is: if there's no assignment ($foo = $bar) or no function call (foo() or $foo()), then we can safely assume the code doesn't affect the program and it can be removed.
A perfect example of what I'm talking about is these 3 lines right here:
After the unused code has been removed your program should now look like so:
The next step is a bit more tedious. We now have to figure out what each of these lines of code does. You'll notice a lot variable assignments where two strings are combined using the bitwise OR “^” operator. These strings are carefully crafted so that when they're combined using the “^” operator they form a coherent and meaningful string value. In order to see what these operations and functions output we're going to evaluate the code line by line using var_dump() within the program. You can use your own PHP environment to evalute the code, or use an online PHP evaluator such as: viper-7.com. As you do this, you'll start to see recognizable string values, function names and so on, being printed out. Also note that, we only want to be evaluating lines of code where an operation occurred such as =, &, ^, etc or a function call was made.
Here's an example of what I mean by going line by line. In this case, I take note of what the variable contains by placing its value in a comment above it.
Here we have our first function call. In PHP you can store function names in a variable and then call that variable like a regular function:
When you come across the if statement, you can comment the “if” line and the closing bracket, in order to evalute the variables within it. After all is said and done our program should now look like this:
Okay we've evaluated all the code and we can see now there's some familiar PHP in the comments. Our second to last step is going to be interpreting what the program does, based on what we have written in the comments above each variable. This part is a little less straight forward and requires some creativity. Also take note that, while some variables were assigned values they may never have been actually used. A second pass will have to be done to remove unused variables.
When we've finished piecing the code together we do one final clean up to really make the code readable. Our final result looks something like below:
Our program has come a long way from its original obfuscated state. There's now recognizable variable names, functions and so on. But, some of you may still be wondering what exactly it is that this program does, so I'll walk you through that too.
You'll notice in the first 2 lines of code the program turns error reporting off, this is to prevent errors from being logged and warnings potentially being displayed to the user. Proceeding that, the program then reads in a hash value from the user's cookies, if the value matches a hard coded hash value, then the program executes the code in the if block. This primitive authentication is done to ensure only the hacker or someone with knowledge of the stored hash value can run certain parts of the program.
Inside the if block, the program attempts to grab the contents of a file stored locally on the server. If the file doesn't exists locally it will attempt to use a text value stored in the user's cookies. It repeats the step again for a second file. Then, it decodes and combines the two file's contents into what is presumably some nasty executable PHP code. The final step is to actually run that code using eval().
As you can see hackers often go through great lengths to mask their intentions and hide their actions. The obfuscation above is just one of the many ways hackers can hide the functionality of their code. Hopefully, you never come across one of these files on your own server. But, if you do, you'll now have the ability do deobfuscate it and learn its innerworkings.