Skip to content
KitploitKITPLOIT
FerramentasExploitsBlog
Log in
Enviar
FerramentasExploitsBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

FeedsContatoPrivacidade© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
cve-2019-1458_POC — POC para cve-2019-1458 | Kitploit
Ferramentas/GitHubGitHub/piotrflorczyk/cve-2019-1458_poc
Análise de VulnerabilidadesExploraçãoEngenharia ReversaAprendizado e EducaçãoExploração de Binários
GitHubpiotrflorczyk/cve-2019-1458_poc

cve-2019-1458_POC

POC para cve-2019-1458

Ver Repositório
181539há 4 anosRevisado pelo Kitploit

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

CVE-2019-1458: Indo do 'relatório in the wild' para POC

Introdução

Em dezembro, a Kaspersky publicou um post em blog sobre [exploit 0day usado ativamente in the wild][1]. Isso despertou meu interesse, pois embora tenham descrito como o exploit funcionava, eles não forneceram nenhum POC em sua análise. Foi por isso que decidi tentar escrever um POC para esta vulnerabilidade com base no post do blog da Kaspersky e na análise do patch.
Este post descreve minha jornada nesse processo.

Coleta de informações:

A primeira coisa foi coletar o máximo de informações possível sobre esta vulnerabilidade. Ao ler o post mencionado, extraí as seguintes informações:

  • A vulnerabilidade está relacionada à funcionalidade de alternância de janelas
  • Requer simular pressionamentos da tecla ALT para ser acionada
  • São necessárias duas chamadas à API não documentada NtUserMessageCall
  • Uma janela de alternância especial precisa ser criada
  • Havia alguma referência à função do kernel win32k!DrawSwitchWndHilite

Além disso, há uma boa captura de tela do código decompilado mostrando algumas das coisas listadas anteriormente. Para ser exato, ela mostra: a criação da janela de alternância, a chamada a uma função chamada toggle_alt_key e múltiplas chamadas a NtUserMessageCall.

Parte do código decompilado do exploit [Fonte da imagem][1]

Muita informação útil, mas ainda assim não descreve exatamente como essa vulnerabilidade funciona e como acioná-la.

Diffing de patches

[O módulo afetado era o win32k.sys][2]. Baixei as versões corrigida e não corrigida desse módulo.
Para Windows 7 x64, essas foram:

  • corrigida: KB4530692
  • não corrigida: KB4525233

Elas podem ser baixadas do [Catálogo do Microsoft Update][3]

Aqui está o resultado do bindiff comparando as duas versões

comparação win32k

Após descartar funções relacionadas à funcionalidade DebugHook, o que realmente nos resta é esta função ligeiramente alterada InitFunctionTables()

Alterações em InitFunctionTables

Definitivamente não é o maior patch que existe.
Isso não ajudará a identificar imediatamente a causa raiz dessa vulnerabilidade. Mas vale notar que alguns valores iniciais para variáveis em *(gpsi+0x14E), *(gpsi+0x154), *(gpsi+0x180) foram adicionados. Portanto, isso pode ser um bug relacionado a variável não inicializada.

Construção do POC - passo a passo

Nesta seção, apresentarei como construí progressivamente um POC que aciona essa vulnerabilidade, enquanto simultaneamente descobria o que a vulnerabilidade realmente era.

Por onde começar

O diffing de patches não forneceu muitas informações úteis no início, então dependi principalmente do post do blog da Kaspersky na primeira etapa do desenvolvimento.
Para ter um bom ambiente de teste, preparei uma VM Win7 SP1 x64 com a última versão vulnerável do win32k em execução. Além disso, anexei o Windbg a essa VM para fazer depuração de kernel e, durante isso, configurei também o caminho do servidor de símbolos.
Comecei minha investigação olhando para win32k!DrawSwitchWndHilite, mencionado no post do blog. Ela é chamada a partir de dois lugares: xxxMoveSwitchWndHilite e xxxPaintSwitchWindow; esta última chamou minha atenção imediatamente, por causa das chamadas a GetKeyState/GetAsyncKeyState ao redor, que foram mencionadas no relatório original. Além disso, essas chamadas verificam se a tecla ALT está pressionada.

