23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

admin 2024年11月28日21:09:54评论2 views字数 4010阅读13分22秒阅读模式

1.Resx(原理部分)

这个插件与.resx和.resources文件的安全问题有关,感觉实战里还是有很多机会应用的上的,师傅们可以酌情研究一下。除了原理部分,还会提供几个应用场景,可以切到第二第三小节观看。

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

这里看一下ResxPlugins的test功能,看看用于测试的sink点是怎样的:

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

可以看到,这个plugins提供给我们几个主要的模式,主要有CompiledDotResources、BinaryFormatter、SoapFormatter等等。其中前者和后两者对应的sink点不同。先看看ResourceSet()构造方法吧,看起来只需传入一个文件地址 or stream即可实现RCE?

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

ResourceSet()中有两个关键的方法调用,一个是ResourceReader()一个是ResourceSet.ReadResources(),先跟进一下前者

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

前者把我们传入的Stream传入BinaryReader(),赋值给_store变量,然后又调用ResourceReader.ReadResources() 跟进一下:

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

这里实例化了BinaryFormatter,并且设置好了Binder,然后将BinaryFormatter对象赋值给_objFormatter。这块分析完了,再继续看看ResourceSet.ReadResources()

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

这里先拿到迭代器对象,然后调用其Value属性,这里会走入

System.Resources.ResourceReader.ResourceEnumerator.Value

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

其get属性有一个GetValueForNameIndex方法的调用,跟进:

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

其中有一个LoadObjectV2方法的调用,继续跟进,这个方法略复杂,不过在最后我们可以看到DeserializeObject()方法的调用

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

跟进:

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

经典的BinaryFormatter反序列化点,且传入的内容我们可控。不过这里还有些细节,因为这里会判断resources文件是否有效,普通的binaryFormatter payload是行不通的:

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

异常出现在

System.Resources.ResourceReader._ReadResources()

这里对序列化数据做了一些判断

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

理论上来说也可以生成一个原始BinaryFormatter的序列化payload,然后一步一步将其修饰到能够通过上述方法的检验,不过我这里就摸鱼了,直接用Resx插件生成一个来实验:

ysoserial.exe -p Resx -M CompiledDotResources -c "calc.exe" --of payload.resources

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

成功实现命令执行。

这是ResourceSet()这个sink点,单参数可控即可实现RCE,非常不错的点,审计中也可以多注意。另一个Sink点如下:

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

看到两个关键的方法调用,分别是ResXResourceReader()和它的GetEnumerator()。我们也来分析一下。

首先是ResXResourceReader()23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

主要就是对一些字段进行了初始化,比如进行fileName属性的赋值

(也可以接受TextReader、String,最后就是给reader字段赋值)

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

接着来看看GetEnumerator()

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

跟进EnsureResData(),这个方法就有意思了,会对reader、fileName、stream几个字段进行判断,比如我这里有fileName字段,那么就会读取目标文件,得到stream

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

接下来,进入ParseXml,看起来和Xml数据的处理有关

 

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

上面这里会获取一些节点,并且分别传入对应的处理方法

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

我们跟进

reader.LocalName.Equals("data")

分支的ParseDataNode()看看,其中有一个GetValue()方法的调用

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

继续跟进,可以找到一个

GenerateObjectFromDataNodeInfo

方法的调用

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

最后可以找到我们想要的东西:

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

这里有点复杂,不过从resx文件结构上看就会简单很多:

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

简单来说,这里会获取data节点的mimetype,决定后续反序列化行为使用的Formatter

例如我们上面的mimetype,符合

ResXResourceWriter.BinSerializedObjectMimeType

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

因此后续可以进入binaryformatter反序列化点,这里会获取Value节点的值,进行base64解码并进行BinaryFormatter反序列化

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

同理,这个后面还有Soap反序列化点

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

这也就是ResxPlugins提供给我们的BinaryFormatter、SoapFormatter两个Mode的原理,都是生成类似下面这样的数据:

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

不过ysoserial.net提供的Payload实际上可以进一步简写,他这么写可能是防止某些奇怪的异常?实际上简写成下面这样也是可以的

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

