Comments (57)
这里有写,就是日志输出不太对。有道理,不过我刚写了个wpf的界面,可以添加需要管控的文件扩展名
from foks-trot.
我现在实现了 #32 提到的功能。在 https://github.com/wangzhankun/FOKS-TROT 仓库,commit hash 是 704f12fb206ee1c75f467d9bc24f64b4bbd320ef
。但是现在有下面的问题,使用程序对处于非机密文件夹的文件打开已经手动加密的文件时候,发现查看到的依然是明文。即使此时关闭驱动,依然能够查看到明文。重启电脑之后才能查看到密文。
我觉得可能是缓冲的问题。但是我创建了一个新的txt文档,重启电脑之后立即进行手动加密。这个时候仍然是只能看到明文。按理说,没有进程打开的话是没有明文缓冲的吧?是因为驱动打开了文件创建了缓冲导致的吗?
from foks-trot.
我没太懂你的逻辑,是手动加密以后,驱动不控制这个文件吗?不控制肯定是明文,因为没有在PostCreate将SOP指针指向密文缓冲,加密的过程中就已经建立了明文缓冲,所以都读取的明文缓冲。可以清除一下
from foks-trot.
你说的这个控制是指什么呀?
from foks-trot.
我目前定位到的问题是,在关闭PocUser之后,确实是执行了AppendTailer。但是成功关闭之后,非机密进程的SearchProtocolHost.exe跳入了PostRead并执行了解密读取。导致后续的其它进程打开看到的是明文缓冲。我在PostRead中设置了特判,如果发现是SearchProtocolHost就不允许解密读取。后续的进程也确实无法看到明文了。
但是比较奇怪的是,即使SearchProtocolHost.exe执行了解密读取,那也应该是放在了密文缓冲里面才对。后续的进程的明文缓冲应该仍然是密文吧?
from foks-trot.
因为没进PostCreate,没有将非授权进程的指针指向密文缓冲,所以全部指向的是明文缓冲。
我的控制的意思就是这样,就是驱动要控制这个文件。 @wangzhankun
from foks-trot.
别清空那个全局缓冲区就行,让这个文件进入到Create中。
from foks-trot.
SearchProtocolHost应该也无法进入PostCreate吧?那么为啥会在PreRead中找的到StreamContext呢?非机密进程的非机密文件夹是如何顺利进入到手动加密的文件进入解密过程?
另外全局缓冲区是不能不清空的吧?即使现在不清空,当驱动重新启动之后,驱动依然无法得知哪些非机密文件夹的文件是手动加密的吧?
from foks-trot.
你没有删除StreamContext,Read还能获取到StreamContext,所以它进来了。
from foks-trot.
加密过程中创建了StreamContext
from foks-trot.
要是想实现驱动重启以后还能知道,可以把链表写入一个文件里,等驱动加载时再读一下文件里的链表就行。
from foks-trot.
但是这个链表的维护就很麻烦吧?涉及到文件重命名、移动复制等问题。
from foks-trot.
确实哈
from foks-trot.
我是想的是,现在主要的问题在于,在加密过程中有非机密进程对手动加密的文件进行了访问获取到了StreamContext?导致PocUser退出的时候StreamContext并没有被删除?那是否可以增加一个lazy delete的标志位,指示当前StreanContext实际上被摧毁了,处于不可用的状态。在PreCreate中以及其它的各种操作中都对StreamContext进行特殊判断处理之类的。
from foks-trot.
加密过程中PocUser对文件创建了StreamContext,不用吧,你在特权加密以后FltDeleteStreamContext就行。
from foks-trot.
是在PocAppendEncTailerThread
函数中调用FltDeleteStreamContext
吗?因为现在是有了一个内核线程一直对StreamContext进行持有所以比较麻烦。冒然调用删除函数的话,如果其它进程已经获取了该StreamContext的话就会宕机吧?
from foks-trot.
我看注释说引入PocAppendEncTailerThread
的目的是防止docx文件的死锁,那么有没有可能,在手动加解密的过程中要求对被加解密文件的独占。然后再PostClose中进行特判,如果是处于手动加解密的模式直接执行诸如AppendEncTailer
等相关的后续操作可以吗?
from foks-trot.
手动加解密本身也是直接执行,并没有把PosUserPanel进程设置为需要等待的进程。今天新的版本可以在Write加密以后立刻执行线程AppendEncTailer。
from foks-trot.
要不加一个标识位吧,不过这个仍然解决不了关机重启以后,对文件无法控制的问题
from foks-trot.
我先调试一下这个新的版本会不会有问题。关机重启的话就没关系了。反正是已经加密的文件,无论是谁查看都一律看见密文。如果需要看明文那就要求手动解密我觉得也可。
再或者,如果非要实现对手动加密的文件对机密进程的透明解密,或许可以直接再PreCreate中读取文件的文件尾,看一下有没有我们的文件标识尾,如果有的话且文件是密文就可以进入到PostCreate中。
from foks-trot.
可以
from foks-trot.
FOKS-TROT.zip
弄好了,你搜一下PocFindOrCreateStreamContextOutsite函数,分别在PocMessageNotifyCallback和PocBypassIrrelevantBy_PathAndExtension函数中。主要就是在特权加密解密前创建StreamContext,路径过滤时,如果有StreamContext,那就忽略路径,这样加密以后正常应该还在控制范围内。不过还是有可能因为加密以后自动删掉了StreamContext而不解密,或者StreamContext自动删除以后还有明文缓冲,导致非授权进程也看到明文。等我把它试着清一下。 @wangzhankun
from foks-trot.
现在添加一个PocFindOrCreateStreamContextOutsite
函数实现的功能是对非机密文件夹下的文件的手动加密,缓冲的问题还是存在的。
from foks-trot.
我觉得手动加解密的最好的解决方法就是独占打开。打开的时候,关闭的时候清除所有的缓存。
from foks-trot.
我看ZwCreateFile
的描述也是建议以独占的形式打开文件。
from foks-trot.
你看我在PocReentryToEncrypt
这样修改测试合适不?特别是关于清除缓存那里。
from foks-trot.
突然想起来,咱们手动加解密之所以出现缓冲的问题是因为StreamContext机制的问题。那么为啥不直接使用非重入的FltCreateFile、FltReadFile、FltWriteFile和FltClose呢?直接对从FltReadFile读出的数据进行加密并写入,不重入到当前的驱动层,不就避免了对StreamContext的管理和缓冲的管理吗?在手动加解密中是否真的有必要使用Reentry机制呢?
from foks-trot.
可以,因为我懒。缓冲的问题存在是指非授权进程还能看到明文?
不重入的话,你把支持4GB以上文件也写一下吧,之前分配一块内存加密或解密,有时候不太够。可以放在循环里一次512MB这样读写加密一下。
要是重入的话,就不要独占了,因为Create也有操作。
from foks-trot.
另外,你在那里清除缓冲,恐怕起不了作用。之所以非授权进程能看到明文,是因为StreamContext计数清零以后被系统自动删除,驱动此时无法控制文件,所以没有把非授权进程指向密文缓冲,如果此时仍有明文缓冲,那就出现这个问题了。
你在这里清除,如果之后StreamContext和明文缓冲又建立了,不是又会出现这种情况。
特权加密和特权解密这块写完仔细测一下,我给你合并到主项目里。按照测试手册(TestManual.md)
from foks-trot.
Poc.zip
这下应该没问题了
from foks-trot.
Poc.zip 这下应该没问题了
这里的代码主要是实现了什么功能呀?你说的那个
特权加密和特权解密这块写完仔细测一下
是指我自己实现一个吗?还是说,你最新的Poc.zip实现了对缓冲等的管理我把这些测试一下呀?
我想用非重入的方式实现一下,这种方法可能会更好一些,你看可以吗?
from foks-trot.
是的,你自己实现一下非重入的吧,等我有时间给你合并一下。
from foks-trot.
这个版本应该加密机密文件夹之外的文件,非授权进程不会看到明文了。
from foks-trot.
FileSize % AES_BLOCK_SIZE == 0
是直接按照块加密,FileSize >= AES_BLOCK_SIZE && FileSize % AES_BLOCK_SIZE != 0
是采用密文挪用的方法进行加密。请问对于FileSize < AES_BLOCK_SIZE
的情况是怎么进行加密的呀?
from foks-trot.
拓展到16字节,然后使用块加密。不要使用那个加密函数自带的padding选项,直接分配一块16个字节的内存就行。
from foks-trot.
对于拓展的内容有要求吗?还是什么内容都行?另外拓展到16字节之后,我需要记录一些特殊的标志吗?以确保解密时正常解密。
from foks-trot.
请问文件标识尾中Flag和KeyAndCiphertextHash的作用是什么呀?它们的默认值都是全0吗?在写入的时候只需要关心FileName,FileSize,IsCipherText,EncryptionAlgorithmType字段即可吗?读取的时候只需要判断Flag是否为全0即可吗?
typedef struct _POC_ENCRYPTION_TAILER
{
CHAR Flag[32];
WCHAR FileName[POC_MAX_NAME_LENGTH];
LONGLONG FileSize;
BOOLEAN IsCipherText;
CHAR EncryptionAlgorithmType[32];
CHAR KeyAndCiphertextHash[32];
}POC_ENCRYPTION_TAILER, * PPOC_ENCRYPTION_TAILER;
```
from foks-trot.
你好,整体的代码逻辑我已经写完了。但是在密文挪用的时候出现了问题,你能帮我看一下?我对比你那边Write.c和Read.c的逻辑,是在是看不出来啥问题。
问题描述
代码实现
from foks-trot.
有问题的地方我都把注释写在右边了,我建议你把加密和解密分开写,要不逻辑有点复杂。单步调试每一种情况,这样应该可以找出问题。
上图写入的文件名是个错的;然后要你那个写入的尾要初始化清零;然后文件尾里的那个FileSize好像不太对,它是个LONGLONG;然后你那个解密写错了。
你可以用驱动来打开已加密的文件,能正常打开说明你加密写的没问题。
ManualEncryptDecrypt.zip
@wangzhankun
from foks-trot.
感谢你的帮助。
FILE_WRITE_THROUGH
System services, file systems, and drivers that write data to the file must actually transfer the data into the file before any requested write operation is considered complete.
我看定义就是确保数据是事实上写入了文件的,这个CreateOption应该没啥问题吧?
encryption_tailer_buffer这块内存要非分页加PAGE对齐
请问这个要求的原因是什么呀?
为什么要从FileObject->FileName.Buffer这里读名字?
这里是为加密准备的。加密的时候需要向文件标识尾中写入文件名。关于这个文件名是有什么格式上的特殊要求吗?我看自动加解密添加的文件标识尾好像是DOS格式的。
好像FileObject->FileName.Buffer确实不太对,我改成了
RtlCopyMemory(encryption_tailer->FileName, FileName, wcslen(FileName) * sizeof(WCHAR));
代码片段中的FileName是DOS格式的路径。
文件加密测试
加密写我跟自动加密之后的文件做了比对分析,加密写是正确的。确实是解密那里有问题。解密的时候忘了考虑文件标识尾了。
from foks-trot.
哦,我知道了。encryption_tailer_buffer 是 FltWriteFile 要求缓冲区是非分页和页面对齐的。我改一下。
from foks-trot.
没事
FILE_WRITE_THROUGH是缓冲的时候用的,非缓冲不需要这个标识
FileObject->FileName.Buffer应该没问题,
不过我看你上面图里的标识尾中的文件名好像不太对,\Users\wangzhankun\Desktop... 这个应该不是DOS名
from foks-trot.
我现在把所有的功能都开发完了,测试也基本通过,但是现在有个bug。如果你有空的吗可以帮忙看一下吗?
这个bug就是在对处在非机密文件夹下的txt文档进行特权加密之后并解密,无论是机密进程还是非机密进程打开该文件都是只能看到密文。
我确定手动加解密这边是没有问题的。我通过debug进行调试发现解密时确实是写入的是正确的内容。而且我在对该测试txt文档手动加密、解密之后,停用驱动之后,非机密进程和机密进程都能正常看到明文了。
该bug与文档大小无关。我测试了5字节、16字节、24字节大小的txt文档,都存在该问题。
复现步骤
- 将系统自带的notepad设置为非机密进程,将notepad++设置为机密进程
// L"C:\\Windows\\System32\\notepad.exe",
L"C:\\Desktop\\npp.7.8.1.bin\\notepad++.exe",
L"C:\\Program Files\\Notepad++\\notepad++.exe",
- 编译安装启动驱动
- 使用PocUserPannel对txt文档(必须处在非机密文件夹下)进行特权加密
- 使用notepad.exe打开该文档仅能看到密文,使用notepad++.exe打开该文档能看到明文
- 使用PocUserPannel对测试文档进行特权解密
- 使用非机密进程notepad.exe打开该文档看到密文,使用机密进程notepad++.exe打开该文档看到密文。
- 执行
sc stop poc
命令停用驱动 - 使用notepad.exe和notepad++.exe打开该测试文档都能看到明文。
代码
https://github.com/wangzhankun/FOKS-TROT
dev 分支
commit hash:
56b2f1b73ac5c3b5d80b33cc321a9b7040cdf9bb
from foks-trot.
我现在就是怀疑应该是缓存的问题。请问有没有什么方法可以把这些缓存给全部清除掉呢?使用ZwCreateFile
打开文件然后删除StreamContext
可行吗?
from foks-trot.
我现在就是怀疑应该是缓存的问题。请问有没有什么方法可以把这些缓存给全部清除掉呢?使用
ZwCreateFile
打开文件然后删除StreamContext
可行吗?
我怀疑就是驱动卸载的时候,Windows会把挂载了该驱动的所用文件系统的缓存给清空掉,所以卸载驱动之后再打开文件就能正常看到明文了。
而在使用特权进程加密文件之后,使用notepad打开该文件,系统缓存了密文。使用特权解密再解密之后,非机密进程和机密进程打开该文件只能看到系统缓存的密文。卸载驱动时,系统会冲刷缓存,之后再打开该文件就能看到明文了。
看样子必须得想办法在手动解密的代码中添加刷新缓存的功能。
from foks-trot.
看起来更像是你没有清掉标识,此时授权进程的读操作将明文再次解密,非授权进程指向原来的密文缓冲。你有比较一下两者的密文是不是相同吗?把这些值清零就行。
驱动卸载那是我清的缓冲,最新的一次更新加上了这个功能。
先把StreamContext这些值清零试试,要是不管用,可以参考我FileObject.c->PocCleanupSectionObjectPointers把明文缓冲和密文缓冲清一下。
@wangzhankun
from foks-trot.
我有两个疑问:
- 我可以直接调用FileObject.c->PocCleanupSectionObjectPointers进行清理吗?
- 按照FileObject.c->PocCleanupSectionObjectPointers方式进行冲刷得话,会不会出现缓存与实际内容不一致导致文件内容被覆盖得情况呢?我是想着可不可以直接把缓存里面的内容丢弃掉呢?因为从理论上讲,我们在使用特权加解密的时候是不允许同时有其它进程对该文件进行读写的,为了保证文件一致性,我建议是丢弃缓存内容。
from foks-trot.
清除缓冲代码
我在手动加解密全部写入完成之后,添加了清除缓冲的代码,
{// 清除缓存
PPOC_STREAM_CONTEXT stream_context = NULL;
__try
{
Status = PocFindOrCreateStreamContext(Instance, FileObject, FALSE, &stream_context, NULL);
if(Status != STATUS_SUCCESS)
{
PT_DBG_PRINT(PTDBG_TRACE_ROUTINES, ("%s@%s@%d PocFindOrCreateStreamContext failed: 0x%x\n", __FUNCTION__, __FILE__, __LINE__, Status));
__leave;
}
Status = PocCleanupSectionObjectPointers(stream_context);
if(STATUS_SUCCESS != Status)
{
PT_DBG_PRINT(PTDBG_TRACE_ROUTINES, ("%s@%s@%d PocCleanupSectionObjectPointers failed: 0x%x\n", __FUNCTION__, __FILE__, __LINE__, Status));
__leave;
}
}
__finally
{
}
}
bug
在执行完清除缓冲之后,在PocPostCreateOperationWhenSafe
中执行到1023行就会报错。原因是StreamContext->ShadowSectionObjectPointers
此时为NULL,访问了错误内存。
问题
我看在PocPostCreateOperationWhenSafe
函数中1023行以及以后的代码中并没有考虑StreamContext->ShadowSectionObjectPointers
为空的情况。如果我在这里添加了判断其是否为空的代码,会影响整体逻辑吗?
from foks-trot.
你把StreamContext相关的值清零就行,这个方法是可以的。不要清除缓冲了,你标识位不置零,这个问题不会解决的。
不要调用PocCleanupSectionObjectPointers函数,那个函数是FltMgr自动调用的,PostCreate那个地方没有问题。
from foks-trot.
你每次的NonCachedIo的Write以后,相应偏移和大小的缓冲都会被文件系统自动清除,解密完以后明文缓冲本来也是空的。
问题就是IsCiphertext标识位没有置零,Read把明文又解密了一次写入了明文缓冲。
from foks-trot.
将IsCipherText置为FALSE之后问题确实解决了。
from foks-trot.
我想着还是把PocFindOrCreateStreamContextOutsite
这个函数注释掉吧?感觉没啥用处。如果是想控制处于非机密文件夹下的被特权加密的文件的话,我认为应该在PreCreate
预读最后的文件标识尾。根据文件是否有文件标识尾来判断是否是被加密的机密文件。机密文件和机密拓展名的作用则是在进程写入的时候做自动加密用。
因为即使是在特权加密之后使用PocFindOrCreateStreamContextOutsite
创建了该文件的StreamContext,那么在系统重启之后,该文件仍然无法得到控制。
from foks-trot.
不错
from foks-trot.
同学, #42 你有空合并一下吧
from foks-trot.
我pull一下最新的代码在我这边合并玩之后,我再开个PR吧。
from foks-trot.
先不急,过段时间我测测再说吧
from foks-trot.
上传到分支wangzhankun即可 @wangzhankun
from foks-trot.
Related Issues (20)
- 对代码进行分类放置
- PreWrite的缓冲IO处理不当 HOT 1
- 联系方式 HOT 1
- 一次性读取的内存空间不足问题 HOT 1
- 手动加解密独占 HOT 24
- 如何进行程序打包安装 HOT 1
- 密文挪用的必要性 HOT 1
- notepad++与notepad泄露密文 HOT 25
- RESOURCE NOT OWNED HOT 1
- 特殊读写序列下文件无法写入,数据全部丢失 HOT 22
- PocAppendEncTailerToFile 为什么打开两次文件
- LengthReturned < 0 蓝屏 HOT 4
- 文件尾部乱码
- word和WPS的写入操作 HOT 1
- 使用git提交时报短读错误 HOT 4
- 一些其他问题
- 一些其他问题 HOT 1
- 支持win11 吗?
- 作者有更新吗或者其它商用版本
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from foks-trot.