
# CVE-2021-43229 Passo a passo
Windows NTFS Vulnerabilidade de Elevação de Privilégio
Diferente de:
Patch: 14 de Dezembro de 2021
De acordo com @AravGarg3 no Twitter, CVE-2021-43229 parece ser explorável e relacionado a um integer overflow.
Fonte: https://twitter.com/AravGarg3/status/1479447843458863104
| Versões secundárias do Windows 10 | Datas de lançamento |
|---|---|
| 1387 | 11/22/2021 |
| 1415 | 12/14/2021 |
Usando BinDiff com IDA Pro, o resultado da comparação de patches mostra as seguintes alterações:
Três candidatos destacam-se:
De acordo com o Guia de Atualização de Segurança da Microsoft de Dezembro, quatro CVEs estão relacionados ao NTFS:
CVE-2021-43240 parece estar relacionado a NtSetShortNameInfo.
NtfsRenameToPrivateDir, TxfAllocateAndStoreNameForTxLogging e TxAllocateFullFilePathForChangeNotify têm todos a mesma nova verificação de comprimento, e parecem estar relacionados a CVE-2021-43229, CVE-2021-43230 e CVE-2021-43231, não necessariamente nessa ordem. Atualmente, não é possível saber qual é qual, a Microsoft é um pouco avarenta com essas informações.
Em todos os três CVEs ocorre um integer overflow durante o cálculo do tamanho da alocação (comprimento do caminho do diretório + comprimento do nome do arquivo), levando a um estouro de buffer baseado em pool com os dois memmove seguintes do caminho do diretório e do nome do arquivo.
NtfsRenameToPrivateDirO caminho para NtfsRenameToPrivateDir é mostrado abaixo:
NtfsCommonSetInformation
|__________________
| |
v v
NtfsSetLinkInfo NtfsSetRenameInfo
|__________________|
|
v
NtfsRemoveSupersededTarget
|
v
NtfsRenameToPrivateDir
Antes de mais nada, para chamar NtfsCommonSetInformation, basta chamar NtSetInformationFile. Em seguida, para passar por NtfsSetLinkInfo e NtfsSetRenameInfo, use respectivamente FileLinkInformationEx e FileRenameInformationEx como classe de informações de arquivo em NtSetInformationFile.
Para alcançar NtfsRemoveSupersededTarget através de NtfsSetRenameInfo, é necessário definir as flags FILE_RENAME_REPLACE_IF_EXISTS e FILE_RENAME_POSIX_SEMANTICS. Renomeie um arquivo com o nome de um existente para acessar NtfsRemoveSupersededTarget. Para NtfsRenameToPrivateDir, é um pouco complicado, porque o arquivo substituído deve estar aberto por algum processo.
Infelizmente, uma verificação de comprimento é feita antes da chamada a NtfsRemoveSupersededTarget.
O método com NtfsSetLinkInfo é semelhante ao NtfsSetRenameInfo, apenas os nomes das flags diferem, seus significados permanecem os mesmos. Mas, assim como em NtfsSetRenameInfo, outra verificação é feita antes da chamada a NtfsRemoveSupersededTarget.
TxfAllocateAndStoreNameForTxLoggingO caminho para TxfAllocateAndStoreNameForTxLogging é mostrado abaixo:
NtfsCommonCreate
|
v
NtfsCreateNewFile
|
v
TxfNewFileCreate
|
v
TxfAllocateAndStoreNameForTxfLogging
Antes de mais nada, para chamar NtfsCommonCreate, basta chamar CreateFile.
A função TxfNewFileCreate é prefixada com Txf, que significa "Transactional NTFS" (NTFS Transacional) e é chamada quando um arquivo transacional é criado. TxfAllocateAndStoreNameForTxfLogging é chamada durante o processo para armazenar o caminho do arquivo transacional.
Apenas duas chamadas são necessárias:
O código vulnerável de TxfAllocateAndStoreNameForTxLogging é mostrado abaixo:
...
and di, 2
add di, [rsi+UNICODE_STRING.Length] ; File name
add di, [rsp+68h+RelativeNormalizedDirectoryPath.Length] ; OVERFLOW HERE
cmp [rsp+68h+arg_20], r12b
jnz loc_16592C
movzx edx, di
add rdx, size UNICODE_STRING ; NumberOfBytes
mov ecx, cs:PoolType
or ecx, 10h ; PoolType
mov r8d, 'afxT' ; Tag
call cs:__imp_ExAllocatePooliWthTag
...
Para acionar o estouro, é necessário criar um arquivo com um comprimento excessivo, mais de 0xFFFF bytes (32767 caracteres).
Um problema que surge é que um nome de arquivo ou diretório não pode ter mais de 256 caracteres - incluindo o caractere NULL. Para resolver isso, será necessário o uso de subpastas profundas. Estranhamente, não é tão fácil, mesmo com subpastas criadas com sucesso, o subarquivo não pode ser criado, certamente devido a algumas verificações feitas anteriormente.
Usando a barra do explorer, é possível notar o formato usado para mostrar o caminho do diretório. Não é o que eu esperava, em vez de usar um caminho "clássico", o explorer usa o formato antiquado do DOS, o formato curto 8.3.
Manter a criação de subpastas como antes e usar o nome curto para os subdiretórios durante a criação do arquivo resolve o problema.
É importante notar que 16 bytes serão adicionados ao tamanho estourado, que é o tamanho da UNICODE_STRING que representará o caminho final. Isso porque a memória solicitada conterá a UNICODE_STRING seguida pelo buffer dessa UNICODE_STRING.
Método:
Condições atuais:
Um write-up interessante da Synacktiv no SSTIC 2020 poderia ser uma ideia para investigar, visando o VS Heap.
O CVE-2020-17087, um caso semelhante de exploração, foi apresentado pela PixiePoint Security usando a técnica mencionada acima.
| Simi | Conf | Função | Informação |
|---|
| NOK | 0.98 | 0.99 | NtfsCommonSetInformation$fin$0 | Modificações de salto |
| 0.97 | 0.99 | NtSetShortNameInfo | ||
| 0.96 | 0.99 | NtfsUpdateSecurity | ||
| NOK | 0.91 | 0.94 | NtfsRenameToPrivateDir$fin$1 | Modificações de salto |
| 0.89 | 0.98 | NtfsInitializeFileInDirectory | ||
| OK | 0.88 | 0.95 | TxfAllocateAndStoreNameForTxLogging | Verificação de comprimento |
| OK | 0.87 | 0.93 | NtfsRenameToPrivateDir | Verificação de comprimento |
| OK | 0.81 | 0.95 | TxfAllocateFullFilePathForChangeNotify | Verificação de comprimento |
| 0.76 | 0.94 | NtfsCommonSetInformation |