概念解释

PHP 反序列化漏洞又叫做 PHP 对象注入漏洞,我觉得这个表达很不直白,也不能说明根本的问题,不如我们叫他 PHP 对象的属性篡改漏洞好了(别说这是我说的~~)

反序列化漏洞的成因在于代码中的 unserialize() 接收的参数可控,从上面的例子看,这个函数的参数是一个序列化的对象,而序列化的对象只含有对象的属性,那我们就要利用对对象属性的篡改实现最终的攻击。

魔法方法

  1. construct(): 当对象创建时会自动调用(但在unserialize()时不会自动调用)
  2. wakeup(): unserialize()时会自动调用
  3. destruct(): 当对象被销毁时会自动调用
  4. toString(): 当反序列化后的对象被输出在模板中的时候(转换成字符串的时候)自动调用
  5. get(): 当从不可访问的属性读取数据
  6. call(): 在对象上下文中调用不可访问的方法时触发

特别说明第四点:

_toString触发条件较多,因此容易被忽略,常见的触发条件如下:

(1)echo ($obj) / print($obj) 打印时会触发

(2)反序列化对象与字符串连接时

(3)反序列化对象参与格式化字符串时

(4)反序列化对象与字符串进行比较时(PHP进行比较的时候会转换参数类型)

(5)反序列化对象参与格式化SQL语句,绑定参数时

(6)反序列化对象在经过php字符串函数,如 strlen()、addslashes()时

(7)在in_array()方法中,第一个参数是反序列化对象,第二个参数的数组中有toString返回的字符串的时候toString会被调用

(8)反序列化的对象作为 class_exists() 的参数的时候

魔法方法的作用

反序列化了其他的类对象以后我们只是控制了是属性,如果你没有在完成反序列化后的代码中调用其他类对象的方法,我们还是束手无策,毕竟代码是人家写的,人家本身就是要反序列化后调用该类的某个安全的方法,你总不能改人家的代码吧,但是没关系,因为我们有魔法方法。

魔法正如上面介绍的,魔法方法的调用是在该类序列化或者反序列化的同时自动完成的,不需要人工干预,这就非常符合我们的想法,因此只要魔法方法中出现了一些我们能利用的函数,我们就能通过反序列化中对其对象属性的操控来实现对这些函数的操控,进而达到我们发动攻击的目的。

利用魔法方法发起攻击

测试代码:

<?php
class K0rz3n {
private $test;
public $K0rz3n = "i am K0rz3n";
function __construct() {
$this->test = new L();
} function __destruct() {
$this->test->action();
}
} class L {
function action() {
echo "Welcome to XDSEC";
}
} class Evil { var $test2;
function action() {
eval($this->test2);
}
} unserialize($_GET['test']);

我们先来分析一下这段代码,首先我们能看到 unserialize() 函数的参数我们是可以控制的,也就是说我们能通过这个接口反序列化任何类的对象(但只有在当前作用域的类才对我们有用),那我们看一下当前这三个类,我们看到后面两个类反序列化以后对我们没有任何意义,因为我们根本没法调用其中的方法,但是第一个类就不一样了,虽然我们也没有什么代码能实现调用其中的方法的,但是我们发现他有一个魔法函数 __destruct() ,这就非常有趣了,因为这个函数能在对象销毁的时候自动调用,不用我们人工的干预,好,既然这样我们就决定反序列化这个类的对象了,接下来让我们看一下怎么利用(我上面说过了,我们需要控制这个类的某些属性,通过控制属性实现我们的攻击)

那我们看一下哪些属性的控制是对我们有用的(这个时候我们就跳过了construct() 方法,毕竟他永远不会被调用),因为这个例子比较简单,destruct() 里面只用到了一个属性 test ,那肯定就是他了,那我们控制这个属性为什么内容我们就能攻击了呢,我们再观察一下 那些地方调用了 action() 函数,看看这个函数的调用中有没有存在执行命令或者是其他我们能利用的点的,果然我们在 Evil 这个类中发现他的 action() 函数调用了 eval(),那我们的想法就很明确了,我们需要将 K0rz3n 这个类中的 test 属性篡改为 Evil 这个类的对象,然后为了 eval 能执行命令,我们还要篡改 Evil 对象的 test2 属性,将其改成我们的 Payload

分析完毕以后我们就可以构建我们的序列化字符串了,构建的方法不是手写(当然你愿意我也不拦着你,理论上是可行的),我们要将这段代码复制一下,然后修改一些内容并进行序列化操作

生成payload

<?php
class K0rz3n {
private $test;
function __construct() {
$this->test = new Evil;
}
} class Evil { var $test2 = "phpinfo();"; } $K0rz3n = new K0rz3n;
$data = serialize($K0rz3n);
file_put_contents("seria.txt", $data);

我们去除了一切与我们要篡改的属性无关的内容,对其进行序列化操作,然后将序列化的结果复制出来,向刚刚的代码发起请求。可以看到我们攻击成功,特别要提醒一下的就是我在图中框起来的部分,上面说过由于是私有属性,他有自己特殊的格式会在前后加两个 %00 ,所以我们在传输过程中绝对不能忘掉。

反序列化漏洞方法小结

  1. 寻找unserialize()函数的参数是否有可控点
  2. 寻找反序列化目标,重点为wakeup()或destruct()魔法函数的类
  3. 一层一层的研究该类在魔法方法中使用的属性和属性调用的方法,看看是否有可控的属性能实现在当前调用的过程中触发的
  4. 找到要控制的属性之后将要用到的代码部分复制下来,构造序列化,发起攻击

To Be Continued

