CTF-Web-PHP反序列化
概念解释
PHP 反序列化漏洞又叫做 PHP 对象注入漏洞,我觉得这个表达很不直白,也不能说明根本的问题,不如我们叫他 PHP 对象的属性篡改漏洞好了(别说这是我说的~~)
反序列化漏洞的成因在于代码中的 unserialize() 接收的参数可控,从上面的例子看,这个函数的参数是一个序列化的对象,而序列化的对象只含有对象的属性,那我们就要利用对对象属性的篡改实现最终的攻击。
魔法方法
- construct(): 当对象创建时会自动调用(但在unserialize()时不会自动调用)
- wakeup(): unserialize()时会自动调用
- destruct(): 当对象被销毁时会自动调用
- toString(): 当反序列化后的对象被输出在模板中的时候(转换成字符串的时候)自动调用
- get(): 当从不可访问的属性读取数据
- 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 ,所以我们在传输过程中绝对不能忘掉。
反序列化漏洞方法小结
- 寻找unserialize()函数的参数是否有可控点
- 寻找反序列化目标,重点为wakeup()或destruct()魔法函数的类
- 一层一层的研究该类在魔法方法中使用的属性和属性调用的方法,看看是否有可控的属性能实现在当前调用的过程中触发的
- 找到要控制的属性之后将要用到的代码部分复制下来,构造序列化,发起攻击
To Be Continued
CTF-Web-PHP反序列化的更多相关文章
- 【CTF WEB】反序列化
反序列化 漏洞代码 <?php error_reporting(0); if(empty($_GET['code'])) die(show_source(__FILE__)); class ex ...
- CTF web题型解题技巧
工具集 基础工具:Burpsuite,python,firefox(hackbar,foxyproxy,user-agent,swither等) 扫描工具:nmap,nessus,openvas sq ...
- 从一道ctf看php反序列化漏洞的应用场景
目录 0x00 first 前几天joomla爆出个反序列化漏洞,原因是因为对序列化后的字符进行过滤,导致用户可控字符溢出,从而控制序列化内容,配合对象注入导致RCE.刚好今天刷CTF题时遇到了一个类 ...
- 31C3 CTF web关writeup
0x00 背景 31c3 CTF 还是很人性化的,比赛结束了之后还可以玩.看题解做出了当时不会做的题目,写了一个writeup. 英文的题解可以看这:https://github.com/ctfs/w ...
- [原题复现+审计][ZJCTF 2019] WEB NiZhuanSiWei(反序列化、PHP伪协议、数组绕过)
简介 原题复现:https://github.com/CTFTraining/zjctf_2019_final_web_nizhuansiwei/ 考察知识点:反序列化.PHP伪协议.数组绕过 ...
- [原题复现+审计][0CTF 2016] WEB piapiapia(反序列化、数组绕过)[改变序列化长度,导致反序列化漏洞]
简介 原题复现: 考察知识点:反序列化.数组绕过 线上平台:https://buuoj.cn(北京联合大学公开的CTF平台) 榆林学院内可使用信安协会内部的CTF训练平台找到此题 漏洞学习 数组 ...
- ctf/web源码泄露及利用办法
和上一篇文章差不多,也算是对web源码泄露的一个总结,但是这篇文章更侧重于CTF 参考文章: https://blog.csdn.net/wy_97/article/details/78165051? ...
- CTF web安全45天入门学习路线
前言 因为最近在准备开发CTF学习平台,先做一个学习路线的整理,顺便也是对想学web的学弟学妹的一些建议. 学习路线 初期 刚刚走进大学,入了web安全的坑,面对诸多漏洞必然是迷茫的,这时的首要任务就 ...
- i春秋CTF web题(1)
之前边看writeup,边做实验吧的web题,多多少少有些收获.但是知识点都已记不清.所以这次借助i春秋这个平台边做题,就当记笔记一样写写writeup(其实都大部分还是借鉴其他人的writeup). ...
- CTF中PHP反序列化和命令注入的一次简单利用
代码来自第六届防灾科技学院网络安全技能大赛,侵删. 目标 获取Linux服务器根目录下的flag 代码 /*home.php*/ class home{ private $method; privat ...
随机推荐
- oculus按键大全
// OVRInput.Update(); if (OVRInput.GetUp(OVRInput.Button.Three)) { Debug.Log("remote click" ...
- echarts 画图报错 this.dom.getContext is not a function
我给 <el-card>绑定了ref,利用$refs获取 echarts实例 const echarts1 = echarts.init(this.$refs.echarts1); 结果 ...
- SQL Server datetime类型为null的有趣实验
@data1 --变量 测试用 @data2 --当前时间 当@data1为null 则格式转换错误 直接控制台什么也不显示 也不报错 当定义'' 显示默认时间
- python之变量
什么是变量? 用来记录事务的变化状态,计算机模拟人,就需要具备人类某一个功能.你通过记录我的名字年龄等一系列的身份信息,以此和我进行匹配,确定我就是phoebe这个人. 为什么有变量? 游戏里的英雄角 ...
- 源代码管理工具:Github
GitHub是一个基于Git的进行版本控制的代码托管网站. Git指的是是一个开放源代码版本控制系统,由Linus Torvalds启动.在时间的累积下,现在的Github是一个最大的开源软件社区.在 ...
- ajax高级(请求服务器脚本,数据库, ajxa xml文件)
请求jsp与请求普通文件不通过的地方,请求jsp可能会传参,比如搜索,用户名,页码这些 html部分:<input type="text" id="txt1&quo ...
- 题解,洛谷P3435
根据题意,分析如右图 显然,对于每个前缀,有这样的性质A==B==C,所以,周期最长则a最短,即求该字符串的最短公共前后缀.通过kmp算法中nex数组的迭代,很容易求得最短前后缀. for(int i ...
- Abp学习(一) abp+vue +mysql框架搭建
一.到Abp官网下载框架 地址:https://aspnetboilerplate.com/Templates 二.打开项目 修改数据库连接为MySql,默认是SQL Server 2.1.修改链接字 ...
- C知识点
1.变量在内存中所占存储空间的首地址,称为该变量的地址:而变量在存储空间中存放的数据,即变量的值. C语言中,指针就是变量的地址.一个变量的值是另一个变量的地址,且变量类型相同,则称该变量为指针变量. ...
- BeanFactory与FactoryBean区别
1. BeanFactory BeanFactory,以Factory结尾,表示它是一个工厂类(接口),用于管理Bean的一个工厂.在Spring中,BeanFactory是IOC容器的核心接口,也是 ...