目录
一、背景介绍
程序员使用脚本语言开发应用的过程中,脚本语言的开发十分快速,但是也伴随着一些问题。比如速度慢。如果我们开发的应用 ,特别是企业级的一些应用就需要去调用一些外部程序。当web应用需要调用一些外部程序是时就会用到一些执行系统命令的函数。
二、漏洞成因
应用在调用这些函数执行系统命令的时候,如果将用户的输入作为系统命令的参数拼接到命令中执行,在没有过滤的情况下就会造成命令执行漏洞。
三、相关函数
system(args)有回显
passthru(args)有回显
exec(args)回显最后一行必须用echo输出
反引号``
popen(handle,mode)无回显
proc_open('cmd','flag','flag')无回显
四、system函数利用
1.
<?php
system($_GET[1], $status);
var_dump($status);
可以看到状态返回码,成功为0,失败为1.
<?php
$arg = $_GET['cmd'];
if($arg) {
system("$arg");
}
?>
2.and(&&) 和or(||)
<?php
$arg = $_GET['cmd'];
if($arg){
system("ping $arg");
}
?>
在终端值行命令使用特殊符号带来不同结果
&&:
左true 右true;两边都执行
左false 右true;都不执行,反之左边执行
左false 右false ;都不执行
||:
左true 右true;执行左边
左false 右true;执行右边
左true右false ;执行左边
左false 右false ;都不执行
|:
左true 右true;优先执行右边的命令
左false 右true;都不执行
左true右false ;都不执行
左false 右false ;都不执行
&:
左true 右true;两边都执行
左false 右true;右边执行
左true右false ;执行左边
左false 右false ;都不执行
用&符号注意用URL编码
<?php
$arg = $_GET['cmd'];
if($arg){
system("dir\"$arg\"");
}
?>
<?php
$arg = $_GET['cmd'];
if($arg){
system("echo '$arg'>1.txt");
}
?>
五、passthru函数、exec函数
<?php
passthru($_GET[1], $stat);
var_dump($stat);
?>
也返回状态码,类似于system
<?php
exec($_GET[1]);
?>
此时是不返回任何值的,(回显最后一行,必须用echo输出
<?php
echo exec($_GET[1]);
?>
<?php
exec($_GET[1], $stat);
var_dump($stat);
?>
想打印所有结果传递第二个参数,参数是引用传递自动填充一个数组
六、popen、proc_open函数
popen打开进程文件指针,打开一个指向进程的管道,该进程由派生给定的command命令执行而产生的。
<?php
$a = popen($_GET[1], 'r');
while ($line = fgets($a)){
echo $line;
}
?>
?php
$des = array(
0 => array("pipe", "r"),//标准输入
1 => array("pipe", "w"),//标准输出
2 => array("file", "./error-output.text", "a")
);
$a = proc_open($_GET[1], $des, $pipes);
var_dump($a);
//echo stream_get_contents($pipes[1]);
while ($b = fgets($pipes[1])){
echo $b;
}
?>
stream_get_contents 读取流中的内容
七、漏洞利用
如果有写权限的话
1、反弹shell,尝试提权
2、执行pwd绝对路径,写一句话木马:
?cmd=echo ^</?php phpinfo()?^> >/var/www/xxx/xx/info.php
Windows系统中 转义符号是^
八、修复方案
1.不要调用其他程序处理,尽量少用执行命令的函数,并在disable_functions中禁用。
2.对参数进行过滤,escapeshellcmd/escapeshellarg过滤。
escapeshellarg 把字符串转码为可以在shell命令里使用的参数
escapeshellcmd 转义特殊字符
3.参数的值尽量使用引号包裹,并在拼接前调用addslashes进行转义
4.exec()函数中数据,避免用户可控。