string
shell_exec
(
string
$cmd
);
等同于执行系统命令行。不能用于检测命令是否执行成功。因为出错或者命令本身不产生输出,对于不产生输出的命令就无法检测是否执行成功。如果有这方面的要求,可以使用exec代替这个函数。
string
exec
(
string
$command
[,
array &$output
[,
int &$return_var
]] )
exec函数只会输出输出结果的最后一行,并不能完整的输出结果。推荐用system函数
把字符串转码为可以在 shell 命令里使用的参数
string
escapeshellarg
(
string
$arg
)
shell 元字符转义
string
escapeshellcmd
(
string
$command
)
escapeshellcmd()
对字符串中可能会欺骗 shell 命令执行任意命令的字符进行转义。 此函数保证用户输入的数据在传送到
exec()
或
system()
函数,或者
执行操作符
之前进行转义。
passthru函数常用于输出图像。因为这个函数可以输出原始的二进制流信息。
如果想对执行一个命令比popen有更好的控制,那就是使用proc_open函数代替popen函数。主要是proc_open的参数更多。
所以对于进程命令的执行推荐使用proc_open.不过一般服务器为了防止意外,所以与系统有关的函数都是被禁止的。
proc_open相关函数的运用
最后来讲一个使用这个系统函数escapeshellcmd过滤之后仍然会产生的一个漏洞:
php escapeshellcmd多字节编码漏洞解析及延伸
试验过程:
正常情况下:
$e = escapeshellcmd($_GET[
'c'
]);
// here we don't care if $e has spaces
$result = system( "echo $e " );
// here we don't care if $e has spaces
$result = system( "echo $e " );
echo
$result;
在浏览器地址栏输入:xxxxx.php?c=loveshell%bf;id;
输出的结果是
如果加入一行代码putenv(“LANG=zh_CN.GBK");
// GBK编码下就会出问题
putenv( "LANG=zh_CN.GBK" );
$e = escapeshellcmd($_GET[ 'c' ]);
// here we don't care if $e has spaces
$result = system( "echo $e " );
putenv( "LANG=zh_CN.GBK" );
$e = escapeshellcmd($_GET[ 'c' ]);
// here we don't care if $e has spaces
$result = system( "echo $e " );
echo
$result;
输出结果就是
l
loveshell縗 uid=99(nobody) gid=4294967295 groups=4294967295
这个id命令就执行了。
这个问题和那个escapeshellcmd无关。因为这个和linux对不同编码下面对php的参数理解不一样。