Exploração de escalada de privilégios locais para o motorista do kernel CPU-Z.
O aplicativo CPU-Z instalará um driver assinado vulnerável para acessar dados do kernel do UserMode. Antes da v1.81, o driver CPU-Z expôs três IOCTLs que permitem que qualquer aplicativo Usermode leia os registros de controle, leia DWords da memória física e escreva Dwords na memória física. Abusamos essa funcionalidade para obter a execução completa do código do modo de kernel e geramos um shell de sistema como prova de conceito.
Esta exploração suporta o Windows XP - Windows 10 1607:
Esta exploração foi testada nos seguintes sistemas com CPU-Z v1.76:
* No Windows 1703 e Posterior Kernel Control Flow Guard (CFG) é ativado por padrão [1], resultando em uma verificação de bug do kernel_security_check_failure.
Para executar este exploração, inicie o aplicativo CPU-Z e execute o exploração.exe de um prompt de comando como um usuário normal. Se for bem -sucedido, ele deve gerar um novo processo cmd.exe em execução como sistema. Observe que esse exploração falhará se for executado em um processo de baixa integridade devido ao uso do NTQUERYSYSTEMINFORMAÇÃO.
O driver do kernel CPU-Z antes da v1.81 permite que qualquer aplicativo Usermode leia os registros de controle, leia o Dwords da memória física e escreva DWords na memória física. Abusamos essa funcionalidade para ler o CR3 e atravessar as tabelas de página para criar uma leitura/gravação arbitrária primitiva em todo o espaço de memória virtual.
Com a leitura/gravação completa, giramos o bit de usuário/supervisor na entrada da tabela de páginas (PTE) contendo nossa carga útil no KernelMode para ignorar o Modo de Execução do Modo Supervisor Prevenção (SMEP). Em seguida, substituímos um ponteiro de função no nt! Haldispatchtable [1] e acionamos a carga útil chamando NtQueryIntervalProfile.
Como prova de conceito, a carga útil atribuirá o token do sistema a um processo cmd.exe suspenso e retomará o processo. Isso deve resultar em um novo prompt de comando em execução como autoridade/sistema NT. A carga útil não depende de compensações estáticas e, portanto, deve funcionar no Windows XP+.
Várias mitigações foram introduzidas nos últimos dois anos que limitam a eficácia dessa exploração. Uma breve descrição está abaixo.
A partir da versão 1.81, o driver fornecido com CPU-Z foi corrigido para limitar o conjunto de chamadas que podem abrir seu objeto de dispositivo e algumas implementações do IOCTL foram removidas. Por solicitações para abrir o objeto do dispositivo do driver, ele verificará se o processo atual possui o SeloadDriverPrivilege ativado. Se este Privilige estiver ausente ou desativado, o driver rejeitará a solicitação com status_access_denied. Observe que, ao executar como administrador, é trivial permitir esse privilégio do UserMode. Além disso, o IOCTL para ler os registros de controle foi removido (embora as implementações de leitura/gravação da memória física permaneçam). Sem a capacidade de ler a base da tabela de páginas da CR3, o método de exploração neste projeto não é mais viável. Observe que o driver CPU-Z fornece vários outros IOCTLs que podem ser usados para exploração, como ler e escrever para registros específicos de modelo arbitrários.
A partir do Windows 10 1703 (Atualização dos criadores), a proteção de fluxo de controle do kernel é ativada por padrão no x86_64. As chamadas através do HALDISPATCHTABLE resultarão em uma verificação de bug do kernel_security_check_failure, pois é protegida pelo CFG. Se a segurança baseada em virtualização (VBS) não estiver ativada, deve ser possível adicionar a carga útil como um destino de chamada válido para ignorar o CFG.
Se a segurança baseada em virtualização (VBS) estiver ativada, ele matará a maior parte dessa exploração. A manipulação de PTE usada para desativar o SMEP não será mais possível, pois os PTEs serão protegidos pelo hipervisor. Além disso, será necessário um desvio CFG no x86_64 para obter a execução do código através do HaldispatchTable, pois o bitmap CFG do kernel não será gravável.
As vulnerabilidades usadas nesta exploração são detalhadas na CVE-2017-15302 e CVE-2017-15303. Outra prova de conceito pode ser vista no CPUZ-DSEFIX [5].
[1] https://community.osr.com/discussion/283374/control-flow-guard-question
[2] https://www.cvedetails.com/cve/cve-2017-15302/
[3] https://www.cvedetails.com/cve/cve-2017-15303/
[4] https://github.com/akayn/bugs/blob/master/cpuid/cve-2017-15302/readme.md
[5] https://github.com/samlarenn/cpuz-dsefix
Além disso, o método de substituição HaldispatchTable usado nesta exploração é um vetor comumente usado para obter a execução do código de um primitivo de leitura/gravação do kernel. Para detalhes adicionais sobre esta técnica, consulte os recursos abaixo.
[6] http://poppopret.blogspot.com/2011/07/windows-kernel-exploitation-basics-part.html
[7] https://www.abatchy.com/2018/01/kernel-exploitation-7
[8] https://osandamalith.com/2017/06/14/windows-kernel-exploitation-arbitrary-overwrite/
[9] https://rootkits.xyz/blog/2017/09/kernel-write-what-where/