项目地址:https://github.com/angelkillah/zer0m0n
传入要监控的pid,具体代码例子:
NTSTATUS Ioctl_DeviceControl(__in PDEVICE_OBJECT pDeviceObject, __in PIRP pIrp){ NTSTATUS status = STATUS_SUCCESS; PIO_STACK_LOCATION pIoStackIrp = NULL; PCHAR buffer; ULONG ioControlCode; ULONG inputLength; ULONG malware_pid = 0; if(pIrp == NULL || pDeviceObject == NULL) return STATUS_INVALID_PARAMETER; pIoStackIrp = IoGetCurrentIrpStackLocation(pIrp); ioControlCode = pIoStackIrp->Parameters.DeviceIoControl.IoControlCode; inputLength = pIoStackIrp->Parameters.DeviceIoControl.InputBufferLength; buffer = pIrp->AssociatedIrp.SystemBuffer; switch(ioControlCode) { case IOCTL_PROC_MALWARE: Dbg("IOCTL_PROC_MALWARE received\n"); status = RtlCharToInteger(buffer, 10, &malware_pid); Dbg("malware_pid : %d\n", malware_pid); if(NT_SUCCESS(status) && malware_pid > 0) StartMonitoringProcess(malware_pid); break; case IOCTL_PROC_TO_HIDE: Dbg("pids to hide : %s\n", buffer); status = ParsePids(buffer); RtlZeroMemory(buffer, inputLength); break; case IOCTL_CUCKOO_PATH: cuckooPath = PoolAlloc(MAX_SIZE); if(inputLength && inputLength < MAX_SIZE) RtlStringCchPrintfW(cuckooPath, MAX_SIZE, L"\\??\\%ws", buffer); else { Dbg("IOCTL_CUCKOO_PATH : Buffer too large\n"); return STATUS_BUFFER_TOO_SMALL; } Dbg("cuckoo path : %ws\n", cuckooPath); break; default: break; } pIrp->IoStatus.Status = status; IoCompleteRequest(pIrp, IO_NO_INCREMENT); return status;}注册接口:pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = Ioctl_DeviceControl;
ring3调用方式,代码如下:
if(kernel_analysis) { Sleep(5000); // get handle to device driver and send IOCTLs hDevice = CreateFile(PATH_KERNEL_DRIVER, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(hDevice != INVALID_HANDLE_VALUE) { // send processes pid to hide processes_to_hide = malloc(MAX_PATH); sprintf(processes_to_hide, "%d,%d,%d", GetCurrentProcessId(), pid_from_process_name(L"VBoxService.exe"), pid_from_process_name(L"VBoxTray.exe")); if(DeviceIoControl(hDevice, IOCTL_PROC_TO_HIDE, processes_to_hide, strlen(processes_to_hide), NULL, 0, &dwBytesReturned, NULL)) fprintf(stderr, "[+] processes to hide [%s] sent to zer0m0n\n", processes_to_hide); free(processes_to_hide); // send malware's pid s_pid = malloc(MAX_PATH); sprintf(s_pid, "%d", pid); if(DeviceIoControl(hDevice, IOCTL_PROC_MALWARE, s_pid, strlen(s_pid), NULL, 0, &dwBytesReturned, NULL)) fprintf(stderr, "[+] malware pid : %s sent to zer0m0n\n", pid); free(s_pid); fprintf(stderr, "[+] cuckoo path : %ls\n", cuckoo_path); // send current directory if(DeviceIoControl(hDevice, IOCTL_CUCKOO_PATH, cuckoo_path, 200, NULL, 0, &dwBytesReturned, NULL)) fprintf(stderr, "[+] cuckoo path %ws sent to zer0m0n\n", cuckoo_path); } else fprintf(stderr, "[-] failed to access kernel driver\n"); CloseHandle(hDevice); }
下面也是一种方法:
NtDebugActiveProcess( __in HANDLE ProcessHandle,
__in HANDLE DebugHandle);通过调用这个传入挂钩的handle,由于内核中hook了这个,因此宿主只要调用这个,就把自己传入进来了。