Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

notepad++与notepad泄露密文 #40

Closed
wangzhankun opened this issue Jun 24, 2022 · 25 comments
Closed

notepad++与notepad泄露密文 #40

wangzhankun opened this issue Jun 24, 2022 · 25 comments

Comments

@wangzhankun
Copy link
Collaborator

wangzhankun commented Jun 24, 2022

测试环境

  • Windows 10
  • 最新的代码(我没有做任何修改,除了将notepad++设置为机密进程,notepad设置为非机密进程)
  • 16字节的txt文档:hello.txt,全是ascii字符
  • 机密文件夹testdata,非机密文件夹src
  • 机密进程 notepad++
  • 非机密进程notepad

bug复现

  1. 启动驱动
  2. 将hello.txt文档从非机密文件夹src拷贝到机密文件夹testdata(此时驱动会自动对该文件进行透明加密)
  3. 使用机密进程notepad++.exe打开该文档看到明文,不关闭该文档
  4. 使用非机密进程notepad打开该文档也能看到明文
  5. 关闭notepad
  6. 再次使用notepad打开该文档看到密文
  7. 如果未能复现,请关闭关闭所有进程,卸载驱动,删除机密文件夹下的hello.txt,回到第一步。这个bug还是挺好复现的,可以多试几次。
@hkx3upper
Copy link
Owner

是这个文件还没加密的时候,就用记事本打开了吧,是不是手速很快?
所以看到的还是明文......

@wangzhankun
Copy link
Collaborator Author

wangzhankun commented Jun 25, 2022

感觉并不是。notepad作为机密进程,notepad++作为非机密进程的时候并没有出现这种情况。而且我当时是复制了三个文件一个是5字节,一个是16字节,一个是27字节。多次重复实验,只有16字节的出现了这种情况。

@hkx3upper
Copy link
Owner

哈,我试试16字节

@hkx3upper
Copy link
Owner

没能复现成功,不过根据你的描述,打开第一次是明文,第二次是密文。真有可能是第一次打开的时候还没有加密,所以没给它指向密文缓冲。
要不你加上这俩货试试。
image

@wangzhankun
Copy link
Collaborator Author

emmm,我这边还挺好复现的。反正看运气,有时候就能看到明文,有时候就能看到密文。
就是视频里面的这种情况。感觉不是我点的太快,也不是还没有完成加密的问题。

@hkx3upper
Copy link
Owner

你没有添加我刚说的这两个标识吗?

@hkx3upper
Copy link
Owner

把DebugView打开,加密完成有日志提示

@wangzhankun
Copy link
Collaborator Author

我加了,也是不行的

你没有添加我刚说的这两个标识吗?

@hkx3upper
Copy link
Owner

哈哈,那我也没办法了,原因就是没进到PostCreate那个切换密文缓冲的地方,你下个断点在PostCreate,看看到底是因为文件还没加密,还是其他原因

@hkx3upper
Copy link
Owner

复现出来了,就是还没加密。我把内存改成2GB,就出现这个问题了。

@hkx3upper
Copy link
Owner

解决了,刷了一下缓冲。 @wangzhankun
碰到这种问题可以尝试解决一下,打开驱动的日志,下个断点啥的。

@wangzhankun
Copy link
Collaborator Author

好的,我测试一下

@wangzhankun
Copy link
Collaborator Author

应该是没啥问题了。

@wangzhankun
Copy link
Collaborator Author

解决了,刷了一下缓冲。 @wangzhankun 碰到这种问题可以尝试解决一下,打开驱动的日志,下个断点啥的。

请问你这边刷新的缓冲是哪一块的缓冲啊?我最近测试又发现了密文泄露的情况。

@wangzhankun
Copy link
Collaborator Author

解决了,刷了一下缓冲。 @wangzhankun 碰到这种问题可以尝试解决一下,打开驱动的日志,下个断点啥的。

具体是修改了哪些代码呀?是哪一次的提交修改的呢?我研究一下。