Callsite interessante para DrawSwitchWndHilite
Chamada a DrawSwitchWndHilite a partir de xxxPaintSwitchWindow

Continuando a seguir as referências cruzadas de chamadas (xxxWrapSwitchWndProc->xxxSwitchWndProc->xxxPaintSwitchWindow->DrawSwitchWndHilite), descobri que o primeiro elemento dessa cadeia é referenciado em InitFunctionTables, função que foi corrigida no patch.

Em seguida, examinei NtUserMessageCall da captura de tela do código decompilado. Aqui está a declaração dessa função```cpp NtUserMessageCall(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, ULONG_PTR ResultInfo, DWORD dwType, BOOLEAN bAnsi)

O exploit está chamando-o com `msg = 0x14` e `dwType = 0xE0`. Vamos ver o que isso faz.```cpp
HINSTANCE hInstance = GetModuleHandle(NULL);
WNDCLASSEX wcx;
ZeroMemory(&wcx, sizeof(wcx));
wcx.hInstance = hInstance;
wcx.cbSize = sizeof(wcx);
wcx.lpszClassName = L"SploitWnd";
wcx.lpfnWndProc = DefWindowProc;

printf("[*] Registering window\n");
ATOM wndAtom = RegisterClassEx(&wcx);
if (wndAtom == INVALID_ATOM) {
    printf("[-] Failed registering SploitWnd window class\n");
    exit(-1);
}

printf("[*] Creating instance of this window\n");
HWND sploitWnd = CreateWindowEx(0, L"SploitWnd", L"", 0, 0, 0, 0, 0, NULL, NULL, hInstance, NULL);
if (sploitWnd == INVALID_HANDLE_VALUE) {
    printf("[-] Failed to create SploitWnd window\n");
    exit(-1);
}
NtUserMessageCall(sploitWnd, WM_ERASEBKGND, 0, 0, 0, 0xE0, 1);

Aqui registrei uma classe de janela simples e criei uma janela dessa classe. Então chamei NtUserMessageCall com os mesmos parâmetros do exploit. Para ver o que acontece internamente, configurei o breakpoint kd> ba e 1 win32k!NtUserMessageCall e executei o código. Existem algumas chamadas sendo feitas para essa função, então tive que capturar a correta, mas não foi tão difícil, era a que tinha uma pilha de chamadas realmente curta.

NtUserMessageCall
NtUserMessageCall

Percorrendo o código passo a passo, descobri que ele chama uma função do array gapfnMessageCall; o índice é calculado com base no valor de msg e é igual a 0, então a chamada é feita para NtUserfnDWORD

NtUserfnDWORD
NtUserfnDWORD

A próxima chamada é feita usando o valor de dwType, e agora o offset de gpsi é igual a 0x40, e a chamada leva a xxxWrapSwitchWndProc (essa função já apareceu quando eu estava verificando a cadeia de chamadas de DrawSwitchWndHilite).
xxxWrapSwitchWndProc simplesmente chama xxxSwitchWndProc.

xxxSwitchWndProc
xxxSwitchWndProc

E este é o fim; o código falha aqui, não indo mais adiante até xxxPaintSwitchWindow, que é onde queremos chegar com base no valor de msg (0x14). Vamos verificar o porquê.

Acionando o caminho correto

O código falha nesse estágio porque, como destacado na imagem anterior, o fnid da nossa janela não é igual a 0x2A0 (FNID_SWITCH) e a mensagem que estamos enviando não é igual a 1; portanto, acabamos em xxxDefWindowProc. Para evitar esse cenário, temos que chamar xxxSwitchWndProc com o fnid definido como FNID_SWITCH, de modo que iremos direto para a instrução switch e, depois, para xxxPaintSwitchWindow.
Como definir o fnid correto? Na verdade, a mesma função faz isso no primeiro bloco if; só precisamos falhar em todas as verificações dentro dele para chegar à instrução que define o fnid.

Aqui estão as condições que precisamos atender para falhar nas três verificações if:

Baixar ferramenta