
Ferramenta Interativa de Exploração de CTF
Quer apenas testar o exploit do SYSTEM? Clique aqui.
Este é o ctftool, uma ferramenta de linha de comando interativa para experimentar com o CTF, um protocolo pouco conhecido usado no Windows para implementar Serviços de Texto. Isso pode ser útil para estudar os internals do Windows, depurar problemas complexos com Processadores de Entrada de Texto e analisar a segurança do Windows.
É possível escrever scripts simples com o ctftool para automatizar a interação com clientes ou servidores CTF, ou realizar fuzzing simples.
Há uma postagem no blog que acompanha o lançamento desta ferramenta disponível aqui.
https://googleprojectzero.blogspot.com/2019/08/down-rabbit-hole.html
O ctftool foi testado no Windows 7, Windows 8 e Windows 10. Versões de 32 bits e x64 são suportadas, mas a x64 foi testada mais extensivamente.
Há ajuda online para a maioria dos comandos, basta digitar help para ver uma lista de comandos e help <comando> para ver ajuda detalhada para um comando específico.
$ ./ctftool.exe
Uma ferramenta interativa de exploração ctf por @taviso.
Digite "help" para comandos disponíveis.
A maioria dos comandos requer uma conexão, veja "help connect".
ctf> help
Digite `help <comando>` para ajuda com um comando específico.
Qualquer linha começando com # é considerada um comentário.
help - Lista comandos disponíveis.
exit - Sai do shell.
connect - Conecta à porta ALPC do CTF.
info - Consulta informações do servidor.
scan - Enumera clientes conectados.
callstub - Pede a um cliente para invocar uma função.
createstub - Pede a um cliente para instanciar CLSID.
hijack - Tenta sequestrar um caminho de servidor ALPC.
sendinput - Envia teclas para uma thread.
setarg - Marshaliza um parâmetro.
getarg - Desmarshaliza um parâmetro.
wait - Aguarda um processo e define-o como thread padrão.
thread - Define a thread padrão.
sleep - Dorme por milissegundos especificados.
forget - Esquece todos os stubs conhecidos.
stack - Imprime o último ponteiro de pilha vazado.
marshal - Envia comando com parâmetros marshallizados.
proxy - Envia comando com parâmetros proxy.
call - Envia comando sem dados adicionados.
window - Cria e registra uma janela de mensagem.
patch - Aplica patch em um parâmetro marshallizado.
module - Imprime o endereço base de um módulo.
module64 - Imprime o endereço base de um módulo 64 bits.
editarg - Altera o tipo de um parâmetro marshallizado.
symbol - Consulta um offset de símbolo a partir de ImageBase.
set - Altera ou exibe vários parâmetros do ctftool.
show - Mostra o valor de variáveis especiais que você pode usar.
lock - Bloqueia a estação de trabalho, muda para o desktop Winlogon.
repeat - Repete um comando várias vezes.
run - Executa um comando.
script - Origina um arquivo de script.
print - Imprime uma string.
consent - Invoca o diálogo de consentimento do UAC.
reg - Consulta um DWORD no registro.
gadget - Encontra o offset de um padrão em um arquivo.
section - Consulta propriedade de seção PE.
A maioria dos comandos requer uma conexão, veja "help connect".
ctf>
A primeira coisa que você vai querer fazer é conectar a uma sessão e ver quais clientes estão conectados.
ctf> connect
A porta do servidor ctf está localizada em \BaseNamedObjects\msctf.serverDefault1
NtAlpcConnectPort("\BaseNamedObjects\msctf.serverDefault1") => 0
Conectado ao servidor CTF@\BaseNamedObjects\msctf.serverDefault1, Handle 00000264
ctf> scan
Cliente 0, Tid 3400 (Flags 0x08, Hwnd 00000D48, Pid 8696, explorer.exe)
Cliente 1, Tid 7692 (Flags 0x08, Hwnd 00001E0C, Pid 8696, explorer.exe)
Cliente 2, Tid 9424 (Flags 0x0c, Hwnd 000024D0, Pid 9344, SearchUI.exe)
Cliente 3, Tid 12068 (Flags 0x08, Hwnd 00002F24, Pid 12156, PROCEXP64.exe)
Cliente 4, Tid 9740 (Flags 0000, Hwnd 0000260C, Pid 3840, ctfmon.exe)
Você pode então experimentar enviando e recebendo comandos para o servidor, ou para qualquer um dos clientes conectados.
Se você não quiser compilar por conta própria, confira a aba de releases
Usei GNU make e Visual Studio 2019 para desenvolver o ctftool. Apenas compilações de 32 bits são suportadas, pois isso permite que a ferramenta funcione no Windows x86 e x64.
Se todas as dependências estiverem instaladas, apenas digitar make em um prompt de comando de desenvolvedor deve ser suficiente.
Eu uso a variante "Build Tools" do Visual Studio, e os únicos componentes que selecionei são MSVC, MSBuild, CMake e o SDK.
Este projeto usa submódulos para algumas dependências, certifique-se de usar um comando como este para buscar todo o código necessário.
git submodule update --init --recursive
Os exemplos funcionam apenas no Windows 10 x64. Todas as plataformas e versões desde o Windows XP são afetadas, mas nenhum PoC está implementado atualmente.
Esta ferramenta foi usada para descobrir muitos problemas críticos de segurança no protocolo CTF que existem há décadas.
Se você apenas quer testar um exploit no Windows 10 x64 1903, execute ou clique duas vezes em ctftool.exe e digite este comando:
Uma ferramenta interativa de exploração ctf por @taviso.
Digite "help" para comandos disponíveis.
A maioria dos comandos requer uma conexão, veja "help connect".
ctf> script .\scripts\ctf-consent-system.ctf
Isso vai aguardar o diálogo UAC aparecer, comprometê-lo e iniciar um shell.
Na verdade, o código do exploit é dividido em dois estágios que você pode usar independentemente. Por exemplo, você pode querer comprometer um processo pertencente a um usuário em uma sessão diferente usando os parâmetros opcionais de connect.
A maioria dos clientes CTF pode ser comprometida, pois o kernel força aplicações que desenham janelas a carregar a biblioteca vulnerável.
Simplesmente conecte a uma sessão, selecione um cliente para comprometer (use os comandos scan e thread, ou apenas wait), então:
ctf> script .\scripts\ctf-exploit-common-win10.ctf
Construir uma cadeia de jumps CFG que funcionasse na maioria dos clientes CTF foi bastante desafiador. Há dois componentes principais no exploit final: uma primitiva de escrita arbitrária e então configurar nossos registradores para chamar LoadLibrary().
Você pode usar
dumpbin /headers /loadconfigpara despejar os alvos de branch na lista branca.
Precisava de um gadget de escrita arbitrária para criar objetos em um local previsível. O melhor gadget utilizável que consegui encontrar foi um decremento arbitrário de dword em msvcrt!_init_time.
Isso significa que, em vez de apenas definir os valores que queremos, temos que decrementar até que o LSB atinja o valor desejado. Isso é muito trabalho, mas nunca precisamos fazer mais do que (2^8 - 1) * len decrementos.

Usando essa primitiva, construo um objeto assim em algum espaço livre não utilizado na seção .data do kernel32. Ele precisa fazer parte de uma imagem para que eu possa prever onde será mapeado, já que a randomização de imagem é por inicialização no Windows.