|
Posted on 2009-03-21 16:19 Tommy Liang 阅读(1257) 评论(0) 编辑 收藏 引用 所属分类: 进程与线程
看了《Rootkit》和《黑客防线2009》的文章,代码写了一下,有些体会:
驱动程序代码:
#include "ntddk.h" #define NT_DEVICE_NAME L"\\Device\\ProtectProcess" #define DOS_DEVICE_NAME L"\\DosDevices\\ProtectProcess" #define IOCTL_PROTECT_CONTROL CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS)
NTSTATUS DispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp); void OnUnload(IN PDRIVER_OBJECT DriverObject);
#pragma pack(1) typedef struct ServiceDescriptorEntry{ unsigned int *ServiceTableBase; unsigned int *ServiceCounterTableBase; unsigned int NumberOfServices; unsigned char *ParamTableBase; } SSDT_Entry,*pSSDT_Entry; #pragma pack() __declspec(dllimport) SSDT_Entry KeServiceDescriptorTable;
#define SYSTEMSERVICE(_func) \ KeServiceDescriptorTable.ServiceTableBase[*(PULONG)((PUCHAR)_func+1)]
NTSYSAPI NTSTATUS NTAPI ZwOpenProcess(OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN PCLIENT_ID ClientId OPTIONAL);
typedef NTSTATUS (*ZWOPENPROCESS)(OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN PCLIENT_ID ClientId OPTIONAL);
ZWOPENPROCESS OldZwOpenProcess; long pid = 0;
NTSTATUS NewZwOpenProcess(OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN PCLIENT_ID ClientId OPTIONAL) { NTSTATUS nStatus = STATUS_SUCCESS; if((long)ClientId->UniqueProcess == pid) { DbgPrint("保护进程 PID:%d\n",pid); return STATUS_ACCESS_DENIED; } nStatus = OldZwOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId); return nStatus; }
void OnUnload(IN PDRIVER_OBJECT DriverObject) { UNICODE_STRING DeviceLinkString; PDEVICE_OBJECT DeviceObjectTemp1 = NULL; PDEVICE_OBJECT DeviceObjectTemp2 = NULL; DbgPrint("驱动程序卸载\n"); RtlInitUnicodeString(&DeviceLinkString,DOS_DEVICE_NAME); IoDeleteSymbolicLink(&DeviceLinkString); if(DriverObject) { DeviceObjectTemp1 = DriverObject->DeviceObject; while(DeviceObjectTemp1) { DeviceObjectTemp2 = DeviceObjectTemp1; DeviceObjectTemp1 = DeviceObjectTemp1->NextDevice; IoDeleteDevice(DeviceObjectTemp2); } } DbgPrint("设备已卸载\n"); DbgPrint("修复SSDT\n"); (ZWOPENPROCESS)(SYSTEMSERVICE(ZwOpenProcess)) = OldZwOpenProcess; DbgPrint("驱动卸载完毕\n"); }
NTSTATUS DispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS nStatus = STATUS_SUCCESS; ULONG IoControlCode = 0; PIO_STACK_LOCATION IrpStack = NULL; long* inBuf = NULL; char* outBuf = NULL; ULONG inSize = 0; ULONG outSize = 0; PCHAR buffer = NULL; PMDL mdl = NULL;
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IrpStack = IoGetCurrentIrpStackLocation(Irp);
switch(IrpStack->MajorFunction) { case IRP_MJ_CREATE: DbgPrint("IRP_MJ_CREATE 被调用\n"); break; case IRP_MJ_CLOSE: DbgPrint("IRP_MJ_CLOSE 被调用\n"); break; case IRP_MJ_DEVICE_CONTROL: DbgPrint("IRP_MJ_DEVICE_CONTROL 被调用\n"); IoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode; switch(IoControlCode) { case IOCTL_PROTECT_CONTROL: inSize = IrpStack->Parameters.DeviceIoControl.InputBufferLength; outSize = IrpStack->Parameters.DeviceIoControl.OutputBufferLength; inBuf = (long*)Irp->AssociatedIrp.SystemBuffer; pid = *inBuf; DbgPrint("=========================================\n"); DbgPrint("IOCTRL_PROTECT_CONTROL 被调用,通讯成功!\n"); DbgPrint("输入缓冲区大小:%d\n",inSize); DbgPrint("输出缓冲区大小:%d\n",outSize); DbgPrint("输入缓冲区内容:%ld\n",*inBuf); DbgPrint("当前保护进程ID:%ld\n",pid); DbgPrint("=========================================\n"); strcpy(Irp->UserBuffer,"OK\n"); break; default: break; } break; default: DbgPrint("未知请求包被调用\n"); break; } nStatus = Irp->IoStatus.Status; IoCompleteRequest(Irp,IO_NO_INCREMENT); return nStatus; }
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING theRegistryPath) { NTSTATUS ntStatus = STATUS_SUCCESS; UNICODE_STRING ntDeviceName; UNICODE_STRING DeviceLinkString; PDEVICE_OBJECT deviceObject = NULL; DbgPrint("驱动程序加载\n"); RtlInitUnicodeString(&ntDeviceName,NT_DEVICE_NAME); ntStatus = IoCreateDevice( DriverObject, 0, &ntDeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &deviceObject);
if(!NT_SUCCESS(ntStatus)) { DbgPrint("无法创建驱动设备"); return ntStatus; } RtlInitUnicodeString(&DeviceLinkString,DOS_DEVICE_NAME); ntStatus = IoCreateSymbolicLink(&DeviceLinkString,&ntDeviceName); if(!NT_SUCCESS(ntStatus)) { DbgPrint("无法创建驱动设备"); return ntStatus; } DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchDeviceControl; DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchDeviceControl; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl; DriverObject->DriverUnload = OnUnload;
DbgPrint("驱动程序已经启动\n"); DbgPrint("修改SSDT\n");
OldZwOpenProcess = (ZWOPENPROCESS)(SYSTEMSERVICE(ZwOpenProcess)); (ZWOPENPROCESS)(SYSTEMSERVICE(ZwOpenProcess)) = NewZwOpenProcess; DbgPrint("驱动程序加载完毕\n"); return STATUS_SUCCESS; }
服务安装程序:
// ProtectInstaller.cpp : Defines the entry point for the console application. //
#include "stdafx.h"
#define BUF_SIZE 4096
int main(int argc, char* argv[]) { char path[BUF_SIZE]; char base[BUF_SIZE]; char sername[BUF_SIZE]; char disname[BUF_SIZE]; memset(path,0,BUF_SIZE); memset(base,0,BUF_SIZE); memset(sername,0,BUF_SIZE); memset(disname,0,BUF_SIZE);
SC_HANDLE rh = NULL; SC_HANDLE sh = NULL; if(argc == 1) { printf("use:install/start/uninstall\n"); exit(0); }
::GetModuleFileName(0,base,BUF_SIZE); int p = strlen(base); while(base[p] != '\\'){ p --; } strncpy(path,base,p+1); memset(base,0,BUF_SIZE); sprintf(base,"%sInstall.ini",path); memset(path,0,BUF_SIZE);
::GetPrivateProfileString("Config","Path","",path,BUF_SIZE,base); ::GetPrivateProfileString("Config","ServiceName","",sername,BUF_SIZE,base); ::GetPrivateProfileString("Config","DisplayName","",disname,BUF_SIZE,base);
printf("[*]Service Name:%s\n",sername); printf("[*]Display Name:%s\n",disname); printf("[*]Driver Path:%s\n",path); sh = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if(!sh){ printf("[-]Error OpenSCManager.\n"); exit(0); } if(argc == 2 && !strcmp(argv[1],"install")) { if(!strcmp(path,"")) { printf("[-]error read Install.ini\n"); exit(0); } rh = CreateService(sh, sername, disname, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, path, NULL,NULL,NULL,NULL,NULL); if(!rh) { printf("[-]error CreateService.\n"); exit(0); } printf("[-]Install Service Complete\n"); } else if(argc == 2 && !strcmp(argv[1],"start")) { rh = OpenService(sh,sername,SERVICE_ALL_ACCESS); if(!rh) { printf("[-]error OpenService.\n"); exit(0); } StartService(rh,NULL,NULL); printf("[-]Start Service Complete\n"); } else if(argc == 2 && !strcmp(argv[1],"uninstall")) { rh = OpenService(sh,sername,SERVICE_ALL_ACCESS); if(!rh) { printf("[-]error OpenService.\n"); exit(0); } SERVICE_STATUS ss; ControlService(rh,SERVICE_CONTROL_STOP,&ss); printf("[-]Stop Service Complete\n"); DeleteService(rh); printf("[-]Delete Service Complete\n"); } CloseServiceHandle(rh); CloseServiceHandle(sh); return 1; }
INI文件:
[Config] Path=D:\hacker\ddk\Protect\sys\i386\Protect.sys ServiceName=Rootkit DisplayName=RootkitKernel
VC05搞了个解决方案
驱动编译通过了,安装程序也通过了,也能启动, 打开DeviceTree看看,搜索 ProtectProcess,找到了: 现在轮到告诉驱动PID的程序:
#include <stdio.h> #include <stdlib.h> #include <windows.h> #include <winioctl.h>
#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. #define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. #endif
#undef UNICODE
#define IOCTL_HELLO_CONTROL CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS)
int main(int argc,char* argv[]) { long pid = 0; char ret[4096]; DWORD ReBytes = 0; HANDLE hDevice = CreateFile(L"\\\\.\\ProtectProcess",GENERIC_READ|GENERIC_WRITE,0,NULL, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if(hDevice == INVALID_HANDLE_VALUE) { if(2 == GetLastError()) { printf("驱动程序未注册\n"); } else { printf("CreateFile() GetLastError reports %d \n",GetLastError()); } return FALSE; } memset(ret,0,4096); printf("请输入要保护的进程PID"); scanf("%ld",&pid); DeviceIoControl(hDevice,IOCTL_HELLO_CONTROL, &pid,sizeof(long),ret,4096,&ReBytes,NULL); printf("Return Value:%s\n",ret); CloseHandle(hDevice); return 1; }
开始的时候,在 CreateFile的第一个参数那里犯了一个错误,没有在前面加上“L”,结果一个下午花了3个小时在烦躁,一直提示驱动未安装,现在好了,PASS。 启动记事本,找到pid,运行通信程序,输入pid,打开任务管理器,好了,现在杀不掉notepad.exe了: 很有意思。
|