序列化与反序列化

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

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

序列化与反序列化

上一篇:Yii2 反序列化漏洞复现


下一篇:mall学习所需知识点