1. 程式人生 > 實用技巧 >[LeetCode No.20] 有效的括號

[LeetCode No.20] 有效的括號

一、序列化和反序列化介紹

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 類,並且設定屬性具有 protectedprivate 屬性

<?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']);
?>