1、序列化的概念(摘自pikachu平台的介紹)
(1)序列化serialize()
序列化說通俗點就是把一個對象變成可以傳輸的字符串,比如下面是一個對象:
class S{
public $test="pikachu";
}
$s=new S(); //創建一個對象
serialize($s); //把這個對象進行序列化
序列化后得到的結果是這個樣子的:O:1:"S":1:{s:4:"test";s:7:"pikachu";}
O:代表object
1:代表對象名字長度為一個字符
S:對象的名稱
1:代表對象里面有一個變量
s:數據類型
4:變量名稱的長度
test:變量名稱
s:數據類型
7:變量值的長度
pikachu:變量值
(2)反序列化unserialize()
就是把被序列化的字符串還原為對象,然后在接下來的代碼中繼續使用。
$u=unserialize("O:1:"S":1:{s:4:"test";s:7:"pikachu";}");
echo $u->test; //得到的結果為pikachu
序列化和反序列化本身沒有問題,但是如果反序列化的內容是用戶可以控制的,且后台不正當的使用了PHP中的魔法函數,就會導致安全問題
常見的幾個魔法函數:
__construct()當一個對象創建時被調用
__destruct()當一個對象銷毀時被調用
__toString()當一個對象被當作一個字符串使用
__sleep() 在對象在被序列化之前運行
__wakeup將在序列化之后立即被調用
2、反序列化漏洞演示:
1、反序列化漏洞的攻擊原理。
(1)一般反序列化漏洞都是通過代碼審計而發現,一般的黑盒測試是很難發現的。
(2)例如我們通過代碼審計發現了漏洞,我們要測試這個漏洞,那么我可以根據站點后台的邏輯進行payload的生成。
(3)我們將生成的payload(一串序列號的字符串)通過前台接口發送至后台,后台在創建、銷毀對象的時候會執行魔法函數,比如取出對象的值,那么如果對象的值是一段惡意的js代碼,那么將會被執行。
2、下面開始正式的演示環節。我們先來觀察代碼:
3、我們根據上邊的邏輯進行構建,生成我們的payload。
(1)我們在我們的站點環境根目錄下創建一個PHP文件(我這里是test.php),寫一段我們的PHP代碼如下:
<?php
class S{
var $test = "<script>alert('xss')</script>";
}
echo '<br>';
$a = new S();
echo serialize($a);
?>
(2)我們通過瀏覽器訪問這個文件。
(3)我們查看頁面源代碼,獲得我們的payload。
4、執行下圖中的操作。