1. 程式人生 > >php序列化漏洞理解

php序列化漏洞理解

觸發 lean 自動 就是 bool http alt his const

0x01什麽是序列化

序列化就是將我們的 對象轉變成一個字符串,保存對象的值方便之後的傳遞與使用。 0x02為什麽要序列化 如果為一個腳本中想要調用之前一個腳本的變量,但是前一個腳本已經執行完畢,所有的變量和內容釋放掉了,我們要如何操作呢?難道要前一個腳本不斷的循環,等待後面腳本調用?這肯定是不現實的。serialize和unserialize就是用來解決這一問題的。serialize可以將變量轉換為字符串並且在轉換中可以保存當前變量的值;unserialize則可以將serialize生成的字符串變換回變量。 0x03怎樣產生了漏洞 這些就是我們要關註的幾個魔術方法了,如果服務器能夠接收我們反序列化過的字符串、並且未經過濾的把其中的變量直接放進這些魔術方法裏面的話,就容易造成很嚴重的漏洞了。當傳給 nserialize() 的參數可控時,我們可以通過傳入一個精心構造的序列化字符串,從而控制對象內部的變量甚至是函數。
  • 構造函數__construct():當對象創建(new)時會自動調用。但在unserialize()時是不會自動調用的。
  • 析構函數__destruct():當對象被銷毀時會自動調用。
  • __wakeup() :如前所提,unserialize()時會自動調用。
  • __toString()當一個對象被當作一個字符串使用
  • __sleep() 在對象在被序列化之前運行

0x04如何利用序列化漏洞

unserialize()後會導致__wakeup() 或__destruct()的直接調用,中間無需其他過程。因此最理想的情況就是一些漏洞/危害代碼在__wakeup() 或__destruct()中,從而當我們控制序列化字符串時可以去直接觸發它們。
如果服務器能夠接收我們反序列化過的字符串、並且未經過濾的把其中的變量直接放進這些魔術方法裏面的話,就容易造成很嚴重的漏洞了。 0x05序列化格式
  • String : s:size:value;
  • Integer : i:value;
  • Boolean : b:value;(保存1或0)
  • Null : N;
  • Array : a:size:{key definition;value definition;(repeated per element)}
  • Object : O:strlen(object name):object name:object size:{s:strlen(property name):property name:property definition;(repeated per property)

0x06實例

這裏借用別人的一個很好的例子來說明一下這個問題。我們針對__wakeup()場景做實驗。

建立一個index2的php文件,如下:

 1 <?php
 2 class chybeta{
 3     var $test = ‘123‘;
 4     function __wakeup(){
 5         $fp = fopen("shell.php","w") ;
 6         fwrite($fp,$this->test);
 7         fclose($fp);
 8     }
 9 }
10 $class3 = $_GET[‘test‘];
11 print_r($class3);
12 echo "</br>";
13 $class3_unser = unserialize($class3);
14 require "shell.php";
15 // 為顯示效果,把這個shell.php包含進來
16 ?>

在同目錄下建立一個空的shell.php文件

我們可以看見上面的存在明顯的漏洞,主要是沒有對接受的test參數做處理,unserialize()後直接調用了魔法方法__wakeup(),該方法就將test直接寫入到了shell.php中。因此我們直接給test傳入一個我們精心構造的參數即可利用漏洞了,例如我們可以構造 test=O:7:"chybeta":1:{s:4:"test";s:19:"";} ,即可看到命令被成功執行。

技術分享圖片

這是我個人的第一次寫博客,只是希望自己能通過寫加深自己對知識的理解,同時通過寫博客來增加對自己的要求,博客有很多不足,希望大家多多指正,我會一直努力學習。

php序列化漏洞理解