OpenProcessToken() дает отказ в доступе

В рамках проекта, который работает как служба, порождающая процесс на экране входа в систему (для управления рабочим столом), мы вызываем OpenProcessToken(), который затем дублируется и создается процесс. Это успешно работает, как и ожидалось, в LocalSystem, однако это не работает под учетной записью домена. Фрагмент кода ниже...

procedure LaunchProcess;
var dwPid, dwSessionId: DWord;
  hUserToken, hProcess: THANDLE;
begin
  dwPid := GetProcessID('winlogon.exe', WTSGetActiveConsoleSessionId);
  hProcess := OpenProcess(MAXIMUM_ALLOWED, FALSE, dwPid);
  if (not OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY or TOKEN_DUPLICATE or
    TOKEN_ASSIGN_PRIMARY or TOKEN_ADJUST_SESSIONID or TOKEN_READ or TOKEN_WRITE, hUserToken)) then
      raise Exception.Create('OpenProcessToken failed (' + SysErrorMessage(GetLastError) + ').');

  {...go on to duplicate token, create environment and launch process...}

end;

Полный исходный код вспомогательной функции можно найти здесь.

Вот тут становится немного неясно. Я понимаю, что OpenProcessToken() требует привилегий, поэтому в конечном итоге я получаю сообщение об ошибке, однако было неясно, какие привилегии мне требуются и как эффективно назначить их учетной записи домена.

Это предполагает, что необходимая привилегия — SeTcbPrivilege ("Действовать как часть операционной системы").

Я прочитал страницу Microsoft (не могу связать, недостаточно репутации - извините) о привилегиях, которая предполагает, что SeTcbPrivilege может быть назначен учетной записи домена с использованием локальной или групповой политики безопасности. Также было высказано предположение, что процесс назначения (например, winlogon.exe) может просто не разрешать ничему, кроме LocalSystem, получать свой токен.

Я попытался настроить учетную запись домена явно с помощью учетной записи службы, но в локальной безопасности и групповой политике перезапустил и выполнил gporesult, чтобы убедиться, что политика вступила в силу, но каждый раз, когда whoami /priv возвращает, SeTcbPrivilege отключен

Мой вопрос заключается в том, возможно ли это вообще (могу ли я получить токен winlogon.exe, используя учетную запись домена), и если да, то можно ли установить привилегию программно, или это должно быть через GPO? (и если это так, учитывая, что мои предыдущие попытки использования GPO не дали результата, как это возможно)


person Ross Harvey    schedule 02.10.2016    source источник


Ответы (2)


  1. Вы можете активировать права с помощью LsaAddAccountRights, вам все равно нужно, по крайней мере, выйти из системы /, возможно, перезагрузиться.
  2. Затем вам нужно включить привилегии для этих прав в вашем коде. Многие вещи происходят автоматически для локальной системы, но не для пользователей.
  3. Для быстрой проверки я активировал и включил SE_TCB_NAME, SE_ASSIGNPRIMARYTOKEN_NAME и SE_INCREASE_QUOTA_NAME.
  4. Затем я смог успешно вызвать OpenProcessToken только с TOKEN_DUPLICATE
  5. Активация этих прав дала мне новый SessionID после выхода из системы. SessionID 2, поэтому ваш вызов WTSGetActiveConsoleSessionId ложно возвратил бы 1

Все это делалось от имени администратора с повышенными правами.

person FredS    schedule 03.10.2016
comment
Спасибо, Фред, я попробую сегодня вечером, я просто хотел подтвердить тип источника, который мне нужен для активации прав, это что-то вроде это? - person Ross Harvey; 04.10.2016
comment
Извините, это определенно область, с которой я не знаком. Из того, что вы сказали, я понимаю, что здесь есть два действия: активация, которая представляет собой процесс назначения привилегии пользователю (предположительно является постоянной), а затем включение что предположительно происходит перед вызовом OpenProcessToken()? Вы помогли мне не только в этом, но и в другом вопросе, и я действительно ценю это, это немного смущает, поскольку вашего ответа должно быть достаточно, чтобы я мог продолжить, но если у вас есть какие-либо указатели, функции API, которые вы использовали, это помогло бы мне в этом, что было бы действительно оценено. - person Ross Harvey; 04.10.2016
comment
@Ross, добавление или активацию можно выполнить с помощью GPO или LSA, вам все равно нужно включить его с помощью AdjustTokenPrivileges, который используется в вашем исходном сообщении, поэтому можно подумать, что вы знаете, что это делает ... и да, вы должны включить его перед вызовами сделаны, которые требуют этого. Я включаю их для процесса в form.create. - person FredS; 04.10.2016
comment
Спасибо, Фред, могу я спросить, когда вы говорите, что включаете привилегии в form.create, вы имеете в виду, что вы AdjustTokenPrivileges своего собственного процесса перед открытием процесса, потому что я использую AdjustTokenPrivileges после OpenProcessToken, который к тому времени уже не работал. Что касается добавления или активации, я пробовал это с GPO и LSP, я использую учетную запись домена, которая также является локальным администратором, но «whoami / priv», похоже, не показывал, что он включен, я хотел бы попробуйте программно, чтобы он был явным (вместо настройки объекта групповой политики, который, казалось, был применен, но, как указано выше, не вступил в силу). - person Ross Harvey; 05.10.2016
comment
@Ross правильно, вам нужно включить привилегии для вашего собственного процесса, прежде чем вызывать что-либо еще. - person FredS; 05.10.2016
comment
Спасибо, Фред, твоя помощь сделала меня намного ближе. Я применил привилегии GPO, включая SE_TCB_NAME, SE_ASSIGNPRIMARYTOKEN_NAME и SE_INCREASE_QUOTA_NAME. Я подтвердил в своей службе, что они применяются правильно (whoami /priv показывает, что они включены). Я использую NTSetPrivilege() для установки тех же привилегий, выполняемых перед вызовом LaunchProcess() и вызываемых только один раз (предположительно, эти привилегии нужно устанавливать только один раз для процесса). Однако, несмотря на то, что мой OpenProcessToken() по-прежнему не работает, доступ запрещен. Установлены ли все необходимые привилегии? - person Ross Harvey; 05.10.2016
comment
Я проанализировал различия между LocalSystem и моей учетной записью домена, под которой работает служба, привилегии Se, отсутствующие в учетной записи домена, следующие: SeLockMemoryPrivilege, SeSystemProfilePrivilege, SeProfileSingleProcessPrivilege, SeIncreaseBasePriorityPrivilege, SeCreatePagefilePrivilege, SeCreatePermanentPrivilege, SeDebugPrivilege, SeAuditPrivilege, SeIncreaseWorkingSetPrivilege, SeTimeZonePrivilege и SeCreateSymbolicLinkPrivilege. Может ли потребоваться что-то из этого, скажем, SeDebugPrivilege? Спасибо, Фред. - person Ross Harvey; 05.10.2016

Ваше приложение работает успешно, когда вы запускаете его с правами администратора? Если это так, перейдите к параметрам проекта, выберите «Приложение» и установите флажок «Включить права администратора» в разделе «Файл манифеста».

person Pat Heuvel    schedule 03.10.2016