防止 Apache/PHP 运行影响另一个 vHost 的代码

Posted

技术标签:

【中文标题】防止 Apache/PHP 运行影响另一个 vHost 的代码【英文标题】:Prevent Apache/PHP from running code that affects another vHost 【发布时间】:2018-11-10 22:28:03 【问题描述】:

情况

我的/var/www/ 目录中有多个文件夹。

创建的用户可以控制特定目录.../var/www/app1 属于 app1:app1www-dataapp1 组的成员)。

这对我想要的效果很好。

问题

如果 app1 用户上传了一个 php 脚本,该脚本更改了 app2s 目录结构中某些内容的文件/文件夹权限,Apache 进程(因为服务器上只安装了一个)将非常乐意运行它,因为它具有访问/var/www/app1 /var/www/app2 文件夹和文件的必要权限。

编辑

据我所知,/var/www/app1/includes/hack.php:

<?php
chmod("/var/www/app2", 777);
?>

Apache 进程(由www-data 拥有)将运行它,因为它有权更改/var/www/app1/var/www/app2 目录。用户app1之后就可以cd /var/www/app2rm -rf /var/www/app2等,这显然不好。

问题

如何避免 Apache 进程的这种交叉污染?我可以指示 Apache 仅运行影响驻留在相关 vHost 根目录及以下目录中的文件/文件夹的 PHP 脚本吗?

【问题讨论】:

我已更新问题以澄清我试图描述的问题。根据:php.net/manual/en/function.chmod.php - 似乎在安全模式下编译 php 会做我所追求的,但我正在寻找一个简单的实现来不断滚动我自己的 php。 @Nic3500 - 这不是重复的。那是指文件/文件夹权限,这个问题是关于跨目录 apache/php 脚本的。如果有的话,它是以下内容的副本:PHP - a different open_basedir per each virtual host 【参考方案1】:

虽然 open_basedir 会有所帮助,但有几种方法可以绕过此限制。虽然您可以破坏 php 中的许多功能以关闭所有后门,但更好的解决方案是停止以有权访问所有文件的用户身份执行 php。为此,您需要为每个虚拟主机使用带有单独进程池/uid/gid 的 php-fpm。

您仍然应该有一个单独的 uid 用于 php 执行与拥有文件的 uid 具有一个公共组,允许对文件进行默认的只读访问。

您还需要有单独的会话数据存储目录。

更精细的机制是在每个所有者的容器前面使用 Apache 流量服务器,每个站点在其自己的 Apache 实例上运行 - 更好的隔离性,但技术要求更高,资源密集度更高。

请记住,如果您使用 mariadb 或类似工具,DBMS 也可以读取和写入任意文件 (SELECT INTO OUTFILE.../LOAD DATA INFILE)

更新

通过将 php-fpm uid appX 的主目录设置为 vhost 的基本目录(应该包含而不是 document_root -见下文)并使用 apparmor 来限制对公共文件(例如 .so 库)和 @HOME 的访问。因此,每个 /var/www/appX 可能包含:

 .htaccess
 .user.ini
 data/ (writeable by fpm-appX)
 html/ (the document root)
 include/
 sessions/ (writeable by fpm-appX)

【讨论】:

我目前正在使用 php-fpm。所以我需要为每个 rootDir (/var/www/app1) 和用户 (app1) 创建一个单独的池,将新的 fpm-pool uid fpm-app1 添加到 gid app1,类似于目录=0770 和文件=0640? 那是兔子(是的),但 0750 是 dirs 我也在使用 MariaDB...关于如何填补这个漏洞的任何想法? 我相信(至少LOAD DATA)需要file 权限,只有rootmysql_ADMINISTRATOR(或其他默认用户被称为)拥有该权限。其他所有用户都没有,也只能访问自己特定的数据库(每个根目录/var/www/app1等,都有自己的db)。 只要 mariadb 用户不是任何 appX 组的成员,他们就无法读取具有 0640 权限的文件或写入具有 0750 权限的目录。如果您选择详细说明/完善我的建议,我只是强调它作为一个考虑因素。【参考方案2】:

您应该在每个站点的 vhost 文件中添加一个 open_basedir 指令。 open_basedir 指令限制站点可以访问的目录。

您可以阅读有关 open_basedir here 的更多信息。

【讨论】:

所以,如果我理解正确,我可以在相关的vhost.conf 文件中使用类似:php_admin_value open_basedir /var/www/app1/,这样可以防止这种恶意代码? 仅以您发布的恶意代码为例。不是,例如 shell_exec('/bin/chmod 777 /far/www/app2') 我实际上在我的php.ini 文件中有:disable_functions =exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source,所以这不是什么大问题。 因此,只要您在 pcre 中使用没有 eval 修饰符的 php 版本,不使用 IMAP 扩展,禁用 sendmail_path 并禁用 htacess 覆盖,那么我需要花一些时间考虑如何破坏您的系统(例如上传自定义 .so 文件并在其上调用 dl())。限制访问的正确方法是使用权限。 @Jack_Hu,是的,添加这将限制 Apache/PHP 代码的访问。 Symcbean 是正确的,还有其他机会绕过限制,但您已经禁用了其中的大部分(如果不是全部)。

以上是关于防止 Apache/PHP 运行影响另一个 vHost 的代码的主要内容,如果未能解决你的问题,请参考以下文章

安装双系统如何防止木马病毒影响其他磁盘

卡巴斯基将 C# 应用程序检测为特洛伊木马病毒 (VHO:***.MSIL.Convagent.gen)

apache 如何设置能实现:正常浏览目录结构(包括虚拟目录)和下载文件,但又禁止PHP,ASP==的运行?

防止github管道受到影响

如何防止方法跨多个线程运行?

另一个工作簿中的更改会影响主工作簿中的 UDF