ZwSetInformationProcess ProcessAccessToken

Тема в разделе "WASM.NT.KERNEL", создана пользователем XshStasX, 2 авг 2011.

  1. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    Суть задачи сменить токен произвольного процесса.
    На виндовс 7 ZwSetInformationProcess с флагом ProcessAccessToken, возвращает STATUS_NOT_SUPPORTED ( 0xC00000BB ).
    Проблема оказалось в одном из флагов структуры EPROCESS.Flags2 а именно PrimaryTokenFrozen если он сброшен то все хорошо.
    Теперь вопрос как сбросить PrimaryTokenFrozen ?
     
  2. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    Если сбросить флаг вручную то ZwSetInformationProcess возвращает 0, и привелегии изменяються на нужные.
    Проблема в том что EPROCESS изменяеться.
    Есть идеи как это обойти ?
    Пока что есть идея вручную сделать все то что делает ZwSetInformationProcess с флагом ProcessAccessToken....
     
  3. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    В общем сводиться примерно к такому упрощенному коду:
    Код (Text):
    1. NTSTATUS
    2. PspAssignPrimaryToken(
    3.     IN PEPROCESS Process,
    4.     IN HANDLE Token OPTIONAL,
    5.     IN PACCESS_TOKEN TokenPointer OPTIONAL
    6.     )
    7. {
    8.         if ( Process->Flags2 & PrimaryTokenFrozen )
    9.         {
    10.                 Status = STATUS_NOT_SUPPORTED
    11.         }
    12.         else
    13.         {
    14.             Status = SeExchangePrimaryToken (Process, NewToken, &OldToken);
    15.             PspLockProcessSecurityExclusive (Process, CurrentThread);
    16.             PspUnlockProcessSecurityExclusive (Process, CurrentThread);
    17.         }
    18. };
    Стек вызовов:

    Код (Text):
    1.     nt!NtSetInformationProcess
    2.             nt!PspAssignPrimaryToken
    nt!PspAssignPrimaryToken експортируются.
    Если кому интересно к теме прикрепил более подробное описание.
    Вчера видемо допустил опечатку, nt!PspSetPrimaryToken не вызывается(покрайней мере в стеке вызовов в windbg ее нет) .
     
  4. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    Теперь у меня уперся вопрос в поиск самой функции SeExchangePrimaryToken.
    Интересно было бы услышать какие либо мысли по данной теме.

    Проблема в том что SeExchangePrimaryToken вызываеться только через NtSetInformationProcess. Покарайней мере мне удалось увидеть еще в ссылки на эту функцию, смотрел в ida6.1

    Что надежней структура EPROCESS или поиск SeExchangePrimaryToken.
     
  5. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    Нашол по "сигнатурам" SeExchangePrimaryToken, привелегии удалось сменить.
    Вот примерный код поиска SeExchangePrimaryToken, осталось проверить на остальных ОС.
    Код (Text):
    1. enum CallType{
    2.     CallRelative,
    3.     CallAbsolute
    4. };
    5.  
    6.  
    7. //  GetInstLenght(myiptr0,&dwLen); дизассемблер длин.
    8.  
    9. DWORD *InstrSearchCall(DWORD *myiptr0,DWORD MaxOffset,CallType *calltype)
    10. {
    11.     DWORD dwLen;
    12.     while (MaxOffset)
    13.     {
    14.      GetInstLenght(myiptr0,&dwLen);
    15.  
    16.      if ( (dwLen == 5) & ( 0xE8 == *(BYTE*)myiptr0) ){ 
    17.         *calltype = CallRelative;
    18.         return myiptr0;
    19.      };
    20.    
    21.      if (MaxOffset < dwLen)
    22.          return NULL;
    23.  
    24.      MaxOffset -= dwLen;
    25.      myiptr0 = (PDWORD)( dwLen + (PCHAR)myiptr0 );
    26.     };
    27.  
    28.     return NULL;
    29. };
    30.  
    31. PVOID SearchSeExchangePrimaryToken(PVOID PspAssignPrimaryToken)
    32. {
    33.  
    34.  
    35.     const DWORD MaxOffset = 0x800; //4096 bytes
    36.     DWORD CurOffset       = 0;
    37.     PDWORD  pMainFunction = (PDWORD)PspAssignPrimaryToken;
    38.  
    39.     if (!pMainFunction)
    40.         return NULL;
    41.  
    42.     while(CurOffset < MaxOffset)
    43.     {
    44.         CallType call_type;
    45.         PDWORD   new_addr;
    46.         PDWORD   AddrCall;
    47.         DWORD   dwInstrSize;
    48.  
    49.         new_addr = InstrSearchCall(pMainFunction,MaxOffset,&call_type);
    50.         GetInstLenght(new_addr,&dwInstrSize);
    51.  
    52.         if (call_type == CallRelative)
    53.         {
    54.             if ( *(BYTE*)(dwInstrSize + (PCHAR)new_addr ) == 0x89 )
    55.             {
    56.                 DWORD tmp;
    57.                 GetInstLenght((PDWORD)(dwInstrSize + (PCHAR)new_addr),&tmp);
    58.                 if (*(BYTE*)(tmp + dwInstrSize + (PCHAR)new_addr ) == 0xEB)
    59.                 {
    60.                     DWORD dwDelta = *(PDWORD)(1 + (PCHAR)new_addr);
    61.                     AddrCall = (PDWORD)( (DWORD)new_addr  +  (DWORD)dwDelta +  5 );
    62.                     return AddrCall;
    63.                 };
    64.             };
    65.         }
    66.         else
    67.             AddrCall = NULL;
    68. /*
    69.         if (AddrCall == NULL )
    70.             return NULL;
    71. */
    72.        
    73.         CurOffset += dwInstrSize + (DWORD)new_addr - (DWORD)pMainFunction ;
    74.         pMainFunction =(PDWORD)( dwInstrSize + (DWORD)new_addr );
    75.     };
    76.  
    77.     return NULL;
    78. };
    79. PVOID SearchPspAssignPrimaryToken()
    80. {
    81.     const DWORD MaxOffset = 0x1000; //4096 bytes
    82.     DWORD CurOffset       = 0;
    83.     PDWORD  pMainFunction = (PDWORD)KernelGetProcAddrEx(GetKernelBase(),CalcHash("NtSetInformationProcess"));
    84.  
    85.    
    86.  
    87.     if (!pMainFunction)
    88.         return NULL;
    89.  
    90.     while(CurOffset < MaxOffset)
    91.     {
    92.         CallType call_type;
    93.         PDWORD   new_addr;
    94.         PDWORD   AddrCall;
    95.         DWORD   dwInstrSize;
    96.  
    97.         new_addr = InstrSearchCall(pMainFunction,MaxOffset,&call_type);
    98.         GetInstLenght(new_addr,&dwInstrSize);
    99.  
    100.         if (call_type == CallRelative)
    101.         {
    102.             if ( *(BYTE*)(dwInstrSize + (PCHAR)new_addr ) == 0xE9 )
    103.             {
    104.                 if (*(BYTE*)(5 + dwInstrSize + (PCHAR)new_addr ) == 0x8b)
    105.                 {
    106.                     DWORD dwDelta = *(PDWORD)(1 + (PCHAR)new_addr);
    107.                     AddrCall = (PDWORD)( (DWORD)new_addr  +  (DWORD)dwDelta +  5 );
    108.                     return AddrCall;
    109.                 };
    110.             };
    111.         }
    112.         else
    113.             AddrCall = NULL;
    114.  
    115.         if (AddrCall == NULL )
    116.             return NULL;
    117.  
    118.        
    119.         CurOffset += dwInstrSize + (DWORD)new_addr - (DWORD)pMainFunction ;
    120.         pMainFunction =(PDWORD)( dwInstrSize + (DWORD)new_addr );
    121.     };
    122.  
    123.     return NULL;
    124. };
    125.  SearchSeExchangePrimaryToken(SearchPspAssignPrimaryToken());   // возвращает адрес SeExchangePrimaryToken
     
  6. steelfactor

    steelfactor New Member

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    501
    Хороший монолог получился )