泄露程序执行记录的 Windows Shim 缓存
Windows Shim 是一种让新操作系统能兼容旧程序的技术。顾名思义,Shim 会在应用程序和操作系统之间增加一层处理逻辑,比如拦截和修改 API 调用的参数和返回值,模拟旧的操作系统,实现兼容应用程序的目的。
由于并非所有的程序都需要进行兼容处理,Windows 为此提供了一个名为 Application Compatibility Database (应用程序兼容性数据库)的数据库,通常简写为 SDB,其中保存了需要兼容的程序清单,以及需要进行的兼容性操作。然而,每次创建进程都要查询数据库会损耗性能,Windows 将查询结果缓存在内存中。该缓存被称作 Application Compatibility Cache,大小为 1024 条,并且在每次系统关机时写入注册表作为持久化保存。正是由于这个特性,导致泄露了用户程序执行记录。
Shim Cache 存放在注册表如下位置:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatCache


可以使用 Zimmerman Tools 中的命令行工具 AppCompatCacheParser
来查看缓存内容:
cmdAppCompatCacheParser.exe --csv c:\temp --csvf results.csv
需要注意的是,由于注册表中保存的是上一次系统关机时写入的持久化缓存,所以工具无法提取到这次开机后运行的程序记录。也因为如此,仅仅删除该注册表键也是无法清除缓存记录的——重启后你仍能在注册表里找到它。
好在 Windows 提供了两个 API 可以用来完成清理缓存操作:
由 Apphelp.dll 提供的
ShimFlushCache()
,最低支持支持 Windows Vista 和 Windows 2008 操作系统c++
BOOL WINAPI ShimFlushCache( _In_opt_ HWND hwnd, _In_opt_ HINSTANCE hInstance, _In_opt_ LPCSTR lpszCmdLine, _In_ int nCmdShow );
由 kernel32.dll 导出的
BaseFlushAppcompatCache()
,最低支持支持 Windows XP 和 Windows 2003 操作系统c++
BOOL WINAPI BaseFlushAppcompatCache(void);
由于 BaseFlushAppcompatCache()
没有参数,我们可以通过 rundll32.exe 来进行调用(必须以管理员身份运行):
cmdrundll32.exe kernel32.dll,BaseFlushAppcompatCache
最后,记得删除注册表中的 AppCompatCache 键值。
顺带一提,我们可以创建自定义的 SDB 数据库,实现代码注入。这种挂马方法比较隐蔽,沙盒无法检测到恶意代码的注入行为,常见的系统分析软件,比如 Autoruns,也不会检测 Shim 数据库。
使用微软的 Compatibility Administrator 工具可以创建自定义 SDB,该程序是 Windows Assessment and Deployment Kit 中的一个组件。通常被用于注入代码的兼容性修复操作有 InjectDll 和 RedirectEXE:

不过这两种操作只能用于 32 位程序。
创建的 .sdb 文件可以用 Windows 自带的 sdbinst
命令安装到其他系统。通过检查下面的注册表项来确认系统是否被植入自定义 SDB:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Custom\
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\InstalledSDB\