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. 漏洞描述 ...
随机推荐
- Educational Codeforces Round 53 (Rated for Div. 2) (前五题题解)
这场比赛没有打,后来补了一下,第五题数位dp好不容易才搞出来(我太菜啊). 比赛传送门:http://codeforces.com/contest/1073 A. Diverse Substring ...
- 浏览器从输入url 到页面展示完成响应过程
用户从输入 url 到浏览器响应,呈现给用户的具体过程 1.用户在输入栏输入地址 (1) 如果有 beforeunload 事件会先执行判断继续还是跳出操作 (2) 浏览器进程识别是 地址还是关键字检 ...
- 悄摸直播 —— JavaCV实现本机摄像头画面远程直播
目录 前言 需要的jar包和依赖 需要实现的模块(附带源码教程) 项目效果展示 前言 最近想用Java实现一个类似于远程直播的功能 像这样:(功能示意图) 需要的jar包和依赖 Maven依赖: &l ...
- Scala 学习(3)之「类——基本概念1」
类 小提示:可以通过:paste进入 Scala 的多行模式,输入对应的代码块之后,按ctrl + D退出多行模式,然后再调用刚才输入的函数或者方法进行测试 //定义类,包含 field 以及方法 c ...
- 递推 dp
工大要建新教学楼了,一座很高很高的楼,它有n层.学校为了减少排电梯的队伍,建造了好多好多电梯,共有m个.为了让电梯有序,学校给每个电梯设定了独特的可停楼层,如 x1 x2 y1 y2 表示,x1楼层到 ...
- 全网最详细!Centos7.X 搭建Grafana+Jmeter+Influxdb 性能实时监控平台
背景 日常工作中,经常会用到Jmeter去压测,毕竟LR还要钱(@¥&*...),而最常用的接口压力测试,我们都是通过聚合报告去查看压测结果的,然鹅聚合报告的真的是丑到家了,作为程序猿这当然不 ...
- AFN请求问题
在使用AFNetworking 2.0 的时候本来一切很顺畅,但是中途遇到几个比较坑的地方 在发送请求后,NSURLSessionDataTask一直报错 Error Domain=com.alam ...
- __new__ 方法
1.构造方法 实例化过程:构造->初始化 构成方法必须要有返回值,返回给初始化方法的self class A: def __init__(self): self.x = 1 print('ini ...
- Djaingo 随机生成验证码(PIL)
基础: https://www.cnblogs.com/wupeiqi/articles/5812291.html 实例: https://www.cnblogs.com/6324TV/p/88112 ...
- 4.JavaSE之标识符
标识符:Java所有的组成部分都需要名字.类名.变量名以及方法名都被称为标识符. 关键字:abstract.assert.boolean.breake.public.static.class...