內核層關機重啓

現在HOOK越來越普遍,很多惡意程序通用hook用戶進程的關機函數禁止關機,有些則是hook winlogon.exe的關機函數,因爲進程的調用關機函數會最終給winlogon.exe發送關機消息。所以在用戶層實現關機已經越來越不安全了。內核驅動禁止關機也不是很安全,通過windbg可以發現xuetr.exe禁止關機的原理是對NtShutdownSystem調用的SeSinglePrivilegeCheck(權限檢查)函數進行call hook。不管了,畢竟玩驅的也不是等閒之輩。我們可以經常遇到在DriverEntry調用NtShutdownSystem可以正常關機重啓,但是通過ioctl關機重啓失效了,NtShutdownSystem的返回值是STATUS_PRIVILEGE_NOT_HELD,也就是權限不足,看來需要提權。提權函數如下:

void AdjustPriv(ULONG ulSe)
{
 NTSTATUS nts = 0;
 TOKEN_PRIVILEGES TokenPrivileges;
 HANDLE tokenHandle;
 nts = ZwOpenProcessToken(NtCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&tokenHandle);
 if (NT_SUCCESS(nts))
 {
  TokenPrivileges.PrivilegeCount = 1;
  TokenPrivileges.Privileges[0].Luid = RtlConvertUlongToLuid(ulSe);
  TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  nts = ZwAdjustPrivilegesToken(tokenHandle, FALSE,  &TokenPrivileges, sizeof(TokenPrivileges), NULL,  NULL);
  ZwClose(tokenHandle);
 }
}

接下來是用戶層通過DeviceIoControl發送ioctl,通知驅動程序關機:

NTSTATUS OnDeviceIoControl( PDEVICE_OBJECT pDeviceObject, PIRP Irp )
{
 NTSTATUS status;
 PIO_STACK_LOCATION IrpStack;
 PVOID InputBuffer;
 PVOID OutputBuffer;
 ULONG InputBufferLength;
 ULONG OutputBufferLength;
 ULONG IoControlCode;
 char* lpBuf = NULL;
 ULONG ulPid = 0;

 status = Irp->IoStatus.Status = STATUS_SUCCESS;
 Irp->IoStatus.Information = 0;

 IrpStack = IoGetCurrentIrpStackLocation( Irp );

 InputBuffer = IrpStack->Parameters.DeviceIoControl.Type3InputBuffer;
 InputBufferLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
 OutputBuffer = Irp->UserBuffer;
 OutputBufferLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
 IoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;

 switch( IoControlCode )
 {
 case IOCTL_SHUTDOWN_POWEROFF: 

  {
   AdjustPriv(SE_SHUTDOWN_PRIVILEGE);
   NtShutdownSystem(ShutdownPowerOff); //關閉電源
  }
  break;
 case IOCTL_SHUTDOWN_NOREBOOT:
  {
   AdjustPriv(SE_SHUTDOWN_PRIVILEGE);
   NtShutdownSystem(ShutdownNoReboot); //關機
  }
  break;
 case IOCTL_SHUTDOWN_REBOOT:
  {
   AdjustPriv(SE_SHUTDOWN_PRIVILEGE);
   NtShutdownSystem(ShutdownReboot); //重啓
  }
  break;
 default:
  status = STATUS_INVALID_DEVICE_REQUEST;
  break;
 }

 IoCompleteRequest( Irp, IO_NO_INCREMENT );

 return status;
}

 

當然這種關機還需要NtShutdownSystem沒被inline hook,ssdt hook或者是call hook爲前提的。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章