Carga segura de las bibliotecas para evitar ataques de precarga de DLL

Seleccione idioma Seleccione idioma
Id. de artículo: 2389418 - Ver los productos a los que se aplica este artículo
Expandir todo | Contraer todo

En esta página

Resumen

Cuando una aplicación carga dinámicamente una biblioteca de vínculos dinámicos (DLL) sin especificar una ruta de acceso completa, Windows intenta encontrar la DLL buscando en un conjunto bien definido de directorios. Si un atacante obtuviera el control de uno de los directorios, podría obligar a que la aplicación cargara una copia malintencionada de la DLL en lugar de la DLL que se esperaba. Estos ataques, conocidos como ?ataques de precarga de DLL?, son habituales en todos los sistemas operativos que admiten la carga dinámica de bibliotecas DLL compartidas. El efecto de tales ataques podría ser que un atacante ejecutara código en el contexto del usuario que ejecuta la aplicación. Cuando la aplicación se ejecuta como administrador, se podría producir una elevación local de privilegios. Conocemos el renovado interés en estos ataques. Para limitar el efecto que este problema tiene en nuestros mutuos clientes, publicamos este documento para la comunidad de desarrolladores a fin de asegurarnos de que conocen este problema y de que disponen de las herramientas necesarias para solucionarlo en sus aplicaciones.

Más información

Descripción de los ataques de precarga de DLL

Ataques basados en LoadLibrary

Cuando una aplicación carga dinámicamente una DLL sin especificar una ruta de acceso completa, Windows intenta encontrar esta DLL buscando en un conjunto bien definido de directorios, lo que se conoce como orden de búsqueda de DLL. Si Windows encuentra la DLL en el orden de búsqueda de DLL, cargará esa DLL. Sin embargo, si Windows no encuentra la DLL en ninguno de los directorios del orden de búsqueda de DLL, devolverá un error en la operación de carga de la DLL. A continuación, se muestra el orden de búsqueda de DLL de las funciones LoadLibraryy LoadLibraryEx, que se usan para cargar DLL de forma dinámica:
  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 enumerados en la variable de entorno PATH
Tenga en cuenta siguiente situación:
  • Una aplicación carga una DLL sin especificar una ruta de acceso completa que espera encontrar en el directorio de trabajo actual de la aplicación.
  • La aplicación estará completamente preparada para tratar la situación en la que no se encuentra la DLL.
  • El atacante conoce esta información acerca de la aplicación y controla el directorio de trabajo actual.
  • El atacante copia su propia versión especialmente creada de la DLL en el directorio de trabajo actual. Se supone que el atacante tiene permiso para realizar esta operación.
  • Windows busca en los directorios en el orden de búsqueda de DLL y encuentra la DLL en el directorio de trabajo actual de la aplicación.
En esta situación, la DLL especialmente creada se ejecuta en 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 de la ruta de búsqueda de DLL mediante la llamada a la API SetDllDirectory con una cadena vacía (??). Si una aplicación depende de la carga de una DLL del directorio actual, obtenga el directorio de trabajo actual y úselo para pasar una ruta de acceso completa de LoadLibrary.

También sabemos que algunos desarrolladores usan LoadLibrary para validar la presencia de un archivo DLL específico a fin de determinar cuál es la versión de Windows que ejecuta el usuario. Debe saber que esto podría volver la aplicación vulnerable. Si la biblioteca afectada no existe en la versión de Windows en la que se ejecuta la aplicación, un atacante podría introducir una biblioteca con ese mismo nombre en el directorio de trabajo actual. Se recomienda encarecidamente no usar esta técnica. En su lugar, utilice 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 forzar a los complementos a usar una ruta de acceso completa para sus llamadas de LoadLibrary, debe llamar a la función SetDllDirectory(??) para quitar el directorio de trabajo actual y, a continuación, a la función SetDllDirectory(?ubicación de instalación del complemento?) para agregar el directorio de instalación del complemento en la ruta de búsqueda de DLL.

Ataques basados en SearchPath

