在PHP中,有一些函数被认为是比较危险的,因为它们可能导致代码执行漏洞。在进行PHP代码审计时,我们需要重点关注这些函数,以确保应用程序的安全性。
以下是一些常见的危险函数和语句:
- eval()
- assert()
- preg_replace()
- call_user_func()
- call_user_func_array()
- array_map()
- a(b)
- system()
- exec()
- shell_exec()
- passthru()
- popen()
- 反引号
PHP代码执行语句
eval语句
eval()
函数将符合PHP语法规范的字符串作为PHP代码执行。
示例代码如下:
// eval.php
$code = $_REQUEST['code'];
eval($code);
要绕过对eval()
语句之前进行的过滤(例如过滤了单双引号),可以使用以下方法:
- ASCII编码
?code=eval(chr(115).chr(121).chr(115).chr(116).chr(101).chr(109).chr(40).chr(39).chr(119).chr(104).chr(111).chr(97).chr(109).chr(105).chr(39).chr(41).chr(59));
- BASE64编码
?code=eval(base64_decode(c3lzdGVtKCd3aG9hbWknKTs));
说明: 虽然可以以函数的方式调用eval(),但是eval()不是PHP的函数,是一种语法结构,不能动态调用。在eval()执行的字符串要以分号结束。
其他命令执行的方式:
?code=phpinfo();
?code=${phpinfo()};
?code=xiu;phpinfo();
?code=?>xiu IS HANDSOME<?php phpinfo();
?code=eval(phpinfo());
assert函数
assert()
将字符串作为PHP代码来执行。
示例代码如下
// assert.php
$code = $_REQUEST['code'];
assert($code);
说明:
assert()
只能执行单条PHP语句。assert()
是一个函数,可以动态调用。- 在高版本的PHP中,
assert()
已被弃用。
preg_replace函数
preg_replace()
函数用于对字符串进行正则匹配后替换。
示例代码如下:
搜索$subject
中匹配$pattern
的部分,以$replacement
进行替换。
// preg_replace.php
$code = preg_replace('~i~', 'I', 'xiu');
$code = preg_replace('~\[(.*)\]~e', '\\1', '[phpinfo()]');
echo $code;
说明:
preg_replace()
函数的第一个参数是正则表达式,'e'是正则表达式的修饰符。
call_user_func
call_user_func()
函数用于调用用户指定的可调用函数。
示例代码如下:
function add($a, $b) {
return $a + $b;
}
$result = call_user_func('add', 1, 2);
echo $result; // 输出:3
// call_user_func.php
$func = 'assert';
$arg = "phpinfo();";
call_user_func($func, $arg);
array_map
array_map()
函数将回调函数作用到给定数组的所有元素上。
例如,有一个数组 $arr1=array(1,2,3,4,5);
,我们想要将每个数加上2并存储到另一个数组$arr2
中,可以使用array_map
:
function addTwo($n) {
return $n + 2;
}
$arr1 = array(1, 2, 3, 4, 5);
$arr2 = array_map('addTwo', $arr1);
print_r($arr2); // 输出: Array ( [0] => 3 [1] => 4 [2] => 5 [3] => 6 [4] =>