returnreturn
Follina a silent Client-Side

By:
Joaquin Lanfranconi
Cybersecurity Researcher

SHARE

Twitter Facebook linkedin

DNS Tunneling

Surely at some time you were in an airport, a cafe, an airplane or a hotel where there was a WiFi network that did not require a password to connect, but at the time of browsing it asked for a subscription or some kind of payment, deriving your navigation to what is known as a captive portal. This is very common as more and more things require an Internet connection. Many times providers block all incoming and outgoing traffic if you are not authorized or authenticated, but usually allow DNS (Domain Name System) resolution that converts a human-recallable address to the IP address associated with it and vice versa. Then, the provider decides whether or not to block the traffic.

In this scenario, it would be interesting to be able to tunnel the browsing traffic through the DNS protocol, and thus have access to the Internet. This technique is called DNS Tunneling. As expected, browsing this way is slow as if it were a modem with a Dial Up connection, but it is still curious and controversial, since it is a protocolthat has not been designed for data transfer beyond name resolution.

How this is achieved

First we must be inside a network with a captive portal. To verify that it is possible to apply this technique, we can perform an ECHO Request (e.g., a ping to google.com or any domain. If we receive the IP address associated with that domain, we can proceed with this attack. If not, most likely the provider has blocked this type of traffic as well.

Once we have checked this, we can attempt to exploit in 6 steps:

1. First of all, we must have a domain to which we can modify the "A" record, which maps the domain name to the IP of our server and the "NS" record, also known as Name Server record, which maps the domain name to a list of DNS servers, assigned to the "A" record, which is our domain. Clearly, the records should be configured as follows:

  • A record = dnsa.mydomain.net -> the public IP of the computer at home.
  • NS record = p.mydomain.net -> dnsa.mydomain.net

t is worth noting that if we use a short subdomain such as "p", it allows us to pack more data per request.

2. Then we must configure the device that will act as a server, which can be a computer at home with internet access or in the cloud.

To do this we will use the "iodine" tool, which works very efficiently with this type of techniques, and should be running on our server at the time of testing, with the following command:

user@server$ sudo iodined -c -f 10.0.0.1 -P passwordsecure123 p.mydomain.net

"-f" determines the internal network to be used. If the 10.0.0.0.0 network is already in use, you can use any other internal network (Example: 172.16.0.0).

"-P" is the password that will be requested to connect to the service.

"p.mydomain.net" is the previously configured domain.

3. Once we have iodine running on the server, we can use this "Check-it" tool from the same developer to verify that everything is configured correctly.

4. Our computer, mobile device (or even a Raspberry Pi) will act as a client. We must be in the network with the captive portal and inside a terminal we will connect to our server with iodine, with the command:

user@notebook$ iodine -r -f -L0 -P passwordsecure123 p.mydomain.net

Thus, iodine will try to connect to our server and find the most efficient way of packaging.

5. We will already be on the same subnet as our server, so we should simply connect to it via SSH to perform a SOCKS tunnel and send all the traffic from our browser through it.

An example would be the following:

user@notebook$ ssh -D 8080 root@10.0.0.1 -N

Logically the subnet varies according to the one used in the command of step 2.

6. That's it! We are now sending all the traffic through DNS Tunneling, we only need to configure our browser to use our remote server as a proxy

If we want to check that everything works as expected, we can use the following command (for Linux based distributions):

user@notebook$ curl api.ipify.org --socks4 127.0.0.1:8080

With this we should receive a response (which means that we already have a connection to the internet) and see the public IP of our remote server.

The focus of this post is on bypassing the captive portal in order to get an internet connection, but the use cases for this technique are many, from bypassing firewalls, to data leak prevention devices, to unmonitored communication channels in an organization's network, and much more.