El soporte técnico Windows Vista Service Pack 1 (SP1) finaliza el 12 de julio de 2011. Para seguir recibiendo actualizaciones de seguridad para Windows, asegúrese de ejecutar Windows Vista with Service Pack 2 (SP2). Para obtener más información, consulte esta página web de Microsoft: El soporte técnico finaliza para algunas versiones de Windows.

Cuando una aplicación carga dinámicamente una biblioteca de vínculos dinámicos (DLL) sin especificar una ruta de acceso completa, Windows intenta localizar la DLL buscando un conjunto de directorios bien definido. Si un atacante obtiene el control de uno de los directorios, puede obligar a la aplicación a cargar una copia malintencionada de la DLL en lugar de la DLL que esperaba. Estos ataques se conocen como "ataques de carga previa de DLL" y son comunes a todos los sistemas operativos que admiten la carga dinámica de bibliotecas dll compartidas. El efecto de estos ataques podría ser que un atacante pueda ejecutar código en el contexto del usuario que ejecuta la aplicación. Cuando la aplicación se ejecuta como administrador, esto podría llevar a una elevación local de privilegios. Sabemos sobre el interés renovado en estos ataques. Para limitar el efecto que este problema tiene en nuestros clientes mutuos, publicamos este documento a la comunidad de desarrolladores para asegurarse de que conocen este problema y tienen las herramientas necesarias para abordar el problema en sus aplicaciones.

Resumen

Descripción de los ataques de carga previa de DLL

Ataques basados en LoadLibrary

Cuando una aplicación carga dinámicamente un archivo DLL sin especificar una ruta de acceso completa, Windows intenta localizar esta DLL mediante una búsqueda lineal a través de un conjunto de directorios bien definido, conocido como Orden de búsqueda de DLL. Si Windows la DLL dentro del orden de búsqueda de DLL, se cargará esa DLL. Sin embargo, Windows encuentra la DLL en ninguno de los directorios del orden de búsqueda de DLL, devolverá un error a la operación de carga de DLL. A continuación se muestra el orden de búsqueda de DLL para las funciones LoadLibraryy LoadLibraryEx,que se usan para cargar archivos DLL dinámicamente:

  1. El directorio desde el que se cargó la aplicación

  2. El directorio del sistema

  3. El directorio del sistema de 16 bits

  4. El directorio de Windows

  5. El directorio de trabajo actual

  6. Los directorios indicados en la variable de entorno PATH



Considere el siguiente escenario:


  • Una aplicación carga un archivo DLL sin especificar una ruta de acceso completa que espera encontrar en el CWD de la aplicación.

  • La aplicación está totalmente preparada para controlar el caso cuando no encuentra la DLL.

  • El atacante conoce esta información sobre la aplicación y controla el CWD.

  • El atacante copia su propia versión especialmente diseñada del archivo DLL en el CWD. Esto supone que el atacante tiene permiso para hacerlo.

  • Windows busca en los directorios del orden de búsqueda de DLL y encuentra la DLL en el CWD de la aplicación.

En este escenario, la DLL especialmente diseñada se ejecuta dentro de la aplicación y obtiene los privilegios del usuario actual.

Recomendación Para evitar este ataque, las aplicaciones pueden quitar el directorio de trabajo actual (CWD) de la ruta de búsqueda de dll llamando a la
API SetDllDirectory con una cadena vacía
(""). Si una aplicación depende de cargar una DLL desde el directorio actual, obtenga el directorio de trabajo actual y úselo para pasar una ruta de acceso completa de LoadLibrary.



También somos conscientes de que algunos desarrolladores usan LoadLibrary para validar si un archivo DLL específico está presente para determinar qué versión de Windows está siendo ejecutada por el usuario. Debe ser consciente de que esto podría hacer que la aplicación sea vulnerable. Si la biblioteca afectada realmente no existe en la versión Windows en la que se ejecuta la aplicación, un atacante podría introducir una biblioteca con el mismo nombre en CWD. Le recomendamos encarecidamente que no use esta técnica. En su lugar, use las técnicas recomendadas que se describen en el artículo de MSDN, "Obtener la versión del sistema".

Una aplicación que carga complementos de terceros y que no puede obligar a los complementos a usar una ruta de acceso calificada para sus llamadas de LoadLibrary debe llamar a SetDllDirectory("") para quitar CWD y, a continuación, llamar a SetDllDirectory("ubicación de instalación del complemento") para agregar el directorio de instalación del complemento a la ruta de búsqueda de DLL.

Ataques basados en SearchPath

