Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
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.

FeedsContactoPrivacidad© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2020-1206 — Análisis técnico de CVE-2020-1206 (SMBleed), vulnerabilidad de divulgación de información del kernel en Windows SMBv3, incluyendo oráculo de fuga de memoria no autenticado y técnicas de explotación combinadas con SMBGhost para RCE. | Kitploit
Herramientas/GitHubGitHub/datntsec/cve-2020-1206
Forensia de MemoriaAnálisis de VulnerabilidadesExplotaciónRecopilación de InformaciónPruebas de PenetraciónExplotación de Binarios
GitHubdatntsec/cve-2020-1206

CVE-2020-1206

Análisis técnico de CVE-2020-1206 (SMBleed), vulnerabilidad de divulgación de información del kernel en Windows SMBv3, incluyendo oráculo de fuga de memoria no autenticado y técnicas de explotación combinadas con SMBGhost para RCE.

Ver Repositorio
56hace 5 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

En la vulnerabilidad SMBGhost (CVE-2020-0796) hablé sobre una técnica de primitiva write-what-where mediante el uso de una vulnerabilidad de desbordamiento de enteros para cambiar el puntero Alloc.Userbuffer para que apunte a una dirección deseada y escribir datos arbitrarios en ella. Al igual que SMB Ghost, esta vulnerabilidad también existe en la función Srv2DecompressData en srv2.sys. Repasemos la función Srv2DecompressData relacionada con la vulnerabilidad SMBGhost (CVE-2020-0796) simplificada por Zecops``` c typedef struct _COMPRESSION_TRANSFORM_HEADER { ULONG ProtocolId; ULONG OriginalCompressedSegmentSize; USHORT CompressionAlgorithm; USHORT Flags; ULONG Offset; } COMPRESSION_TRANSFORM_HEADER, *PCOMPRESSION_TRANSFORM_HEADER;

typedef struct _ALLOCATION_HEADER { // ... PVOID UserBuffer; // ... } ALLOCATION_HEADER, *PALLOCATION_HEADER;

NTSTATUS Srv2DecompressData(PCOMPRESSION_TRANSFORM_HEADER Header, SIZE_T TotalSize) { PALLOCATION_HEADER Alloc = SrvNetAllocateBuffer( (ULONG)(Header->OriginalCompressedSegmentSize + Header->Offset), NULL); If (!Alloc) { return STATUS_INSUFFICIENT_RESOURCES; }

ULONG FinalCompressedSize = 0;


NTSTATUS Status = SmbCompressionDecompress(
    Header->CompressionAlgorithm,
    (PUCHAR)Header + sizeof(COMPRESSION_TRANSFORM_HEADER) + Header->Offset,
    (ULONG)(TotalSize - sizeof(COMPRESSION_TRANSFORM_HEADER) - Header->Offset),
    (PUCHAR)Alloc->UserBuffer + Header->Offset,
    Header->OriginalCompressedSegmentSize,
    &FinalCompressedSize);
if (Status < 0 || FinalCompressedSize != Header->OriginalCompressedSegmentSize) {
    SrvNetFreeBuffer(Alloc);
    return STATUS_BAD_DATA;
}


if (Header->Offset > 0) {
    memcpy(
        Alloc->UserBuffer,
        (PUCHAR)Header + sizeof(COMPRESSION_TRANSFORM_HEADER),
        Header->Offset);
}


Srv2ReplaceReceiveBuffer(some_session_handle, Alloc);
return STATUS_SUCCESS;

}

La función Srv2DecompressData recibe un mensaje comprimido enviado por el cliente y procede a asignar la memoria necesaria, descomprimiendo el mensaje en ella. Después, si el campo Offset es distinto de cero, copia los datos (RawData) que preceden a los datos comprimidos al comienzo de la memoria asignada.

![](https://assets.kitploit.com/production/public/readmes/24502/a5bf8b5059336fb3677162343bace0d0b45085f2eb89e42d85f81e032fe233dc.png)

El fallo de SMBGhost radica en que la función no comprueba el desbordamiento de enteros (integer overflow), lo que provoca una asignación de tamaño incorrecto y causa un desbordamiento de búfer (buffer overflow). Tres meses después de que Microsoft parcheara SMBGhost, se encontró la vulnerabilidad CVE-2020-1206 (SMBleed, como la denomina [Zecops Blog](https://blog.zecops.com/)). Este fallo nos permite filtrar (leak) la dirección de otra máquina y, si se combina con SMBGhost, podemos obtener RCE. Para tener una visión más sencilla de la función Srv2DecompressData, reutilizaremos esta función tal como estaba antes del parche de SMBGhost y supondremos que ya ha sido parcheada.

# Falsificación de OriginalCompressedSegmentSize
Al igual que con SMBGhost, en esta ocasión seguiremos falsificando OriginalCompressedSegmentSize con un número ligeramente mayor que los datos descomprimidos que enviamos. Por ejemplo, si comprimimos datos de x bytes, en lugar de poner x en el campo OriginalCompressedSegmentSize, pondremos x + 0x1000; esto se aclara en la siguiente imagen:

![](https://assets.kitploit.com/production/public/readmes/24502/687d3bdc67e4b2f5bb3cecbe41ea52be98a5c904a8688b325a69acb0a854ca75.png)

Los datos no inicializados del kernel se tratarán como parte del mensaje.

Como dije en el análisis de [CVE-2020-0796](https://github.com/datntsec/CVE-2020-0796), Srv2DecompressData seguirá omitiendo la fase de comprobación posterior a la función SmbCompressionDecompress si la descompresión se realiza correctamente:``` c
if (Status < 0 || FinalCompressedSize != Header->OriginalCompressedSegmentSize) {
    SrvNetFreeBuffer(Alloc);
    return STATUS_BAD_DATA;
}

