https://buuoj.cn/challenges#[%E5%AE%89%E6%B4%B5%E6%9D%AF%202019]easy_serialize_php
一眼反序列化,首先是源码解析:

这里分一下类方便快速理解:


应该是flag.php这里我自己找到了没截图所以搜索的auto,我看其他大佬wp里面直接搜索的auto,没去深究,有其深意大伙可以评论区教教,第二点:我们想要得到flag肯定是利用最后一句话:

各个部分大概功能都理解了那么就到了本题,明显的是get传入show_image来使用方法,然后利用post的变量覆盖对里的img赋值来绕过filter和if的img替换最终输出给到我们的flag文件。
再注意过程,首先是post变量覆盖和调用show_image方法,这时候在序列化之前我们的img变量会变成固定的base加密,然后才进行序列化,之后是filter过滤,最后是反序列化,然后输出参数值。
这里能够查询的位置是$userinfo['img']而这个对应的其实是过滤后的$_SESSION['img'],但是,它不是直接赋值的,而是采用了反序列化,如果改变序列化以后的字符串,就可以对访问你想要选择的内容。
这就要用到我们的新知识点,反序列化中的字符串逃逸,大家可以去b站或者其他blog找大佬的讲解更能理解,这里我个人推荐智慧少年xenny讲解的PHP序列化和反序列化系列:
那么我还是浅谈一下我个人的理解:
这道题的wp里有其他大佬讲的字符串逃逸很认真细致,这里给予大家分享链接:
https://www.jianshu.com/p/8e8117f9fd0e
有的wp有充分的思考过程和做题步骤思路以及payload讲解,值得学习深究:
https://blog.csdn.net/weixin_52585514/article/details/124291588 https://blog.csdn.net/a1262443306/article/details/117461839 https://www.freesion.com/article/9924532991/
在这里感谢分享经验与思路的各位大佬。
关于字符串逃逸,首先要说到严格的反序列化规则,在其源代码中,有专门的函数规则,在xenny的视频中有所展示,例如。

XENNY视频截图
理解了这个特点后,由于有的反序列会加例如waf一类的保护措施,来令例如flag的内容转换为诸如空格或者index等其他内容,这会导致一个新的问题:又是举一个例子,要不直接回到题目进行例如吧,
首先我们知道在序列化前img会变成固定值,那么可以在本地进行测试看看他的回显:

三个键值,同时SESSION是其设定的,img确实是固定值,如果传入的SESSION里面有flag,
注意这里user后的s:24,由于本来的6个flag被过滤了,这会导致读取后面的24个字符,如果满足条件则继续,反序列化结果也变成了:
可见后面的img固定内容就被忽略了,而最后反序列化内容的结果也变成我们想要的flag文件内容了。而由于我们的目的也就达到了,借用大佬的一段话:
设想,如果我们能够控制原来SESSION数组的funcion的值但无法控制img的值,我们就可以通过这种方式间接控制到img对应的值。这个感觉就像sql注入一样,他本来想读取的base64编码是:,但是由于过滤掉了flag,向后读取的过程中把键值function放到了第一个键值的内容里面,用代替了真正的base64编码,读取了的内容。而识别完成后最后面的被忽略掉了,不影响正常的反序列化过程。
了解完字符串逃逸的知识后,我们构造payload:
两种逃逸方法:键值逃逸和键名逃逸
首先是键值逃逸:
借用大佬payload(菜菜,写太久了,环境过期辣,写那么多了让我懒一懒= =)
_SESSION[user]=flagflagflagflagflagflag&_SESSION[function]=p";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:2:"ab";s:2:"sb";}
这里就对整个过程比较眼熟了,首先是加在最后的img固定在,然后经过filter过滤s:24读取内容进行逃逸,s:24 将";s:8:“function”;s:62:"p给吞掉了,而由于SESSION有三个键,所以需要在后面添加一个键

这里正常流程是显示这个最终的flag文件名,因为他base后同样是20个字符串所以只需要替换就可以得到最终flag

然后是键名逃逸payload:
_SESSION[flagphp]=;s:2:"db";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}
"a:2:{s:7:"phpflag";s:48:";s:1:"1";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}"
同理
这里附上多个大佬payload,方便大家理解和自己构造payload:
get:f=show_image post:_SESSION[fl1gfl1g]=";s:3:"aaa";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";}
_SESSION[user]=flagflagflagflagflagphp&_SESSION[function]=";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:1:"1";s:1:"1";} _SESSION[flagphp]=;s:1:"1";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}
最后吐槽一句这个开做题环境的时候写专栏老是说环境错误,每次这个红框框弹出来我都心脏骤停,写了几k的内容要是没了我真的会谢。最后这道题对我来说受益匪浅,也不枉我花费那么多时间去搜索与总结那么多wp以及其他讲解相关知识点的视频来学习这个知识了。歇了歇了