nt文件系统(3)--文件透明加密



前言

前面已经总结了几种常见的文件系统过滤驱动,接下来将其延申至应用领域,其中一种比较常见的便是文件透明加密系统,这是一种防止企业内部数据泄露的手段,是实现泄露数据追踪的有效方法之一。

简述

文件透明加密系统可以简单理解对系统中指定类型的文件进行加解密,这一过程对于用户是没有感知的,但是当用户试图将文件通过某途径泄露(拷贝等)时,其被泄露的只会是一个被加密过的文件,也就限制了文件的流通。

文件透明加密系统中着重需要关注的几个问题:

  • 进程的有效标识
  • 加密文件的有效标识
  • 双缓存问题(授权进程与非授权进程不能打开同一块缓存)
  • 安全性问题

本文将一一逐一说明,当然限于自身能力及参考资料过少的问题,其中部分并不能很详细的说清。

基础回顾

文件系统过滤基础

image-20221010185916016

上图展示了文件IO的基本过程。

image-20221010185929977

上图展示了文件过滤驱动在IO过程中所处的位置。

要实现一个文件透明加密首先需要做的就研究 IRP 的过滤,假设当前已经使用了微过滤框架,那么最少需要对以下几大类进行注册。

  1. IRP_OPERATION:基本的 I/O 操作
  2. IRP_GENERATED_IO:由 Minifilter 自身构造的 I/O 请求
  3. FAST_IO_OPERATION:基于系统缓存机制的快速访问 I/O 请求,它会直接访问系统缓存内容

重入问题

由于在文件透明加密系统中需要用到读写文件相关的函数,故需要解决重入问题。
minifilter 中可以简单的通过 Flt 系列函数避免 IRP 重入问题。
至于在传统的过滤驱动中避免 IRP 重入,存在有多种方法,这里就不细说了。

文件缓存管理器

操作系统为了更快的响应读写,提供了对于文件数据的缓存功能。
当应用程序以缓存方式发送的 I/O 请求, I/O 管理器会以 Fast I/O 快速方式来处理该请求, 它不会产生 IRP 数据包, 而是直接访问缓存管理器和系统中的缓存区交互, 从而导致过滤驱动实例无法截取到它。
在常规的文件系统过滤驱动中,fastio 是一个相对不易处理的部分,可以选择直接返回FALSE,统一使用IRP过滤,当然这种方式会大大降低文件的操作效率。

在单缓存情况下,为了实现授信进程缓存与非授信进程缓存之间的切换,需要对 IRP 的 IRP_MJ_CLOSE 或者 IRP_MJ_CLEANUP 例程进行处理,可以通过 CcFlushCache 例程清除缓存数据,但是这种做法又可能导致其它问题。

相对较好的办法是使用双缓存机制,即为授信与非授信进程各分配一块缓存区,缺点是会增加设计复杂度及内存开销。

可信进程识别

很多示例或说明中,要么使用md5 要么使用文件名作为可信任进程,
关于这点,其中各有缺点。
当然本来也不应该对该系统的安全性做到抛根挖底,这种对抗性的问题除非自己实现一个操作系统方可解决。
一般的对抗会在牢固和兼容性中间找平衡。

加密

加密文件标识

关于加密标识存放的位置,有多种选择,有人说放文件头,有人说放文件尾,有人说拆开成独立文件,也有人放在文件流(这种只适用于NTFS),这个见仁见智了,各有优缺。

加密算法

加密算法可以采用非对称算法,也可以使用对称算法,从算法的速度上讲,对称算法比非对称算法要快上一丢丢。
有用 AES 的 有用 RSA的,还有用位异或表的,也有那种多重加密的。
总之,速度跟强度一般成正比。

文件映射

在使用文件映射读写文件时,其又是一种情况。

image-20221010185958644

能直接从缓存管理器->虚拟内存管理器中请求到数据称为:缓存读写请求
若缓存管理器中不能直接请求得到,
会经由虚拟内存管理器->IO管理器向文件系统发出非缓存的分页IO请求,这种称为分页读写请求

故分页读写请求可以跟非缓存读写请求归并到一起,都是由文件系统直接向下层设备请求数据并返回

双缓存

根据 《基于文件过滤驱动的透明加密那点事儿》一文的说明,使用双缓存的方式属于三代以后的技术。

第一代中并不使用驱动实现。
第二代中需要不断的清理缓存,既复杂,且容易出现问题。
另一种便是完全忽略 fastio及缓存读写,虽然效率低下,但可以避免第二代中的技术难题。
第三代和第四代均使用 Layerfsd的双缓存实现,区别仅在于一个是传统过滤驱动,一个是新的 minifilter。

虽然我很想花大量篇幅谈这个,但是网上只能找到两份代码作为参考

  • 一份略残缺基于 minifilter – (X70FSD)
  • 一份很乱基于 sfilter 实现 – (SfilterdoubleFcb)

剩下的七七八八的论文中都将这块视作黑盒,草草几句带过。

X70FSD 我只简单读了一下,基本是参考 fastfat 来实现,另外它并不完整,只有核心部分,剩下的部分基本可以从核心推导出来,中间还用到内核非导出函数,具体可行自行阅读,建议阅读时对着 fastfat 一起。

总结

本文展示文件透明加密系统的一些基础内容。

参考

参考论文