使用 Runkit 实现简易的 PHP 后门检测

这是今天在帮某大检查他被黑的机器的时候想出的歪门邪道。
原理很简单,就是把 PHP 原有的函数改名,然后用自己的函数替换掉那个原来的函数。

啊,首先呢,你必须要有 root 权限~ 用虚拟主机的同学们请自觉做鸟兽散。

Runkit 在 PECL 的版本非常老,最新的版本居然是 2006-06-06 年的。
当然老没有关系,有些发行版就喜欢用老的东西,以及大部分虚拟主机用户还喜欢用 PHP 5.2 甚至更老的版本呢。不过这个例外,由于版本太老了所以连在 PHP 5.2 上都跑不了,所以我们要去 GitHub 上下最新的开发分支。

1
2
3
4
5
6
7
cd /tmp
git clone https://github.com/zenovich/runkit.git
cd runkit
phpize
./configure
make
make install

然后在 php.ini 里加上相关条目:

1
2
3
[runkit]
extension="runkit.so"
runkit.internal_override = On

找不到 php.ini 在哪儿的,请在 Web 目录下放置如下文件,然后用浏览器打开就能看到咯:

1
2
<?php
echo php_ini_loaded_file();

当然呢,对于蛋疼的 DirectAdmin 用户,我们还需要在 php.ini 里把 extension_dir 修改为 /usr/local/bin/php-config --extension-dir 所显示的目录才行。

然后找个地方放下这个文件,我是放在了 /usr/local/lib/php/security.php,下文也以此为例子。
注意的是:

1. 必须去掉这个文件的写权限,不怕死的可以不去掉。
2. 开启了 **open_basedir** 选项的,这个文件需要放置在 **open_basedir** 里面所列出的目录里,不然会出错。
3. 请把 `/tmp` 换成其他可写的日志目录,或者换成 syslog 什么的。

再修改 php.ini,找到 auto_prepend_file 这行,改为:

1
auto_prepend_file = /usr/local/lib/php/security.php

最后重启 apache 进程即可看到效果啦~ 日志是介个样子的

1
2
3
4
5
6
================
URI = /login.php
Client = 125.33.92.240
Header = Location: index.php
Backtrace = /home/xxxxxx/domains/xxxxxx.net/public_html/global.php:354:header
/home/xxxxxx/domains/xxxxxx.net/public_html/login.php:45:ObHeader