PHP中有一个非常古老的安全漏洞,它涉及在单个主进程共享多个PHP-FPM池的环境中处理OPCache的方式。这是现在运行PHP的最常见方式,也可能会对您产生影响。

漏洞

PHP有一种加速其解释器动态特性的方法,称为字节码缓存。PHP在每个页面加载中进行解释,这意味着PHP被转换为服务器理解并可以执行的字节码。由于大多数PHP页面不会每秒都更改,因此PHP会将该字节码缓存在内存中,并将其作为响应提供,而不必 每次都编译(“ 解释 ”)PHP脚本。

在默认的PHP-FPM设置中,进程树如下所示。

php-fpm:master 进程(/etc/php-fpm.conf)
\ _ php-fpm:pool site1(uid:701)
\ _ php-fpm:pool site2(uid:702)
\ _ php-fpm:pool site3 (uid:703)

有一个PHP-FPM主进程以root用户身份启动。然后,它会生成额外的FPM池,每个FPM池都可以作为自己的用户运行,以便为网站提供服务。PHP OPCache(字节码缓存)保存在主进程中。

所以这就是问题所在:PHP在从内存中获取脚本并存储在其字节码中时不会验证用户ID。PHP中“共享内存”的概念意味着所有内容都存储在同一个内存段中,并且包含一个文件时只检查字节码中是否已存在某个版本。

如果脚本的某个版本存在于字节码中,则无需额外检查即可提供。

如果字节码中不存在脚本版本,则FPM池(作为非特权uid运行)将尝试从磁盘读取它,并且Linux将阻止从该进程无法访问的文件中读取。

解决方案:升级PHP并设置其他配置

经过很久的时间,此错误现已解决,您可以在PHP.ini中配置进行修复。

$ cat /etc/php.d/opcache.ini 
... 
opcache.validate_permission(默认为“0”)
       引导OPcache检查每次访问缓存文件时的文件可读性。
       当少数用户(PHP-FPM池)重用公共OPcache共享内存时,应在共享主机环境中启用此指令。

opcache.validate_root(默认为“0”)
       此指令可防止不同“chroot” 环境中的文件名冲突。应该为可能在
       不同“chroot”环境中提供请求的站点启用它。

opcache.validate_permissionopcache.validate_root的引入意味着您现在可以强制PHP的OPCache也检查文件的权限并强制验证文件的根路径,以避免chrooted环境读取每个人的文件(更多信息)在原来的错误报告)。

但是,即使升级了PHP版本,如果使用其默认设置也是不安全的。

我理解为什么它们这样,为了保持与以前版本的兼容性并避免破坏次要版本的更改。

如果你必须在升级PHP版本后,再设置opcache.validate_permissionopcache.validate_root为启用才管用 !!

修复版本:PHP 5.6.29,7.0.14,7.1.0

这个修复没有得到太多关注,只是在有人发布oss-security邮件列表后才注意到它。要解决这种情况,至少需要升级到以下版本;

任何低于5.6的东西都已经过了生命周期,并且不会得到修复,即使在PHP 5.5中引入了OPCache。您需要最近的5.6或更新的版本才能缓解此问题。

如果您仍然运行PHP 5.5(许多人都这样做)并希望安全,那么最好的办法是运行多个PHP主服务器(每个池一个主服务器)或完全禁用OPCache。

 

间接本地权限升级到root

这一直是PHP的一个长期问题,实际上比第一眼看上去更严重。

如果您设法破坏单个网站(对于PHP中大多数没有更新的CMS,并不是很难),这个共享内存允许您访问所有其他网站,如果他们的网页已经缓存在OPCache中

您可以有效地使用此共享内存缓冲区作为读取其他网站的PHP文件,读取其配置文件,访问其数据库并窃取所有数据的通道。为此,您通常需要root访问服务器,但PHP的OPCache为您提供了一个方便的快捷方式来完成类似的事情。

您所需要的只是文件的路径,可以通过opcache_get_status()检索(如果启用,恩,默认是),或者您可以猜测路径,这在共享托管环境中通常并不难。

这实际上使得此共享内存体系结构几乎与本地权限提升漏洞一样糟糕,具体取决于您要完成的任务。如果您的目标是从通常需要root权限的服务器窃取数据,那么您就可以获得它。

如果你的目标是实际获得root并运行root-only脚本(也就是:在较低端口上绑定等),那将是不可能的。

好的消息是,在新的PHP版本中通过配置现在已经提供修复项了。坏消息是,您需要更新到最新版本才能获得它并且明确启用它才可以修复。

其他来源

参看:

本文地址:http://blog.p2hp.com/archives/5808 转载请注明来自lenix的博客。

解决PHP的一个长期存在的通过Opcache泄漏敏感数据的问题。
标签: