Acronis 的“ngscan”反恶意软件扫描驱动程序在筛选器通信端口上存在不正确/不当的访问控制。 该微筛选器驱动程序支持以下可能被利用的功能:
对 ngscan.sys 驱动程序的分析始于使用 Ida Pro 对该驱动程序进行反编译。研究人员注意到,虽然创建了设备对象,但并未创建用于通过 DeviceIoControl 与驱动程序交互的符号链接。
因此,分析继续转向观察筛选器通信端口的功能。
在初始化期间,驱动程序会创建五(5)个通信端口,以支持来自其他进程的交互。

图 1:支持创建最多五(5)个筛选器通信端口(FCP)的例程
观察到该函数被调用,使用默认 DACL 初始化这 5 个 FCP,而最后一个 FCP 则以 NULL DACL 创建。

图 2:使用默认/NULL DACL 创建 FCP
分析继续通过观察筛选器驱动程序指定的 CreateNotifyCallback 和 MessageNotifyCallback 函数进行。 每当进程打开一个连接并向通信端口发送消息时,这些回调函数就会被调用。

初步检查 MessageNotifyCallback 后发现,传入消息的缓冲区必须满足以下要求:
一旦这些检查通过,将从 InputBuffer 中解析出一个函数编号,并在以下 switch 分支中用于选择使用所提供的输入执行哪个函数。

图 3:MessageNotifyCallback 支持的部分函数
对每个受支持的函数进行检查后,发现了两个可能被滥用以实现任意文件读取的相关函数。

图 4:支持创建扫描上下文并返回该扫描上下文文件句柄的函数(第 206、233 行)
虽然“扫描上下文”的确切功能尚不完全清楚,但分析表明,可以为用户在 InputBuffer 中指定的任意文件创建文件扫描上下文。 一旦创建了扫描上下文,扫描上下文 ID 会通过输出缓冲区返回给用户。

图 5:创建扫描上下文例程将扫描上下文数据返回给用户

图 6:发送给微筛选器驱动程序的数据,请求访问受保护的 SAM 注册表文件(\??\C:\Windows\System32\config\SAM)

图 7:微筛选器驱动程序的响应,包含扫描上下文 ID(0x3aaf)
一旦创建了扫描上下文并获取了其 ID,请求应用程序就可以再次向通信端口发送消息,从而打开与该扫描上下文对应的文件句柄。

图 8:获取已创建扫描上下文对应的文件句柄
标记为 CreateFileReturnHandle0 的函数仅在前一个函数 SearchScanContextsByID 返回有效扫描上下文时才会被调用。
例如,仅当请求进程提供了先前通过调用上述扫描创建函数所创建的有效上下文 ID 时。
请求程序通过将扫描上下文 ID 提供给图 8(图 4,第 233 行)中指定的函数,成功打开了该特权文件的句柄。

图 9:成功获取 SAM 文件的文件句柄
使用 processhacker,通过查看请求进程的句柄确认了对该文件句柄的访问:

图 10:包含 SAM 文件句柄的进程

图 11:授予所获句柄的读取访问权限
对受支持函数的进一步探索显示,可以控制三个注册表键,这些键可能被利用来获得代码执行能力。

图 12:支持打开注册表键句柄的函数

图 13:打开注册表键,指定要注入进程的挂钩监视 DLL

图 14:OpenKey 函数展示了使用用户可控数据修改注册表键的能力
目前尚未确定 Acronis 套件为进行挂钩而执行 DLL 注入的具体条件,但若启用了挂钩监视,则认为由 x64HookLib 和 x86HookLib 注册表键指定的 DLL 会被注入到指定进程中。

图 15:x64HookLibKey 指定挂钩 DLL C:\ProgramData\Acronis\NGMP\shared\acr_protect.x64.dll
上文关于任意文件读取的分析中省略了打开扫描上下文的过程。
进程可以不创建扫描上下文,而是通过反复向 GetScanContextByID 函数发送请求来暴力枚举扫描上下文 ID,循环遍历 ContextID 值,直到找到一个或多个有效的扫描上下文。