.NET高级代码审计(第四课) JavaScriptSerializer反序列化漏洞

0X00 前言

在.NET处理 Ajax应用的时候,通常序列化功能由JavaScriptSerializer类提供,它是.NET2.0之后内部实现的序列化功能的类,位于命名空间System.Web.Script.Serialization、通过System.Web.Extensions引用,让开发者轻松实现.Net中所有类型和Json数据之间的转换,但在某些场景下开发者使用Deserialize 或DeserializeObject方法处理不安全的Json数据时会造成反序列化攻击从而实现远程RCE漏洞,本文笔者从原理和代码审计的视角做了相关介绍和复现。

0X01 JavaScriptSerializer序列化

下面先来看这个系列课程中经典的一段代码:

TestClass类定义了三个成员,并实现了一个静态方法ClassMethod启动进程。 序列化通过创建对象实例分别给成员赋值

使用JavaScriptSerializer类中的Serialize方法非常方便的实现.NET对象与Json数据之间的转化,笔者定义TestClass对象,常规下使用Serialize得到序列化后的Json

从之前介绍过其它组件反序列化漏洞原理得知需要 __type这个Key的值,要得到这个Value就必须得到程序集全标识(包括程序集名称、版本、语言文化和公钥),那么在JavaScriptSerializer中可以通过实例化SimpleTypeResolver类,作用是为托管类型提供类型解析器,可在序列化字符串中自定义类型的元数据程序集限定名称。笔者将代码改写添加类型解析器

0x02 JavaScriptSerializer反序列化

2.1、反序列化用法

反序列化过程就是将Json数据转换为对象,在JavaScriptSerializer类中创建对象然后调用DeserializeObject或Deserialize方法实现的

DeserializeObject方法只是在Deserialize方法上做了一层功能封装,重点来看Deserialize方法,代码中通过JavaScriptObjectDeserializer.BasicDeserialize方法返回object对象

在BasicDeserialize内部又调用了DeserializeInternal方法,当需要转换为对象的时候会判断字典集合中是否包含了ServerTypeFieldName常量的Key,

ServerTypeFieldName常量在JavaScriptSerializer类中定义的值为“__type”,

剥茧抽丝,忽略掉非核心方法块ConvertObjectToType、ConvertObjectToTypeMain 、ConvertObjectToTypeInternal,最后定位到ConvertDictionaryToObject方法内

这段代码首先判断ServerTypeFieldName存在值的话就输出赋值给对象s,第二步将对象s强制转换为字符串变量serverTypeName,第三步获取解析器中的实际类型,并且通过System.Activator的CreateInstance构造类型的实例

Activator类提供了静态CreateInstance方法的几个重载版本,调用方法的时候既可以传递一个Type对象引用,也可以传递标识了类型的String,方法返回对新对象的引用。下图Demo展示了序列化和反序列化前后的效果:

2.2、打造Poc

默认情况下JavaScriptSerializer不会使用类型解析器,所以它是一个安全的序列化处理类,漏洞的触发点也是在于初始化JavaScriptSerializer类的实例的时候是否创建了SimpleTypeResolver类,如果创建了,并且反序列化的Json数据在可控的情况下就可以触发反序列化漏洞,借图来说明调用链过程

笔者还是选择ObjectDataProvider类方便调用任意被引用类中的方法,具体有关此类的用法可以看一下《.NET高级代码审计(第一课) XmlSerializer反序列化漏洞》,因为Process.Start方法启动一个线程需要配置ProcessStartInfo类相关的属性,例如指定文件名、指定启动参数,所以首先得考虑序列化ProcessStartInfo,这块可参考《.NET高级代码审计(第三课) Fastjson反序列化漏洞》 ,之后对生成的数据做减法,去掉无关的System.RuntimeType、System.IntPtr数据,最终得到反序列化Poc

笔者编写了触发代码,用Deserialize<Object>反序列化Json成功弹出计算器。

0x03 代码审计视角

3.1、Deserialize

从代码审计的角度其实很容易找到漏洞的污染点,通过前面几个小节的知识能发现需要满足一个关键条件new SimpleTypeResolver() ,再传入Json数据,就可被反序列化,例如下面的JsonHelper类

攻击者只需要控制传入字符串参数input便可轻松实现反序列化漏洞攻击。Github上也存在大量的不安全案例代码

3.2、DeserializeObject

JavaScriptSerializer还有一个反序列化方法DeserializeObject,这个方法同样可以触发漏洞,具体污染代码如下

0x04 案例复盘

最后再通过下面案例来复盘整个过程,全程展示在VS里调试里通过反序列化漏洞弹出计算器。

1. 输入http://localhost:5651/Default Post加载value值

2. 通过DeserializeObject反序列化 ,并弹出计算器

最后附上动态效果图

0x05 总结

JavaScriptSerializer凭借微软自身提供的优势,在实际开发中使用率还是比较高的,只要没有使用类型解析器或者将类型解析器配置为白名单中的有效类型就可以防止反序列化攻击(默认就是安全的序列化器),对于攻击者来说实际场景下估计利用概率不算高,毕竟很多开发者不会使用SimpleTypeResolver类去处理数据。最后.NET反序列化系列课程笔者会同步到 https://github.com/Ivan1ee/https://ivan1ee.gitbook.io/ ,后续笔者将陆续推出高质量的.NET反序列化漏洞文章,欢迎大伙持续关注,交流,更多的.NET安全和技巧可关注实验室公众号。

