EreTIk's Box » Cтатьи, исходники » Открытие описателя объекта нити процесса SYSTEM из процесса с правами администратора (Windows 7)


Исходные данные: Windows 7, процесс, работающий от лица администратора и нить процесса SYSTEM


Проблема: при попытке открытия нити получаем STATUS_ACCESS_DENIED


Расследование: Security Descriptor нити позволяет ее отрывать с достачно широкими правами:

0: kd> !process poi(nt!PsInitialSustemProcess) 3 PROCESS fffffa8006cd3040 SessionId: none Cid: 0004 Peb: 00000000 ParentCid: 0000 DirBase: 00187000 ObjectTable: fffff8a000001a10 HandleCount: 1062. Image: System VadRoot fffffa800723ab20 Vads 6 Clone 0 Private 9. Modified 6211841. Locked 2. DeviceMap fffff8a000008aa0 Token fffff8a000004040 ElapsedTime 4 Days 22:57:47.523 UserTime 00:00:00.000 KernelTime 00:00:18.439 QuotaPoolUsage[PagedPool] 0 QuotaPoolUsage[NonPagedPool] 0 Working Set Sizes (now,min,max) (16, 0, 0) (64KB, 0KB, 0KB) PeakWorkingSetSize 3451 VirtualSize 3 Mb PeakVirtualSize 16 Mb PageFaultCount 125516 MemoryPriority BACKGROUND BasePriority 8 CommitCharge 31 THREAD fffffa8006cd3ab0 Cid 0004.0008 <...> fffff8000485cfa0 Gate <...> THREAD fffffa800bcff040 Cid 0004.2214 <...> fffff88003301690 QueueObject 0: kd> !object fffffa800bcff040 Object: fffffa800bcff040 Type: (fffffa8006cafbc0) Thread ObjectHeader: fffffa800bcff010 (new version) HandleCount: 0 PointerCount: 2 0: kd> dt nt!_OBJECT_HEADER fffffa800bcff010 +0x000 PointerCount : 0n2 +0x008 HandleCount : 0n0 +0x008 NextToFree : (null) +0x010 Lock : _EX_PUSH_LOCK +0x018 TypeIndex : 0x8 '' +0x019 TraceFlags : 0 '' +0x01a InfoMask : 0 '' +0x01b Flags : 0x2 '' +0x020 ObjectCreateInfo : 0x00000000`00000001 _OBJECT_CREATE_INFORMATION +0x020 QuotaBlockCharged : 0x00000000`00000001 Void +0x028 SecurityDescriptor : 0xfffff8a0`000048ce Void +0x030 Body : _QUAD 0: kd> !sd 0xfffff8a0`000048c0 1 ->Revision: 0x1 ->Sbz1 : 0x0 ->Control : 0x8814 SE_DACL_PRESENT SE_SACL_PRESENT SE_SACL_AUTO_INHERITED SE_SELF_RELATIVE ->Owner : S-1-5-32-544 (Alias: BUILTIN\Administrators) ->Group : S-1-5-18 (Well Known Group: NT AUTHORITY\SYSTEM) ->Dacl : ->Dacl : ->AclRevision: 0x2 ->Dacl : ->Sbz1 : 0x0 ->Dacl : ->AclSize : 0x3c ->Dacl : ->AceCount : 0x2 ->Dacl : ->Sbz2 : 0x0 ->Dacl : ->Ace[0]: ->AceType: ACCESS_ALLOWED_ACE_TYPE ->Dacl : ->Ace[0]: ->AceFlags: 0x0 ->Dacl : ->Ace[0]: ->AceSize: 0x14 ->Dacl : ->Ace[0]: ->Mask : 0x001fffff ->Dacl : ->Ace[0]: ->SID: S-1-5-18 (Well Known Group: NT AUTHORITY\SYSTEM) ->Dacl : ->Ace[1]: ->AceType: ACCESS_ALLOWED_ACE_TYPE ->Dacl : ->Ace[1]: ->AceFlags: 0x0 ->Dacl : ->Ace[1]: ->AceSize: 0x18 ->Dacl : ->Ace[1]: ->Mask : 0x00120848 ->Dacl : ->Ace[1]: ->SID: S-1-5-32-544 (Alias: BUILTIN\Administrators) ->Sacl : ->Sacl : ->AclRevision: 0x2 ->Sacl : ->Sbz1 : 0x0 ->Sacl : ->AclSize : 0x1c ->Sacl : ->AceCount : 0x1 ->Sacl : ->Sbz2 : 0x0 ->Sacl : ->Ace[0]: ->AceType: SYSTEM_MANDATORY_LABEL_ACE_TYPE ->Sacl : ->Ace[0]: ->AceFlags: 0x0 ->Sacl : ->Ace[0]: ->AceSize: 0x14 ->Sacl : ->Ace[0]: ->Mask : 0x00000003 ->Sacl : ->Ace[0]: ->SID: S-1-16-16384 (Label: Mandatory Label\System Mandatory Level)

