php反序列化漏洞原理,PHP反序列化原理及漏洞解析
什么是PHP序列化
PHP序列化與反序列化的過程
一個反序列化漏洞的例子
CVE-2016-7124
一. 什么是PHP序列化與反序列化
1. PHP序列化
PHP序列化是指把變量轉化成可保存或傳輸的字符串的過程,PHP序列化函數有serialize、json_encode。
以下例子可以實現PHP序列化
1
2
3
4
5
6
7
8
9
10
11
12
13<?php
class test
{
public $name = 'jacky';
public $age = '18';
public $heavy = '81.5';
public $boolean = true;
public $null = NULL;
public $array = array(1,2,3,4,5);
}
$jacky = new test;
echo serialize($jacky);
?>
輸出的結果為
O:4:”test”:6:{s:4:”name”;s:5:”jacky”;s:3:”age”;s:2:”18”;s:5:”heavy”;s:4:”81.5”;s:7:”boolean”;b:1;s:4:”null”;N;s:5:”array”;a:5:{i:0;i:1;i:1;i:2;i:2;i:3;i:3;i:4;i:4;i:5;}}
其中每項的標識所代表的含義
標識
含義
s
字符串(string)
i
整型(integer)
b
布爾(boolean)
d
雙精度(double)
N
空(NULL)
a
數組(array)
同時,序列化過程中還會對不同屬性的變量進行不同方式的變化
public的屬性在序列化時,直接顯示屬性名
protected的屬性在序列化時,會在屬性名前增加0x00*0x00,其長度會增加3
private的屬性在序列化時,會在屬性名前增加0x00classname0x00,其長度會增加類名長度+2
2. 反序列化
PHP反序列是指將經過序列化的數據轉化成原先的狀態,PHP反序列化函數有unserialize、json_decode。
二. PHP序列化與反序列化的過程
1. PHP魔法函數
PHP中包含很多魔法函數,他們可以在某些情況下自動執行而不需要手動調用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16__construct() #類的構造函數
__destruct() #類的析構函數
__call() #在對象中調用一個不可訪問方法時調用
__callStatic() #用靜態方式中調用一個不可訪問方法時調用
__get() #獲得一個類的成員變量時調用
__set() #設置一個類的成員變量時調用
__isset() #當對不可訪問屬性調用isset()或empty()時調用
__unset() #當對不可訪問屬性調用unset()時被調用。
__sleep() #執行serialize()時,先會調用這個函數
__wakeup() #執行unserialize()時,先會調用這個函數
__toString() #類被當成字符串時的回應方法
__invoke() #調用函數的方式調用一個對象時的回應方法
__set_state() #調用var_export()導出類時,此靜態方法會被調用。
__clone() #當對象復制完成時調用
__autoload() #嘗試加載未定義的類
__debugInfo() #打印所需調試信息
2. 如何進行序列化
在對象被序列化之前,會檢查是否有__sleep()函數,如果存在,該函數會清理對象,并返回一個數組,數組中包含被序列化的對象的所有屬性的名稱。如果該方法不返回任何內容,則序列化后的字符串將變為N并提示Notice。__sleep()的預期用途是提交需要掛起的數據或執行類似的清理任務。如果有一個非常大的對象,不需要完全保存其所有屬性,該功能將非常有用。
在反序列化之前,會檢查是否具有__wakeup()魔術方法。如果存在該方法,則在反序列化時執行該方法。__wakeup()魔術方法可以重構對象可能具有的任何資源。__wakeup()預期用途是重新建立在序列化期間可能已丟失的任何數據庫連接,并執行其他重新初始化任務。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39<?php
class test
{
public $value;
function __construct(){
echo "__construct";
echo "
";
}
function __destruct(){
echo "__destruct";
echo "
";
}
function __wakeup(){
echo "__wakeup";
echo "
";
}
function __toString(){
echo "__toString";
echo "
";
return $this->value;
}
function setValue($parm){
echo "setValue";
echo "
";
$this->value = $parm;
}
}
$test = new test;
$test->setValue("Jacky");
$ser_test = serialize($test);
echo $ser_test."
";
$obj = unserialize($ser_test);
echo $obj."
";
?>
1
2
3
4
5
6
7
8
9
10//output
__construct
setValue
O:4:"test":1:{s:5:"value";s:5:"Jacky";}
__wakeup
__toString
Jacky
__destruct
__destruct
3. __autoloading()函數
傳統的PHP只能反序列化定義過的類,意味著每個PHP文件都需要包含很多文件,在當前主流的PHP框架中,都采用了__autoloading()自動加載類來完成這項繁重的工作。在簡化了工作的同時,也為序列化漏洞造成了便捷。
4. 反序列化過程中魔術方法的執行順序
__wakeup()> __toString()> __destruct()
三. 一個反序列化漏洞的例子
右擊查看源代碼,可以看到如下提示
1
2
3
4
5
6
7
8
9
10$user = $_GET["txt"];
$file = $_GET["file"];
$pass = $_GET["password"];
if(isset($user)&&(file_get_contents($user,'r')==="welcome to the bugkuctf")){
echo "hello admin!
";
include($file); //hint.php
}else{
echo "you are not admin ! ";
}
首先我們嘗試將$user的值改為welcome to the bugkuctf,由于使用的是file_get_contents()函數,所以需要使用PHP偽協議來傳入$user的值,payload如下
下一步處理$file的值,可以看到代碼中有文件包含,并提示了所包含的文件時hint.php,這里需要使用另一個PHP偽協議來傳入$file的值,payload如下
將出現的字符通過base64解密,可以得到如下代碼
1
2
3
4
5
6
7
8
9
10
11
12
13<?php
class Flag{//flag.php
public $file;
public function __tostring(){
if(isset($this->file)){
echo file_get_contents($this->file);
echo "
";
return ("good");
}
}
}
?>
可以看到,在flag.php文件中有一個Flag類,此外,我們可以用同樣的方法得到index.php文件中的內容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31$txt = $_GET["txt"];
$file = $_GET["file"];
$password = $_GET["password"];
if(isset($txt)&&(file_get_contents($txt,'r')==="welcome to the bugkuctf")){
echo "hello friend!
";
if(preg_match("/flag/",$file)){
echo "不能現在就給你flag哦";
exit();
}else{
include($file);
$password = unserialize($password);
echo $password;
}
}else{
echo "you are not the number of bugku ! ";
}
?>
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的php反序列化漏洞原理,PHP反序列化原理及漏洞解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php88,php88微博
- 下一篇: comsol matlab 循环,com