我试图构建一个可以用于任意代码执行的函数列表。其目的不是列出应该列入黑名单或以其他方式禁止的函数。更确切地说,我希望在搜索受感染的服务器以寻找后门时,有一个易于grep-able的红旗关键字列表。
其思想是,如果您想构建一个多用途的恶意PHP脚本——例如c99或r57这样的“web shell”脚本——您将不得不在文件中的某个位置使用一个或多个相对较小的函数集,以便允许用户执行任意代码。搜索这些函数可以帮助您更快地将数万个PHP文件缩小到需要仔细检查的相对较小的脚本集。
显然,例如,以下任何一种代码都被认为是恶意的(或糟糕的编码):
<? eval($_GET['cmd']); ?>
<? system($_GET['cmd']); ?>
<? preg_replace('/.*/e',$_POST['code']); ?>
等等。
前几天在搜索一个受感染的网站时,我没有注意到一段恶意代码,因为我没有意识到preg_replace可以通过使用/e标志而变得危险(真的吗?为什么会出现这种情况?)还有其他我错过的吗?
以下是我目前列出的清单:
Shell执行
系统
执行
popen
撇号操作符
pcntl_exec
PHP执行
eval
Preg_replace(带/e修饰符)
create_function
包括[_once] /要求[_once](详见mario的回答)
有一个能够修改文件的函数列表可能也很有用,但我想99%的情况下,利用代码将至少包含上述函数之一。但是如果你有一个所有能够编辑或输出文件的函数的列表,把它贴出来,我会把它包括在这里。(我没有计算mysql_execute,因为它是另一类利用的一部分。)
让我们将pcntl_signal和pcntl_alarm添加到列表中。
在这些函数的帮助下,您可以绕过php.ini或脚本中创建的任何set_time_limit限制。
例如,该脚本将运行10秒,尽管set_time_limit(1);
(感谢塞巴斯蒂安·伯格曼的推文和要点:
<?php
declare(ticks = 1);
set_time_limit(1);
function foo() {
for (;;) {}
}
class Invoker_TimeoutException extends RuntimeException {}
class Invoker
{
public function invoke($callable, $timeout)
{
pcntl_signal(SIGALRM, function() { throw new Invoker_TimeoutException; }, TRUE);
pcntl_alarm($timeout);
call_user_func($callable);
}
}
try {
$invoker = new Invoker;
$invoker->invoke('foo', 1);
} catch (Exception $e) {
sleep(10);
echo "Still running despite of the timelimit";
}
我的VPS设置为禁用以下功能:
root@vps [~]# grep disable_functions /usr/local/lib/php.ini
disable_functions = dl, exec, shell_exec, system, passthru, popen, pclose, proc_open, proc_nice, proc_terminate, proc_get_status, proc_close, pfsockopen, leak, apache_child_terminate, posix_kill, posix_mkfifo, posix_setpgid, posix_setsid, posix_setuid
PHP有足够多的潜在可破坏函数,您的列表可能太大,grep无法处理。例如,PHP有chmod和chown,它们可以用来简单地禁用一个网站。
EDIT:也许您希望构建一个bash脚本,在一个文件中搜索按危险(坏的函数、更坏的函数、永远不应该使用的函数)分组的函数数组,然后计算该文件所造成的危险的相对百分比。然后将其输出到目录树中,并在每个文件旁边标记百分比,如果超过阈值,例如30%的危险。