Привилегия Windows Vista / Windows 7: SeDebugPrivilege & OpenProcess - PullRequest
25 голосов
/ 29 мая 2010

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

Контекст

Я работаю над приложением, которое требует доступа к памяти других процессов на текущем компьютере. Это, очевидно, требует прав администратора. Это также требует SeDebugPrivilege (нет, это не ошибочное написание SetDebugPrivilege), которое, как я считаю, я получаю правильно, хотя я сомневаюсь, что дополнительные привилегии не нужны и, следовательно, причина моих проблем. До сих пор код успешно работал во всех версиях Windows XP, а также в моей тестовой 64-битной среде Vista и 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, чтобы знать, что это может быть, и я надеюсь, что кто-то имеет представление о том, что может быть причиной.

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 под Вышеуказанные условия были бы весьма признательны.

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

1 Ответ

13 голосов
/ 07 июня 2010

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

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


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

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

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



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

...