php代碼注入漏洞pHp中的魔法函數(shù)反序列化漏洞原理(2)_php注入代碼

2023-11-28    分類: 網(wǎng)站建設

序列化和反序列化簡介

() 將對象轉(zhuǎn)換為字符串, () 將字符串恢復為對象。在pHp應用中,序列化和反序列化一般用于緩存,比如緩存等。簡單來說,序列化就是將一個對象轉(zhuǎn)換成可以傳輸?shù)淖址葱蛄谢褪怯靡粋€對象替換原來的字符。

簡單示例

';
echo "我是分割線";
$c=unserialize($b); //把序列化后的字符串反序列化
echo '
'; echo $c->suifeng; ?>

下面我們來看看反序列化后輸出字符的含義

第一個輸出是

O:4:"test":1:{s:7:"";s:5:"";}

O->object
4->object的長度
test->object的名稱
1->object中變量個數(shù)
s->變量名數(shù)據(jù)類型
7->變量名長度
suifeng->變量名
S->變量值數(shù)據(jù)類型
5->變量值長度
shuai->變量的值

pHp 其他數(shù)據(jù)類型

a - array
b - boolean
d - double
i - integer
o - common object
r - reference
s - string
C - custom object
O - class
N - null
R - pointer reference
U - unicode string

pHp 常用魔法函數(shù)

() //創(chuàng)建對象時調(diào)用

() //在對象被銷毀之前調(diào)用

() //調(diào)用類中不存在的方法時執(zhí)行

() //調(diào)用類中不存在的靜態(tài)方法方法時執(zhí)行。

() //反序列化后會立即調(diào)用

() //在對象序列化之前調(diào)用

() //對象作為字符串時調(diào)用

() //用于從不可訪問的屬性中讀取數(shù)據(jù)

() //用于將數(shù)據(jù)寫入不可訪問的屬性

() //調(diào)用函數(shù)的方式,調(diào)用對象時的響應方式

() // 在不可訪問的屬性上調(diào)用 () 或 () 來觸發(fā)

() // 當 () 用于不可訪問的屬性時觸發(fā)

,, 序列化對象的區(qū)別

php v7.x在反序列化時對訪問類型不敏感

變量

直接變量名反序列化

變量

\x00 + * + \x00 + 變量名

您可以使用 S:5:"\00*\00op" 代替 s:5:"?*?op"

變量

\x00 + 類名 + \x00 + 變量名

反序列化漏洞的條件

1、函數(shù)的參數(shù)可控

2、后臺使用pHp中對應的魔術函數(shù)

反序列化漏洞原理

讓我們先運行下面的代碼

';
}
function __destruct(){
echo '調(diào)用了析構函數(shù)
'; } function __wakeup(){ echo '調(diào)用了蘇醒函數(shù)
'; } } echo '創(chuàng)建對象a
'; $a=new AbC; echo '序列化
'; $a_ser=serialize($a); echo '反序列化
'; $a_unser=unserialize($a_ser); echo '對象快死了!'; ?>

pHp語言本身的漏洞

還有一個反序列化漏洞是由于pHp語言本身的一個漏洞遇到了某些特征而導致的

示例:導致失敗 (CVE-2016-7124)

php版本

在序列化字符串中,如果代表對象屬性個數(shù)的值大于實際屬性個數(shù),則跳過()的執(zhí)行

序列化問題

當 () 被調(diào)用或 .在php.ini中為1,pHp內(nèi)部調(diào)用會話管理器,將訪問用戶序列化后存放在指定目錄下(默認為/tmp)。

pHp中共有三種序列化處理器,如下:

處理器

對應的存儲格式

php

鍵名+豎線+()函數(shù)反序列化的值

鍵名長度+鍵名+()函數(shù)反序列化的值對應的字符

(php>=5.5.4)

()函數(shù)反序列化處理的數(shù)組

配置文件php.ini包含這些與存儲配置相關的配置項:

.="" -- 設置的存儲路徑,默認為/tmp

。 --指定會話模塊是否在請求開始時啟動會話網(wǎng)站開發(fā),默認為0不啟動

。 --定義用于序列化/反序列化的處理程序的名稱。默認使用php

.="" --設置用戶自定義存儲函數(shù),如果要使用pHp內(nèi)置的存儲機制php代碼注入漏洞,可以使用這個函數(shù)(數(shù)據(jù)庫等),比如存儲為文件默認情況下

并且pHp中默認使用pHp引擎。如果我們要修改到另一個引擎,我們需要添加代碼('.', 'The to be set'),例如:

;

:即元數(shù)據(jù)、壓縮文件的屬性等信息,以序列化方式存儲

:壓縮文件的內(nèi)容

:簽名,放在文件末尾

這里有兩個關鍵點,一個是文件標識符,必須以();?>結(jié)尾,但是對前面的內(nèi)容沒有限制,也就是說我們可以很容易的偽造一個圖片文件或者其他文件來繞過一些上傳限制;二是反序列化。存儲在phar中的元數(shù)據(jù)信息是以序列化的方式存儲的。當文件操作函數(shù)通過phar://偽協(xié)議解析phar文件時,數(shù)據(jù)會被反序列化,這樣的文件操作函數(shù)有很多

先決條件

phar.=Off 在 php.ini 中設置

php >=5.3.0

演示測試

根據(jù)文件結(jié)構,我們自己構建一個phar文件。 pHp 有一個內(nèi)置的 phar 類來處理相關操作

startbuffering();
$phar->setStub(""); //設置stub
$o = new TestObject();
$phar->setMetadata($o); //將自定義的meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要壓縮的文件
//簽名自動計算
$phar->stopbuffering();
?>  

很明顯是以序列化的形式存儲的

如果我們現(xiàn)在通過 phar:// 包裝器對現(xiàn)有的 phar 文件執(zhí)行文件操作,它的序列化元數(shù)據(jù)將被反序列化。這意味著我們在元數(shù)據(jù)中注入的對象被加載到應用程序的范圍內(nèi)。如果這個應用程序有一個命名類并且定義了魔法方法() 或 has(),這些方法將被自動調(diào)用。這意味著我們可以在我們的代碼庫中觸發(fā)任何析構函數(shù)或喚醒方法。更糟糕的是,如果這些方法對我們注入的數(shù)據(jù)進行操作,這可能會導致更多漏洞。

以下是受影響的功能列表

此時可以使用phar://協(xié)議

使用條件

可以上傳phar文件

文件操作函數(shù)的參數(shù)可控,不過濾:,/phar等特殊字符

有一些魔術方法可用作“跳板”

反序列化字符轉(zhuǎn)義

當 pHp 反序列化時,底層代碼使用 ;作為字段分隔符,}作為結(jié)尾(字符串除外),根據(jù)長度判斷內(nèi)容。同時,反序列化過程必須嚴格按照序列化過程進行。成功實現(xiàn)反序列化的規(guī)則。

