某商城系统反序列化漏洞
0x1 漏洞分析
漏洞文件:
/module/Shopfront/src/Shopfront/Controller/ BrandController.php
68行将sort_c参数进行base64解码,然后进行了反序列化操作。
该cms采用的是ZendFramework 2 框架,版本是2.4
我们看一下phpggc里面有没有相关的payload
有一个版本号大于2.0.1的payload,我们生成一下
测试
发现代码执行成功
0x2 poc构造
当然利用工具构造poc很方便,但是我们尝试一下自己构造,能够更清楚的理解到这条反序列化利用链的构造
这条利用链先是调用的是\Zend\Log\Logger的__destruct函数
遍历了writers,再调用它的shutdown方法。
这里选择的是\Zend\Log\Writer\Mail类的shutdown方法
184行进入函数
遍历$numEntriesPerPriority,然后会触发$numEntries的__toString方法
\Zend\Tag\Cloud类
调用render方法
然后调用了getTagDecorator方法返回对象的render方法
\Zend\Tag\Cloud\Decorator\HtmlCloud
先判断$tag是否为数组,然后implode处理,传出wrapTag方法
171行获取到了$escaper对象,接着满足一些条件进入到$escaper对象的escapeHtmlAttr方法。
\Zend\Escaper\escaper
在166行进行了preg_replace_callback处理,采用的是$this->htmlAttrMatcher方法。我们设置为\Zend\Filter\FilterChain 类的filter 方法
这里先进行了针对对象的clone操作,再遍历了$chain,依次传入到call_user_func函数中,再对$valueFiltered值进行处理后又会传回到$valueFiltered进行下一个$filter方法的处理,也就是我们只需要调用一个类的一个可以返回我们可控字符串的方法,就可以使$valueFiltered变量可控。
这里采用的是\Zend\Json\Expr类的__toString方法,返回我们指定的字符串
然后再对返回字符串进行处理。
也就是传入的$chain要是数组格式,$chain[0][0]= \Zend\Json\Expr这个类,$chain[0][1]=__toString,也就是要执行的方法,$chain[1]就是我们要执行的函数,比如assert。
这里有一个问题,就是我们传入数组的话,clone会出错,就不能进入到代码执行的步骤。所以得采用和数组相当的一个类。这里采用的是SplFixedArray类解决了这个问题。
那我们根据一些特定条件以及漏洞触发链,自己构造一个poc
生成poc
测试