[LeetCode No.20] 有效的括號
阿新 • • 發佈:2020-12-27
一、序列化和反序列化介紹
1、序列化
將複雜的資料結構(object) 轉換為適合與傳輸和儲存的位元組型別(byte)。(儲存)
2、反序列化
將位元組型別轉換為複雜資料結構(object) 。(程式使用)
二、序列化
<?php class Site{ public $name = 'ctf'; public function get_name() { echo $name; echo md5('admin'); } } $a = new Site(); $b = serialize($a); echo $b; ?>
三、反序列化
<?php
class Site{
public $name = 'ctf';
public function get_name()
{
echo md5('admin');
}
}
$a = new Site();
$b = serialize($a);
$obj = unserialize($b);
$obj->get_name();
?>
四、CTF反序列化案列
unserialize() 會檢查是否存在一個 __wakeup() 方法。如果存在,則會先呼叫 __wakeup 方法,預先準備物件需要的資源
<?php
$data = file_get_contents("php://input");
class Site{
public $name = 'ctf';
public function __wakeup()
{
echo "flag:".md5('123456');
}
}
$obj = unserialize($data);
?>
五、不安全反序列化實驗
<?php class User{ public $name = 'ctf'; public $isAdmin = false; } $user = unserialize($_POST['flag']); if($user->isAdmin === true){ echo "flag:".md5('admin888'); }else{ echo "no flag"; } ?>
六、物件中的屬性修飾符
在php程式碼中,定義 User
類,並且設定屬性具有 protected
和 private
屬性
<?php
class User{
protected $name = 'ctf' ;
private $isAdmin = true ;
}
$user = new User();
echo serialize($user);
?>
1、protected修飾的屬性在序列化之後,修改為 \x00*\x00 屬性名。 //圖片上的方塊換成16進製為\X00
2、private修飾的屬性在序列化之後,修改為\x00 類名 \x00 屬性名
七、序列化字串中的 + 號
<?php
@error_reporting(1);
include 'flag.php';
class ctf{
public $flag ;
function __toString(){
if(isset($this->flag)){
$filename = "./{$flag}";
if(file_get_contents($filename)){
return file_get_contents($filename);
}
}
}
}
if(isset($_GET['data'])){ //判斷是否傳遞引數
$data = $_GET['data']; //將引數賦值給data
preg_match('/[oc]:\d+:/i',$data,$matches); //進行正則匹配,將匹配的結果儲存到matches中
if(count($matches)){ //長度是否大於0
die('no flag');
}else{
$c = unserialize($data); //反序列化傳遞進來的值(此時會呼叫魔術方法)
echo $c;
}
}else{
highlight_file('./2.php');
}
?>
繞過正則匹配,使用+號。 url編碼為 %2b
八、魔術方法
__construct:構造方法
__destruct:析構方法:
__wakeup:執行unserialize() 時,會先呼叫這個函式
__toString:類被當作字串時迴應的方法
<?php
class User{
function __construct()
{
echo "__construct<br/>";
}
function __destruct()
{
echo "__construct<br/>";
}
function __wakeup()
{
echo "__wakeup<br/>";
}
function __toString()
{
echo "__construct<br/>";
return '';
}
}
$u = new User();
$s = serialize($u);
echo $s."<br/>";
$o = unserialize($s);
echo $o;
?>
九、PHP序列化漏洞案例
<?php
class Test{
public $cmd = "whoami";
function __wakeup(){
system($this->cmd);
}
}
$obj = unserialize($_GET['cmd']);
?>