Aunque el campo OriginalCompressedSegmentSize se establece en x + 0x1000 en lugar de x, después de una descompresión exitosa, la variable FinalCompressedSize no contiene el valor x, sino que contendrá el valor x + 0x1000:```c NTSTATUS SmbCompressionDecompress( USHORT CompressionAlgorithm, PUCHAR UncompressedBuffer, ULONG UncompressedBufferSize, PUCHAR CompressedBuffer, ULONG CompressedBufferSize, PULONG FinalCompressedSize) { // ...

NTSTATUS Status = RtlDecompressBufferEx2(
    ...,
    FinalUncompressedSize,
    ...);
if (status >= 0) {
    *FinalCompressedSize = CompressedBufferSize;
}

// ...

return Status;

}

Debido a que después de una descompresión exitosa, FinalCompressedSize se actualiza para contener el valor de CompressedBufferSize (correspondiente a OriginalCompressedSegmentSize pasado a la función SmbCompressionDecompress). La actualización y la comprobación posterior son casi innecesarias, lo que puede provocar algunos errores inesperados.

# Explotación básica

La estructura de mensaje que Zecops utiliza para demostrar la vulnerabilidad es el [mensaje SMB2 WRITE](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/e7046961-3318-4350-be2a-a8d69bb59ce8). Esta estructura contiene campos como el número de bytes que se pueden escribir, flags, etc., seguidos de un búfer de longitud arbitraria. Esto es bastante perfecto para explotar el error, ya que podemos crear un mensaje y especificar el encabezado, con un búfer que contiene datos no inicializados.

Basándonos en el POC de [Zecops](https://blog.zecops.com/) en el repositorio WindowsProtocolTestSuites de Microsoft, para tener una visión más clara de esto, añadiremos esta pequeña adición a la función de compresión:``` c
// HACK: fake size
if (((Smb2SinglePacket)packet).Header.Command == Smb2Command.WRITE)
{
    ((Smb2WriteRequestPacket)packet).PayLoad.Length += 0x1000;
    compressedPacket.Header.OriginalCompressedSegmentSize += 0x1000;
}

Tenga en cuenta que este PoC requiere credenciales y permisos de escritura compartidos, que suelen estar disponibles en muchos casos. Sin embargo, el error devuelto se aplica a todos los mensajes (incluidos los mensajes con o sin credenciales), por lo que es posible que podamos explotarlo sin necesidad de autenticación. Además, la memoria que filtraremos proviene de asignaciones anteriores en NonPagedPoolNx, y dado que podemos controlar el tamaño de la asignación, controlaremos en cierta medida los datos que filtraremos.

SMBleed POC Source Code

Entonces, ¿es posible filtrar una dirección del kernel sin credenciales? Para responder a esta pregunta, analicemos SMB más a fondo.

Profundizando en SMB

Al autenticarse, el cliente envía los siguientes mensajes:

SMB2 NEGOTIATE → SMB2 SESSION_SETUP → SMB2 SESSION_SETUP

Si las credenciales son incorrectas, la sesión se termina después del segundo paquete SMB2 SESSION_SETUP:

Supongamos que no tenemos credenciales; comprobaremos si hay algún comando que pueda enviarse sin necesidad de autenticación. Tras buscar, observamos:

  • El primer comando que debe enviarse es SMB2 NEGOTIATE y también es el único comando SMB2 NEGOTIATE durante toda una sesión.
  • Los comandos siguientes, hasta que la autenticación tenga éxito, deben ser SMB2 SESSION_SETUP.

El mensaje SMB2 NEGOTIATE no se comprime. El bug está en la función de descompresión, por lo que no lo consideraremos y solo examinaremos los mensajes SMB2 SESSION_SETUP.

SMB2 SESSION_SETUP

Descargar herramienta