Existe un ataque similar cuando una aplicación usa la API de SearchPath para localizar un archivo DLL y cargar dinámicamente la ruta devuelta por SearchPath. A continuación se muestra el orden de búsqueda predeterminado para la API de SearchPath:

  • El directorio desde el que se cargó la aplicación

  • El directorio de trabajo actual

  • El directorio del sistema

  • El directorio del sistema de 16 bits

  • El directorio de Windows

  • Los directorios indicados en la variable de entorno PATH

No se recomienda este patrón porque no es seguro. No se recomienda la función SearchPath como método para localizar un archivo .dll si el uso previsto del resultado se encuentra en una llamada a la función LoadLibrary. Esto puede resultar en localizar el archivo de .dll incorrecto porque el orden de búsqueda de la función SearchPath difiere del orden de búsqueda usado por la función LoadLibrary. Si tiene que buscar y cargar un archivo .dll, use la función LoadLibrary.

ShellExecute y CreateProcess


Las variaciones de estos problemas también pueden existir cuando los desarrolladores llaman a funciones similares como ShellExecutey CreateProcesspara cargar ejecutables externos. Le recomendamos a los desarrolladores que tengan cuidado cuando carguen archivos binarios y especifiquen la ruta de acceso completa. Esto debería suponer menos complejidad al cargar un archivo binario en lugar de una biblioteca.

Pasos recomendados para desarrolladores de software

Se recomienda a los desarrolladores que realicen lo siguiente:

  • Valide sus aplicaciones para instancias de cargas de biblioteca no seguras (ejemplos de cada una se proporcionan más adelante en este artículo). Entre ellas se incluyen las siguientes:

    • El uso de SearchPath para identificar la ubicación de una biblioteca o componente.

    • El uso de LoadLibrary para identificar la versión del sistema operativo.

  • Use rutas de acceso completas para todas las llamadas a LoadLibrary, CreateProcess y ShellExecute donde pueda.

  • Implemente llamadas a SetDllDirectory con una cadena vacía ("") para quitar el directorio de trabajo actual del orden de búsqueda de DLL predeterminado donde sea necesario. Tenga en cuenta que SetDllDirectory afecta a todo el proceso. Por lo tanto, debe realizar esta inicialización una vez al principio del proceso, no antes ni después de las llamadas a LoadLibrary. Dado que SetDllDirectory afecta a todo el proceso, varias conversaciones que llaman a SetDllDirectory con valores diferentes podrían causar un comportamiento no definido. Además, si el proceso está diseñado para cargar archivos DLL de terceros, se necesitan pruebas para determinar si crear una configuración de todo el proceso causará incompatibilidades. Un problema conocido es que cuando una aplicación depende de Visual Basic para Aplicaciones, una configuración de todo el proceso puede causar incompatibilidades.

  • Use la función SetSearchPathModepara habilitar el modo de búsqueda de procesos seguros para el proceso. Esto mueve el directorio de trabajo actual al último lugar de la lista de búsqueda de SearchPath durante la duración del proceso.

  • Evite usar SearchPath para comprobar la existencia de un archivo DLL sin especificar una ruta de acceso completa, incluso si el modo de búsqueda seguro está habilitado, ya que esto puede provocar ataques de precarga de DLL.

Instrucciones sobre cómo identificar cargas de biblioteca no seguras

En el código fuente, los siguientes son ejemplos de cargas de biblioteca no seguras:

  • En el siguiente ejemplo de código, la aplicación busca "schannel.dll" con la ruta de búsqueda menos segura. Si un atacante puede colocar schannel.dll en CWD, se cargará incluso antes de que la aplicación busque en Windows directorios de la biblioteca adecuada.

    DWORD retval = SearchPath(NULL, "schannel", ".dll", err, result, NULL); 
    HMODULE handle = LoadLibrary(result);
  • En el siguiente ejemplo de código, la aplicación intenta cargar la biblioteca desde las distintas ubicaciones de aplicación y sistema operativo descritas al principio de este documento para la llamada LoadLibrary(). Si hay algún riesgo de que el archivo no esté presente, es posible que la aplicación intente cargar el archivo desde el directorio de trabajo actual. Este escenario es ligeramente menos peligroso que el ejemplo anterior. Sin embargo, aún expone al usuario de la aplicación a un riesgo si el entorno no es completamente predecible.

    HMODULE handle = LoadLibrary("schannel.dll");




