最近在整理旧电脑资料,发现之前记录了一个Yii2框架的漏洞复现攻击流程,有点意思,所以重新整理一下。(顺便吐槽Yii3这都开发设计多久了,进度还在卡脖子)

一、漏洞信息
漏洞编号:CVE-2020-15148
影响版本:Yii2 < 2.0.38
漏洞描述:任意请求调用unserialize()反序列化函数,可进行远程代码执行、Get Webshell等。
参考:CVE-2020-15148 Record
二、POP链执行分析
2.1 yii\db\BatchQueryResult
在php中,unserialize()类时会自动执行__wakeup()、__destruct()等魔术方法。Yii2框架的BatchQueryResult类,就使用了__destruct()方法,并且在该魔术方法中,调用了私有属性_dataReader的close()方法。

2.2 _dataReader 伪造成DbSession
这是此次pop链的关键点之一,伪造成DbSession,并覆写writeCallback,当调用close()方法会触发执行。
为什么是DbSession?因为该类继承了MultiFieldSession, 而该类的composeFields方法会执行call_user_func函数调用writeCallback属性。具体看如下代码截图


2.3 覆写writeCallback
writeCallback是一个回调函数,参数是$this,不符合注入预期参数。后面这几层调用目的都是为了可以调用我们传入的字符串函数和参数,实现注入。这里使用yii\rest\IndexAction的run方法来执行。

2.4 覆写checkAccess和id
这条pop链最终使用Alipay\AlipayRequester的execute作为远程代码调用,看看这个类的构造函数就知道为什么选择它了,各项属性都符合预期,可谓是天选之类😆

三、POC
Yii2框架使用也很广泛,拿之前较火的某匠商城来验证,搜索找到使用\Yii::$app->serializer->decode方法,构造序列化数据注入一句话木马,就可以进行POC测试。


Get Webshell

四、修复建议
最佳方式:升级Yii2框架至最新版本
如果无法升级,可以通过以下方式进行修复:
在BatchQueryResult类中增加
1 | public function __wakeup() |
临时修复引用:官方commit
五、总结
这个CVE是2020年的了,官方也早就发布了修复版本,这次算是回顾一下流程,pop链的调用设计还是很巧妙的,所以整理出来。
Yii2作为老牌框架,在一些erp系统、gov项目中都能常常见到它的身影,所以CVE影响还是很大的,至少现在都2025年了,还有很多项目没有进行修复升级。
Yii3估计是等不到了,就算出来了,还能在这新时代下立足吗?不确定。
- 本文作者: 暮秋人
- 本文链接: https://muqiuren.pages.dev/2025/06/yii2-unserialize-pop-attack/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!