轩辕的编程宇宙公众号文章

PHP漏洞炸锅了,一个编程语言怎么会有漏洞呢?

轩辕的编程宇宙

公众号 · 1 篇文章

大家好,我是轩辕。

昨天晚上,安全圈子里又炸锅了,这一次的主角是PHP,就是那个“世界上最好的编程语言”,PHP 这两天爆了两个严重漏洞。

所有运行PHP网站的运维管理员,这两天估计忙的够呛。

可能很多人纳闷,PHP不是一个编程语言吗,一个编程语言怎么会有漏洞呢?这是啥意思?

今天这篇带你把这个问题搞懂,看看这一次为啥这么严重。

一门编程语言,怎么还会有漏洞

你打开一个网站,点一下登录。

浏览器会给服务器发一个请求,说“我要登录,这是我的账号密码”。

服务器收到以后,得有个程序来处理:密码对不对,从数据库里取数据,再拼成一个网页发回给你。

PHP 就是干这个活的,是一门做网站用的编程语言,用得很广。

大名鼎鼎的 WordPress 就是用 PHP 写的,Drupal、Joomla 也是。

所以 PHP 一出问题,一大片网站都得跟着检查。

那为什么一个编程语言会有漏洞呢?

答案是,PHP 是一门解释执行的语言。

开发者写的 PHP 代码,其实只是一堆文字,电脑自己看不懂,不能直接运行。

得有另一个程序,在运行的时候解析这些代码,把它们编译成内部指令,再执行。

这个程序就叫 PHP 解释器。平时说“升级 PHP”,指的就是升级它。

而解释器也是人写出来的软件,主要用 C 语言写的。是软件,就可能有 bug。

所以这次的漏洞,出在底下负责执行代码的 PHP 解释器里。开发者代码写得再认真,也躲不掉。

为什么连登录页都拦不住

还是刚才点登录的那个请求,看看它到了服务器上是怎么走的。

最先接手的不是 PHP,而是一个叫 Web 服务器的软件,比如 Apache。

静态网页的内容是提前写好的,谁来看都一样,它直接发出去就行。

但登录这种动态网页,得根据你是谁、数据库里查到了什么现场算,它干不了,就交给 PHP 解释器。

怎么交给解释器,有不同的接法。

其中一种叫 mod_php,是把 PHP 解释器当成一个模块,直接装进 Apache 里,在 Apache 的进程里运行。

另一种常见的叫 PHP-FPM,解释器单独跑,Web 服务器把请求转给它。

这次官方点名风险最高的,就是 mod_php 这种接法,下面就按它来讲。

请求交到解释器手里以后,它先把请求里带的数据拆开整理好,比如你填的表单内容、上传的文件。

这一步是解释器自己在干活,跟网站开发者写的代码无关。

然后才开始执行网站的 PHP 代码,比如检查你登没登录,有没有权限,最后把结果发回去。

PHP 官方公告里有一句话:

before any application code runs

意思是,网站自己的代码还没开始跑,攻击就已经发生了。

解释器在第一步就出了事,第二步的登录检查根本没机会执行。

官方已经在 Apache 搭配 mod_php 的环境下,验证过这条攻击路径。

所以才说,连登录页都拦不住。

漏洞一:内存不够用了

这次的两个漏洞,都出在解释器管理内存的环节。

PHP 解释器处理请求的时候,要先在内存里把各种内部结构准备好。

漏洞出在准备到一半,内存突然不够了。

有两种情况:一种是撞上了 PHP 给每个请求设的内存上限,一种是系统那边真的分不出内存了。

解释器里有些代码碰到这种情况,会直接跳出去,不往下做了。

结果有些数据只初始化了一半,成了半成品。

跳出去之后,还得收拾现场,把这次请求用过的东西清理掉。

问题是,清理的时候,把这些半成品当成正常数据去处理了。

本来报个错就完事,结果报错之后的收尾,反倒出了问题。

这怎么就变成被攻击了呢?

因为攻击者能专门构造请求,控制它在什么时候出错,出错时内存里是什么内容。

程序顺着这些错误数据往下走,最后就可能执行攻击者指定的代码。

这就是大名鼎鼎的远程代码执行RCE,攻击者在你的服务器上,执行它的代码。

官方在 mod_php 默认的输入和内存限制下,验证过完整的代码执行。不过能不能稳定利用,还得看具体的 PHP 版本和服务器环境。

