我托管的 Wordpress 网站被黑客入侵了。没什么大不了的,通常是favicon_ea9b28.ico
一个包含 PHP 代码的恶意文件。
问题是,在我删除了坏脚本并清理了其他修改过的文件,并将所有插件和主题更新到最新版本后,网站再次遭到黑客攻击。几周以来,这种情况已经发生过好几次了。肯定有一段易受攻击的代码尚未解决。
我如何找到它?我的意思是,PHP 中是否有任何类型的日志记录,用于记录在磁盘上创建新文件的情况?例如脚本 xyz.php 在第 123 行调用fopen('favicon_ea9b28.ico', 'wb')
?
编辑:服务器本身肯定没有受到损害,因为只需从目录中删除运行 php-fpm 的用户的写入权限,并将所有者更改为root
,即可“修复”问题,但随后媒体库将无法使用,因此这不是真正的修复。然而,它确实表明服务器没有受到损害。
鉴于这不是服务器入侵,这不是重复的,因为这个问题假设服务器没有被攻破。无论在我的特定情况下该假设是否正确,我都需要一种方法来处理 PHP Web 应用程序攻破,而不是服务器攻破。
答案1
尝试安装 WordPress 插件“wordfence”,我经常使用它,因为它不仅可以跟踪实时流量,还可以阻止 IP,它还会向您发送有关插件(包括其本身)和整个 WordPress 安装缺少的安全更新的电子邮件。
它还可以扫描 WP 文件并让您了解可疑内容。
您还可以在 Linux 上针对 WordPress 文件手动运行 head 和 tail 命令,或者 grep 所有文件,您需要注意文件中是否存在 base64。这部分更多是用于清理,尽管 wordfence 也会识别类似的东西
答案2
似乎不存在任何 PHP 函数调用的日志记录,但确实存在一种挂钩和记录网站收到的任何 HTTP POST 请求的方法,并且日志记录包括 POST 数据。这样,您甚至可以在调用 fopen 之前获得日志,因此您可以轻松找出受感染的文件。策略是:
- 启用 POST 数据记录
- 等待恶意文件出现
- 查看日志以查找受感染的 PHP 脚本
现在详细说明每一点。
1)启用 POST 数据记录
首先,你需要一个 PHP 脚本,在调用时记录 HTTP POST 数据。从头开始编写一个并不难,但更简单的是使用现有的我稍微修改了一下,使其更具可读性和安全性:
<?php
if ( isset($_POST) && is_array($_POST) && count($_POST) > 0 )
{
$log_dir = dirname( __FILE__ ) . '/logs/';
$log_name = "posts-" . $_SERVER['REMOTE_ADDR'] . "-" . date("Y-m-d-H") . ".log";
$log_entry = gmdate('r') . "\t (local time: " . date('r') . ")\t" . $_SERVER['REQUEST_URI'] . "\n";
foreach ($_POST as $k => $v)
{
if ( $k == "pwd" || $k == "passwd" || $k == "password" || $k == "pass" || $k == "secret" )
{
$v = "*******";
}
$log_entry .= $k." => ".$v."\n------\n";
}
$log_entry .= "\n///////////// END OF POST DATA /////////////\n\n\n";
$fp=fopen( $log_dir . $log_name, 'a' );
fputs($fp, $log_entry);
fclose($fp);
chmod($log_dir . $log_name, 0600);
}
?>
在您的网站根文件夹中创建两个目录,例如postdata/logs
,将脚本保存为postdata/logger.php
并根据您的服务器设置所有者和权限:
root@myserver:/home/user/htdocs/www.example.com# mkdir -p postdata/logs
root@myserver:/home/user/htdocs/www.example.com# vi postdata/logger.php
root@myserver:/home/user/htdocs/www.example.com# chown -R user postdata
root@myserver:/home/user/htdocs/www.example.com# chmod -R a-rw postdata
root@myserver:/home/user/htdocs/www.example.com# chmod -R u+r postdata
root@myserver:/home/user/htdocs/www.example.com# chmod u+w postdata/logs
现在让我们告诉 PHP 必须先运行该脚本。您可以通过添加
php_value auto_prepend_file /home/user/htdocs/www.example.com/postdata/logger.php
到您的网站.htaccess
文件,但是,由于我正在运行忽略的 PHP-FPM .htaccess
,因此我将该配置添加到我的 PHP-FPM 池中:
echo 'php_value[auto_prepend_file] = /home/user/htdocs/www.example.com/postdata/logger.php' >> /etc/php/7.1/fpm/pool.d/user.conf
然后我重新启动 PHP-FPM 守护进程。
2)等待恶意文件出现
这通常只是监控服务器的问题。Munin
当出现问题时,可以自动警告你,也可以手动使用工具(例如find
查找最近更改的文件等)mailq
。例如
$ find . -mtime -1 -iname \*.php
将列出过去 24 小时内修改过的所有 PHP 文件。请注意,CMS 可能进行的自动更新是合法的,它们确实会修改 PHP 文件,因此这些更新可能算作误报。
3)查看日志以查找受感染的 PHP 脚本
cd /home/user/htdocs/www.example.com/postdata/logs
less posts-10.7.33.101-2018-05-01-00.log
如果记录的 POST 数据看起来很奇怪,则可能是向受感染的脚本发送了邮件。您可以在日志文件的第一行找到脚本名称:
$ head -n 1 posts-10.7.33.101-2018-05-01-00.log
Mon, 30 Apr 2018 22:28:40 +0000 /wp-content/plugins/one-page-navigator/admin/bsf-core/irclzkpf.php
没错!这就是我遇到的恶意脚本。我不确定网站中是否还有其他恶意或原创但被感染的脚本,但我只需保留第 1 步,其余一切都轻而易举。
请注意,删除/编辑该脚本是不够的,因为现在攻击者已经使用它来破坏网站中的其他脚本。但是,通过查找base64_decode
函数调用或\\x.*\\x.*\\x.*\\x.*\\x.*\\x
字符序列很容易找到它们。我认为即使 WordFence 的扫描功能也可以找到它们,以防您像我一样运行 Wordpress。
并且,请注意,POST 数据日志文件将以纯文本形式包含任何用户凭据,除了一些常见的密码字段情况,因此我的记录器脚本版本用于chmod
限制对日志文件的访问,但这不符合任何体面的安全措施。采取自己的步骤来限制对 POST 数据日志文件的访问,并在完成后立即删除它们。
答案3
@lucio-crusca 通过记录 POST 数据的回答非常有趣。
除了他的回答之外,我想说的是,当攻击者感染您的服务器时,他们通常(并非总是)创建一个具有执行权限的文件。
下面是查找目录中所有可执行文件的命令:
find /var/www/my-wordpress -executable -type f
您可以重命名这些文件(出于评估目的)或直接删除它们。
#Rename
find /var/www/my-wordpress -executable -type f -exec mv {} /tmp/wp/{}_back \;
#Delete
find /var/www/my-wordpress -executable -type f -exec rm {} \;
我更喜欢将它移动到/tmp,因为我从 Web 应用程序中删除了该文件但保留它只是为了防止我删除了错误的文件或者我只是想知道如何构建该文件。
此外,设置正确的权限非常重要。我是那些认为 apache 用户(httpd、www-data、apache...)一定不能在服务器上写入任何内容但wp-content/uploads
或您配置的任何公共目录。如果攻击者以 apache 用户身份访问您的服务器,这将防止插件或核心被攻击者修改。我喜欢使用这个脚本设置 Wordpress 权限。
允许www-data
在公共目录中写入,例如wp-content/uploads
不阻止攻击者编写 php 文件并从外部调用它。在这种情况下,使用 apache2 作为 Web 服务器,您可以在公共目录中添加 .htaccess 文件以禁用 php 执行。以下是.htaccess 文件我将其放置在 wp-content/upload 中以避免在公共目录中执行 php。