Подтвердить что ты не робот

Windows Vista/Windows 7: SeDebugPrivilege & OpenProcess

Все, что мне удалось найти по поводу эскалации с соответствующими привилегиями для моих нужд, согласилось с моими текущими методами, но проблема существует. Я надеюсь, что, возможно, у кого-то есть опыт работы с Windows Vista/Windows 7, который может осветить некоторый свет, где есть только темнота. Я уверен, что это затянется, но, пожалуйста, несите меня.

Контекст

Я работаю над приложением, которое требует доступа к памяти других процессов на текущем компьютере. Это, очевидно, требует прав администратора. Он также требует SeDebugPrivilege (нет, это не орфографическая ошибка SetDebugPrivilege), которая, как я полагаю, должна быть правильно приобретена, хотя я сомневаюсь, что больше не нужны привилегии и, следовательно, причина моих проблем. Код до сих пор успешно работал во всех версиях Windows XP, а также в моей тестовой Vista 32-битной и Windows 7-разрядной среде.

Процесс

  • Программа всегда будет работать с правами администратора. Это можно предположить на этом посту.
  • Эскалация текущего процесса Access Token для включения прав SeDebugPrivilege.
  • Использование EnumProcesses для создания списка текущих PID в системе
  • Открытие дескриптора с помощью OpenProcess с правами доступа PROCESS_ALL_ACCESS
  • Использование ReadProcessMemory для чтения памяти другого процесса.

Проблема:

Все работает отлично во время разработки и моего личного тестирования (включая Windows XP 32 и 64, Windows Vista 32 и Windows 7 x64). Тем не менее, во время тестового развертывания на обеих компьютерах с Windows Vista (32-разрядная версия) и Windows 7 (64-разрядные) коллеги существует проблема с правами/правами с OpenProcess не удалось с общей ошибкой Access Denied. Это происходит как при работе с ограниченным пользователем (как и следовало ожидать), так и при явном запуске в качестве администратора (щелкните правой кнопкой мыши → "Запуск от имени администратора" и при запуске из командной строки на уровне администратора).

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

Похоже, что хотя используемые учетные данные позволяют UAC "запускаться как администратор", процесс все еще не получает правильные права, чтобы иметь возможность OpenProcess в другом процессе. Я не достаточно знаком с внутренними компонентами Vista/Windows 7, чтобы знать, что это может быть, и я надеюсь, что у кого-то есть представление о том, что может быть причиной.

The Kicker

Человек, который сообщил об этой ошибке, и какая среда может регулярно воспроизводить эту ошибку, имеет небольшое приложение, названное в соответствии с строками RunWithDebugEnabled, которое представляет собой небольшую программу начальной загрузки, которая, как представляется, увеличивает свои собственные привилегии, а затем запускает исполняемый файл (таким образом наследуя эскалированные привилегии). При запуске с этой программой, используя те же учетные данные администратора домена в приглашении UAC, программа работает правильно и может успешно вызывать OpenProcess и работает по назначению.

Так что это определенно проблема с получением правильных привилегий, и известно, что учетная запись администратора домена является учетной записью администратора, которая должна иметь доступ к правильным правам. (Очевидно, получение этого исходного кода было бы замечательным, но я бы не был здесь, если бы это было возможно).

Примечания

Как отмечалось, ошибки, о которых сообщают неудачные попытки OpenProcess, - это Access Denied. Согласно документации MSDN OpenProcess:

Если вызывающий активировал привилегию SeDebugPrivilege, запрашиваемый доступ предоставляется независимо от содержимого дескриптора безопасности.

Это заставляет меня думать, что, возможно, в этих условиях есть проблема либо с (1) Получение SeDebugPrivileges, либо (2) Требование других привилегий, которые не были упомянуты в любой документации MSDN и которые могут отличаться между Доменом Учетная запись администратора и учетная запись локального администратора

Пример кода:

