13.Fastjson(.NET)反序列化点后篇

2024-10-29 19:47   广东  

1.关于AssemblyInstaller

在前篇我们基本介绍了.NET Fastjson反序列化问题的一些基本情况,在最后提到了黑名单里的几个关键类,我们使用的只是ObjectDataProvider,其它几个之前确实没见过,所以这里来研究一下别的sink点

那么就从第一个AssemblyInstaller开始,从他的名字就可以看出来,这玩意涉及程序集的加载安装

涉及程序集的加载,那确实很敏感了,我们来看看是怎么个安装法,首先我们要写一个符合Installer规则的类,然后编译成exe:

写一个MyCustomInstaller类,实现Installer。并且要使用一个特性:

[RunInstaller(true)]

然后写一个构造函数,里面调用StartCalculator()方法,一个弹计算器的方法。然后需要实现Install方法

编译成ConsoleApp3.exe

然后我们使用官方给出的demo去加载ConsoleApp3.exe

可见,我们构造方法中的恶意代码确实被成功执行了,但是这里是依次调用Install()、Commit()方法才实现执行的。而Fastjson并不能随意调用目标类中的方法,因此我们需要搞清楚AssemblyInstaller构造方法、Install()、Commit()这几个方法背后的奥秘。首先看到AssemblyInstaller

这里对Path属性赋值,我们来看看Path属性的set

注意看,这里调用

Assembly.LoadFrom()

去对我们传入的exe路径进行了加载,得到Assembly对象,并赋值给assembly属性。这是个关键步骤,但是还不能触发恶意代码

那么压力就给到Install()、Commit(),注意到这俩方法一上来就调用本类的

InitializeFromAssembly()

从名字上看就涉及Assembly的初始化

于是我们跟进这个方法,这个方法一上来就把前面提到的assembly属性传入GetInstallerTypes方法,执行结果给array赋值,注意这个array是Type[]类型的

这个方法里面在做什么也是一目了然

后续遍历array并传入

Activator.CreateInstance()

调用目标类构造方法生成对象,也就导致恶意代码被执行

因此其实最关键的有两步,第一步是触发Path的set,完成

Assembly.LoadFrom()

再接着是要触发

InitializeFromAssembly()

那么除了commit和install两个方法,还有什么地方能触发InitializeFromAssembly()呢?最好是一些属性的get和set,这里很容易找到:

HelpText属性的get,就可以触发

因此我们的测试代码可以写成这样:

同样是只用Get和Set就能完成RCE,当然你可能会说这样实战还得要求我们上传一个exe文件,也挺麻烦,但其实不用,我们可以给ConsoleApp3.exe改为ConsoleApp3.jpg

然后用file://协议去加载

同样能实现RCE(当然我实测不用file://协议也行,反正后缀名无所谓的)

不过这个HelpText需要get才能触发,而这边的Fastjson好像又没有$ref触发get的姿势,所以得想办法找一些触发get的链子(Json.Net相关反序列化点里我们介绍过不少了),这里就要牵扯到黑名单中的另一个类

system.windows.forms.bindingsource


2.关于bindingsource

Bindingsource里有两个属性的set方法组合起来就可以触发任意类的指定属性的get方法,分别是DataMember和DataSource。其中DataSource这边先赋值一下,赋值成你想触发特定get方法的对象

然后DataMember这边赋值成你想要触发get的目标类中的对应属性名

进入ResetList()方法,这里把dataSource传入GetListFromType方法得到一个List,然后和dataMember一起传入GetList()方法

这里面有几个关键步骤

也即会从目标类中搜索特定属性,属性名也就是dataMember的值,然后会调用GetValue()方法获取其值,这会触发get操作:

So这里就可以把链子续上了,我们给dataSource设置成AssemblyInstaller类的对象,然后给dataMember设置成HelpText即可。


3.关于WorkflowDesigner

可以看到,和“画布”功能有关,当时就在想这个不会又和Xaml扯上关系了吧

往下看一下它支持的方法:

明牌了啊这直接,这个类确实支持处理Xaml。那我们来找找有没有什么属性的set可以触发恶意操作

注意到

PropertyInspectorFontAndColorData

属性的set操作,这里把传入的值传给XmlReader进行处理,然后进一步传给

XamlReader.Load()

梦开始的地方,希望你还记得这个方法,我们在XmlSerializer反序列化问题的学习中了解过这个方法,它和

XamlReader.Parse()

都可以加载xaml格式的数据,可以实现RCE

因此我们还是准备一个恶意xaml代码

读取这个文件的内容,并传给PropertyInspectorFontAndColorData属性

成功RCE,这个显然比上一个sink点简单多了。不过这里需要加一个[STAThread]特性


4.ResourceDictionary

又是WPF相关,推测最终的Sink点又是XamlReader,实际上也确实是。

其Source属性里这一段,涉及XamlReader,我们跟进

GetObjectAndCloseStreamCore()

这个方法里有一个关键点是一个委托的调用,把XamlReader传进去了

这个委托对应的方法是

AppModelKnownContentFactory.XamlConverterCore()

该方法最后有XamlReader.Load()的调用,可以执行Xaml代码

那么还有一个关键点在于,这个stream,我们可控吗?一路追溯这个参数的来源

又注意到,s的值是从远端文件中获取

因此可以做一个恶意服务端,返回恶意Xaml内容,借助这个链子实现RCE


5.ExchangeSettingsProvider

这玩意需要有Exchange环境,找半天没找到相关的源码,然后发现Y4er师傅在自己的博客上也分析了本文的几个.net Fastjson利用sink点,里面就给出了相关的源码

可以看到ByteData属性的set方法,拿到传入的value之后丢给binaryFormatter的Deserialize()方法,好简单的二次反序列化(


6.参考

https://y4er.com/posts/several-other-gadgets-of-dotnet/#systemactivitiespresentationworkflowdesigner

HW专项行动小组
大师!教我打攻防
 最新文章