php|反序列化|本地|bugku
本地编写简单代码测试
无类情况
1、无类情况下,代码的序列化测试
1 |
|
运行结果:
s:6:”dralin”;
s:字符串;6:字符串长度;dralin:字符串内容。
2、无类情况下,代码的反序列化测试
1 |
|
运行结果:
还原成原本的字符串。
(1)、无类情况下较为简单,就是简单的转化。
(2)、以上两个实例可以简单区分序列化(将对象转为字符串)与反序列化(将字符串还原成对象)。
有类情况
前言:有类情况下较上述情况复杂,因为有类的话会在程序执行的特定时间点,会自动调用魔术方法。
1 |
|
运行结果:
这里调用析构函数时并不是在调用serialize()后立刻执行,而是在所有语句执行完后在执行。如果序列化那段代码放到反序列化那段代码后,即:
1 | $a = new ABC; |
那么就会只执行一次(因为本身就在最后)。
ctf真题bugku
题目:点login咋没反应
开启环境后,进来发现只有一个平平无奇的登录框。
查看源码,发现有一个css文件可以访问
访问后,发现就是一个普通的css样式,我刚开始看的时候还是没有发现什么问题,但是,细看上面有一个?4495,这是什么呢?
突然想起和网址栏上的属性与属性值,好像可以把这串东西填入,填入哪里呢?不久两个地方可以填吗,一个是这个css文件,另一个就是刚才的源码网址。
先试一下源码网址填入/?4495
http://114.67.175.224:13957/?4495
发现跳转到一个界面。
关键来了,这里有几个注意点:
1、$KEY值给出,那么下面必然会用到。
2、flag.php被包含了进来,那么猜测flag可能存在于这个文件,我该思考如何把里面的内容读出。
3、以cookie方式传输值,且属性是”BUGKU”(cookie传值时,写成BUGKU=****)。
4、如果get请求包含4495,那么就会自动跳回此原来界面,而不会执行else if的语句打印flag。
5、else if内存在一个反序列化的函数,那么思路就是编程把$KEY的值序列化,然后通过cookie传输则可获取flag。
按照如上思路,先获取序列化的$KEY
1 |
|
抓包,添加cookie,且get请求内的4495要去掉
把获取到的flag提交即可。
有类情况下的靶场练习(pikachu)
上面两道题都是无类情况,该情况构造序列化payload的代码相对简单,接下来是学习有类情况下如何构造payload。
由于是本地靶场,那么我可以先查看源码。
发现存在一个class类,而且存在一个创建对象会触发的魔术方法,那么可以考虑利用,但是发现就算利用的上也没啥大用,总不能改别人代码吧。此路不通,那么往下看,发现一个判断,意思是如果是接收的是序列化的值,那么会转为对象并赋值给unser;如果不是序列化的值,没用。
而且,它的打印输出语句不是echo,那么就要考虑写js语句(觉得应该是如果简单输出字符串,那么就对获取信息没啥用,所以考虑可获取cookie的js语句)。
构造payload(编程,目的是把payload序列化):
1 |
|
关于上述代码的注意点:
如果对方有类,那么你构造的代码必须也含有类(类名也要相同),然后创建一个对象传输你要传输的数据(我称之为一一对应)。
运行后,获取到序列化的payload:
1 | O:1:"S":1:{s:4:"test";s:39:"<script>alert(document.cookie)</script>";} |
把这句payload放入文本框,并submit,成功弹出cookie信息。