void sample()
{
   /////////////////////////////////////////////////////////
   //   Note: Enabling SeDebugPrivilege adapted from sample
   //     MSDN @ http://msdn.microsoft.com/en-us/library/aa446619%28VS.85%29.aspx
   // Enable SeDebugPrivilege
   HANDLE hToken = NULL;
   TOKEN_PRIVILEGES tokenPriv;
   LUID luidDebug;
   if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken) != FALSE)
   {
      if(LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luidDebug) != FALSE)
      {
         tokenPriv.PrivilegeCount           = 1;
         tokenPriv.Privileges[0].Luid       = luidDebug;
         tokenPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
         if(AdjustTokenPrivileges(hToken, FALSE, &tokenPriv, 0, NULL, NULL) != FALSE)
         {
            // Always successful, even in the cases which lead to OpenProcess failure
            cout << "SUCCESSFULLY CHANGED TOKEN PRIVILEGES" << endl;
         }
         else
         {
            cout << "FAILED TO CHANGE TOKEN PRIVILEGES, CODE: " << GetLastError() << endl;
         }
      }
   }
   CloseHandle(hToken);
   // Enable SeDebugPrivilege
   /////////////////////////////////////////////////////////

   vector<DWORD> pidList = getPIDs();  // Method that simply enumerates all current process IDs

   /////////////////////////////////////////////////////////
   // Attempt to open processes
   for(int i = 0; i < pidList.size(); ++i)
   {
      HANDLE hProcess = NULL;
      hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pidList[i]);
      if(hProcess == NULL)
      {
         // Error is occurring here under the given conditions
         cout << "Error opening process PID(" << pidList[i] << "): " << GetLastError() << endl;
      }
      CloseHandle(hProcess);
   }
   // Attempt to open processes
   /////////////////////////////////////////////////////////
}




Спасибо!

Если у кого-то есть представление о возможных разрешениях, привилегиях, правах и т.д., которые могут отсутствовать, чтобы правильно открыть другой процесс (предполагая, что исполняемый файл был правильно "Запуск от имени администратора" ) в Windows Vista и Windows 7 под вышеуказанные условия, это было бы очень признано.

Меня бы здесь не было, если бы я не был абсолютно в тупик, но я надеюсь, что опыт и знания группы будут яркими. Я благодарю вас за то, что вы нашли время, чтобы прочитать эту стену текста. Только хорошие намерения оцениваются, благодаря тому, что он является типом человека, который делает Qaru настолько полезным для всех!

4b9b3361

Ответ 1

Итак, после многого отладки и заботы многих людей для информации, я наконец смог отследить парня, который написал приложение RunWithDebugEnabled, и получить краткое изложение того, как он работает.

Проблема в этом случае заключается в том, что привилегия Debug programs в локальной политике для администратора домена была удалена, и, таким образом, токен SeDebugPrivilege отсутствовал в токене доступа к процессу. Он не может быть включен, если он вообще отсутствует, и я до сих пор не знаю, как добавить привилегию в существующий токен доступа.


Как работает текущая магия:
Таким образом, магическое приложение RunWithDebugEnabled будет использовать права администратора для установки себя как службы и запускать себя, поэтому работает под учетной записью пользователя SYSTEM, а не администратором домена. С привилегиями SYSTEM приложение затем создает новый токен доступа, который идентичен токену администратора, только с присутствующим токеном SeDebugPrivilege. Этот новый токен используется для CreateProcessAsUser() и запускает программу с недавно включенным SeDebugPrivilege, который ранее отсутствовал.

Мне действительно не нравится это "решение" здесь, и я продолжаю поиск "более чистого" способа получения этой привилегии. Я буду размещать это как еще один вопрос здесь, на SO, который я попытаюсь вспомнить, чтобы связать здесь также, чтобы помочь другим следовать и для дальнейшего использования.

РЕДАКТИРОВАТЬ: Выдавать себя за систему (или эквивалент) из учетной записи администратора



Я благодарю всех вас за ваше время и энергию, помогая отлаживать и решать эту проблему. Это очень ценится!