天天看點

PHP反序列化(執行個體)

執行個體

在反序列化過程中,其功能就類似于建立了一個新的對象(複原一個對象可能更恰當),并賦予其相應的屬性值。如果讓攻擊者操縱任意反序列資料有可控的反序列化點, 那麼攻擊者就可以實作任意類對象的建立,如果一些類存在一些自動觸發的方法(魔術方法),那麼就有可能以此為跳闆進而攻擊系統應用。

挖掘反序列化漏洞的條件是:

1. 代碼中有可利用的類,并且類中有__wakeup(),__sleep(),__destruct()這類特殊條件下可以自己調用的魔術方法。

2. unserialize()函數的參數可控。

代碼:

<?php
class A{
    var $test = "demo";
    function __destruct(){
        @eval($this->test);
    }
}
$test = $_POST['test'];
$len = strlen($test)+1;
$p = "O:1:\"A\":1:{s:4:\"test\";s:".$len.":\"".$test.";\";}"; // 構造序列化對象
$test_unser = unserialize($p); // 反序列化同時觸發_destruct函數
?>      

這裡可控的反序列化點在$p,來構造序列号的對象,最後反序列化$p回調__destruct()函數,我們注入payload,需要對$test

的值進行覆寫,可以用hackbar來改。

PHP反序列化(執行個體)

這是控制序列化的點,比如可以直接改$p 在__destruct方法執行eval之前就把變量$test的值替換成payload了。

<?php
class test{
    var $test = '123';
    function __wakeup(){
        $fp = fopen("flag.php","w");
        fwrite($fp,$this->test);
        fclose($fp);
    }
}
$a = $_GET['id'];
print_r($a);
echo "</br>";
$a_unser = unserialize($a);
require "flag.php";
?>           

這是通過魔術方法__wakeup把test的值寫入flag.php中,調用unserialize()反序列化時候會調用__wakeup(),構造payload:

PHP反序列化(執行個體)

然後再id處注入就可以了,在執行unserialize()方法時會觸發__wakeup()方法執行,将傳入的字元串反序列化後,會替換掉test類裡面$test變量的值,

将php探針寫入flag.php檔案中,并通過下面的require引用實作代碼執行.