我們來分析一段代碼

';
echo $c->suifeng;
?>

發(fā)現(xiàn)序列化為O:4:"test":1:{s:7:"";s:5:"";},反序列化也正常進行。當我們修改序列化結(jié)果為 O:4:"test":1:{s:7:"";s:5:"";}i:1;s:4:"test";正常解析。

但是如果我們修改它的長度,就會報錯,比如O:4:"test":1:{s:7:"";s:4:"";}

知道了這個特性,下面我們來分析一下代碼

可以看到反序列化為a:2:{i:0;s:5:"";i:1;s:4:"1234";},當我們修改參數(shù)為 進程首先反序列化$user,然后執(zhí)行函數(shù)中的函數(shù),用它替換test,導致長度不一致,最終導致反序列化失敗。

a:2:{i:0;s:9:"";i:1;s:4:"1234";}

a:2:{i:0;s:9:"";i:1;s:4:"1234";}

假設這個代碼流是創(chuàng)建賬戶的代碼流,此時$可以被用戶控制,那么我們可以通過控制可控參數(shù)使反序列化字符轉(zhuǎn)義。它的本質(zhì)其實和sql注入一樣,雙引號和大括號的閉合,但是反序列化字符的轉(zhuǎn)義需要滿足其特性的一些條件。接下來我們構建它。

因為它是用 ; 嚴格分隔的作為字段并以 } 結(jié)尾(字符串除外),我們可以這樣關閉它。

可以看到我們構造了$=";i:1;s:6:"";},它被序列化為a:2:{i:0;s:29:"";i: 1; s:6:"";}";i:1;s:4:"1234";},經(jīng)過這個序列化后,我們會反序列化它,紅色部分不會進入反序列化。但是可以看到替換后反序列化還是沒有成功,我們來分析一下。

替換后我們得到

a:2:{i:0;s:29:"";i:1;s:6:"";}";i:1;s:4:"1234";},紅色部分is 反序列化時會被忽略,要反序列化的字段是

a:2:{i:0;s:29:"";i:1;s:6:"";}

可以看到這里的 s:29:"" 顯然是錯誤的,所以我們的反序列化會失敗,那么我們?nèi)绾伪3终_呢?這是我們在反序列化字符轉(zhuǎn)義特征時需要考慮的。東西。

在 ('test','',$) 代碼中,test 被替換為比前一個 test 多一個字符,所以只要我們添加足夠多的 test 來替換它相同的長度,這將允許我們的反序列化正常進行。

我們構建

";i:1;s:6:"";}

這樣php代碼注入漏洞網(wǎng)站開發(fā),我們修改了零錢業(yè)務的密碼

本文題目:php代碼注入漏洞pHp中的魔法函數(shù)反序列化漏洞原理(2)_php注入代碼
標題來源:http://www.bm7419.com/news49/297249.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設計服務器托管、關鍵詞優(yōu)化用戶體驗、品牌網(wǎng)站設計、網(wǎng)站排名

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)