序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。
反序列化与 serialize() 对应的,unserialize()可以从已存储的表示中创建PHP的值,单就本次环境而言,可以从序列化后的结果中恢复对象(object)本质上serialize()和unserialize()在PHP内部实现上是没有漏洞的,漏洞的主要产生是由于应用程序在处理对象、魔术函数以及序列化相关问题的时候导致的。当传给 unserialize() 的参数可控时,那么用户就可以注入精心构造的payload。当进行反序列化的时候就有可能会触发对象中的一些魔术方法,造成意想不到的危害。
php中有一类特殊的方法叫“Magic function”(魔术方法), 这里我们着重关注一下几个:
__construct():当对象创建(new)时会自动调用。但在unserialize()时是不会自动调用的。(构造函数)
__destruct():当对象被销毁时会自动调用。(析构函数)
__wakeup() :如前所提,unserialize()时会自动调用。
漏洞复现靶场
我们首先进行代码审计,寻找存在反序列化的函数。
flag in ./flag.php <?php
Class readme{ //定义类readme
public function __toString() //定义函数 __toString() 是魔术方法的一种,具体用途是当一个对象被当作字符串对待的时候,会触发这个魔术方法
{
return highlight_file('Readme.txt', true).highlight_file($this->source, true);
//高亮显示Readme.txt中的内容 一会再赋值
}
}
if(isset($_GET['source'])){//get接收到就执行
$s = new readme(); // new 一个readme
$s->source = __FILE__; //php中的__FILE__常量返回文件的完整路径和文件名.
echo $s;//输出
exit;
}
//$todos = [];
if(isset($_COOKIE['todos'])){//小饼干传参
$c = $_COOKIE['todos'];//赋值
$h = substr($c, 0, 32);//从第一个开始取32个
$m = substr($c, 32);//从第32个开始取到结束
if(md5($m) === $h){//判断md5加密的值是否全等于变量h
$todos = unserialize($m);//执行反序列化
}
构造序列化值,进行md5加密按照方法将加密后的部分放到前面,未加密的部分放到后面。之后进行url编码——>小饼干传参
拿到flag
打赏我,让我更有动力~
© 2016 - 2024 掌控者 All Rights Reserved.
heqirong
发表于 2020-11-24
同学,作业交错地方了
评论列表
加载数据中...