@hkx3upper
Copy link
Owner

hkx3upper commented Jun 25, 2022

就是最新的一次提交,刷新的明文缓冲。你那个情况不是因为明文还没加密,然后就用非授权进程打开了,我就在非授权进程打开之前刷了一下明文缓冲,让它尽快从缓冲中刷下。

if (FlagOn(Data->Iopb->Parameters.Create.SecurityContext->DesiredAccess, (FILE_READ_DATA)) &&
        POC_IS_AUTHORIZED_PROCESS != ProcessType)
    {
        if (NULL == StreamContext->FlushFileObject)
        {
            Status = PocInitFlushFileObject(
                StreamContext->FileName,
                &StreamContext->FlushFileObject);
        }

        Status = PocFlushOriginalCache(
            FltObjects->Instance,
            StreamContext->FileName);
    }

还有泄露吗?那说明判断条件还可以放宽松一点。

@wangzhankun
Copy link
Collaborator Author

wangzhankun commented Jun 26, 2022

测试使用的文件是在非机密文件夹下,使用PocUserPannel手动加密的文档。

代码使用的是我那边的 https://github.com/wangzhankun/FOKS-TROT/tree/dev
dev分支,已合并拉取你最新的代码。

commit hash: f1d8b6f

BUG复现步骤

  1. 将notepad++.exe设置为机密进程,notepad.exe设置为非机密进程
  2. 启动驱动
  3. 使用notepad++.exe打开已加密文件,写入若干字节
  4. 使用notepad.exe打开同一文件看到明文,关闭notepad.exe
  5. 再次使用notepad.exe打开同一文件仍然看到明文(无论notepad.exe关闭打开多少次都是看到明文)
  6. 关闭notepad++.exe
  7. 再次使用notepad.exe打开改文件看到密文

@wangzhankun
Copy link
Collaborator Author

就从log来看,我比较奇怪的是,为啥非机密进程MsMpEng.exe在notepad++写入文件并保存之后尝试读取该文件时,其条件判断为

 FltObjects->FileObject->SectionObjectPointer != StreamContext->ShadowSectionObjectPointers. CachedIO = TRUE. StreamContext->IsCipherText = TRUE

这不久意味着非机密进程MsMpEng.exe也是看到了明文吗?

