方法是我们关心和寻求的。
只需使用ObjectDataProvider的ObjectInstance方法实例化XamlReader,再指定MethodName为Parse,并且给MethodParameters传递序列化之后的资源字典数据,这样就可以完成XmlSerializer反序列化攻击链的打造。
0x04 代码审计视角
从代码审计的角度其实很容易找到漏洞的污染点,通过前面几个小节的知识能发现序列化需要满足一个关键条件Type.GetType,程序必须通过Type类的静态方法GetType,例如以下demo
首先创建XmlDocument对象载入xml,变量typeName通过Xpath获取到Item节点的type属性的值,并传给了Type.GetType,紧接着读取Item节点内的所有Xml数据,最终交给Deserialize方法反序列化,这是一个近乎完美的利用点。再来看笔者在github上收集到的XmlSerializer反序列化类:XmlSerializeUtil.cs
此处值参数类型为Type,代码本身没有问题,问题在于程序开发者可能会先定义一个字符串变量来接受传递的type值,通过Type.GetType(string)返回 Type对象再传递进DeserializeXml,在代码审计的过程中也需要关注此处type的来源。
0x05 案例复盘
最后再通过下面案例来复盘整个过程,全程展示在VS里调试里通过反序列化漏洞弹出计算器。
1.输入http://localhost:5651/Default?node=root&value=type加载了远程的(192.168.231.135)1.xml文件
2. 通过xmlHelper.GetValue得到root节点下的所有XML数据
3. 这步最关键,得到root节点的type属性,并提供给GetType方法,XmlSerializer对象实例化成功
4. XmlSerializer.Deserialize(xmlReader)成功调出计算器
最后附上动图
0x06 总结
由于XmlSerializer是系统默认的反序列类,所以在实际开发中使用率还是比较高的,攻击者发现污染点可控的时候,可以从两个维度去寻找利用的点,第一从Web应用程序中寻求可以执行命令或者写WebShell的类和方法;第二就是本文中所说的利用ObjectDataProvider、ResourceDictionary、XamlReader组成的攻击链去执行命令或者反弹Shell ,最后.NET反序列化系列课程笔者会同步到 https://github.com/Ivan1ee/、https://ivan1ee.gitbook.io/,后续笔者将陆续推出高质量的.NET反序列化漏洞文章,大致课程大纲如下图