Lemon's blog

PHP危险函数总结

Record my learning process of PHP.

字数统计: 1.3k阅读时长: 5 min
2019/08/14 Share

前言:PHP中有很多危险函数,如phpinfo() ,这次就来详细总结一下PHP中的危险函数,并借助大师傅们的例子来进行代码审计的练习。

一、PHP代码执行函数

eval()函数

定义和用法:

eval() 函数把字符串按照 PHP 代码来计算.
该字符串必须是合法的 PHP 代码,且必须以分号结尾。

这个用法就会产生漏洞,通过一个例子来看一下:

1
2
3
4
5
6
7
8
9
<?php
$var = "var";
if (isset($_GET["arg"]))
{
$arg = $_GET["arg"];
eval("\$var = $arg;");
echo "\$var =".$var;
}
?>

输入:http://127.0.0.1/1.php?arg=phpinfo()就会发现已经执行了eval函数
在这里插入图片描述
再输入一串字符串,让eval()函数作为命令执行

1
2
http://127.0.0.1/1.php?arg=var_dump(scandir('./'))
#scandir()函数列出./(当前)目录中的文件和目录:

在这里插入图片描述
除此之外,还可以结合system()函数来获取当前运行的服务的信息

1
http://127.0.0.1/1.php?a=system("net start");

在这里插入图片描述
这就是为什么这个函数是危险函数的原因了,将只要是合法并且符号PHP语法的字符串都可以进行解析,当然这里举的例子都是没有任何防护的,一般eval函数都是被加了黑名单的,但是如果存在这样的漏洞,真的会造成很严重的后果。

assert()函数

定义和用法:

assert ( mixed $assertion [, Throwable $exception ] ) : bool
assert() 会检查指定的 assertion 并在结果为 FALSE 时采取适当的行动。
判断一个表达式是否成立。返回true or false。
如果 assertion 是字符串,它将会被 assert() 当做 PHP 代码来执行。

一般情况下,黑名单都会禁用eval()函数,所以用assert来代替eval来执行具体操作。

例如:

1
assert("phpinfo()")  <=>  <?phpinfo()?>

与eval函数的区别:

1
assert()把整个字符串参数当php代码执行,eval()把合法的php代码执行。

preg_replace()函数

定义和用法:

preg_replace 函数执行一个正则表达式的搜索和替换。
preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] ) : mixed

正常来说preg_replace()函数是用于正则表达式的,但preg_replace 函数也可能会导致命令执行。

如果subject 中有 pattern 的匹配则preg_replace/e 修正符会将 replacement 参数当作 php 代码,并且以 eval 函数的方式执行。

通过一个简单的例子来看一下该函数的用法:

在这里插入图片描述
输入payload:

1
2
3
?pat=/test/e&rep=phpinfo()&sub=jutst test
也可以为
?pat=/test/e&rep=var_dump(`net user`)&sub=jutst test

在这里插入图片描述

create_function()函数

定义和用法:

string create_function ( string $args , string $code )
函数作用:从创建一个匿名函数传递的参数,并返回一个唯一的名称

下面通过一个例子来了解一下这个函数

1
2
3
4
5
6
7
8
9
<?php
error_reporting(0);
$sort_by = $_GET['sort_by'];
$sorter = 'strnatcasecmp';
$databases=array('1234','4321');
$sort_function = ' return 1 * ' . $sorter . '($a["' . $sort_by . '"], $b["' . $sort_by . '"]);';
usort($databases, create_function('$a, $b', $sort_function));
?>
#usort() 使用用户自定义的比较函数对数组进行排序

首先构造出匿名函数的原型:

1
2
3
4
function test($a,$b)
{
return 1 * ' . $sorter . '($a["' . $sort_by . '"], $b["' . $sort_by . '"]);
}

构造payload:

1
http://localhost/test/1.php?sort_by='"]);}phpinfo();/*

在这里插入图片描述
传入后便可以得到:

1
return 1 * strnatcasecmp($a[""]);}phpinfo();/*"], $b[""]);}phpinfo();/*"]);

可以看到构造的语句中注释符/*将后面"], $b[""]);}phpinfo();/*"]);这一段给注释掉了

此时匿名函数就变成了

1
2
3
4
5
function test($a,$b)
{
return 1 * strnatcasecmp($a[""]);
}
phpinfo();

因此可以注入成功

call_user_func函数

定义和用法:

mixed call_user_func ( callable $callback [, mixed $parameter [, mixed $… ]] )
第一个参数 callback 是被调用的回调函数,其余参数是回调函数的参数。

通过一个例子来了解一下这个函数:

1
2
3
4
5
<?php
$filter= 'assert';
$value = 'phpinfo()';
call_user_func($filter, $value);
?>

这里$filter作为回调函数进行调用,phpinfo()则是是回调函数的参数,所以可以执行命令
在这里插入图片描述

二、命令执行函数

exec()函数

定义和用法:

exec — 执行一个外部程序

shell_exec()函数

定义和用法:

通过 Shell 执行命令,并将执行结果作为字符串返回。

passthru()函数

定义和用法:

允许执行一个外部程序并回显输出,类似于 exec()。

escapeshellcmd()函数

定义和用法:

escapeshellcmd() 对字符串中可能会欺骗 shell 命令执行任意命令的字符进行转义。
escapeshellcmd ( string $command ) : string

在DVWA中练习命令注入就会了解以上函数,这里就不再举例。
DVWA_命令注入

三、包含函数

require()
include()
require_once()
include_once()

这些包含函数在之前的博客中也有过介绍,这里就不阐述了
DVWA——文件包含

四、文件操作函数

copy()————————拷贝文件
file_get_contents()———将整个文件读入一个字符串
file_put_contents()———将一个字符串写入文件
file()—————————-把整个文件读入一个数组中
fopen()————————打开文件或者url
move_uploaded_file()—-将上传的文件移动到新位置
readfile()———————-输出文件
rename()———————重命名一个文件或目录
rmdir()————————删除目录
unlink & delete()———–删除文件

读取:可以读取配置等文件
写入:可以写入shell代码相关的内容

总结:这次了解了PHP常用的一些危险函数,下次就通过做题将这些函数用于实践。

参考博客:
常见危险函数及特殊函数
PHP代码命令注入小结

CATALOG
  1. 1. 一、PHP代码执行函数
    1. 1.0.1. eval()函数
    2. 1.0.2. assert()函数
    3. 1.0.3. preg_replace()函数
    4. 1.0.4. create_function()函数
    5. 1.0.5. call_user_func函数
  • 2. 二、命令执行函数
    1. 2.0.1. exec()函数
    2. 2.0.2. shell_exec()函数
    3. 2.0.3. passthru()函数
    4. 2.0.4. escapeshellcmd()函数
  • 3. 三、包含函数
  • 4. 四、文件操作函数