Existe un ataque parecido cuando una aplicación usa la API SearchPath para encontrar un archivo DLL y cargar dinámicamente la ruta que devuelve SearchPath. A continuación, se muestra el orden de búsqueda predeterminado de la API 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 enumerados en la variable de entorno PATH
Este patrón no se recomienda porque no es seguro. No se recomienda utilizar la función SearchPath como método para encontrar una .dll si el uso previsto de la salida está en una llamada a la función LoadLibrary . El resultado puede ser que se encuentre la .dll errónea porque el orden de búsqueda de la función SearchPath difiere del orden de búsqueda usado en la función LoadLibrary . Si tiene que buscar y cargar una .dll, utilice la función LoadLibrary.

ShellExecute y CreateProcess

También pueden existir variantes de estos problemas cuando los desarrolladores llaman a funciones parecidas como ShellExecutey CreateProcesspara cargar ejecutables externos. Se recomienda a los desarrolladores que tengan cuidado cuando carguen archivos binarios y especifiquen la ruta de acceso completa. Debería ser menos complejo cuando carga un archivo binario en lugar de una biblioteca.

Pasos recomendados para los desarrolladores de software

Se recomienda a los desarrolladores hacer lo siguiente:
  • Validar sus aplicaciones para los casos de cargas de biblioteca no seguras (más adelante en este artículo se proporcionan ejemplos de cada uno). Entre los que se incluyen:
    • El uso de SearchPath para identificar la ubicación de una biblioteca o un componente.
    • El uso de LoadLibrary para identificar la versión del sistema operativo.
  • Utilice siempre que pueda las rutas de acceso completas para todas las llamadas a las funciones LoadLibrary, CreateProcess y ShellExecute :
  • Implemente llamadas a SetDllDirectory con una cadena vacía (??) para quitar el directorio de trabajo actual del orden de búsqueda de DLL cuando sea necesario. Tenga en cuenta que SetDllDirectory afecta a todo el proceso. Por lo tanto, esta acción sólo debe hacerla una vez al principio del proceso de inicialización, no antes y después de las llamadas a LoadLibrary. Como SetDllDirectory afecta a todo el proceso, la llamada de varios subprocesos a SetDllDirectory con valores diferentes podría ocasionar un comportamiento indefinido. Además, si el proceso está diseñado para cargar archivos DLL de terceros, será necesario probarlo para determinar si la creación de una configuración de todo el proceso provocará incompatibilidades. Existe un problema conocido por el cual cuando una aplicación depende de Visual Basic for Applications, una configuración de todo el proceso podría provocar incompatibilidades.
  • Utilice la función SetSearchPathMode para habilitar el modo seguro de búsqueda de procesos para el proceso. De esta forma, el directorio de trabajo actual pasa al último lugar en la lista de búsqueda de SearchPath a lo largo de la duración del proceso.
  • Evite el uso de SearchPath para comprobar la existencia de una DLL sin especificar una ruta de acceso completa, aunque esté habilitado el modo de búsqueda seguro, dado que esto puede conducir a ataques de precarga de DLL.

Ayuda para identificar cargas de bibliotecas no seguras

En el código fuente, los siguientes son ejemplos de cargas de bibliotecas no seguras:
  • En el siguiente ejemplo de código, la aplicación busca ?schannel.dll? mediante el uso de la ruta de búsqueda menos segura. Si un atacante pudiera introducir schannel.dll en el directorio de trabajo actual, se cargaría incluso antes de que la aplicación busque la biblioteca adecuada en los directorios de Windows.
    DWORD retval = SearchPath(NULL, "schannel", ".dll", err, result, NULL); 
    HMODULE handle = LoadLibrary(result);
  • En el siguiente código de ejemplo, la aplicación intenta cargar la biblioteca a partir de las diversas ubicaciones de aplicación y sistema operativo descritas al comienzo de este documento para la llamada LoadLibrary(). Si hay algún riesgo de que el archivo no esté presente, la aplicación puede intentar cargar el archivo desde el directorio de trabajo actual. Este escenario es ligeramente menos peligroso que el ejemplo anterior. Sin embargo, todavía pone en peligro al usuario de la aplicación si el entorno no es completamente predecible.
    HMODULE handle = LoadLibrary("schannel.dll");