因此实战中可以多注意ResXResourceReader()、ResourceSet()等关键词(也要多注意调用栈上的其他方法),如果开发者用了相关的方法处理.resx/.resources文件,那么是很有可能造成RCE的

 

2.Resx应用其一(某微软白文件的反序列化)

测试这个问题时的意外发现,某个有微软签名的应用居然也有该问题,跟一些会搞免杀的师傅交流了一下,在进程链操作上应该能有用途。这个文件和处理resx文件密切相关,不给出具体的名字,师傅们可以自己找找。该文件中有一个ReadResources()方法,其第二个参数接受一个实现了IResourceReader的类的对象,并且调用了它的GetEnumerator

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

往上寻找调用并尝试寻找reader入参为ResXResourceReader类的对象的调用点,可以找到一个:

ReadResources(string filename, bool useSourcePath)

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

继续寻找ReadResources()的调用点,找到ProcessFileWorker()

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

继续寻找ProcessFileWorker()的调用,找到:

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

继续寻找,可以找到Main()函数中的调用:

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

inFiles从用户提交的参数中获取,于是:

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

该文件有微软签名:

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

哼哼,留给各位大师傅们解解谜,和处理Resx有关的exe,应该还是很好找的

 

3.Resx应用其二(webshell)

在web目录下新建一个App_LocalResources目录

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

将前文提到的恶意resx文件放在App_LocalResources目录下

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

访问任意一个页面,触发RCE

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

如果没有App_LocalResources这个目录,我们也可以自己创建,经验比较丰富的师傅应该能想到Windows下UDF提权的场景,通过类似下面这样的文件名:

App_LocalResources::$index_allocation

可以实现目录的创建,或者使用以前提到过的创建文件夹的链子进行文件夹创建

调试这个问题从调用栈来看非常复杂

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

不过很多从安全从业者视角看起来很复杂的问题,对于开发人员是常识(不信可以自行百度一下App_LocalResources和resx在WEB开发中的应用

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

因此我们可以知道,如果有App_GlobalResources文件夹,也是可以实现攻击的,不过App_GlobalResources只能位于应用根目录:

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

 

4.GetterCallGadgets

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

顾名思义,这个plugins是帮助我们触发任意属性的Get的,听到这个功能会不会感觉非常耳熟呢?没错,其核心思路就是通过PropertyGrid、ComboBox、ListBox、CheckedListBox相关的一些set去触发目标属性的get,我们以前已经学习过相关的链子了。这个工具的实现方法也非常简单粗暴:

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

以我们前面介绍过的System.Security.SecurityException类的Method属性为例,其set可以设置序列化payload,并在get中进行反序列化流程,因此我们可以先将这个类以及set赋值的行为转化为json,并放在一个json文件里(我这里是innergadget.json)

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

然后现在我们要手搓链子尝试触发上述Method属性的get会比较麻烦,我们应该怎么使用GetterCallGadgets plugins快速生成链子呢?使用如下参数:

ysoserial.exe -p GetterCallGadgets -g ListBox -m Method -i .innergadget.json

m参数决定你要触发哪个属性的Get。其实这个工具就是把之前介绍的通过PropertyGrid、ComboBox、ListBox、CheckedListBox触发Get的姿势写成了小工具,不用我们每次都手动写链子,算是半自动了。

 

5.NetNonRceGadgets

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

从名字上看这个Plugins就是用来生成一些不能RCE的链子的,恰巧我们之前也学习过了:

23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

PictureBox和InfiniteProgressPage两个是造成SSRF的链子,FileLogTraceListener是创建目录的链子。用法也很明了,比如:

ysoserial.exe -p NetNonRceGadgets -g PictureBox -f Json.Net -i "http://192.168.1.100/ssrf"

这样就是使用PictureBox这个gadget,攻击的反序列化点类型是Json.Net,触发后往http://192.168.1.100/ssrf地址发起请求

 

接下来,进入ParseXml,看起来和Xml数据的处理有关

原文始发于微信公众号(HW专项行动小组):23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年11月28日21:09:54
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   23.学习ysoserial.net的plugins第二弹(Resx以及实战应用)https://cn-sec.com/archives/3447138.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息