.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安全和技巧可关注实验室公众号。
.NET高级代码审计(第四课) JavaScriptSerializer反序列化漏洞的更多相关文章
- .NET高级代码审计(第二课) Json.Net反序列化漏洞
0X00 前言 Newtonsoft.Json,这是一个开源的Json.Net库,官方地址:https://www.newtonsoft.com/json ,一个读写Json效率非常高的.Net库,在 ...
- .NET高级代码审计(第一课)XmlSerializer反序列化漏洞
0X00 前言 在.NET 框架中的 XmlSerializer 类是一种很棒的工具,它是将高度结构化的 XML 数据映射为 .NET 对象.XmlSerializer类在程序中通过单个 API 调用 ...
- .NET高级代码审计(第五课) .NET Remoting反序列化漏洞
0x00 前言 最近几天国外安全研究员Soroush Dalili (@irsdl)公布了.NET Remoting应用程序可能存在反序列化安全风险,当服务端使用HTTP信道中的SoapServerF ...
- .NET高级代码审计(第三课)Fastjson反序列化漏洞
0X00 前言 Java中的Fastjson曾经爆出了多个反序列化漏洞和Bypass版本,而在.Net领域也有一个Fastjson的库,作者官宣这是一个读写Json效率最高的的.Net 组件,使用内置 ...
- 【原创 深度学习与TensorFlow 动手实践系列 - 4】第四课:卷积神经网络 - 高级篇
[原创 深度学习与TensorFlow 动手实践系列 - 4]第四课:卷积神经网络 - 高级篇 提纲: 1. AlexNet:现代神经网络起源 2. VGG:AlexNet增强版 3. GoogleN ...
- [代码审计]四个实例递进php反序列化漏洞理解【转载】
原作者:大方子 原文链接:https://blog.csdn.net/nzjdsds/article/details/82703639 0x01 索引 最近在总结php序列化相关的知识,看了好多前辈师 ...
- 【C语言探险】 第四课的第二部分:串
内容简单介绍 1.课程大纲 2.第二部分第四课: 字符串 3.第二部分第五课预告: 预处理 课程大纲 我们的课程分为四大部分,每个部分结束后都会有练习题,并会发布答案.还会带大家用C语言编写三个游戏. ...
- 【Linux探索之旅】第二部分第四课:文件操纵,鼓掌之中
内容简介 1.第二部分第四课:文件操纵,鼓掌之中 2.第二部分第五课预告:用户和权限 文件操纵,鼓掌之中 既然上一课我们学习了Linux中的文件组织方式,那么现在就该是玩弄,啊不,是操纵它们的时候了. ...
- 【C语言探索之旅】 第二部分第四课:字符串
内容简介 1.课程大纲 2.第二部分第四课: 字符串 3.第二部分第五课预告: 预处理 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C语言编写三个游戏. ...
随机推荐
- jquery纯数字验证
$(document).ready(function(){ //纯数字验证,只让输入数字,比如-号等都不然输入. $('#user-defined').unbind(); $('#user-de ...
- mysql Error_code: 1593
mysql slave_IO_running no 查看data目录下的.err文件提示:mysql Error_code: 1593 解决方法: 1.检查 data目录下auto.cnf 文件中 ...
- SQL表两列取一列唯一值的记录
问下SQL表两列取一列唯一值的 A列 B列 C列 1001 AA 2012-01-02 1001 BB 2012-02-05 100 ...
- django网页图片验证码功能
在一个正常的登录系统中,验证码是非常重要的,用于识别人机,毕竟我们都知道,这个世界中存在着万恶的爬虫,验证码有很多种方式,有图片的,有邮件的,有短信的,有拼图的,不管什么样的验证码,目的都是验证访问用 ...
- Reading CLR via c# 4th Edition
In fact, at runtime, the CLR has no idea which programming language the developer used for thesource ...
- mysql里几个超时配置参数wait_timeout,net_read_timeout等
以下这些配置项单位都是秒,在mysql命令行中可以使用show global variables like '变量名';可查询配置值. connect_timeout:连接响应超时时间.服务器端在这个 ...
- 利用Delphi-cross-socket 库提升kbmmw 跨平台开发
以前我写过了,通过httpsys 提升windows 下,delphi 多层应用.随着delphi 10.2 对linux 的支持,很多人也想在linux 下 发布kbmmw 服务器,但是官方仅通过i ...
- 2019.01.02 bzoj2467: [中山市选2010]生成树(矩阵树定理)
传送门 矩阵树定理模板题. 题意简述:自己看题面吧太简单懒得写了 直接构建出这4n4n4n个点然后按照题面连边之后跑矩阵树即可. 代码: #include<bits/stdc++.h> # ...
- 使用express框架和mongoose在MongoDB新增数据
1.安装 express npm i express --save 2.安装 mongoDB npm i mongodb --save 3.安装mongoose npm i mongoose --sa ...
- es5数组的新方法
1.every方法 //逻辑判断返回值为一个Boolean值 every方法就是每一个返回函数的返回值都是true的时候,才为true,否则为false var arr=[1,2,5,88,5,555 ...