系统安全

Win7、win8、win10下实现精准截获Explorer拷贝行为

介绍了windows下对Explorer的拷贝动作的精确截获,这个在企业数据安全dlp产品系列中减少审计的噪音很有效,方便运营人员做针对性的审计。

在企业数据安全中我通常需要监测用户的拷贝行为,特别像explorer这样的进程,方法很多比如文件过滤驱动监测文件的打开与读写,但是这样会有很多噪音产生,实现的不好的话也可能会造成用户在桌面操作感受不良好,比如卡,所以我们需要的是一种更精准地方法,下面我们就来分析下如何去更加精准的定位拷贝。

一、            分析

我们都知道windows软件读写的方法很多比如c库一些读写函数,fopen 、fread、fwrite,c++流函数std::stream,但是都会进入windows的底层读写,还有一类文件操作函数就是Shell函数SHFileOperation,不管什么函数最后都会调用windows自己常用的文件操作函数就是CreateFileA、CreateFileW、ReadFile、WriteFile,我们可以使用调试器去在CreateFileW函数设置断点,但是这个一个问题我们必须在explorer进程空间里设断点,但是会阻碍正常的桌面UI操作,为了方便我们操作桌面,写一个文件过滤驱动,去过滤我们需要的信息,比如我们把一个.txt文件从目录A拷贝到目录B,我们可以在过滤驱动的IRP_MJ_CREATE的例程函数里这样写

这样过滤会减少很多干扰,利用windbg的虚拟机的双机器调试。

加载驱动后,我们可以设置断点在if ( FileObject.RelatedFileObject()),这行代码上。

然后拷贝一个txt的文件从A到B,如下图这里windbg调试器就会停下,进入刚才设置的断点位置。输入命令kb发现堆栈是从user层到内核层在到本驱动的PreCreate函数,这时user层显示的只是地址,是因为符号没加载,继续输入.reload  /user,慢慢就显示了

引起注意的是红色框显示的堆栈:

Nt!NtCreateFile

KernelBase!CreateFile

Kernel32!CreateFileWImplementation

Shell32!CFSTransfer:_OpenSrcFileWithRetry

Shell32! CFSTransfer::OpenItem

Shell32!CDelegatingTansfer:: OpenItem

Shell32! CCopyOperation::Do

Shell32! CCopyWorkItem::_DoOperation

Shell32! CCopyWorkItem::_SetupAndPerformOp

Shell32! CCopyWorkItem::ProcessWorkItem

Shell32!CRecursiveFolderoperation::Do

Shell32!CFileOperation::_EnumRootDo

Shell32!CFileOperation::PrepareAndDoOperation

Shell32!CFileOperation::PreformOperation

Shell32!SHFileOperationEx

由上可以看出最主要的是调用了SHFileOperationEx函数,这好说了,使用IDA打开shell32.dll分析这个函数

IDA显示这个函数调用了SHCreateFileOperation继续跟进SHCreateFileOperation它创建的是GUID_947aab5f_0a5c_4c13_b4d6_4bf7836fc9f8这个类的实例,隶属于FileOperaton, 写过com的人都知道947aab5f_0a5c_4c13_b4d6_4bf7836fc9f8这个实例id就是com中的 IFileOperation的com库接口,查看windows的sdk定义如下

我们回到之前那个Ex函数,创建完IFileOperation的实例后,就开始调用里面的函数

分别调用了

Call dword ptr[esi+0x20h]

Call dword pre[esi+0x2Ch] 或者Call  dword pre[esi+0x4Ch]

Call dword pre[esi+0x44h] 或者 Call dword pre[esi+0x3Ch]

 

其他函数都是设置Explorer的拷贝Item的属性的函数,+0×44这个函数对应的是IFileOperation::Copy Items,而+0x3C对应的函数是IFileOperation::Move tems,而我们这次的拷贝动作调用的就是IFileOperation::CopyItems,下面我们有方案了我们可以hook这个IFileOpertion的接口库实现精准截获桌面的拷贝动作。

一、            实现

CopyItems为例子

定义一个CFileOperation

在初始化的时候我们需要获取接口并却修改截获CopyItems和MoveItems的指针接口

这里生成了dll后我们需要注入到桌面进程中,这样就可以实现截获CopyItems接口,注意这里只是完成了第一步,这个接口传进来的参数只是一个Item内存结构,我们需要获取具体的数据,下面继续。

从上面分析我们得知winvista以后的桌面拷贝操作最终使用的是IFileOperation接口,在shell32.dll里对应的就是CFileOperation类

CopyItems对应的就是

继续进入

CFileOperation::_AddOperationMulti

可以看到首先判断DestFile这个参数是否是Folder文件夹,如果是文件夹就是开始枚举ShellItem这个参数,我们继续进入EnumShellItemsFromUnknown函数

从上面我们看出该函数会QueryInterface各个接口:

_GUID_70629033_e363_4a28_a567_0db78006e6d7

_GUID_b63ea76d_1f85_456f_a19c_48159efa858b

_GUID_d0191542_7954_4908_bc06_b2360bbe45ba

_GUID_0000010e_0000_0000_c000_000000000046

如果以上接口都不存在的话,就调用

SHGetIDListFromObjectSHCreateShellItemArrayFromIDLists来获取接口,

在实际调用中发现以上几个不是所有操作系统都支持,而最后两个函数却支持winvista以后的所有系统,所以我们就用最后两个函数来获取源信息,而这两个函数在shell32.dll都是导出的接口定义如下:

最后获取的是IShellItemArray接口,接口定义为:

大致我们可以写出获取信息的文件的函数

以上是获取源文件的信息,而拷贝目的的信息获取就很简单了,CopyItem的定义的目的中的参数

IShellItem *psiDestinationFolder,中的IShellItem 定义如下

根据定义我们就可以通过GetDisplayName去获取目的文件的信息:

综合起来,我们可以实现如下:

至此我们就很就精准地截获了windows桌面程序的拷贝、剪切的具体动作,也获取详细的文件名称,我们甚至还能准确地得知该动作是否成功,更加详细的信息就留给读者去研究,总之shell32.dll是个很值得开发人员去研究的,里面有很多意想不到的东西,甚至能写出很简单的程序实现很复杂有效的功能,可以充分利用windows系统给我们提供的便捷的库。

转自FREEBUF,原文链接:http://www.freebuf.com/column/134192.html

(0)

本文由 安全周 作者:空心 发表,转载请注明来源!

热评文章

发表评论