There a several ways of tunneling data through other services, like SSH or HTTP Proxys.
But it is also possible to tunnel via DNS, which is sometimes available in very restricted networks like Airport WLAN and such.
It works pretty straight forward:
You need a server and a domain. Setup a nameserver record and install one of the available DNS tunneling daemons.
Setup a client with the DNS tunneling client and tunnel your data through DNS requests.
Instead of sending dns requests like:
-> ‘Hey Server, what ip has www.google.com?’
<- 'Ist has 18.104.22.168 dear client'
the system will send something like this:
-> ‘Hey Server, please send this paket for me: base64[packet(http, get 'www.google.com')].mydomain.com’
<- 'Dear client, base64[Response(first part, '
<- 'Dear client, base64[Response(second part, '…’)]’
The server has to send multiple packets because DNS responses have a limited size. Also the transferred data is base64 encoded, otherwise it could not be transferred via the DNS protocol.
Check out this pages if you like to know more: