今天第一次学习TP的反序列化,参考文章:ThinkPHP3.2.3反序列化链子分析
步骤和参考文章一样,这里增加一些自己的思考。
首先是建立反序列化子链的入口
这里通过base64传输并解码,然后进行反序列化,一般反序列化的调用是通过类销毁时调用的析构函数,所以全局搜索__destruct。
像这种虽然有可控参数 ,但是第一参数很少,第二没有什么实际的作用,所以应该找参数比较多的。
这种我们可以将类赋值给$this->img,并且调用对应类的destroy()方法 。因此需要
找到合适的destroy()方法,接下来就是寻找destroy.。
( 这里关于原文中参数可控不可控我并没有看太懂,以我的理解只能以为 $this->sessionName可控,sessID并不控,如果有大神可以帮忙解释一下。)然后Memcache中的$this->handle可控,所以接下来就寻找可以操作的delete方法。
这个方法,$option貌似不可控,但可以看到在下边的if判断中只判断其为空的情况,所以不传入值,也会进入if判断,而其中的$this->data,$this->pk都是可控的,所以还会调用delete本身。于是可以看下边的代码。
在519行,该方法调用了$this->db的delete方法,其中$this->db可控,之前的代码中只有507行的_parseOptions对option做了处理,但是也并没有很好的过滤,所以我们进入底层delete方法中实际执行的代码看一下是否存在过滤处理,并且如何执行sql的。
这里通过parseTable进行处理,但是没有过滤,所以可以使用。
总结:反序列化链子首先要明确我们要执行的操作,然后通过查找魔术方法,一步步查找合适的执行方法(最好可控变量比较多的),然后进行调用 。