【问题标题】:Prevent Apache/PHP from running code that affects another vHost防止 Apache/PHP 运行影响另一个 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

标签: php apache permissions vhosts


【解决方案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 是正确的,还有其他机会绕过限制,但您已经禁用了其中的大部分(如果不是全部)。
猜你喜欢
  • 2021-06-16
  • 2014-12-18
  • 2010-12-09
  • 1970-01-01
  • 2013-08-04
  • 2016-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多