Трассируем nt!NtOpenThread до функции nt!ObpIncrementHandleCountEx, которая вызывает обработчик nt!PspThreadOpen (обработчик создания описателей объектов, типа "нить"). В теле nt!PspThreadOpen видим (псевдо-код):

NTSTATUS __stdcall PspThreadOpen(<...>)
{
<...>
  if ( PrevMode == 1
    && !(TargetProcess->Flags2 & 0x800)
    && ThreadObject->Tcb.Process->Flags2 & 0x800
    && GrantedAccess & 0xFF3FD )
  {
    result = 0xC0000022; // == STATUS_ACCESS_DENIED
  }
  else
<...>
                

Маска 0x800 - проверка флага защищенного процесса. А процесс SYSTEM как раз защищенный:

1: kd> dt nt!_EPROCESS poi(nt!PsInitialSystemProcess) ProtectedProcess +0x43c ProtectedProcess : 0y1

Именно из-за этого и ошибка.


Ссылки по protected-процессам:


Updated (30.09.2016)


Все вышеперечисленное ограничения на открытие описателей касаются, в том числе, и объекта процесса. Например на Windows 7 за создание описателя на процесс отвечает PspProcessOpen с таким псевдо-кодом:

  if ( PrevMode == 1
    && !_bittest(&DestinationProcess->Flags2, 11)
    && _bittest(&OpenedProcess->Flags2, 11)
    && GrantedAccess & 0xFE7FE )
  {
    result = STATUS_ACCESS_DENIED;
  }
                

Но с приходом Windows 10.0.14393 в ядре появилась поддержка Linux-процессов (Windows Subsystem for Linux, WSL), которые называются Pico-процессами. И эти PICO-процессы обрабатываются по аналогии с защищенными процессами (псевдо-кодо из Windows 10.0.14393):

  • PspThreadOpen
    || OpenedThread->PicoContext
    && !DestinationProcess_->PicoContext
    && PrevMode
    && ~*(_DWORD *)&PspPicoProviderRoutines[0x4C] & GrantedAccess )
  {
    result = STATUS_ACCESS_DENIED;
  }
                
0: kd> ? dwo(nt!PspPicoProviderRoutines+0x4c) Evaluate expression: 1050625 = 00000000`00100801
  • PspProcessOpen
    || OpenedProcess->PicoContext
    && !DestinationProcess->PicoContext
    && PrevMode
    && ~*(_DWORD *)&PspPicoProviderRoutines[0x48] & GrantedAccess )
  {
    result = STATUS_ACCESS_DENIED;
  }
                
0: kd> ? dwo(nt!PspPicoProviderRoutines+0x48) Evaluate expression: 1052673 = 00000000`00101001

То есть из Win32-процесса (не Pico) можно открыть объект Pico-процесса максимум с правами PROCESS_TERMINATE | PROCESS_QUERY_LIMITED_INFORMATION | SYNCHRONIZE.

А из Win32-процесса (не Pico) можно открыть объект нити Pico-процесса максимум с правами THREAD_TERMINATE | THREAD_QUERY_LIMITED_INFORMATION | SYNCHRONIZE.


ΞρεΤΙκ