CTF-Web-PHP反序列化的更多相关文章

  1. 【CTF WEB】反序列化

    反序列化 漏洞代码 <?php error_reporting(0); if(empty($_GET['code'])) die(show_source(__FILE__)); class ex ...

  2. CTF web题型解题技巧

    工具集 基础工具:Burpsuite,python,firefox(hackbar,foxyproxy,user-agent,swither等) 扫描工具:nmap,nessus,openvas sq ...

  3. 从一道ctf看php反序列化漏洞的应用场景

    目录 0x00 first 前几天joomla爆出个反序列化漏洞,原因是因为对序列化后的字符进行过滤,导致用户可控字符溢出,从而控制序列化内容,配合对象注入导致RCE.刚好今天刷CTF题时遇到了一个类 ...

  4. 31C3 CTF web关writeup

    0x00 背景 31c3 CTF 还是很人性化的,比赛结束了之后还可以玩.看题解做出了当时不会做的题目,写了一个writeup. 英文的题解可以看这:https://github.com/ctfs/w ...

  5. [原题复现+审计][ZJCTF 2019] WEB NiZhuanSiWei(反序列化、PHP伪协议、数组绕过)

    简介  原题复现:https://github.com/CTFTraining/zjctf_2019_final_web_nizhuansiwei/  考察知识点:反序列化.PHP伪协议.数组绕过   ...

  6. [原题复现+审计][0CTF 2016] WEB piapiapia(反序列化、数组绕过)[改变序列化长度,导致反序列化漏洞]

    简介  原题复现:  考察知识点:反序列化.数组绕过  线上平台:https://buuoj.cn(北京联合大学公开的CTF平台) 榆林学院内可使用信安协会内部的CTF训练平台找到此题 漏洞学习 数组 ...

  7. ctf/web源码泄露及利用办法

    和上一篇文章差不多,也算是对web源码泄露的一个总结,但是这篇文章更侧重于CTF 参考文章: https://blog.csdn.net/wy_97/article/details/78165051? ...

  8. CTF web安全45天入门学习路线

    前言 因为最近在准备开发CTF学习平台,先做一个学习路线的整理,顺便也是对想学web的学弟学妹的一些建议. 学习路线 初期 刚刚走进大学,入了web安全的坑,面对诸多漏洞必然是迷茫的,这时的首要任务就 ...

  9. i春秋CTF web题(1)

    之前边看writeup,边做实验吧的web题,多多少少有些收获.但是知识点都已记不清.所以这次借助i春秋这个平台边做题,就当记笔记一样写写writeup(其实都大部分还是借鉴其他人的writeup). ...

  10. CTF中PHP反序列化和命令注入的一次简单利用

    代码来自第六届防灾科技学院网络安全技能大赛,侵删. 目标 获取Linux服务器根目录下的flag 代码 /*home.php*/ class home{ private $method; privat ...

随机推荐

  1. keras构建1D-CNN模型

    接触过深度学习的人一定听过keras,为了学习的方便,接下来将要仔细的讲解一下这keras库是如何构建1D-CNN深度学习框架的 from keras.datasets import imdb fro ...

  2. Communications link failure:The last packet successfully received from the server was 0 millisecond ago

    出现这种错误的大致情况如下: 1.数据库连接长时间未使用,断开连接后,再去连接出现这种情况.这种情况常见于用连接池连接数据库出现的问题 2.数据库连接的后缀参数问题 针对上述两种情况,解决方案如下 1 ...

  3. microbit问题记录

    问题: 1.电子罗盘东南西北:不太好用 2.    micropython代码:震动.声音显示不对 makecode代码:声音不好用 已解决: 1.摇杆下和左不管用了(已解决:改软件包代码) 2.ma ...

  4. 在vscode中用tsc编译ts文件的时候报错,tsc : 无法加载文件,因为在此系统上禁止运行脚本;SecurityError

    1. TypeScript安装成功,在C盘的Administrator目录下,运行 tsc -v 也可看到TypeScript的版本.  2. 但在vscode中的时候运行tsc 编译ts文件的时候报 ...

  5. C语言初级阶段4——数组3——字符数组

    C语言初级阶段4--数组3--字符数组 字符数组的定义:储存字符类型数据的集合 1.注意:如果用字符串给字符数组初始化,那么不需要{},但是要有"". 2.%s :用来输出字符串的 ...

  6. 求小于N的最大素数

    问题 求小于N的最大素数 分析 枚举:从可能的集合中一一列举各元素 枚举过程中需要考虑的问题: 给出解空间 减少搜索的空间 采用合适的搜索顺序 枚举关键字(枚举核心):减少规模 代码实现 1 impo ...

  7. Spring 笔记二 IOC

    1.IOC IOC:Inversion  od  controller ,控制反转,控制的是资源的获取方式,由原来的自己创建 new 变成 Spring 容器创建. DI:Dependency  In ...

  8. Selenium显式、隐式等待

    显式等待: 显式等待是你在代码中定义等待一定条件发生后再进一步执行你的代码.简单的说就是在指定时间内,一直等待某个条件成立,条件成立后立即执行定位元素的操作:如果超过这个时间条件仍然没有成立,则会抛出 ...

  9. 实验八-Web部署

    进入华为云中购置的虚拟机 配置openEuler cd /etc/yum.repos.d vi openEuler_x86_64.repo 安装LAMP 在shell中 通过下面命令安装Apache: ...

  10. lisp入门资料收集

    1.一些文档 http://acl.readthedocs.io/en/latest/zhCN/index.html http://daiyuwen.freeshell.org/gb/lisp.htm ...