1、漏洞原理
代码执行漏洞的核心在于应用程序未能正确验证或过滤用户输入的数据,导致这些数据被直接或间接地解释为可执行代码并运行。
2、示例代码
<?php eval($_GET['CMD']);?>
3、相关函数
assert()函数:
同函数eval相似,只是不需要同eval函数一样执行phpinfo()时加上;分号
代码示例:
<?php
assert($_GET['cmd']);?>
preg_replace函数
该函数有三个参数,用于执行正则表达式的搜索和替换,搜索subject
中匹配pattern
的部分,如果匹配成功以replacement
进行替换
preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )
代码示例:
<?php
$arg = $_GET['cmd'];
@preg_replace("/abc/e",$arg,"abced"); //在字符串abced中匹配abc并用传入的值进行替换,并且传入的值被当作代码来执行
echo $arg;
?>
//pattern 存在 /e 模式修正符,允许代码执行/e 模式修正符,是 preg_replace()将$replacement参数值当做php代码来执行
create_function函数
代码示例
HP中的匿名函数,相当于定义了一个没有名字的函数,该函数直接用变量进行调用。第一个参数参数是函数传递的参数,第二个参数相当于函数中的函数体。
create_function ( string $args , string $code )
<?php
$a = create_function('$arg',$_REQUEST['x']);
?>
需要使用}花括号闭合前面代码,/*注释后面模块;测试使用圆括号等不行,不知道什么原因。
array_map函数
array_map()函数返回用户自定义函数作用后的数组。回调函数接受的参数数目应该和传递给array_map()函数的数组数目一致。
array_map()将调用sum_num()函数,去执行该函数,这也就是上面所说的函数回调。且后面传入的参数要与回调的函数参数数目保持一致。
<?php
highlight_file(__FILE__);
function sum_num($a, $b)
{
return $a + $b;
}
$a = array(22,33);
$b = array(22,33);
var_dump(array_map("sum_num",$a,$b));
//
//$cmd = array_map($_REQUEST['arg1'],array($_REQUEST['arg2']))
?>
call_uesr_func()函数
同array_map有点相似,array_map的回调函数作用的参数是数组,且组内值和调用函数的一直。
第一个参数作为回调函数调用,其余参数是回调函数的参数。
示例代码:
<?php
highlight_file(__FILE__);
$cmd = call_user_func($_REQUEST['arg1'], $_REQUEST['arg2']);
?>
array_filter函数
把输入数组中的每个键值传给回调函数,与call_user_func_array()不同的是,该函数的第一个参数为回调函数的参数,而第二个参数则是传入的回调函数。
当传入的参数可控时就会造成RCE;前端传参正好和call_user_func相反
<?php
highlight_file(__FILE__);
array_filter(array($_REQUEST['arg1']),$_REQUEST['arg2']);
?>
其他的函数还有usort、array_walk等
4、总结
在代码审计中有很多关于代码执行的函数,需要对上面的函数有一定的了解和印象,在实际中再次遇到上述函数时可以马上想起该函数和代码执行或者RCE有关,然后在进一步分析传入的参数是否可控,从而才有可能找到该漏洞。首先要对函数有一定的了解,自己尝试手动敲代码,让自己对这些函数加深一些印象。