首页 > CTF, Windows驱动开发 > ISCC2011内核关-移形换影

ISCC2011内核关-移形换影

这是ISCC 2011 内核关的第三题-移形换影,可以通过SSDT HOOK来解决。主要是HOOK NtOpenFile和NtCreateFile这两个函数来实现。

题目描述:在同一个目录下有两个文件:111.txt和222.txt。你能不能写一个内核程序,当使用记事本打开111.txt时却显示222.txt的内容? 如果你知道系统服务描述表这个概念,just a piece of cake!(注意需要提交源代码)

提示信息:无

我的说明:SSDT HOOK是个老话题了,网上有很多的介绍,看雪论坛有非常多的好文章供大家学习。比较经典的一篇文章是李马的《城里城外看SSDT》

效果截图:
通过SSDT HOOK来实现TXT文件的读写Hijack

我的代码:

// ISCC2011 Kernel3
// Author: 代码疯子
// Blog: http://www.programlife.net/
#include <ntddk.h>
 
// KeServiceDescriptorTable的类型
typedef struct _KSERVICE_TABLE_DESCRIPTOR {
    PULONG_PTR Base;	// SSDT基址
    PULONG Count;		// 包含服务表项被调用的计数的表
						// 只在Checked版本有效
    ULONG Limit;		// 当前系统支持的服务个数
    PUCHAR Number;		// 系统服务参数表
} KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCR;
 
// 声明KeServiceDescriptorTable
extern PKSERVICE_TABLE_DESCR KeServiceDescriptorTable;
 
// 函数声明
// 需要HOOK的函数有ZtOpenFile
NTKERNELAPI NTSTATUS 
	ZwOpenFile(
		OUT PHANDLE  FileHandle,
		IN ACCESS_MASK  DesiredAccess,
		IN POBJECT_ATTRIBUTES  ObjectAttributes,
		OUT PIO_STATUS_BLOCK  IoStatusBlock,
		IN ULONG  ShareAccess,
		IN ULONG  OpenOptions
	);
 
// 以及ZwCreateFile
NTKERNELAPI NTSTATUS 
	ZwCreateFile(
		__out PHANDLE  FileHandle,
		__in ACCESS_MASK  DesiredAccess,
		__in POBJECT_ATTRIBUTES  ObjectAttributes,
		__out PIO_STATUS_BLOCK  IoStatusBlock,
		__in_opt PLARGE_INTEGER  AllocationSize,
		__in ULONG  FileAttributes,
		__in ULONG  ShareAccess,
		__in ULONG  CreateDisposition,
		__in ULONG  CreateOptions,
		__in_opt PVOID  EaBuffer,
		__in ULONG  EaLength
    );
 
 
// 被HOOK函数指针声明
// ZwOpenFile函数指针
typedef NTSTATUS (*_ZwOpenFile)(
			OUT PHANDLE  FileHandle,
			IN ACCESS_MASK  DesiredAccess,
			IN POBJECT_ATTRIBUTES  ObjectAttributes,
			OUT PIO_STATUS_BLOCK  IoStatusBlock,
			IN ULONG  ShareAccess,
			IN ULONG  OpenOptions
		);
 
// ZwCreateFile函数指针
typedef NTSTATUS (*_ZwCreateFile)(
			__out PHANDLE  FileHandle,
			__in ACCESS_MASK  DesiredAccess,
			__in POBJECT_ATTRIBUTES  ObjectAttributes,
			__out PIO_STATUS_BLOCK  IoStatusBlock,
			__in_opt PLARGE_INTEGER  AllocationSize,
			__in ULONG  FileAttributes,
			__in ULONG  ShareAccess,
			__in ULONG  CreateDisposition,
			__in ULONG  CreateOptions,
			__in_opt PVOID  EaBuffer,
			__in ULONG  EaLength
		);
 
// 保存被挂钩函数原始地址
_ZwOpenFile		oldZwOpenFile;
_ZwCreateFile	oldZwCreateFile;
 
#define GetSystemFunc(FuncName) \
		KeServiceDescriptorTable->Base[*(PULONG)((PUCHAR)FuncName + 1)]; 
 
// 一些变量
PMDL MDSystemCall;
PVOID *MappedSCT;
 
// 获得服务索引号
#define GetIndex(_Function) *(PULONG)((PUCHAR)_Function + 1)
 
// 卸载钩子
#define UnHook(_OldFunc, _NewFunc){ \
	(PVOID)InterlockedExchange( \
		(PLONG)&MappedSCT[GetIndex(_OldFunc)], \
		(LONG)_NewFunc) ;\
	}
 
// 安装钩子
#define HookOn(_OldFunc, _NewFunc){ \
	(PVOID)InterlockedExchange( \
		(PLONG)&MappedSCT[GetIndex(_OldFunc)], \
		(LONG)_NewFunc) ;\
	}
 
