
Ferramenta de tunelamento DNS usando PowerShell e Nslookup para exfiltrar dados e entregar payloads via registros DNS TXT/MX, contornando o Constrained Language Mode e defesas de endpoint.
Inspirado pelo trabalho recente que realizei envolvendo beacons DNS do Cobalt Strike, em conjunto com uma declaração de missão para tentar evadir o Microsoft Defender for Endpoint, passei algum tempo investigando como o DNS poderia ser usado para transferir um payload para uma máquina alvo. Além disso, quis me desafiar tentando fazer isso de uma forma que seja possível mesmo quando o PowerShell está no Modo de Linguagem Restrita (Constrained Language Mode). Esta pesquisa teve como alvo implementações mais modernas do Windows (ou seja, Win10+, Server 2019+), mas como você verá mais adiante, pode ser possível em versões inferiores.
O tunelamento DNS é uma técnica que existe há muito tempo e é usada por diversos atacantes. Em um nível básico, envolve o uso do protocolo DNS como meio de infiltração/exfiltração de dados ou como um canal de comunicação C2. Existem muitas postagens em blogs que você pode consultar para obter mais informações sobre este tópico.
Por ser uma técnica tão antiga e conhecida, muitas organizações possuem métodos de detecção implementados para tentar preveni-la.
O tipo de registro DNS de escolha para tunelamento DNS tem sido historicamente o TXT. Isso porque os registros TXT podem conter mais dados do que outros registros e também são sensíveis a maiúsculas/minúsculas (case-sensitive), algo que os outros registros não são, o que pode ter impacto quando começamos a falar sobre codificação.
O Modo de Linguagem Restrita (Constrained Language Mode, CLM) é um modo de linguagem restritivo para o PowerShell que reduz bastante as capacidades e a funcionalidade permitida do PowerShell. Como uma breve lista, .NET, objetos COM e os favoritos dos atacantes como (new-object net.webclient).downloadstring... estão indisponíveis. Este link fornece mais informações. As organizações colocam essa política em vigor para usuários normais como parte das regras de redução da superfície de ataque. Na prática, isso apenas torna nossa vida mais difícil como atacantes.
A maioria deve estar pelo menos superficialmente familiarizada com o DNS pelo uso de ferramentas como Nslookup. Mas em um nível básico, o cliente envia uma consulta e o servidor DNS retorna uma resposta para essa consulta. Existem vários tipos diferentes de registros DNS: CNAME, A, AAAA, TXT, MX e NS, apenas para citar alguns. Cada um desses registros pode armazenar e retornar informações diferentes. Esses registros são configurados em um arquivo de zona (Zonefile), que é servido por um servidor DNS.
Um exemplo de arquivo de zona é mostrado aqui:``` $ORIGIN example.com. @ 3600 SOA ns1.p30.dynect.net. ( zone-admin.dyndns.com. ; address of responsible party 2016072701 ; serial number 3600 ; refresh period 600 ; retry period 604800 ; expire time 1800 ) ; minimum ttl 86400 NS ns1.p30.dynect.net. 86400 NS ns2.p30.dynect.net. 86400 NS ns3.p30.dynect.net. 86400 NS ns4.p30.dynect.net. 3600 MX 10 mail.example.com. 3600 MX 20 vpn.example.com. 3600 MX 30 mail.example.com. 60 A 204.13.248.106 3600 TXT "v=spf1 includespf.dynect.net ~all" mail 14400 A 204.13.248.106 vpn 60 A 216.146.45.240 webapp 60 A 216.146.46.10 webapp 60 A 216.146.46.11 www 43200 CNAME example.com.
Se alguém consultar registros NS para example.com, a consulta retornaria ns1.p30.dynect.net, ns2.p30.dynect.net, ns3.p30.dynect.net e ns4.p30.dynect.net.
# Pesquisa
## Registro de nome de domínio
Antes de começarmos, precisamos falar brevemente sobre a configuração de registros DNS para apontar para um IP que controlamos e onde executaremos um servidor DNS. Conforme mostrado abaixo, comprei um domínio e configurei registros DNS que apontam o subdomínio "dns" para o subdomínio "ns1", ao qual é atribuído o IP público do servidor.

Isso significa que quaisquer consultas feitas para "dns.edu....com" serão direcionadas para "ns1.edu....com", que possui o IP 3..86. Nesse IP, configuraremos um servidor DNS para servir nossos registros. Isso será retomado mais tarde.
## Encontrando uma ferramenta do lado do cliente
Minha busca começou com uma simples pesquisa no Google por "powershell dns module", que retornou [este](https://docs.microsoft.com/en-us/powershell/module/dnsclient/?view=windowsserver2022-ps) link. De particular interesse foi o comando Resolve-DnsName. Parece ser basicamente uma implementação PowerShell do conhecido binário Nslookup.exe. Observe que tipos específicos de registros podem ser solicitados:

Ok, então temos um módulo PowerShell capaz de fazer consultas DNS e recuperar a resposta. Funciona no Modo de Linguagem Restrita (Constrained Language Mode - CLM)? A resposta é: mais ou menos.
Como você pode ver aqui, se eu abrir uma nova janela do PowerShell, executar Resolve-DnsName, colocar o PowerShell em CLM (e testar com a simples chamada ::WriteLine) e depois executar Resolve-DnsName novamente, funciona sem problemas:

No entanto, se eu abrir uma nova janela do PowerShell e imediatamente colocá-la em CLM e depois tentar executar Resolve-DnsName, ele falha:

Parece que, se um módulo foi carregado anteriormente, ele consegue ser executado após a aplicação do CLM; no entanto, o CLM impede seu carregamento se ele ainda não tiver sido carregado. Pensando adiante em um ambiente alvo onde o CLM é aplicado por padrão para os usuários (e sem saber se determinados módulos estão pré-carregados ou se o DnsClient está entre eles), optei neste momento por deixar o Resolve-DnsName de lado e recorrer ao bom e velho Nslookup.exe.

O Nslookup.exe é um item essencial do kit de ferramentas de TI e um binário muito conhecido, utilizado para fins legítimos. As probabilidades estão a nosso favor de que ele seja permitido para execução mesmo em ambientes onde a lista de permissões de aplicativos é uma preocupação.
O Nslookup retornará basicamente as mesmas informações que nossa consulta Resolve-DnsName; só teremos que manipulá-lo de forma um pouco diferente quando chegar a hora.
## Transformando um executável em registros DNS?
Ok, então temos uma maneira de fazer consultas DNS no computador da vítima. Como podemos fornecer nosso payload em um formato que o Nslookup consiga recuperar?