Relatório CVE-2023-28218
Visão geral do bug
Erro que leva à escalada de privilégios no kernel do Windows. O erro aparece no driver Windows Ancrillary Function Driver for WinSock (AFD.sys). O erro foi lançado com o patch de 11/04/2023. Tem pontuação CVSS:3.1 7.0 / 6.1 e é avaliado como Important.
Descrição do bug
- Tipo de erro:
Double fetch e Integer overflow levando a pool overflow.
- O erro ocorre nas funções
Afd!AfdComputeCMSGLength e Afd!AfdCopyCMSGBuffer.

Ambas as funções recebem v82 como parâmetro de entrada. v82 é um endereço controlado pelo usermode. Na função Afd!AfdComputeCMSGLength, este endereço é referenciado diretamente para obter o valor. Em seguida, calcula o comprimento do buffer CMSG para retornar. Então um pool será alocado com este tamanho. Ao controlar os dois parâmetros de entrada a1 e a2, podemos controlar o tamanho que será retornado no parâmetro a3.

Na função Afd!AfdCopyCMSGBuffer, o endereço v82 é referenciado diretamente para obter o valor. Após algumas etapas de verificação, este valor será usado como tamanho da operação memmove.

Nesta função há um erro de Integer overflow, combinado com o fato de que ambas as funções buscam diretamente do endereço em usermode, podemos alterar o valor dele durante a execução. Isso leva a um valor de tamanho muito grande no memmove. Ao copiar para uma região de memória inacessível, um try catch ocorrerá. Mas a cópia das regiões de memória anteriores já aconteceu. Com isso, podemos copiar com o tamanho que desejarmos.

- Para disparar o PoC, primeiro é necessário criar um
socket com o parâmetro type igual a SOCK_DGRAM. Em seguida, usar o handle deste socket como parâmetro para chamar a função bind. Finalmente, criar 2 threads, uma thread chamará continuamente o DeviceControl com IOCTL 0x120D3. Configurar o userbuffer adequadamente para contornar algumas verificações. A outra thread irá alterar continuamente o valor armazenado no endereço usermode que serve como parâmetro para as duas funções mencionadas.
Exploração
- Com este erro, podemos estourar um pool NX não paginado com tamanho e dados totalmente controláveis pelo usermode.
- A abordagem de exploração será pulverizar muitos objetos Namedpipe, depois liberar alguns objetos para criar buracos no heap. Em seguida, alocar o pool após calcular o tamanho pela função
Afd!AfdComputeCMSGLength, este tamanho precisa coincidir com o tamanho do objeto Namedpipe. Assim, o pool será alocado nos objetos que acabaram de ser liberados. Usar o bug para estourar os objetos Namedpipe adjacentes, e então usar os mecanismos do Namedpipe para obter acesso de leitura/escrita na memória do kernel. Ler o token do processo system e depois escrever no token do processo atual.
Faixa afetada
- Windows Server 2012 R2 (instalação Server Core) build anterior à versão 6.3.9600.20919
- Windows Server 2012 R2 build anterior à versão 6.3.9600.20919
- Windows Server 2012 (instalação Server Core) build anterior à versão 6.2.9200.24216
- Windows Server 2012 build anterior à versão 6.2.9200.24216
- Windows Server 2008 R2 for x64-based Systems Service Pack 1 (instalação Server Core) build anterior à versão 6.1.7601.26466
- Windows Server 2008 R2 for x64-based Systems Service Pack 1 build anterior à versão 6.1.7601.26466
- Windows Server 2008 for x64-based Systems Service Pack 2 (instalação Server Core) build anterior à versão 6.0.6003.22015
- Windows Server 2008 for x64-based Systems Service Pack 2 build anterior à versão 6.0.6003.22015
- Windows Server 2008 for 32-bit Systems Service Pack 2 (instalação Server Core) build anterior à versão 6.0.6003.22015
- Windows Server 2008 for 32-bit Systems Service Pack 2 build anterior à versão 6.0.6003.22015
- Windows Server 2016 (instalação Server Core) build anterior à versão 10.0.14393.5850
- Windows Server 2016 build anterior à versão 10.0.14393.5850
- Windows 10 Version 1607 for x64-based Systems build anterior à versão 10.0.14393.5850
- Windows 10 Version 1607 for 32-bit Systems build anterior à versão 10.0.14393.5850
- Windows 10 for x64-based Systems build anterior à versão 10.0.10240.19869
- Windows 10 for 32-bit Systems build anterior à versão 10.0.10240.19869
- Windows 10 Version 22H2 for 32-bit Systems build anterior à versão 10.0.19045.2846
- Windows 10 Version 22H2 for ARM64-based Systems build anterior à versão 10.0.19045.2846
- Windows 10 Version 22H2 for x64-based Systems build anterior à versão 10.0.19045.2846
- Windows 11 Version 22H2 for x64-based Systems build anterior à versão 10.0.22621.1555
- Windows 11 Version 22H2 for ARM64-based Systems build anterior à versão 10.0.22621.1555
- Windows 10 Version 21H2 for x64-based Systems build anterior à versão 10.0.19044.2846
- Windows 10 Version 21H2 for ARM64-based Systems build anterior à versão 10.0.19044.2846
- Windows 10 Version 21H2 for 32-bit Systems build anterior à versão 10.0.19044.2846
- Windows 11 version 21H2 for ARM64-based Systems build anterior à versão 10.0.22000.1817
- Windows 11 version 21H2 for x64-based Systems build anterior à versão 10.0.22000.1817
- Windows 10 Version 20H2 for ARM64-based Systems build anterior à versão 10.0.19042.2846
- Windows 10 Version 20H2 for 32-bit Systems build anterior à versão 10.0.19042.2846
- Windows 10 Version 20H2 for x64-based Systems build anterior à versão 10.0.19042.2846
- Windows Server 2022 (instalação Server Core) build anterior à versão 10.0.20348.1668
O patch
- O erro foi corrigido substituindo as duas funções antigas por duas novas funções; as funções antigas tiveram o sufixo
_old adicionado ao nome. As novas funções já. Nas duas novas funções, embora ainda haja double fetch, o valor buscado é verificado antes de ser usado. As funções Rtl são usadas para substituir as operações aritméticas, prevenindo Integer overflow.
Conclusão
- O bug tem um alcance de afetados muito amplo, ameaçando muitos sistemas. No entanto, o payload de exploração ainda tem uma pequena taxa de falha ao executar, causando travamento do Windows devido ao spray no heap. Além disso, após escalar os privilégios do processo cmd para System, se este processo for encerrado, também causará travamento do Windows. Isso porque durante a exploração o objeto Namedpipe foi corrompido.
Anexos
- POC mínimo

- POC de exploração
