Solución:
Respuesta corta
Hay tres problemas independientes que reclaman el nombre de “Escritorio seguro”:
- Funciones integradas de Windows como GINA y el modelo de proveedor de credenciales.
- Separación de aplicaciones privilegiadas y no privilegiadas que se ejecutan como el mismo usuario (nominalmente previene la escalada de privilegios), que pueden estar relacionadas o no con:
SwitchDesktop()
, que es lo que KeePass está usando y puede o no (no estoy seguro) ser resistente a la inyección de DLL.
Respuesta detallada
Como introducción rápida a cómo se construyen las GUI de Windows, básicamente todo se ejecuta a través de una función llamada CreateWindow()
(Me refiero a todo, cada botón, cada menú, todo) y se le da un hWnd
o manija de ventana. La modificación de estas ventanas se realiza a través de otra función, SendMessage()
.
Aquí está el truco. Como aplicación de modo de usuario, al realizar las llamadas a la API adecuadas, puedo enviar mensajes con bastante facilidad a otras ventanas. Es bastante trivial hacer que los botones desaparezcan de las formas de otras personas. Es un poco más difícil realizar la inyección de DLL y conectar el bucle de mensajes que recibe los mensajes (el sistema operativo envía mensajes de Windows cuando les suceden cosas), pero no mucho más difícil. Si puedo enganchar esos eventos, podría enviar automáticamente su formulario de “sí / no”. O podría cambiar la etiqueta de ReallyDodgyVirus.exe
para explorer.exe
y no serías más sabio.
Insertar: Un artículo realmente bueno sobre las diversas técnicas para introducir su código en el espacio de direcciones de un proceso en ejecución.
Ahora, ¿qué está haciendo KeePass?
Una lectura muy breve de la fuente muestra que están usando CreateDesktop()
, SwitchDesktop()
y CloseDesktop()
para crear un segundo escritorio conectado al dispositivo de visualización físico en el que se encuentra. En inglés, le piden al kernel que cree para ellos un escritorio aislado cuyo hWnd
los objetos están fuera del rango de búsqueda de cualquier otra aplicación SendMessage()
.
Debo señalar que SwitchDesktop
suspende la actualización de la interfaz de usuario del escritorio predeterminado. No estoy seguro de si los bucles de mensajes también están congelados; sospecho que no, ya que el escritorio se crea como un nuevo hilo.
En este caso, KeePass es dibujar la interfaz de usuario, por lo que la ejecución es no, como yo lo entiendo, como NT AUTHORITY/SYSTEM
. En cambio, el nuevo escritorio se crea de forma aislada del resto del escritorio actual, que lo protege. Estaré feliz de que me corrijan en eso. Sin embargo, consulte MSDN para SwitchDesktop:
La función SwitchDesktop falla si el escritorio pertenece a una estación de ventana invisible. SwitchDesktop también falla cuando se llama desde un proceso que está asociado con un escritorio seguro, como los escritorios WinLogon y ScreenSaver. Los procesos que están asociados con un escritorio seguro incluyen procesos UserInit personalizados. Por lo general, estas llamadas fallan con un error de “acceso denegado”.
Creo que esto significa que estos cuadros de diálogo (protectores de pantalla, inicio de sesión de Windows) están integrados más profundamente en Windows, de modo que siempre se ejecutan como NT AUTHORITYSYSTEM
y el UserInit
proceso crea los subprocesos en autenticación válida en el nivel de privilegio requerido.
La razón por la que menciono esto es porque creo que hay dos problemas: diferentes escritorios y separación de privilegios. De la discusión de Mark Russinovich sobre el tema de Secure Desktop:
El mecanismo de integridad de Windows y UIPI se diseñaron para crear una barrera protectora alrededor de las aplicaciones elevadas. Uno de sus objetivos originales era evitar que los desarrolladores de software tomaran atajos y aprovecharan aplicaciones ya elevadas para realizar tareas administrativas. Una aplicación que se ejecuta con derechos de usuario estándar no puede enviar entradas sintéticas de mouse o teclado a una aplicación elevada para hacer que cumpla sus órdenes o inyectar código en una aplicación elevada para realizar operaciones administrativas.
Como dice SteveS, UAC ejecuta un proceso de escritorio separado como NT AUTHORITY/SYSTEM
. Si puede atrapar a UAC en acción (consent.exe
) a través del explorador de procesos, se ve así:
Escalar privilegios como un proceso del que no tengo los detalles específicos, pero esto es lo que creo que entiendo: Creo que el proceso de escalada de privilegios en la API de Windows provoca un proceso que se ejecuta como NT AUTHORITY/SYSTEM
(por lo tanto, puede ejecutar el nuevo proceso con los privilegios que desee, en este caso un Administrador). Cuando una aplicación solicita mayores privilegios, esa pregunta se le hace en un nuevo escritorio localmente, al que ninguna de sus aplicaciones puede obtener el identificador de escritorio ni ninguno de los identificadores de elementos de la GUI. Cuando da su consentimiento, consent.exe
crea el proceso como usuario privilegiado. Por lo tanto, el proceso que se ejecuta como NT AUTHORITYSYSTEM
es una consecuencia de la necesidad de crear un nuevo proceso privilegiado, no como un método para crear un escritorio seguro. El hecho de que el escritorio sea diferente al predeterminado es lo que agrega seguridad en ambos casos.
Creo que lo que Mark quiere decir anteriormente es que, además de estos escritorios seguros, están sucediendo dos cosas:
- De hecho, su escritorio de administrador predeterminado se ejecuta sin privilegios, a diferencia de Windows XP y versiones anteriores y
- Las aplicaciones sin privilegios y privilegiadas ahora existen en escritorios separados (descargo de responsabilidad: podrían ser simplemente ACL en los objetos en la memoria, no estoy seguro), lo que garantiza que el código sin privilegios no pueda acceder a los objetos con privilegios.
La interfaz de usuario de inicio de sesión de Windows vuelve a ser diferente en Vista / 7.
Claramente, ninguno de estos métodos lo defenderá contra los rootkits en modo kernel, pero evitan la escalada de privilegios y el compromiso de la integridad de la interfaz de usuario al aislar las aplicaciones privilegiadas o, en el caso de KeePass, el cuadro de diálogo confidencial.
Editar
Después de mirar más detenidamente el código KeePass, vi esta práctica pieza de C #:
Bitmap bmpBack = UIUtil.CreateScreenshot();
if(bmpBack != null) UIUtil.DimImage(bmpBack);
/* ... */
SecureThreadParams stp = new SecureThreadParams();
stp.BackgroundBitmap = bmpBack;
stp.ThreadDesktop = pNewDesktop;
A partir de esto, puede ver que, de hecho, para imitar a consent.exe, KeePass toma una captura de pantalla del fondo, lo atenúa y crea su nuevo escritorio con el fondo del escritorio anterior. Por lo tanto, sospecho que el escritorio antiguo continúa ejecutándose incluso cuando no se está procesando. Esto creo que confirma que no hay magia NT AUTHORITYSYSTEM
la acción está sucediendo tanto con KeePass como consent.exe
(Sospecho que consent.exe está haciendo lo mismo en la interfaz de usuario, simplemente se inicia en el contexto de NT AUTHORITYSYSTEM
).
Editar 2
Cuando digo inyección de DLL, estoy pensando específicamente en la inyección de DLL para corromper la interfaz de usuario. La inyección de DLL sigue siendo posible en KeePass como proceso, pero no estoy seguro de si podría usarse para influir en esa interfaz de usuario segura. Sin embargo, podría usarse para acceder a la memoria del proceso y sus subprocesos, obteniendo así la pre-encriptación de la contraseña ingresada. Difícil, pero creo que es posible. Agradecería que alguien me aconsejara sobre esto si lo supiera.
Un “Escritorio seguro” es un escritorio que solo puede ejecutar el sistema. Eso suena un poco extraño y probablemente no explique mucho.
En Windows, un escritorio es una vista que le permite interactuar con procesos. Cuando inicia sesión en Windows (el indicador de inicio de sesión), está en un escritorio. Cuando inicias sesión y ves el menú de inicio, estás en un escritorio separado. Cuando bloquea su PC, está en otro escritorio. Cuando aparece UAC, estás en otro escritorio. Hay bastantes escritorios diferentes en Windows.
Un escritorio seguro es un escritorio que está fuera del alcance de la accesibilidad de otras aplicaciones. El escritorio de inicio de sesión es un escritorio seguro (creado por winlogon.exe), al igual que el escritorio de UAC. Ningún otro proceso puede interactuar con el escritorio, por lo tanto, ningún otro proceso puede hacer cosas como activar un botón o leer el contenido de un cuadro de texto. Por eso UAC es (en teoría) útil.
Las aplicaciones de terceros pueden crear un escritorio seguro para solicitar información (como una contraseña maestra) y luego pasarla a la aplicación en cuestión. De esta manera, ningún otro proceso puede, en teoría, husmear la contraseña.
Un buen comienzo sobre escritorios seguros es la primera mitad de este artículo sobre cómo funciona UAC en el escritorio seguro: http://blogs.msdn.com/uac/archive/2006/05/03/589561.aspx.
Si te gustó nuestro trabajo, tienes el poder dejar un escrito acerca de qué te ha impresionado de este escrito.