Zend框架反序列化漏洞复现分析
1. 环境安装
composer下载
composer create-project zendframework/skeleton-application
然后进入目录 php -S 0.0.0.0:8099 -t public 启动
修改module/Application/src/Controller/IndexController.php
生成poc,poc.php
发送请求,环境搭建成功
2. 漏洞分析:
查看POC
根据POC进行分析
1. Zend\Http\Response\Stream
__destruct方法中的unlink,unlink函数的第一个参数为String类型,如果$this->streamName为一个类,即可触发__toString
方法
2. Zend\View\Helper\Gravatar
根据$a = new Zend\Http\Response\Stream($b);
对Zend\View\Helper\Gravatar进行分析
__toString调用了getImgTag方法,跟进getImgTag
跟进setSrcAttribForImg
发现attributes参数可控,跟进htmlAttribs
$this->getView(),发现$view可控
也就是我们可以控制$this->getView(),
3. 根据$b = new Zend\View\Helper\Gravatar($c);
$this->getView()则为new Zend\View\Renderer\PhpRenderer
类,跟进PhpRenderer,PhpRenderer有plugin方法
跟进getHelperPluginManager,
$__helpers也是可以控制的
也就是$this->getHelperPluginManager()可以控制
3.$c = new Zend\View\Renderer\PhpRenderer($d);
$b为Zend\Config\ReaderPluginManager。跟进
ReaderPluginManager,该类中没有get方法,但是该类继承AbstractPluginManager,跟进AbstractPluginManager,get方法
Has方法的$name为escapehtml,$name 为escapehtml,$options不可控只能为空,所以$instance从parent:get取值,跟进parent:get
因为$escaper = $this->getView()->plugin('escapehtml'); $escapeHtmlAttr = $this->getView()->plugin('escapehtmlattr');
所以$this->services需要有2个key, $this->services = ["escapehtml"=>$services,"escapehtmlattr"=>$services];
根据 $d = new Zend\Config\ReaderPluginManager($e);
$e为$e = new Zend\Validator\Callback(); 所以
也就是$this->services需要为Zend\Validator\Callback,继续跟进validate,![]()
$this->instanceOf可控,需要为Zend\Validator\Callback()
$escaper为Zend\Validator\Callback(),key 为1调用的时候会自动调用,__invoke,
然后调用isValid。跟进isValid