|
Posted on 2009-03-21 16:19 Tommy Liang 阅读(1263) 评论(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了:  很有意思。
|