// 自己的函数
NTSTATUS newZwOpenFile(
			OUT PHANDLE  FileHandle,
			IN ACCESS_MASK  DesiredAccess,
			IN POBJECT_ATTRIBUTES  ObjectAttributes,
			OUT PIO_STATUS_BLOCK  IoStatusBlock,
			IN ULONG  ShareAccess,
			IN ULONG  OpenOptions
		)
{
	NTSTATUS status = STATUS_SUCCESS;
 
	UNICODE_STRING usSrcPath = RTL_CONSTANT_STRING(L"\\??\\D:\\111.txt");
	UNICODE_STRING usDstPath = RTL_CONSTANT_STRING(L"\\??\\D:\\222.txt");
 
	// 判断是否是试图打开111.txt
	// 如果是则改写ObjectAttributes中的路径
	// 使之成为222.txt
	if (!RtlCompareUnicodeString(&usSrcPath, 
			ObjectAttributes->ObjectName,
			TRUE))
	{
		// 一些提示信息
		KdPrint(("-------------- CHANGE PATH --------------\r\n"));
		KdPrint(("%wZ", ObjectAttributes->ObjectName));
		KdPrint((" --> "));
		RtlCopyUnicodeString(ObjectAttributes->ObjectName, &usDstPath);
		KdPrint(("%wZ\r\n", ObjectAttributes->ObjectName));
	}
 
	return oldZwOpenFile(FileHandle, 
				DesiredAccess, 
				ObjectAttributes, 
				IoStatusBlock, 
				ShareAccess, 
				OpenOptions);
}
 
NTSTATUS newZwCreateFile(
			__out PHANDLE  FileHandle,
			__in ACCESS_MASK  DesiredAccess,
			__in POBJECT_ATTRIBUTES  ObjectAttributes,
			__out PIO_STATUS_BLOCK  IoStatusBlock,
			__in_opt PLARGE_INTEGER  AllocationSize,
			__in ULONG  FileAttributes,
			__in ULONG  ShareAccess,
			__in ULONG  CreateDisposition,
			__in ULONG  CreateOptions,
			__in_opt PVOID  EaBuffer,
			__in ULONG  EaLength
		)
{
	NTSTATUS status = STATUS_SUCCESS;
 
	UNICODE_STRING usSrcPath = RTL_CONSTANT_STRING(L"\\??\\D:\\111.txt");
	UNICODE_STRING usDstPath = RTL_CONSTANT_STRING(L"\\??\\D:\\222.txt");
 
	if (!RtlCompareUnicodeString(&usSrcPath, 
			ObjectAttributes->ObjectName,
			TRUE))
	{
		KdPrint(("-------------- CHANGE PATH --------------\r\n"));
		KdPrint(("%wZ", ObjectAttributes->ObjectName));
		KdPrint((" --> "));
		RtlCopyUnicodeString(ObjectAttributes->ObjectName, &usDstPath);
		KdPrint(("%wZ\r\n", ObjectAttributes->ObjectName));
	}
 
	return oldZwCreateFile(FileHandle, 
				DesiredAccess, 
				ObjectAttributes, 
				IoStatusBlock, 
				AllocationSize,
				FileAttributes,
				ShareAccess, 
				CreateDisposition,
				CreateOptions,
				EaBuffer,
				EaLength);
}
 
VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{
	KdPrint(("Stop Hook...\n"));
	// 卸载钩子
	UnHook(ZwOpenFile, oldZwOpenFile);
	UnHook(ZwCreateFile, oldZwCreateFile);
}
 
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,
					PUNICODE_STRING pRegistryPath)
{
	// 卸载函数
	pDriverObject->DriverUnload = DriverUnload;
 
	// 找到原来的ZwOpenFile函数地址
	oldZwOpenFile = GetSystemFunc(ZwOpenFile);
	oldZwCreateFile = GetSystemFunc(ZwCreateFile);
 
	MDSystemCall = MmCreateMdl(NULL, \
						KeServiceDescriptorTable->Base, \
						KeServiceDescriptorTable->Limit * 4);
	if (!MDSystemCall)
	{
		KdPrint(("MmCreateMdl Failure...\n"));
		return STATUS_UNSUCCESSFUL;
	}
 
	MmBuildMdlForNonPagedPool(MDSystemCall);
	MDSystemCall->MdlFlags |= MDL_MAPPED_TO_SYSTEM_VA;
	MappedSCT = MmMapLockedPages(MDSystemCall, KernelMode);
 
	// 安装HOOK
	HookOn(ZwOpenFile, newZwOpenFile);
	HookOn(ZwCreateFile, newZwCreateFile);
	KdPrint(("Start Hook...\n"));
 
	return STATUS_SUCCESS;
}

觉得文章还不错?点击此处对作者进行打赏!


本文地址: 程序人生 >> ISCC2011内核关-移形换影
作者:代码疯子(Wins0n) 本站内容如无声明均属原创,转载请保留作者信息与原文链接,谢谢!


更多



分类: CTF, Windows驱动开发 标签: , , ,
  1. 本文目前尚无任何评论.