所以内存满了本身没事,毛病出在满了之后那段处理逻辑。

漏洞二:内存释放了,又被用了

第二个漏洞更隐蔽一点。

服务器不会每来一个请求,就重新启动一次 PHP 解释器。

通常是开着好几个解释器进程,一直待命,轮流处理请求。

上一个请求处理完,它用的内存就释放掉了。

但某些致命错误,会让进程内部还留着一条记录,仍然指着那块已经释放的内存。

下一个请求进来,同一个进程就可能拿着这条旧记录,去读那块内存。

这叫 Use After Free,释放后使用。

问题在于,那块内存释放之后,系统可能已经把它分给别的数据了。

位置没变,里面的内容却换了,程序还当成旧的在用。

后果轻则崩溃,重则把别的数据读出来,甚至也能被拿去执行代码。

研究人员演示过,能泄露出来的有密码、登录凭证、API 密钥这类敏感信息。

而且这种泄露,不用先拿到代码执行就能做。

网站看着一切正常,数据可能已经漏出去了。

攻击者是怎么发起攻击的

前面讲了两个漏洞,现在把它们串起来,看看攻击者拿它能干什么。

先说一个前提:攻击者不需要账号。

在 mod_php 这种环境下,漏洞在登录检查之前就能触发。只要他能访问到你的网站,就能把请求发过来。

他发的是专门构造过的请求,走的是网站正常的入口,跟普通访客一样。

请求到了服务器,Apache 把它交给 PHP 解释器。解释器开始拆这个请求里的数据,一件件在内存里准备。

这时候,第一个漏洞就有机会了。

攻击者构造的请求,会让解释器在准备到一半的时候,撞上内存不够用。

解释器跳出去,留下一堆半成品。收拾现场的时候,又把半成品当成正常数据来处理。

因为出错的时机和内存里的内容,都是攻击者提前设计好的,程序就会顺着他准备的数据往下走。

走到最后,解释器会去执行攻击者想跑的代码。

代码一跑起来,攻击者就等于能在你的服务器上动手了。

权限只是 PHP 进程的权限,但网站的配置文件、数据库密码、网站文件,基本都够得着。

第二个漏洞走的是另一条路,目标也不一样。

攻击者先发请求,触发那种会留下旧记录的致命错误。

同一个进程接着处理的下一个请求,就会顺着旧记录,去读那块已经释放的内存。

那块内存这时候可能已经装了别的数据,比如密码、登录凭证、API 密钥。

这条路不用拿到代码执行,就能把数据读走,网站全程看着一切正常。

所以两个漏洞,一个能让攻击者在你的服务器上跑代码,一个能让他读走进程里的敏感数据。而且在 mod_php 环境下,都不用先登录。

当然,真要成功,还得看你的 PHP 版本、接法和服务器环境。PHP-FPM 就得借助网站应用自己的代码路径,条件更多一点。

这次的影响有多大

两个漏洞合起来,叫 PHP2Shell,编号是 CVE-2026-109618 和 CVE-2026-109619。

研究人员已经在 WordPress、Drupal、Joomla 上,演示了不用登录就能执行代码。

官方要求所有处理网页请求的 PHP 都检查更新。点名的有 mod_php、PHP-FPM,还有 php-cgi、FrankenPHP、LiteSpeed,说白了都是把 PHP 接到网站上的不同方式。

不同接法下,利用难度不一样。但基金会确认,PHP-FPM 这种接法下,也能通过网站应用自己的代码走到漏洞,实现远程执行。

正式披露之前,消息先泄露了出去,官方只好把原定 10 月 22 日的发布提前了一天。

随后 Cloudflare 观察到了攻击流量,还有人在改攻击内容,想绕过防护。

另外,攻击者拿到代码执行,一般也只是 PHP 进程的权限,不是服务器最高权限。

但网站的配置文件、数据库密码、网站文件,基本都在这个权限够得着的范围里。

话说,你们公司还在用PHP做网站吗?

好了,今天就分享到这里。

如果觉得还不错的话,求个点赞。

路过的朋友欢迎点个关注吧,及时获得下期文章推送~

往期推荐


前往微信阅读全文

内容来自公众号,可前往微信查看原文。

查看作者的更多文章 →订阅更新、RSS 与阅读指南 →