WordPress朗讀免費seo網站診斷免費
Web滲透—PHP反序列化????????課程學習分享(課程非本人制作,僅提供學習分享)
靶場下載地址:GitHub - mcc0624/php_ser_Class: php反序列化靶場課程,基于課程制作的靶場
課程地址:PHP反序列化漏洞學習_嗶哩嗶_bilibili
七、wakeup和sleep
1.__sleep()
序列化serialize()函數(shù)會檢查類中是否存在一個魔術方法__sleep()。
如果存在,該方法會先被調用,然后才執(zhí)行序列化操作。
此功能可以用于清理對象,并返回一個包含對象中所有應被序列化的變量名稱的數(shù)組。
如果該方法未返回任何內容,則NULL被序列化,并產生一個E_NOTICE級別的錯誤。
<?php
class?User?{const?SITE?=?'uusama';public?$username;public?$nickname;private?$password;public?function?__construct($username,?$nickname,?$password){$this->username?=?$username;$this->nickname?=?$nickname;$this->password?=?$password;}public?function?__sleep(){return?array('username',?'nickname'); //__sleep()執(zhí)行返回需要序列化的變量名,過濾掉password變量}
}
$user?=?new?User('a',?'b',?'c');
echo?serialize($user); //serialize()只序列化sleep返回的變量
?>
觸發(fā)時機:序列化serialize()之前
功能:對象被序列化之前觸發(fā),返回需要被序列化存儲的成員變量,刪除不必要的屬性
參數(shù):成員屬性(return array)
返回值:需要被序列化存儲的成員屬性('username','nickname')
2.__sleep()例題
通過審計代碼,發(fā)現(xiàn)通過benben參數(shù)傳入的值會賦值傳給$cmd,而當執(zhí)行序列化前會先執(zhí)行__sleep(),只返回username成員屬性,通過system()函數(shù)包含,所以可以直接傳入命令進行執(zhí)行。
3.__wakeup()
unserialize()會檢查是否存在一個__wakeup()方法。
如果存在,則會先調用__wakeup()方法,預先準備對象需要的資源。
預先準備對象資源,返回void,常用于反序列化操作中重新建立數(shù)據庫連接或執(zhí)行其他初始化操作。
__wakeup()在反序列化unserialize()之前;__destruct()在反序列化unserialize()之后。
<?php
class?User?{const?SITE?=?'uusama';public?$username;public?$nickname;private?$password;private?$order;public?function?__wakeup(){$this->password?=?$this->username; //反序列化之前觸發(fā)wakeup,給password賦值}
}
$user_ser?=?'O:4:"User":2:{s:8:"username";s:1:"a";s:8:"nickname";s:1:"b";}'; //字符串中沒有定義password
var_dump(unserialize($user_ser)); //userialize()結果包含password的值
?>
觸發(fā)時機:反序列化unserialize()之前
功能:(無)
參數(shù):(無)
返回值:(無)(包含password的賦值)
4.__wakeup()
解題代碼:
<?php
class User {public $username = "whoami";
}
$user_ser = new User();
echo serialize($user_ser);
?>輸出結果:
O:4:"User":1:{s:8:"username";s:6:"whoami";}
通過審計代碼,發(fā)現(xiàn)通過benben參數(shù)傳入值會直接賦值給$user_ser,并反序列化$user_ser,所以我們需要向benben參數(shù)內傳入序列化值。而反序列化被調用前會先執(zhí)行__wakeup(),調用username成員屬性,通過system()函數(shù)包含,所以我們要通過序列化給username成員變量賦值傳入系統(tǒng)命令。
八、toString和invoke
1.__toString()
表達方式錯誤導致魔術方法觸發(fā)(把對象當成字符串調用時觸發(fā))
常用于構造POP鏈接
<?php
class?User?{var?$benben?=?"this?is?test!!";public?function?__toString(){return?'格式不對,輸出不了!';}
}
$test?=?new?User()?; //把類User實例化寧賦值給$test,此時$test是個對象
print_r($test); //調用對象可以使用print_r或者var_dump
echo?$test;
?>
觸發(fā)時機:把對象當成字符串調用
功能:(無)
參數(shù):(無)
返回值:(無)
如果使用echo或者print只能調用字符串的方式去調用對象,即把對象當成字符串使用,此時自動觸發(fā)toString()
2.__invoke()
格式表達錯誤導致魔術方法觸發(fā)(把對象當成函數(shù)調用時觸發(fā))
<?php
class?User?{var?$benben?=?"this?is?test!!";public?function?__invoke(){echo??'它不是個函數(shù)!';}
}
$test?=?new?User()?; //把類User實例化并賦值給$test為對象
echo?$test?->benben; //正常輸出對象里的值benben
echo?$test()?->benben; //加()是把test當成函數(shù)test()來調用,此時觸發(fā)invoke()
?>
觸發(fā)時機:把對象當成函數(shù)調用
功能:(無)
參數(shù):(無)
返回值:(無)