原文地址:https://www.cnblogs.com/Ivan1ee/p/10581973.html

时间: 2024-08-30 15:17:20

.NET高级代码审计(第四课) JavaScriptSerializer反序列化漏洞的相关文章

【python】第二模块 步骤一 第四课、数据库的高级查询

第四课.数据库的高级查询 一.课程介绍 1.1 课程介绍 学习目标 数据统计分析 聚合函数.分组查询.HAVING子句 多表连接查询 内连接.外连接.以及多表查询的多种语法 子查询 单行子查询.多行子查询.WHERE子查询.FROM子查询.SELECT子查询 原文地址:https://www.cnblogs.com/miaophp/p/12670511.html

python基础,python第四课

第四课学习的主要内容有生成器,迭代器,pyton装饰器,python开发规范,Json & pickle 序列化与反序列化 生成器 列表生成式 >>> b = [i+1 for i in range(0,10)] >>> b [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 生成器(Generator) 生成器的一种简单写法,把上面的列表生成式的[],换成()就成了生成器了,python3.0中通过__next__调用 >>> b

【Linux探索之旅】第二部分第四课:文件操纵,鼓掌之中

内容简介 1.第二部分第四课:文件操纵,鼓掌之中 2.第二部分第五课预告:用户和权限 文件操纵,鼓掌之中 既然上一课我们学习了Linux中的文件组织方式,那么现在就该是玩弄,啊不,是操纵它们的时候了. 文件操作有哪些呢?一般就是显示文件内容啦,还有拷贝文件,移动文件,删除文件,等等. 这一课我们还会学习链接的知识,认识硬链接和软链接的区别和原理. 当然了,虽说是文件操作,但是目录操作我们也会说.因为在Linux中,一切皆文件,目录也是文件. 这一课有很重要的基础概念,而且要学不少命令,都是很常用

【C语言探索之旅】 第一部分第四课第一章:变量的世界之内存那档事

内容简介 1.课程大纲 2.第一部分第四课第一章:变量的世界之内存那档事 3.第一部分第四课第二章预告:变量的世界之声明变量 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C语言编写三个游戏. C语言编程基础知识 什么是编程? 工欲善其事,必先利其器 你的第一个程序 变量的世界 运算符 条件表达式 循环语句 实战:第一个C语言小游戏 函数 练习题 习作:完善第一个C语言小游戏 C语言高级技术 模块化编程 进击的指针,C语言王牌 数组 字符串 预处理 创

【C语言探索之旅】 第一部分第四课第二章:变量的世界之变量声明

内容简介 1.课程大纲 2.第一部分第四课第二章:变量的世界之变量声明 3.第一部分第四课第三章预告:变量的世界之显示变量内容 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C语言编写三个游戏. C语言编程基础知识 什么是编程? 工欲善其事,必先利其器 你的第一个程序 变量的世界 运算符 条件表达式 循环语句 实战:第一个C语言小游戏 函数 练习题 习作:完善第一个C语言小游戏 C语言高级技术 模块化编程 进击的指针,C语言王牌 数组 字符串 预处理

C语言探索之旅】 第一部分第四课第三章:变量的世界之显示变量内容

内容简介 1.课程大纲 2.第一部分第四课第三章:变量的世界之显示变量内容 3.第一部分第五课预告:基本运算 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C语言编写三个游戏. C语言编程基础知识 什么是编程? 工欲善其事,必先利其器 你的第一个程序 变量的世界 基本运算 条件表达式 循环语句 实战:第一个C语言小游戏 函数 练习题 习作:完善第一个C语言小游戏 C语言高级技术 模块化编程 进击的指针,C语言王牌 数组 字符串 预处理 创建你自己的变量

【C语言探索之旅】 第二部分第四课:字符串

内容简介 1.课程大纲 2.第二部分第四课: 字符串 3.第二部分第五课预告: 预处理 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C语言编写三个游戏. C语言编程基础知识 什么是编程? 工欲善其事,必先利其器 你的第一个程序 变量的世界 运算那点事 条件表达式 循环语句 实战:第一个C语言小游戏 函数 练习题 习作:完善第一个C语言小游戏 C语言高级技术 模块化编程 进击的指针,C语言王牌 数组 字符串 预处理 创建你自己的变量类型 文件读写 动态

第四课 文件系统(下)

====================第四课 文件系统(下)==================== 一.sync/fsync/fdatasync------------------------ 1. 大多数磁盘I/O都通过缓冲进行, 写入文件其实只是写入缓冲区,直到缓冲区满, 才将其排入写队列. 2. 延迟写降低了写操作的次数,提高了写操作的效率, 但可能导致磁盘文件与缓冲区数据不同步. 3. sync/fsync/fdatasync用于强制磁盘文件与缓冲区同步. 4. sync将所有被修改

【连载】创业能力培训第四课总结

创业能力培训第四课总结 以一个故事开头: 老师问:3加4等于多少? 学生答:3加4等于8 老师说了3句话: 1.很好! 2.离答案很接近了哦! 3.还有没有人有别的答案? 表扬,保持其积极性. 具备什么样的条件才能创业 一.明确的创业动机和目标 1.人无我有 2.人有我优 3.人优我特 二.熟悉所要创业的领域(行业.市场.客户等) 三.一定的创业资源(部分即可) 四.一定的知识技能 五.拥有创业精神 创业3要素: 1.机会 2.资源 3.团队 团队: 1.才能互补 2.责任共担 3.共同的创业目