c++ windows uac privileges openprocess

c++ - Privilegio de Windows Vista/Windows 7: SeDebugPrivilege & OpenProcess



uac privileges (1)

Todo lo que he podido encontrar acerca de escalar a los privilegios apropiados para mis necesidades ha coincidido con mis métodos actuales, pero el problema existe. Espero que alguien tenga alguna experiencia interna de Windows Vista / Windows 7 que pueda iluminar algo donde solo hay oscuridad. Estoy seguro de que esto se hará largo, pero por favor tengan paciencia conmigo.

Contexto

Estoy trabajando en una aplicación que requiere acceder a la memoria de otros procesos en la máquina actual. Esto, obviamente, requiere derechos de administrador. También requiere SeDebugPrivilege (no, no es un error de ortografía de SetDebugPrivilege ), que creo que estoy adquiriendo correctamente, aunque cuestiono si no son necesarios más privilegios y, por lo tanto, la causa de mis problemas. Hasta ahora, el código ha funcionado con éxito en todas las versiones de Windows XP y en mis entornos de prueba Vista 32 bit y Windows 7 64 bit.

Proceso

  • El programa siempre se ejecutará con derechos de administrador. Esto se puede asumir a lo largo de este post.
  • SeDebugPrivilege Access Token del proceso actual para incluir los derechos de SeDebugPrivilege .
  • Uso de EnumProcesses para crear una lista de los PID actuales en el sistema
  • Abrir un identificador utilizando OpenProcess con derechos de acceso PROCESS_ALL_ACCESS
  • Uso de ReadProcessMemory para leer la memoria del otro proceso.

Problema:

Todo ha funcionado bien durante el desarrollo y mis pruebas personales (incluidos Windows XP 32 y 64, Windows Vista 32 y Windows 7 x64). Sin embargo, durante una implementación de prueba en las máquinas Windows Vista (32 bits) y Windows 7 (64 bits) de un colega, parece que hay un problema de privilegio / derechos con OpenProcess falla con un error genérico de Access Denied . Esto ocurre tanto cuando se ejecuta como un Usuario limitado (como se esperaría) y también cuando se ejecuta explícitamente como Administrador (haga clic con el botón derecho en → Ejecutar como Administrador y cuando se ejecuta desde un indicador de comandos de nivel de Administrador).

Sin embargo, este problema no ha sido reproducible para mí en mi entorno de prueba. He presenciado el problema de primera mano, por lo que confío en que el problema existe. La única diferencia que puedo distinguir entre el entorno real y mi entorno de prueba es que el error real se produce cuando se utiliza una cuenta de Administrador de dominio en el indicador de UAC, mientras que mis pruebas (que funcionan sin errores) utilizan una cuenta de administrador local en el Solicitud de UAC.

Parece que a pesar de que las credenciales que se utilizan permiten que UAC se ejecute como administrador, el proceso aún no está obteniendo los derechos correctos para poder OpenProcess en otro proceso. No estoy lo suficientemente familiarizado con los aspectos internos de Vista / Windows 7 para saber qué podría ser esto, y espero que alguien tenga una idea de cuál podría ser la causa.

El pateador

La persona que ha reportado este error, y el entorno de quién puede reproducir este error regularmente, tiene una pequeña aplicación nombrada en la línea de RunWithDebugEnabled que es un pequeño programa bootstrap que parece escalar sus propios privilegios y luego lanzar el ejecutable que se le pasa. heredando los privilegios escalados). Cuando se ejecuta con este programa, utilizando las mismas credenciales de administrador de dominio en el indicador de UAC, el programa funciona correctamente y puede llamar a OpenProcess con éxito y funciona según lo previsto.

Por lo tanto, este es definitivamente un problema con la adquisición de los privilegios correctos, y se sabe que la cuenta del Administrador del dominio es una cuenta de administrador que debería poder acceder a los derechos correctos. (Obviamente, obtener este código fuente sería genial, pero no estaría aquí si fuera posible).

Notas

Como se indicó, los errores informados por los intentos fallidos de OpenProcess son Access Denied . Según la documentación de MSDN de OpenProcess :

Si la persona que llama ha habilitado el privilegio SeDebugPrivilege, el acceso solicitado se otorga independientemente del contenido del descriptor de seguridad.

Esto me lleva a creer que quizás haya un problema en estas condiciones ya sea con (1) Obtener los SeDebugPrivileges o (2) Requerir otros privilegios que no se hayan mencionado en ninguna documentación de MSDN y que puedan diferir entre una cuenta de administrador de dominio y una cuenta local. Cuenta de administrador

Código de muestra:

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 ///////////////////////////////////////////////////////// }




¡Gracias!

Si alguien tiene alguna idea de los posibles permisos, privilegios, derechos, etc., me puede faltar para abrir correctamente otro proceso (suponiendo que el ejecutable se haya ejecutado correctamente como "Ejecutar como administrador") en Windows Vista y Windows 7 en las condiciones anteriores , sería muy apreciado.

No estaría aquí si no estuviera absolutamente perplejo, pero tengo la esperanza de que una vez más la experiencia y el conocimiento del grupo brillen. Le agradezco por tomarse el tiempo para leer este muro de texto. Solo se aprecian las buenas intenciones, ¡gracias por ser el tipo de persona que hace que Stack Overflow sea tan útil para todos!


Así que después de un montón de depuración y molestar a mucha gente en busca de información, finalmente pude localizar al tipo que escribió la aplicación RunWithDebugEnabled y obtener un resumen de cómo funciona.

El problema, en este caso, es que se Debug programs privilegio de Debug programs en la política local para el administrador del dominio y, por lo tanto, el token SeDebugPrivilege no estaba presente en el token de acceso del proceso. No se puede habilitar si no está presente en absoluto, y aún no conozco ninguna forma de agregar el privilegio a un token de acceso existente.


Cómo funciona la magia actual:
Por lo tanto, la aplicación mágica RunWithDebugEnabled usaría sus derechos de Administrador para instalarse como un servicio y comenzar a ejecutarse, por lo tanto, se ejecuta bajo la cuenta de usuario del SYSTEM lugar del Administrador de Dominio. Con los privilegios del SYSTEM , la aplicación crea un nuevo token de acceso que es idéntico al token de Administrador, solo con el token SeDebugPrivilege presente. Este nuevo token se usa para CreateProcessAsUser() y ejecuta el programa con el SeDebugPrivilege recién habilitado que faltaba antes.

En realidad no me gusta esta "solución" aquí, y he continuado mi búsqueda de una forma más "limpia" para obtener este privilegio. Pondré esto como otra pregunta aquí en SO, que trataré de recordar vincular aquí también para ayudar a otros a seguir adelante y para futuras referencias.

EDITAR: suplantar el SISTEMA (o equivalente) de la cuenta del administrador



Les agradezco a todos por su tiempo y energía para ayudar a depurar y resolver este problema. ¡Realmente es muy apreciado!