00000098	7.48111296	PocPostCreateOperationWhenSafe@885: POC_IS_AUTHORIZED_PROCESS ProcessName = \Device\HarddiskVolume3\Program Files\Notepad++\notepad++.exe, FileName = \Device\HarddiskVolume3\Users\wangzhankun\Desktop\123\16.txt.	
00000099	7.48169374	PocPreWriteOperation->RealToWrite = 25.	
00000100	7.48171186	PocPreWriteOperation->Encrypt success. StartingVbo = 0 Length = 25 ProcessName = \Device\HarddiskVolume3\Program Files\Notepad++\notepad++.exe File = \Device\HarddiskVolume3\Users\wangzhankun\Desktop\123\16.txt.	
00000102	7.48258162	PocPostCloseOperationWhenSafe->PsCreateSystemThread PocAppendEncTailerThread \Device\HarddiskVolume3\Users\wangzhankun\Desktop\123\16.txt init success. FileSize = 25.	
00000103	7.49285936	PocPreReadOperation@121 FltObjects->FileObject->SectionObjectPointer != StreamContext->ShadowSectionObjectPointers. CachedIO = TRUE. StreamContext->IsCipherText = TRUE.	
00000104	7.49288893	PocPreReadOperation@123 Process = \Device\HarddiskVolume3\ProgramData\Microsoft\Windows Defender\Platform\4.18.2205.7-0\MsMpEng.exe FileName = \Device\HarddiskVolume3\Users\wangzhankun\Desktop\123\16.txt.	
00000105	7.49295902	PocPreReadOperation@147: READ CACHEDIO. ProcessName = \Device\HarddiskVolume3\ProgramData\Microsoft\Windows Defender\Platform\4.18.2205.7-0\MsMpEng.exe. FileName = \Device\HarddiskVolume3\Users\wangzhankun\Desktop\123\16.txt.	
00000106	7.49296904	PocPreReadOperation@276 \Device\HarddiskVolume3\ProgramData\Microsoft\Windows Defender\Platform\4.18.2205.7-0\MsMpEng.exe cachedio read end of file \Device\HarddiskVolume3\Users\wangzhankun\Desktop\123\16.txt Length = 4096. NewLength = 25	
00000107	7.75505781	PocPreReadOperation@121 FltObjects->FileObject->SectionObjectPointer != StreamContext->ShadowSectionObjectPointers. CachedIO = TRUE. StreamContext->IsCipherText = TRUE.	
00000108	7.75507450	PocPreReadOperation@123 Process = \Device\HarddiskVolume3\Windows\System32\SearchProtocolHost.exe FileName = \Device\HarddiskVolume3\Users\wangzhankun\Desktop\123\16.txt.	
00000109	7.75508308	PocPreReadOperation@147: READ CACHEDIO. ProcessName = \Device\HarddiskVolume3\Windows\System32\SearchProtocolHost.exe. FileName = \Device\HarddiskVolume3\Users\wangzhankun\Desktop\123\16.txt.	
00000110	7.75509977	PocPreReadOperation@276 \Device\HarddiskVolume3\Windows\System32\SearchProtocolHost.exe cachedio read end of file \Device\HarddiskVolume3\Users\wangzhankun\Desktop\123\16.txt Length = 196608. NewLength = 25	
00000135	19.53550720	PocAppendEncTailerToFile->CcSetFileSizes chipertext cache map size.	
00000139	19.53554153	PocAppendEncTailerThread->Append tailer success. FileName = \Device\HarddiskVolume3\Users\wangzhankun\Desktop\123\16.txt.	

@wangzhankun
Copy link
Collaborator Author

wangzhankun commented Jun 26, 2022

我记得Read的时候判定一个进程是不是机密进程就是根据 FltObjects->FileObject->SectionObjectPointer == StreamContext->ShadowSectionObjectPointers是否成立判定的吧?二者相等就是非机密进程不解密,二者不等就要解密?

现在就是很奇怪,不知道为啥MsMpEng.exeSearchProtocolHost.exe看到的就是 FltObjects->FileObject->SectionObjectPointer != StreamContext->ShadowSectionObjectPointers,因此可以看到明文。我想着notepad看到明文的原因应该也是如此。

因此在实际判定的时候,是不是还是要根据进程是不是机密进程来判断呢?

@wangzhankun
Copy link
Collaborator Author

查看分析log,我发现MsMpEng.exe是在添加文件标识尾PocAppendEncTailerThread->Append tailer success.之前读取的文件。

00000370	142.00338745	PocPostCloseOperation@1186@E:\aboutme\GitHub\FOKS-TROT\FOKS-TROT-src\FOKS-TROT-src\Poc\Poc.c leave.	
00000371	142.06571960	PocPreReadOperation@117 Process = \Device\HarddiskVolume3\Windows\System32\SearchProtocolHost.exe FileName = \Device\HarddiskVolume3\Users\wangzhankun\Desktop\123\16.txt.	
00000372	142.06573486	PocPreReadOperation@119 FltObjects->FileObject->SectionObjectPointer != StreamContext->ShadowSectionObjectPointers. CachedIO = TRUE. StreamContext->IsCipherText = TRUE.	
00000373	142.06576538	PocPreReadOperation@142: READ CACHEDIO. ProcessName = \Device\HarddiskVolume3\Windows\System32\SearchProtocolHost.exe. FileName = \Device\HarddiskVolume3\Users\wangzhankun\Desktop\123\16.txt.	
00000374	142.06579590	PocPreReadOperation@271 \Device\HarddiskVolume3\Windows\System32\SearchProtocolHost.exe cachedio read end of file \Device\HarddiskVolume3\Users\wangzhankun\Desktop\123\16.txt Length = 196608. NewLength = 28	
00000375	142.06660461	PocPostCloseOperation@1186@E:\aboutme\GitHub\FOKS-TROT\FOKS-TROT-src\FOKS-TROT-src\Poc\Poc.c leave.	
00000430	152.71815491	PocAppendEncTailerThread->Append tailer success. FileName = \Device\HarddiskVolume3\Users\wangzhankun\Desktop\123\16.txt.	
00000432	152.71817017	PocAppendEncTailerThread@1641@E:\aboutme\GitHub\FOKS-TROT\FOKS-TROT-src\FOKS-TROT-src\Poc\FileFuncs.c End.