A continuación, se muestran ejemplos de cargas de bibliotecas mejores y más seguras:
  • En el código de ejemplo siguiente, se carga la biblioteca directamente mediante una ruta de acceso completa. No hay riesgo de que el atacante introduzca código malintencionado a menos que ya tenga permisos de escritura para el directorio de destino de la aplicación.
    HMODULE handle = LoadLibrary("c:\\windows\\system32\\schannel.dll");


    Nota: para obtener información acerca de cómo determinar el directorio del sistema, consulte los siguientes recursos:

    GetSystemDirectory
    http://msdn.microsoft.com/es-es/library/ms724373%28VS.85%29.aspx
    SHGetKnownFolderPath
    http://msdn.microsoft.com/es-es/library/bb762188%28v=VS.85%29.aspx
  • En el código de ejemplo siguiente, el directorio de trabajo actual se quita de la ruta de búsqueda antes de llamar a la función LoadLibrary. De esta manera, se reduce el riesgo considerablemente dado que el atacante tendría que controlar el directorio de la aplicación, el directorio de Windows o cualquier directorio que se especificara en la ruta de acceso del usuario para usar un ataque de precarga de DLL.
    SetDllDirectory ("");
    HMODULE handle = LoadLibrary("schannel.dll");
  • En todos los sistemas que tengan instalada la actualización de seguridad 963027 (descrita en MS09-014), el siguiente código movería permanentemente el directorio de trabajo actual al último lugar del orden de búsqueda. Toda llamada posterior a la función SetSearchPathMode desde el interior de ese proceso que intenta cambiar el modo de búsqueda dará error.
    
    
    SetDllDirectory ("");
    HMODULE handle = LoadLibrary("schannel.dll");
  • En el siguiente código de ejemplo, el directorio de trabajo actual se quita de la ruta de búsqueda antes de llamar a la función LoadLibrary. De esta manera, se reduce el riesgo considerablemente dado que el atacante tendría que controlar el directorio de la aplicación, el directorio de Windows o cualquier directorio que se especificara en la ruta de acceso del usuario para usar un ataque de precarga de DLL.
    SetSearchPathMode (BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE | BASE_SEARCH_PATH_PERMANENT );
    HMODULE handle = LoadLibrary("schannel.dll");

Uso del Monitor de procesos para detectar cargas no seguras de forma dinámica

Microsoft publica una herramienta llamada Monitor de procesos. Esta herramienta permite a los desarrolladores y administradores seguir de cerca el comportamiento de un proceso en ejecución. El Monitor de procesos se puede utilizar para detectar de forma dinámica si una de las aplicaciones podría ser vulnerable a este tipo de problema.
  • Para descargar el Monitor de procesos, visite la siguiente página web de Microsoft:
    http://technet.microsoft.com/es-es/sysinternals/bb896645.aspx
  • Intente iniciar la aplicación con el directorio de trabajo actual definido como un directorio concreto. Por ejemplo, haga doble clic en un archivo con una extensión cuyo identificador de archivos esté asignado a la aplicación.
  • Configure el Monitor de procesos con los siguientes filtros:
    Contraer esta imagenAmpliar esta imagen
    Imagen de filtro del Monitor de procesos
  • Si se llega a una ruta de acceso vulnerable, verá algo similar a lo siguiente:
    Contraer esta imagenAmpliar esta imagen
    Imagen de filtro de Monitor de procesos 2


    La llamada al recurso compartido de archivo remoto para cargar una DLL indica que se trata de un programa vulnerable.

