安全矩阵

 找回密码
 立即注册
搜索
查看: 4592|回复: 0

Web安全:safe_mode的安全特性

[复制链接]

991

主题

1063

帖子

4315

积分

论坛元老

Rank: 8Rank: 8

积分
4315
发表于 2020-10-17 20:52:35 | 显示全部楼层 |阅读模式
原文链接:Web安全:safe_mode的安全特性

safe_mode即PHP安全模式。简单来说,PHP安全模式就是以安全模式运行PHP代码。PHP的安全模式提供了一个基本安全的共享环境,在一个有多个用户账户存在的PHP开发的Web服务器上,当其上运行的PHP打开了安全模式,那么一些函数将被完全禁止,并且会限制一些可用的功能。当安全模式打开的时候,一些尝试访问文件系统的函数功能将被限制。当安全模式打开时,这些函数的功能将会受到限制:chdir、move u_ploadedfile、chgrp、parse_ini file、chown、rmdir、co_py、rename、fopen、require、highlight file、show__source、include、symlink、link、touch、mkdir、unlink。同样地,一些PHP扩展中的函数也将会受到影响(在安全模式下dl函数将被禁止,如果要加载扩展的话,只能修改php.ini文件中的扩展选项,设置在PHP引擎启动的时候加载)。在PHP安全模式打开的情况下,执行系统程序,必须要在safe_mode_exec_dir选项中指定目录的程序,否则执行将失败,即使允许执行,也会自动地传递给escapeshellcmd函数进行过滤。这些执行命令的函数功能将会受到影响:exec、shell exec、_passthru、system、popen。另外,背部标记操作符(`)也将被关闭。当在安全模式下运行时,虽然不会引起错误,但是putenv函数功能将失效。同样地,其他一些尝试改变PHP环境变量的函数set time limit、set include_path也将被忽略。怎么开启PHP的安全模式呢?在php.ini文件里面设置safe_mode=on就可以了,如图1所示。


图1  设置safe_mode=on

接下来,我们来举例说明。打开php.ini文件,保证safe_mode=on,设置safe_mode_exec_dir,如图2所示。

图2  设置safe_mode_exec_dir

接下来,我们执行exec_cmd.php文件,其代码如下。

<?php
//eg:dir /x ipconfig /all netstat -ano
$a = $_GET['a'];
//非安全执行命令
echo exec($a);
echo shell_exec($a);
echo passthru($a);
system($a);
popen($a.' >> 2.txt','r');
echo '<br />';
//安全执行命令
echo exec(escapeshellcmd($a));
echo shell_exec(escapeshellcmd($a));
echo passthru(escapeshellcmd($a));
system(escapeshellcmd($a));
popen(escapeshellcmd($a.' >> 2.txt'),'r');
echo '<br />';
//更安全地执行命令
echo exec(escapeshellarg($a));
echo shell_exec(escapeshellarg($a));
echo passthru(escapeshellarg($a));
system(escapeshellarg($a));
popen(escapeshellarg($a.' >> 2.txt'),'r');
echo '<br />';
?>

在浏览器中输入http://localhost:81/exec_cmd.php?a=dir/x,Web服务器返回信息如图3所示。

图3  返回信息

我们可以看到以下这3行代码执行的时候报错。

echo shell_exec($a);
echo shell_exec(escapeshellcmd($a));
echo shell_exec(escapeshellarg($a));

那么,我们注释掉这3行代码再来执行呢?Web服务器返回信息如图4所示。

图4  返回信息

浏览器无信息输出(说明其他命令也没有被执行,至少没有被成功地执行)。事实上,它的意思已经很明确了,如下。

Warning: shell_exec() [function.shell-exec]: Cannot execute using backquotes in Safe Mode in D:\WWW\exec_cmd.php on line 9
Warning: shell_exec() [function.shell-exec]: Cannot execute using backquotes in Safe Mode in D:\WWW\exec_cmd.php on line 19
Warning: shell_exec() [function.shell-exec]: Cannot execute using backquotes in Safe Mode in D:\WWW\exec_cmd.php on line 29

这是因为我们开启了PHP的safe_mode,才导致shell_exec函数执行报错。如果我们关闭PHP的safe_mode,那么,exec_cmd.php文件肯定是可以正常执行的。在浏览器中输入http://localhost:81/exec_cmd.php?a=dir /x,Web服务器返回信息如图5所示。

图5  返回信息

我们可以看到dir /x命令已经在代码中执行了。在安全模式开启时,可不可能通过safe_mode_exec_dir绕过safe_mode再执行系统命令呢?在PHP安全模式打开的情况下,需要执行系统程序的时候,必须在safe_mode_exec_dir选项中指定目录的程序,否则执行将失败。即使允许执行,也会自动传递给escapeshellcmd函数进行过滤。接下来,我们将safe_mode_exec_dir设置为C:\Windows\System32\,并且safe_mode=on,重新启动Apache使该设置生效,设置如图6所示。

图6  设置safe_mode_exec_dir=C:\Windows\System32\

在浏览器中再次输入http://localhost:81/exec_cmd.php?a=dir /x,Web服务器返回信息如图7所示。

图7  返回信息

我们可以看到dir /x命令依然可以被系统执行。这是因为dir命令所在的目录为C:\Windows\System32\,它是我们在开启safe_mode之后,通过safe_mode_exec_dir设置的一个可执行的目录(即该目录下的PHP代码中的命令函数可以调用cmd执行命令,而不用管safe_mode是否被设置)。这样,我们就算绕过了safe_mode的限制,达到了重新执行系统命令的目的。

接下来,介绍一下命令执行的安全性问题。exec_cmd.php代码里面,使用了两个函数分别调用cmd来执行命令的一些函数,例如exec、shell_exec调用cmd执行系统命令前的参数过滤,这两个函数分别是escapeshellcmd函数与escapeshellarg函数。我们可以通过如下代码来说明一下这两个函数的区别,测试文件为escape_2.php,其代码如下。

<?php
$a = $_GET['a'];
echo '渗透测试输入的原始命令:'.$a;
echo '<br />';
echo 'escapeshellcmd函数作用后:'.escapeshellcmd($a.' >> 2.txt'); echo '<br />';
echo 'escapeshellarg函数作用后:'.escapeshellarg($a.' >> 2.txt'); echo '<br />';
?>

在浏览器中输入http://localhost:81/escape_2.php?a=dir /x,Web服务器返回信息如图8所示。

图8  返回信息

我们由图可知,返回信息如下。

“渗透测试输入的原始命令:dir /x

escapeshellcmd函数作用后:dir /x ^>^> 2.txt

escapeshellarg函数作用后:"dir /x >> 2.txt""。

我们仔细一看,第一个函数用“^”扰乱了“>”,第二个函数使用"将传入函数的参数(即命令)进行前后闭合。没看出什么“所以然”,继续使用不同的测试用例。在浏览器输入http://localhost:81/escape_2.php?a=<>?/-';"\|~`.!,Web服务器返回信息如图9所示。

图9  返回信息

我们由图可知,返回信息如下。

“渗透测试输入的原始命令:<>?/-';”\|~`.!

escapeshellcmd函数作用后:^<^>^?/-^'^;^”^\^|^~^`.! ^>^> 2.tx

tescapeshellarg函数作用后:"<>?/-'; \|~`.! >> 2.txt""。

这里基本上看出点端倪了,原来,eacapeshellcmd函数就是使用“^”把预定义特殊字符扰乱,而escapeshellarg函数将预定义特殊字符里面的双引号过滤掉,强制使用自己的双引号把字符串前后闭合起来。这样的设计似乎比较安全,基本没有什么cmd命令注入(或者bash命令注入),但是会发现,在宽字节的系统中依然存在这样的命令注入。

总结:

(1)safe_mode配置安全使用。

(2)safe_mode_exec_dir配置安全使用。

(3)exec、shell_exec、passthru、system、popen命令函数安全使用。

(4)escapeshellcmd、escapeshellarg过滤函数安全使用。

(5)一句话,安全无绝对(no system is safe)。


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-11-28 10:46 , Processed in 0.013012 second(s), 18 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表