@hkx3upper
Copy link
Owner

image
关闭notepad++之后,notepad才能看到密文,此时还没有写入标识尾,红圈里的判断逻辑导致没有进入PostCreateWhenSafe中。
另外,这些函数都应该放到PostCreateWhenSafe中,因为这里的IRQL不一定安全。

@hkx3upper
Copy link
Owner

hkx3upper commented Jun 26, 2022

image
这里说过,CachedIo时能根据进程名判断进程,NonCachedIo时不能。
MsMpEng.exe和SearchProtocolHost.exe这两个进程,只是在NonCachedIo时会代替换来的进程读写(进行一些安全方面的处理),这无所谓。
好像你这情况确实是在CachedIo时读的,不过这个也无所谓,要相信FileObject->SOP也好过相信进程名。因为各种DPC,APC的存在,某个线程可以插入到别的进程中。

@hkx3upper
Copy link
Owner

哈哈,我就说得测一测才能合并嘛。

@wangzhankun
Copy link
Collaborator Author

那在PostCreateWhenSafe里面这样写?

    Status = PocBypassIrrelevantBy_PathAndExtension(
        Data);
    if (POC_IRRELEVENT_FILE_EXTENSION == Status)
    {//不是机密文件夹下的机密后缀名文件
        Status = PocFindOrCreateStreamContext(
            Data->Iopb->TargetInstance,
            Data->Iopb->TargetFileObject,
            FALSE,
            &StreamContext,
            &ContextCreated);
        if(STATUS_SUCCESS != Status)
        {//没有找到 StreamContext
            Status = PocIsFileUnderControl(FltObjects->Instance, FltObjects->FileObject);
            if (STATUS_SUCCESS != Status)
            {
                //既不是 机密文件夹下的机密拓展名的文件,也没有已经创建好的 StreamContext 也不存在文件标识尾,则不进行处理
                Status = FLT_POSTOP_FINISHED_PROCESSING;
                goto EXIT;
            }
            else
            {
                //do nothing
            }
        }
        else
        {//找到了StreamContext
            //do nothing
        }
    }
    else
    {
        // 机密文件夹下的机密后缀名文件
        // do nothing
    }

    /*
    * 创建StreamContext,这也是驱动唯二可以创建StreamContext的地方之一,
    * 其他地方都是查找
    */
   if(NULL == StreamContext)//上文中有可能已经找到了StreamContext
    {
        Status = PocFindOrCreateStreamContext(
        Data->Iopb->TargetInstance,
        Data->Iopb->TargetFileObject,
        TRUE,
        &StreamContext,
        &ContextCreated);

        if (STATUS_SUCCESS != Status)
        {
            PT_DBG_PRINT(PTDBG_TRACE_ROUTINES, ("%s->PocFindOrCreateStreamContext failed. Status = 0x%x.\n",
                __FUNCTION__, Status));
            Status = FLT_POSTOP_FINISHED_PROCESSING;
            goto EXIT;
        }
    }

@wangzhankun
Copy link
Collaborator Author

推迟到PostCreateWhenSafe做判断解决了密文泄露的问题了。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants