-
-
[原创]Windows Shim Engine 初探即利用
-
发表于:
2015-3-27 18:04
14521
-
[原创]Windows Shim Engine 初探即利用
Windows Shim Engine 初探即利用
用过EMET的同学应该知道,EMET会注入一个EMET.dll到被保护进程,不过以前我并没有关心过这个注入的过程。最近注意到Windows中的“程序兼容性”实现,才发现EMET正是利用的这个机制来加载它的dll到指定进程的。稍微了解了一下这个兼容性机制之后,发现这基本上是一个Pattern Matching + 程序修补引擎。
Pattern Matching就是指以什么条件来判断一个程序需要兼容性引擎的介入,介入之后需要做什么。
修补的话基本上两个方面,一个是通过Hook IAT实现API欺骗,以便模拟旧的API的行为,另一个是直接Patch程序的代码。所以其实这个兼容性引擎也被MS用来修补CVE。
稍微具体说一下:基本上整个框架是由apphelp.dll和Windows\AppPatch下面的文件来完成的,sdb是数据库,dll是shim(垫片,用来实现“假”API的逻辑)
这个已经被很多人研究过了,总体来说Windows有几个系统级别的数据库,这些数据库记录了一些已知的、会有兼容性问题的程序或者安装程序列表。每个条目会保存一些条件,比如exe名字是什么、版本是多少、目录下会存在什么文件之类的,只有这些条件都满足的时候,一个兼容性操作才会匹配。至于什么时候去匹配的,这是在父进程CreateProcess的时候,由apphelp.dll去检查的。一旦匹配,apphelp会读取一些信息,然后放到新的进程的内存中,新进程PEB会有指针和flag帮助ntdll找到这些信息。新的进程开始后,ntdll会读取PEB中的相关信息,然后加载修补引擎,这里也就使apphelp,然后进行修补操作。至于信息的查找和转递过程,这个和os的实现有关,不过总之,最终结果就是新进程中的apphelp.dll会加载database中指定的需要的shim。
EMET则是利用了这个机制,虽然EMET.dll不是一个真正的shim(垫片),不过它利用的是这个加载shim的时机去加载自己。所以EMET会自己建立一个sdb,把一些需要保护的exe名字加入列表,基本上匹配条件只是exe的名字。然后兼容性操作(需要加载的shim)设置为EMET.dll。注册这个sdb到windows,就完事了。可见一个自定义的sdb可以被用来编写自己的 修(注) 补(入) 逻辑。不过一个比较麻烦的地方有两个,一个是sdb的建立比较烦,MSDN提到了sdb相关API,不过却是“半公开”状态,一个是shim的接口不公开。
经过前人的研究,大概了解了sdb的构造,它基本就是一个树,每个节点是一个TAG。可以理解为一个文件系统的目录,目录里面可以有文件,也可以有子目录。LIST类别的TAG相当于目录,其他类别的TAG相当于文件,根目录就是TAG_ROOT。一些项目比如sdb2xml, sdb-explorer可以帮助理解sdb本身的结构。它们利用的就是apphelp中的sdb API。至于怎么构造,为了方便起见,我做了一个简易的sdb打包器,从xml中读取信息,然后打包成sdb,实测可用。
shim的话,就是一个dll,但是要导出两个接口函数:
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)