今天是2026年7月27日
今天学习了PHP反序列化,具体学习情况如下:
class定义类
序列化和反序列化:
序列化就是把内存中的数据(对象、属性。。。)转换成一段可以保存或传输的字符串(方便数据传输的字符串),反序列化就是把这段字符串还原成原来的数据结构。
它们都是为了方便数据传输
危险点:如果服务器对用户可控内容执行unserialize()
数组:echo serialize({"user" => "alice", "admin" => false});
结果:a:2{s:4"user";s:5"alice";s:5:"admin";b:0;}
对象:
class User {
public $name = "alice";
public $role = "user";
}
echo serialize(new User()); #实体化后序列化
O:object(对象)
public、protected、private属性
a
\0*\0b
\0类名\0b
PHP魔术方法:
$this -> username #指向
魔术方法第一类:
魔术方法第二类:
魔术方法第三类:
魔术方法第四类:
今日练习:
1.
进入靶场给了这样一段代码:

代码逻辑是让账号密码与$u、$p相等就能拿到flag,直接传参:

拿到flag
2.
进入靶场

代码逻辑和上一题差不多,但是多了一个反序列化,$user会接收被传入参数的cookie再被反序列化后的值,所以要在cookie中加入参数user,并为其赋值,既然是反序列化,那我就传个序列化的值:

为了保证数据原封不动的传输给PHP,这里是进行了url编码:
Cookie:user=O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A8%3A%22password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D
构造payload:
https://d5396e49-da1a-40a6-9188-6b2f2590a9c2.challenge.ctf.show/?username=xxxxxx&password=xxxxxx
Cookie: user=O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A8%3A%22password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D
拿到flag:ctfshow{4159fe9e-6f37-481a-bddc-9fe3f4a7363c}

3.
进入靶场

直接构造payload:

把序列化结果给nss传参拿到flag:NSSCTF{6e0a1bac-f5f7-473f-8cbe-c1f6e0772304}

今日作业
进入靶场

发现没给题目,在源码中也没找到,用dirsearch扫一下发现两个目录:

/flag.php中没有任何数据,在/robots.txt中找到了题目入口:

进入/c145.php目录,看到真正的题目:

题目的代码逻辑大概就是让我把if判断的admin的值从user改成admin,把passwd从123456改成ctf就能拿到flag,并给了一个可传参的参数p,p再经过反序列化。于是根据代码,我想到如下payload:

这段代码的意思是让admin的值为admin,passwd的值为ctf,刚好满足题目要求,然后再经过序列化、url编码(保持原始数据),得到最终payload:
O%3A4%3A%22wllm%22%3A2%3A%7Bs%3A5%3A%22admin%22%3Bs%3A5%3A%22admin%22%3Bs%3A6%3A%22passwd%22%3Bs%3A3%3A%22ctf%22%3B%7D

成功拿到flag:NSSCTF{68024802-bfc3-4054-b015-1c7695bc3087}
今日学习分享
本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
评论交流
欢迎留下你的想法