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. 漏洞描述 ...
随机推荐
- 「洛谷P3202」[HNOI2010]弹飞绵羊 解题报告
P3203 [HNOI2010]弹飞绵羊 题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一 ...
- 「2018-12-02模拟赛」T3 约束排列 解题报告
3.约束排列(place.pas/cpp/in/out) 问题描述: 给出 n 个互不相同的小写字母,表示出现的字符类型,以及 k 个约束关系: .....,表示 ai 必须出现在 bi 前面(ai, ...
- day3(if和for)
if if <条件判断 1>: <执行 1>elif <条件判断 2>: <执行 2>elif <条件判断 3>: <执行 3> ...
- 虚拟机安装LEDE旁路由实现软路由功能
如何在虚拟上安装LEDE软路由,接下来我们一步一步操作. 1.首先到https://firmware.koolshare.cn/ 下载虚拟机下专用盘如图标记均可 2.虚拟机创建 选择下载好的文件 保持 ...
- Java读取数据库中的xml格式内容,解析后修改属性节点内容并写回数据库
直接附代码: 1.测试用的xml内容 <mxGraphModel> <root> <mxCell id="-1" /> <mxCell i ...
- No property andp found for type String! Traversed path: CmsPage.siteId.
Respository没有找到该参数 1)由该参数,函数名写错,不符合JPA规范 2)实体类没有该参数
- 唬人的Java泛型并不难
泛型 public interface Foo<E> {}public interface Bar<T> {}public interface Zar<?> {} ...
- 为WPF, UWP 及 Xamarin实现一个简单的消息组件
原文地址:Implementing a simple messenger component for WPF, UWP and Xamarin 欢迎大家关注我的公众号:程序员在新西兰了解新西兰IT行业 ...
- dp-最大连续子序列的和
https://www.felix021.com/blog/read.php?1587 什么是最大连续子序列和呢 ? 最大连续子序列和是所有子序列中元素和最大的一个 . 问题 : 给定一个序列 { - ...
- 三分钟网络基础-ARP协议
什么是 ARP 协议 地址解析协议 ARP (Address Resolution Protocal):在同一局域网下,根据已知道的主机或路由器的 IP 地址,找出其相应的硬件地址. 高速缓存 每一个 ...