Recursos adicionales

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/es-es/library/ms682586(VS.85).aspx
Documentación de MSDN sobre la función SearchPath
http://msdn.microsoft.com/es-es/library/aa365527(v=VS.85).aspx
Documentación de MSDN sobre la función LoadLibrary
http://msdn.microsoft.com/es-es/library/ms684175(VS.85).aspx
Documentación de MSDN sobre la función SetDllDirectory
http://msdn.microsoft.com/es-es/library/ms686203(VS.85).aspx
Documentación de MSDN sobre la función SetSearchPathMode
http://msdn.microsoft.com/es-es/library/dd266735(VS.85).aspx
Entrada de blog de David Leblanc, ingeniero de seguridad principal para Microsoft Office
http://blogs.msdn.com/b/david_leblanc/archive/2008/02/20/dll-preloading-attacks.aspx
Entrada de blog de Andrew Roths, equipo de ingeniería de MSRC encargado de los ataques de precarga de DLL
http://blogs.technet.com/b/srd/archive/2009/04/14/ms09-014-addressing-the-safari-carpet-bomb-vulnerability.aspx

Propiedades

Id. de artículo: 2389418 - Última revisión: viernes, 27 de agosto de 2010 - Versión: 2.0
La información de este artículo se refiere a:
  • Windows 7 Enterprise
  • Windows 7 Home Basic
  • Windows 7 Home Premium
  • Windows 7 Professional
  • Windows 7 Ultimate
  • Windows Server 2008 R2 Standard
  • Windows Server 2008 R2 Enterprise
  • Windows Server 2008 R2 Datacenter
  • Windows Server 2008 Service Pack 2 sobre las siguientes plataformas
    • Windows Server 2008 for Itanium-Based Systems
    • Windows Server 2008 Datacenter
    • Windows Server 2008 Enterprise
    • Windows Server 2008 Standard
    • Windows Web Server 2008
  • Windows Server 2008 for Itanium-Based Systems
  • Windows Server 2008 Datacenter
  • Windows Server 2008 Enterprise
  • Windows Server 2008 Standard
  • Windows Web Server 2008
  • Windows Vista Service Pack 2 sobre las siguientes plataformas
    • Windows Vista Business
    • Windows Vista Enterprise
    • Windows Vista Home Basic
    • Windows Vista Home Premium
    • Windows Vista Starter
    • Windows Vista Ultimate
    • Windows Vista Enterprise 64-bit edition
    • Windows Vista Home Basic 64-bit edition
    • Windows Vista Home Premium 64-bit edition
    • Windows Vista Ultimate 64-bit edition
    • Windows Vista Business 64-bit edition
  • Service Pack 1 para Windows Vista sobre las siguientes plataformas
    • Windows Vista Business
    • Windows Vista Enterprise
    • Windows Vista Home Basic
    • Windows Vista Home Premium
    • Windows Vista Starter
    • Windows Vista Ultimate
    • Windows Vista Enterprise 64-bit edition
    • Windows Vista Home Basic 64-bit edition
    • Windows Vista Home Premium 64-bit edition
    • Windows Vista Ultimate 64-bit edition
    • Windows Vista Business 64-bit edition
  • Microsoft Windows Server 2003 Service Pack 2 sobre las siguientes plataformas
    • Microsoft Windows Server 2003, Standard Edition (32-bit x86)
    • Microsoft Windows Server 2003, Enterprise Edition (32-bit x86)
    • Microsoft Windows Server 2003, Datacenter Edition (32-bit x86)
    • Microsoft Windows Server 2003, Web Edition
    • Microsoft Windows Server 2003, Datacenter x64 Edition
    • Microsoft Windows Server 2003, Enterprise x64 Edition
    • Microsoft Windows Server 2003, Standard x64 Edition
    • Microsoft Windows XP Professional x64 Edition
    • Microsoft Windows Server 2003, Datacenter Edition for Itanium-Based Systems
    • Microsoft Windows Server 2003, Enterprise Edition for Itanium-based Systems
  • Service Pack 3 para Microsoft Windows XP sobre las siguientes plataformas
    • Microsoft Windows XP Home Edition
    • Microsoft Windows XP Professional
Palabras clave: 
atdownload kbbug kbexpertiseinter kbfix kbsecbulletin kbsecurity kbsecvulnerability KB2389418

Enviar comentarios

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com