应用有时需要调用一些执行系统命令的函数,当服务器没有严格过滤用户提供的参数时,就有可能导致用户提交恶意代码被服务器执行,从而造成命令执行漏洞。
代码层过滤不严
系统的漏洞造成命令注入
调用的第三方组件存在代码执行漏洞
(1) system ()
该函数会把执行结果输出,并把输出结果的最后一行作为字符串返回,如果执行失败则返回false
示例:
";
system($cmd);
echo "
";
?>
(2) passthru ()
此函数只调用命令,并把运行结果原样地直接输出,该函数没有返回值。
示例:
";
passthru($cmd);
echo "
";
?>
(3) exec()
不输出结果,返回执行结果的最后一行
示例:
";
echo exec($cmd) ;
echo "
";
?>
(4) shell_exec()
不输出结果,返回执行结果
使用反引号(``)时调用的就是此函数
示例:
";
echo shell_exec($cmd) ;
echo "
";
?>
Windows和Linux都支持的命令连接符:
cmd1 | cmd2 只执行cmd2
cmd1 || cmd2 只有当cmd1执行失败后,cmd2才被执行
cmd1 & cmd2 先执行cmd1,不管是否成功,都会执行cmd2
cmd1 && cmd2 先执行cmd1,cmd1执行成功后才执行cmd2,否则不执行cmd2
Linux还支持分号(;) ,cmd1 ; cmd2 按顺序依次执行,先执行cmd1再执行cmd2
1、尽量少使用执行命令的函数或者直接禁用
2、参数值尽量使用引号包括
3、在使用动态函数之前,确保使用的函数是指定的函数之一
4、在进入执行命令的函数/方法之前,对参数进行过滤,对敏感字符进行转义
由于服务器对危险函数过滤不严,导致用户输入的一些字符串可以被转换成代码来执行,从而造成代码执行漏洞
用户能够控制函数输入
存在可执行代码的危险函数
这两个函数都可以将输入的字符串参数作为PHP程序代码来执行。
eval()
的参数必须是合法的php代码,所以必须以分号 ;
结尾。
assert ( mixed $assertion [, string $description ] )
如果assertion是字符串,它将会被 assert() 当做 PHP 代码来执行。
示例1:
常见的动态执行函数:
call_user_func()
call_user_func_array()
array_map()
这三个函数的作用是可以调用其他函数。
mixed call_user_func ( callable $callback [, mixed $parameter [, mixed $... ]] )
callback:要回调的函数
parameter:要向callback函数中传入的参数
mixed call_user_func_array ( callable $callback , array $param_arr )
callback:要回调的函数
param_arr:要向callback函数中传入的参数,以数组形式
array array_map ( callable $callback , array $array1 [, array $... ] )
callback:要回调的函数
array1:数组,遍历运行 callback 函数
示例:
";
call_user_func_array('show', array("333", "444"));
?>
mixed preg_replace ( mixed pattern, mixed replacement, mixed subject [, int limit])
此函数可以用来执行一个正则表达式的搜索和替换。
$pattern: 正则表达式匹配的内容
$replacement: 用于替换的字符串或字符串数组。
$subject: 要搜索替换的目标字符串或字符串数组。
当$pattern存在 /e
模式修正符,允许代码执行
示例1:
1、尽量不要执行外部的应用程序或命令
2、使用自定义函数或函数库来替代外部应用程序或命令的功能
3、将执行函数的参数做白名单限制,在代码或配置文件中限制某些参数