Muy buenas! Hoy os traigo un post de programacion en .Net para automatizar la auditoria de UACs que aceptamos en el equipo.
Para entender las ideas de este post primero deberiais de leeros la entrada que he escrito en el blog de vista-tecnica sobre como activar la auditoria de procesos y como detectar cuales requieren elevacion.
Dicho esto, y esperando que antes os hayais leido el post anteriormente referenciado, empezamos.
Desde .Net es posible acceder a los eventos que ha generado el sistema y capturarlos en tiempo real. Eso es lo que vamos a explicar y a ver con el evento 4688 de Windows Vista. Existe un objeto en System.Diagnostics llamado EventLog que nos permite acoplarnos a uno de los ficheros de eventos que se generan en el sistema. Nosotros en este caso queremos monitorizar eventos de seguridad. Para ello definiremos el objeto de la siguiente manera:
EventLog eventLog = new EventLog("Security");
eventLog.EnableRaisingEvents = true;
eventLog.EntryWritten += new EntryWrittenEventHandler(eventLog_EntryWritten);
Con esta tres lineas generamos el objeto EventoLog asociado a los eventos de seguridad, le permitimos capturar los eventos que se vayan produciendo y le asociamos una funcion donde trataremos los eventos que nos lleguen.
Una vez dentro del metodo EntryWrittenEventHandler filtraremos por eventos con ID 4688 y posteriormente trataremos el mensaje que nos devuelve el evento:
if (e.Entry.InstanceId == 4688)
{
string msg = e.Entry.Message;
msg = msg.Substring(309, msg.Length - 309);
string[] msgList = msg.Split(',');
for(int i = 0; i < msgList.Length; i++)
msgList[i] = (msgList[i].Replace('\'', ' ')).Trim();
/* List of elements in the Entry.Message array:
* 0 - SID
* 1 - User
* 2 - Machine
* 3 - ???
* 4 - PID
* 5 - Process name
* 6 - Token Elevation Type (%%1936, %%1937, %%1938)
* 7 - Parent PID
*/
if(msgList[6] == "%%1937")
{
try
{
int pid = Convert.ToInt32(msgList[4], 16);
Process p = Process.GetProcessById(pid);
Console.WriteLine("El siguiente programa ha requerido elevacion:");
if(p.MainWindowTitle.Length > 0)
Console.WriteLine("Window Title: " + p.MainWindowTitle);
Console.WriteLine("Path: " + msgList[5]);
Console.WriteLine();
}
catch (ArgumentException ee)
{
Console.WriteLine(ee.Message);
}
}
}
El mensaje contiene el TokenElevationType que es lo que nos interesa. Cuando este vale 1937 quiere decir que el proceso ha requerido elevacion.
Esto funciona perfectamente con los procesos tales como ejecucion de programas o instalaciones, que contienen un titulo de la ventana mas o menos descriptivo, pero no ocurre asi con los procesos administrativos del sistema que requieren elevacion, tales como cambiar parametros de configuracion de red o agregar cuentas al equipo. En estos casos el proceso que se llama es dllhost.exe, que si lo analizamos con el Process Explorer recibe como parametro un GUID que referencia en el registro del sistema a una ventana. Existe asociado tambien la descripcion de la misma, que podria indicarnos que tarea administrativa ha requerido elevacion…
Pero como capturarlo y leer el registro correspondiente lo dejamos para otro post.
P.D. Venga, ahora criticarme por mi codigo y pedidme de nuevo que libere el Thumbando… ¿No habeis tenido suficiente sufrimiento con este codigo?
¿Cuando podremos disponer de la primera release Open Source de Thumbando?
Comment by Rafa Vargas — 2008/09/29 @ 9:09 PM
Me esperaba algo mas inteligente por tu parte, Vargas… ¿Que te parece la idea del post?
Comment by Pedro Laguna — 2008/09/29 @ 9:13 PM
[...] Este parámetro no se puede ya filtrar desde el visor de eventos, pues no es un parámetro del evento, si no un valor dentro del mensaje generado por el mismo. Si quieres saber cómo automatizar la captura del evento de elevación de privilegios puedes pasarte por mi blog personal donde explico cómo capturar el evento de elevación de privilegios mediante programación en .Net. [...]
Pingback by Detectar procesos que requieran elevación de privilegios en Windows Vista - vista-tecnica — 2008/10/10 @ 5:45 AM