A continuación se muestran ejemplos de cargas de biblioteca mejores y seguras:

  • En el siguiente ejemplo de código, la biblioteca se carga directamente mediante una ruta de acceso completa. No hay ningún riesgo de que el atacante introduzca código malintencionado a menos que ya tenga permisos de escritura en el directorio de destino de la aplicación.

    HMODULE handle = LoadLibrary("c:\\windows\\system32\\schannel.dll");



    Nota Para obtener información sobre cómo determinar el directorio del sistema, vea los siguientes recursos:

    GetSystemDirectory

    http://msdn.microsoft.com/en-us/library/ms724373%28VS.85%29.aspxSHGetKnownFolderPath

    http://msdn.microsoft.com/en-us/library/bb762188%28v=VS.85%29.aspx

  • En el siguiente ejemplo de código, el directorio de trabajo actual se quita de la ruta de búsqueda antes de llamar a LoadLibrary. Esto reduce significativamente el riesgo, ya que el atacante tendría que controlar el directorio de la aplicación, el directorio de Windows o cualquier directorio que se especifique en la ruta de acceso del usuario para usar un ataque de carga previa de DLL.

    SetDllDirectory ("");
    HMODULE handle = LoadLibrary("schannel.dll");
  • En todos los sistemas que tienen instalada la actualización de seguridad 963027 (descrita en MS09-014),el código siguiente movería permanentemente CWD al último lugar del orden de búsqueda. Las llamadas posteriores a la función SetSearchPathMode desde dentro de ese proceso que intenten cambiar el modo de búsqueda producirán errores.

    SetDllDirectory ("");
    HMODULE handle = LoadLibrary("schannel.dll");
  • En el siguiente ejemplo de código, el directorio de trabajo actual se quita de la ruta de búsqueda antes de llamar a LoadLibrary. Esto reduce significativamente el riesgo, ya que el atacante tendría que controlar el directorio de la aplicación, el directorio de Windows o cualquier directorio que se especifique en la ruta de acceso del usuario para usar un ataque de carga previa de DLL.

    SetSearchPathMode (BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE | BASE_SEARCH_PATH_PERMANENT );
    HMODULE handle = LoadLibrary("schannel.dll");

Usar el Monitor de proceso para detectar dinámicamente cargas no seguras

Microsoft publica una herramienta denominada Monitor de proceso. Esta herramienta permite a los desarrolladores y administradores realizar un seguimiento estrecho del comportamiento de un proceso en ejecución. El Monitor de procesos se puede usar para detectar dinámicamente si una de las aplicaciones puede ser vulnerable a este tipo de problema.

  • Para descargar Process Monitor, visite la siguiente página web de Microsoft:

    http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx

  • Intente iniciar la aplicación con CWD establecido en un directorio específico. Por ejemplo, haga doble clic en un archivo que tiene una extensión cuyo controlador de archivos está asignado a la aplicación.

  • Configurar el Monitor de proceso con los siguientes



    filtros:texto alternativo

  • Si se encuentra una ruta vulnerable, verá algo similar a lo siguiente: texto alternativoLa llamada al recurso compartido de archivos remoto para cargar una DLL indica que se trata de un

    programa vulnerable.

Más información

Para obtener más información, visite las siguientes páginas web de Microsoft: Orden de búsqueda de biblioteca de vínculos

dinámicos

http://msdn.microsoft.com/en-us/library/ms682586(VS.85).aspxDocumentación de MSDN sobre la función SearchPath

http://msdn.microsoft.com/en-us/library/aa365527(VS.85).aspxDocumentación de MSDN sobre la función LoadLibrary

http://msdn.microsoft.com/en-us/library/ms684175(VS.85).aspxDocumentación de MSDN sobre la función SetDllDirectory

http://msdn.microsoft.com/en-us/library/ms686203(VS.85).aspxDocumentación de MSDN sobre la función SetSearchPathMode

http://msdn.microsoft.com/en-us/library/dd266735(VS.85).aspxEntrada de blog de David Leblanc, ingeniero de seguridad principal con Microsoft Office

http://blogs.msdn.com/b/david_leblanc/archive/2008/02/20/dll-preloading-attacks.aspxEntrada de blog de Andrew Roths, equipo de ingeniería de MSRC sobre ataques de precarga de DLL

http://blogs.technet.com/b/srd/archive/2009/04/14/ms09-014-addressing-the-safari-carpet-bomb-vulnerability.aspx

Recursos adicionales

¿Necesita más ayuda?

Ampliar sus conocimientos
Explorar los cursos
Obtener nuevas características primero
Unirse a Microsoft Insider

¿Le ha sido útil esta información?

¿Cómo de satisfecho está con la calidad de la traducción?
¿Qué ha afectado a tu experiencia?

¡Gracias por sus comentarios!

×