3.4 使用应用程序兼容性的DLL注入
微软Windows应用程序兼容性基础设施/框架(应用垫片shim)是一项功能,允许为旧版本的操作系统(如Windows XP)创建的程序在现代版本的操作系统(如Windows 7或Windows 10)上运行。如Windows XP创建的程序能够在现代版本的操作系统(如Windows 7或Windows 10)上运行。上述功能是通过应用程序兼容性修复(垫片shim)实现的。
垫片是由微软提供给开发者的,这样他们就可以在不重写代码的情况下对其程序进行修复。当垫片被应用于一个程序,并且当垫片后的程序被执行时,垫片引擎将垫片后的程序所做的API调用重定向到垫片代码;这是通过将IAT中的指针替换为垫片代码的地址来实现的。
*关于应用程序如何使用IAT的细节已在前文的Windows API调用流程中涉及。
换句话说,它钩住了Windows API,将调用重定向到shim代码,而不是在DLL中直接调用API。作为API重定向的结果,shim代码可以修改传递给API的参数,重定向API,或者修改Windows操作系统的响应。下图应该可以帮助大家理解Windows操作系统中正常应用程序和shimed应用程序之间的交互差异。
为了帮助大家更好理解垫片的功能,下面让我们看一个例子。
假设几年前(在Windows 7发布之前),你写了一个应用程序(xyz.exe),在执行某些有用的操作之前检查操作系统版本。假设你的应用程序通过调用kernel32.dll中的GetVersion()API来确定操作系统的版本的API,并以此来确定操作系统的版本。简而言之,只有当操作系统的版本是Windows XP时,该应用程序才会做某些有用的事情。
现在,如果你把应用程序(xyz.exe)放在Windows 7上运行,它将不会做任何有用的事情,因为Windows 7上通过GetVersion()返回的操作系统版本与Windows XP不一致。要使该程序在Windows 7上运行,你可以修复代码并重建程序,或是可以在该程序(xyz.exe)上应用一个名为WinXPVersionLie的垫片。
在应用垫片后,当垫片应用程序(xyz.exe)在Windows 7上执行时,当它试图通过调用GetVersion()来确定操作系统版本时,垫片引擎拦截并返回一个不同的Windows版本(Windows XP而不是而不是Windows 7)。
更具体的说,当被垫片的应用程序被执行时,垫片引擎修改了IAT并将GetVersion()API调用重定向到垫片内代码(而不是kernel32.dll)。换句话说,WinXPVersionLie 垫片是在欺骗应用程序,使其相信自己是在Windows XP上运行,而没有修改应用程序中的代码。
关于垫片引擎工作的详细信息,可参阅Alex Ionescu的博文《应用程序兼容性数据库的秘密》(SDB)
浏览网址:http://www.alex-ionescu.com/?p=39
*左右滑动查看更多
微软提供了数以百计的垫片(例如WinXPVersionLie),可以应用于一个应用程序以改变其行为。其中一些垫片被攻击者滥用,以实现持久性,注入代码,并以较高的权限执行恶意代码。
3.4.1 创建一个shim垫片
有许多垫片可以被攻击者滥用于恶意的目的。在本小节中,我们将会引导大家完成创建一个用于将DLL注入目标进程的垫片的过程;这将帮助你了解攻击者创建一个垫片并滥用这一功能是多么容易。
在这个案例中,我们将为 notepad.exe 创建一个 shim(主要是 shimeng.dll 和 apphelp.dll — 这是应用程序兼容性接口),并使其加载一个我们选择的 DLL。为一个应用程序创建一个垫片可以分为四个步骤:
1.选择要进行垫片的应用程序
2.为该应用程序创建垫片数据库
3.保存数据库(.sdb文件)
4.安装数据库
要创建和安装一个垫片,需要有管理员权限。你可以通过使用微软提供的一个工具来执行前面所有的步骤,这个工具叫做Application Compatibility Toolkit(ACT)。
对于Windows 10,它与Windows ADK捆绑在一起;根据版本不同,它可以从以下网址下载:
https://developer.microsoft.com/en-us/windows/hardware/windows-assessment-deployment-kit
(Windows 7现已不支持下载)
*左右滑动查看更多
在64位版本的Windows上,ACT将安装两个版本的兼容性管理员工具(32位和64位)。要对32位程序进行调整,你必须使用32位版本的兼容性管理员工具(同理要对64位程序进行调整,需使用64位版本)。
要想了解关于调整引擎工作的详细信息,请参考Alex Ionescu的博文《应用程序兼容性数据库的秘密》(SDB)
浏览网址:http://www.alex-ionescu.com/?p=39
*左右滑动查看更多
为了演示这个概念,此处我们将使用32位版本的Windows 7,选择的目标进程是notepad.exe。我们将创建一个InjectDll垫片来使notepad.exe加载一个名为abcd.dll的DLL。要创建一个垫片,从开始菜单中启动兼容性管理员工具(32位),然后右键点击新数据库|应用程序修复。
在下面的对话框中,输入我们要调整的应用程序的细节。程序的名称和供应商名称可以是任何东西,但程序文件的位置应该是正确的。
在按下 "下一步 "按钮后,你将看到一个 "兼容模式 "对话框;你可以直接按 "下一步 "按钮。在下一个窗口中,你将会看到兼容性修复(Shims)对话框;在这里你可以选择各种Shims。
在这种情况下,我们对InjectDll 垫片感兴趣。选择InjectDll垫片复选框,然后点击参数按钮,输入DLL的路径(这是我们希望记事本加载的DLL),如下图所示。点击 "确定 "并按下 "下一步 "按钮。需要注意的一点是,InjectDll垫片选项只在32位兼容管理员工具中可用,这意味着你只能将这个shim应用到32位进程中。
接下来,你将看到一个屏幕,指定哪些属性将被程序(notepad)匹配。当notepad.exe运行时,所选的属性将被匹配,在匹配条件得到满足后,将应用垫片。为了使匹配条件不那么严格,此处取消了所有的选项,在这里显示。
在点击 "完成 "后,一个完整的应用程序和应用的修复的摘要就会呈现在你面前,如下图所示。在这一点上,包含notepad.exe的shim信息的shim数据库被创建。
下一步是保存数据库;要做到这一点,点击 "保存 "按钮,在出现提示时,给你的数据库起个名字并保存文件。在这种情况下,数据库文件被保存为notepad.sdb(你可以自由选择任何文件名)。
数据库文件被保存后,下一步是安装数据库。你可以通过右击保存的垫片,点击安装按钮进行安装,如下图所示。
另一种安装数据库的方法是使用一个内置的命令行工具,sdbinst.exe;可以通过使用以下命令安装数据库。
sdbinst.exe notepad.sdb
现在,如果你调用notepad.exe,abcd.dll将从c:test目录加载到notepad的进程地址空间,如下图所示。
3.4.2 shim工件
在这一点上,我们已经了解了如何使用shim将DLL加载到目标进程的地址空间。在我们研究攻击者如何使用 shim 之前,必须了解安装 shim 数据库(通过右键点击数据库并选择安装或使用sdbinst.exe工具)。
当你安装数据库时,安装程序为数据库创建一个GUID,并将.sdb文件复制到 %SystemRoot%AppPatchCustom<GUID>.sdb或%SystemRoot%AppPatchCustomCustom64<GUID>.sdb(分别用于32位和64位垫片)。
它还在以下注册表键中创建两个注册表项:
HKLMSOFTWAREMicrosoftWindows
NTCurrentVersionAppCompatFlagsCustom
HKLMSOFTWAREMicrosoftWindows
NTCurrentVersionAppCompatFlagsInstalledSDB
*左右滑动查看更多
下面的截图显示了创建的注册表项:
HKLMSOFTWAREMicrosoftWindows
NTCurrentVersionAppCompatFlagsCustom
这个注册表项包含应用垫片的程序名称,以及相关的垫片数据库文件(.sdb)。
第二个注册表包含数据库信息和shim数据库文件的安装路径。
HKLMSOFTWAREMicrosoftWindows
NTCurrentVersionAppCompatFlagsInstalledSDB
*左右滑动查看更多
创建这些组件的目的是为了在执行应用程序时,加载器通过查询这些注册表项来确定应用程序是否需要垫片,并调用垫片引擎,该引擎将使用位于AppPatch/目录中的.sdb文件的配置来垫片应用程序。由于安装shim数据库而产生的另一个组件时,在控制面板的已安装程序列表中添加了一个条目。
(未完待续)
— 往期回顾 —
原文始发于微信公众号(安恒信息安全服务):九维团队-青队(处置)| 代码注入和钩子(五)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论