网页防篡改核心技术探讨(一)静态页面(原创)
互联网中,很多信息都是由www服务器发布,对于网站www服务器的攻击常常成为安全的重灾区。网页防篡改技术,也成为很多安全公司关注的方向。对于静态网页防篡改技术,我只研究了其中核心的对静态发布路径下网页文件进行保护的技术。谈到对于文件的保护,windows系统中最核心的技术,当属文件过滤驱动。在winDDK的早期版本中,专门分出一个IFS ddk的开发包,到后来全部合并为WINDDk开发。
文件过滤驱动,windows系统启动后长驻内核,对文件系统的所有操作进行监控,比如,新建、删除、重命名、读、写等操作。我们只要对于www发布服务虚拟目录对应的物理路径进行比较,并且对文件操作进程区别对待,就能实现对指定路径下的文件进行保护功能。
节选代码部分:
/*++
Copyright (c) 2009-2011
Module Name:
fileguard.c
Abstract:
本模块实现文件防止篡改的功能,功能将不断扩展
目前已经实现的功能有:
对于指定路径下文件的以下保护功能。
1、防删除
2、防重命名
Environment:
Kernel mode
author:peowner
--*/
//处理删除和重命名
NTSTATUS
SfSetInformation(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS status;
PNAME_CONTROL fileName = NULL;
PSFILTER_DEVICE_EXTENSION devExt = (PSFILTER_DEVICE_EXTENSION)(DeviceObject->DeviceExtension);
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( Irp );
BOOLEAN cacheName;
NAME_LOOKUP_FLAGS LookupFlags = 0x00000000;
PLIST_ENTRY p=NULL;
KIRQL oldIrql;
WCHAR name_buf[32] = { 0 };
UNICODE_STRING proc_name = { 0 };
ULONG length;
PAGED_CODE();
if (irpSp->Parameters.SetFile.FileInformationClass == FileDispositionInformation) //删除操作
{
KdPrint(("FileGuard:哈哈!开始过滤删除操作了! \n"));
status = NLAllocateNameControl( &fileName, &gSfNameBufferLookasideList );
if (NT_SUCCESS( status )) {
SetFlag( LookupFlags, NLFL_USE_DOS_DEVICE_NAME );
NLGetDosDeviceName ( DeviceObject,&devExt->NLExtHeader ) ;
status = NLGetFullPathName( irpSp->FileObject,
fileName,
&devExt->NLExtHeader,
LookupFlags,
&gSfNameBufferLookasideList,
&cacheName );
if (NT_SUCCESS( status )) {
RtlInitEmptyUnicodeString(&proc_name,name_buf,32*sizeof(WCHAR));
length = Sf_GetProcessName(&proc_name);
KdPrint(("FileGuard删除文件的进程名称为:%wZ\n",&proc_name));
KdPrint(("删除文件全路径为:%S\n",fileName->Name.Buffer));
KdPrint(("全路径获取成功!\n"));
// ExAcquireFastMutex(&RuleLock); //获取互斥量 ,保证线程安全性
KeAcquireSpinLock(&RuleSpinLock, &oldIrql);
for(p = rule_list_head.Flink; p != &rule_list_head; p = p->Flink)
{
PRULE_FILE_CONTEXT prfc =CONTAINING_RECORD(p,RULE_FILE_CONTEXT,rule_list_entry);
// PRULE_FILE_CONTEXT prfc =(PRULE_FILE_CONTEXT)p ;
// KdPrint(("删除规则文件名为:%S \n",prfc->SafePathName.Buffer));
//KdPrint(("删除规则文件全路径长度为:%d",wcslen(prfc->SafePathName.Buffer)));
//当前irp文件路径以保护路径开始,则拒绝删除
if (_wcsnicmp(fileName->Name.Buffer,prfc->SafePathName.Buffer, wcslen(prfc->SafePathName.Buffer)) == 0)
{
//ExReleaseFastMutex(&RuleLock); //释放互斥量
KeReleaseSpinLock( &RuleSpinLock, oldIrql );
Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_ACCESS_DENIED;
}
}
//ExReleaseFastMutex(&RuleLock); //释放互斥量
KeReleaseSpinLock( &RuleSpinLock, oldIrql );
}
}
}
if (irpSp->Parameters.QueryFile.FileInformationClass == FileRenameInformation) //重命名操作
{
KdPrint(("FileGuard:哈哈!开始过滤重命名操作了! \n"));
status = NLAllocateNameControl( &fileName, &gSfNameBufferLookasideList );
if (NT_SUCCESS( status )) {
SetFlag( LookupFlags, NLFL_USE_DOS_DEVICE_NAME );
NLGetDosDeviceName ( DeviceObject,&devExt->NLExtHeader ) ;
status = NLGetFullPathName( irpSp->FileObject,
fileName,
&devExt->NLExtHeader,
LookupFlags,
&gSfNameBufferLookasideList,
&cacheName );
if (NT_SUCCESS( status )) {
KdPrint(("重命名文件全路径为:%S\n",fileName->Name.Buffer));
KdPrint(("全路径获取成功!\n"));
// ExAcquireFastMutex(&RuleLock); //获取互斥量 ,保证线程安全性
KeAcquireSpinLock(&RuleSpinLock, &oldIrql);
for(p = rule_list_head.Flink; p != &rule_list_head; p = p->Flink)
{
PRULE_FILE_CONTEXT prfc =CONTAINING_RECORD(p,RULE_FILE_CONTEXT,rule_list_entry);
// PRULE_FILE_CONTEXT prfc =(PRULE_FILE_CONTEXT)p ;
// KdPrint(("重命名规则文件名为:%S \n",prfc->SafePathName.Buffer));
// KdPrint(("重命名规则文件全路径长度为:%d",wcslen(prfc->SafePathName.Buffer)));
//当前irp文件路径以保护路径开始,则拒绝重命名
if (_wcsnicmp(fileName->Name.Buffer,prfc->SafePathName.Buffer, wcslen(prfc->SafePathName.Buffer)) == 0)
{
// ExReleaseFastMutex(&RuleLock); //释放互斥量
KeReleaseSpinLock( &RuleSpinLock, oldIrql );
Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_ACCESS_DENIED;
}
}
//ExReleaseFastMutex(&RuleLock); //释放互斥量
KeReleaseSpinLock( &RuleSpinLock, oldIrql);
}
}
}
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->NLExtHeader.AttachedToDeviceObject,
Irp );
}
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法