
Análise técnica detalhada e exploit de prova de conceito para CVE-2024-30051, um estouro de buffer baseado em heap na Windows DWM Core Library possibilitando escalonamento local de privilégios para o nível Integrity System.
Nesta postagem de blog, explicarei uma vulnerabilidade na biblioteca Core DWM do Microsoft Windows que analisei quando o exploit para o Core Impact estava sendo desenvolvido. Permite que um atacante não privilegiado execute código como um usuário DWM com privilégios de Integrity System (CVE-2024-30051).
Como não havia informações públicas suficientes na época para desenvolver o exploit, tive que fazer muito reverse engineering, então aqui mostrarei como reverter o patch KB5037771 para Windows 23H2 usando IDA PRO. Usarei o BINDIFF para realizar a diff binária entre a dwmcore.dll versão 10.0.22621.3447 e a versão 10.0.22621.3593, mostrarei como o heap overflow é produzido e, em seguida, o explorarei elevando privilégios. Por fim, criarei um PoC funcional.
Índice:
[Vulnerabilidade de Elevação de Privilégio da Biblioteca Core DWM do Windows (CVE-2024-30051) 1](#windows-dwm-core-library-elevation-of-privilege-vulnerability-cve-2024-30051)
[Detalhes da vulnerabilidade: 2](#vulnerability-details)
[Diferenças para encontrar o bug: 3](#diffing-to-find-the-bug)
[Análise do PoC explorando CVE-2024-30051: 8](#analysis-of-the-poc-exploiting-cve-2024-30051)
[1)Inicialização 8](#initialization)
[2)Hooking 8](#hooking)
[3)Criando a janela 16](#creating-the-window)
[4)Criar Dispositivo 16](#create-device)
[5) Criar Fábrica 22](#create-factory)
[6) Criar Contexto de Dispositivo 28](#create-a-device-context)
[7)Criar Dispositivo de Composição 29](#create-a-composition-device)
[8)Chamando a função hook3 31](#calling-dcompositioncreatedevice-function)
[9)Criando alvo para o HWND 32](#creating-a-target-for-handle-hwnd)
[10)Criando Superfície 33](#creating-surface)
[11)Chamando BeginDraw, EndDraw e CreateVisual. 34](#calling-begindraw-enddraw-and-createvisual)
[11)Chamando Visual SetContent 36](#calling-visual-setcontent)
[12)Liberar objetos 38](#release-objects)
[13)Commit do Dispositivo de Composição 38](#commit-composition-device)
[14)Chamando hook2 39](#calling-hook2)
[15)Chamando hook 39](#remember-that-the-vulnerable-function-can-be-reached-using-some-methods-of-the-cprimitivegroup-class.-at-this-point-it-creates-a-heap-then-hook2-captures-and-saves-the-corresponding-heaphandle.)
[16)Chamando hook4 41](#calling-the-function-hook4)
[17)Realizando Heap Spray 49](#performing-heap-spray)
[18)Modificando o chunk base antes do envio. 51](#modifying-the-base-chunk-previous-to-send)
[19)Depurando o processo DWM 52](#debugging-the-dwm-process)
[20)Elevando Privilégios ao nível Integrity System 62](#elevating-privileges-to-integrity-system-level)
Vulnerabilidade de Elevação de Privilégio da Biblioteca Core DWM do Windows CVE-2024-30051
Lançado: 14 de maio de 2024
CNA de atribuição: Microsoft CVE-2024-30051
Impacto: Elevação de Privilégio
Severidade Máxima: Importante
Fraqueza:
CWE-122: Estouro de Buffer Baseado em Heap
CVSS: 3.1 7.8 / 7.2
A vulnerabilidade existe devido a um erro de cálculo de tamanho em uma divisão inteira dentro da principal biblioteca DWM do Windows chamada dwmcore.dll. Um usuário local pode causar um estouro de buffer no heap no método CCommandBuffer::Initialize em dwmcore.dll e pode executar código arbitrário com o usuário DWM com Privilégios de Integrity System. O exploit realizará um Heap Spray no processo DWM para preparar a memória e, finalmente, produz um Heap Overflow em dwmcore.dll que será acionado ao liberar certas partes do heap spray.
Uma vez que o exploit seja bem-sucedido, o processo DWM carregará nossa DLL personalizada que executa nosso código ou nosso executável (no nosso caso, um CMD) como o usuário DWM que possui Privilégios de Integrity System.

Vamos percorrer essa vulnerabilidade e ver como ela nos permite executar como um usuário DWM com Integrity Level SYSTEM. Observe que, como este não é um usuário pertencente ao grupo Administradores, ele tem algumas restrições de privilégio.
O patch para Windows 11 23H2 pode ser baixado de:
https://www.catalog.update.microsoft.com/Search.aspx?q=KB5037771
windows11.0-kb5037771-x64_19a3f100fb8437d059d7ee2b879fe8e48a1bae42.msu
A versão vulnerável de dwmcore.dll é: 10.0.22621.3447
A versão corrigida de dwmcore.dll é: 10.0.22621.3593
Analisando as funções alteradas, fica claro que a versão corrigida de CCommandBuffer::Initialize tem muitos blocos adicionados, tornando-a bastante diferente da versão não corrigida.

Após reverter estaticamente essa função, há duas chamadas para CD2DSharedBuffer::GetBufferSize.
A primeira chamada obtém o tamanho para alocar no new e a segunda chamada obtém o mesmo tamanho para o memcpy.

Tudo parece inicialmente correto. No entanto, antes da alocação, ele realiza algumas operações com o tamanho.

Ele obtém buffer_size e buffer_size2 chamando a mesma função CD2DSharedBuffer::GetBufferSize, retornando ambas o mesmo valor. Mas no new ele realiza uma pré-operação, uma divisão inteira do buffer_size por 0x90 e depois multiplicando por 0x90, enquanto no memcpy ele usa o buffer_size2 retornado sem operar sobre ele.
Com essas operações, descobri que o tamanho finalmente usado no new e no memcpy podem ser diferentes.
buffer_size = buffer_size2 (tamanhos retornados)
size_new= buffer_size/0x90 x 0x90
size_memcpy=buffer_size2
Por exemplo, se buffer_size for 0x91
buffer_size = buffer_size2=0x91
size_new= buffer_size/0x90 x 0x90 =0x90
size_memcpy= buffer_size2= 0x91
Este exemplo prova que há um heap overflow. Está copiando mais bytes do que alocados, e o tamanho é controlável.
Por exemplo, se buffer_size for 0x23f como usado no POC.
buffer_size = buffer_size2=0x23F
size_new= buffer_size/0x90 x 0x90 =0x1b0
size_memcpy== buffer_size2=0x23f
Com a função vulnerável analisada, quis ver como chegar à função vulnerável CCommandBuffer::Initialize. É aqui que as coisas começam a ficar complicadas.