The Domain Name System (DNS) is one of the fundamental services of the Internet. By resolving domain names to IP addresses, it makes routing of IP packets possible and thereby lets browsers and other clients connect to remote servers using all kinds of protocols. By blindly connecting to the IP address returned by the DNS server, however, users put a lot of trust into DNS, because by default, DNS responses are not validated or verified.
In this blog post, I’d like to demonstrate how to easily set up a DNS server that allows you to easily forge certain entries manually — thereby allowing you to either block certain domains from your network or to pretend that you are a certain website. This scenario is commonly referred to as DNS forgery or DNS spoofing.
Contents
1. Why forge DNS entries?
DNS is responsible for managing the Internet’s namespace of domains by translating domain names into IP addresses. Even though it sounds like a very simple task, this translation carries a great responsibility because it is an essential step to make communication between most machines even possible. Before a machine can connect to another machine and start the actual communication, a DNS request must resolve the name of the destination machine. In short, before you can connect to “example.com”, you first need to know its IP address.
And because machines blindly connect to the IP address returned by the DNS server, being able to forge specific (or all) of its entries means that the client connects to a different server – i.e. the connection is rerouted to a destination of your choice.
There are multiple reasons for wanting to reroute traffic. The two most prominent ones are to block access to a site or service, or to eavesdrop the connection using a man-in-the-middle attack (MITM).
- Blocking sites: Especially in the last couple of years, many governments all over the world have used DNS forgery/spoofing to block access to various kind of Internet content (e.g. social networks, political/religious content, pornography, piracy sites, etc.). And although blocking on DNS-level is pointless (using a different DNS server circumvents the blockage), it’s very easy to implement (as shown in this post) and is hence often used.
- Eavesdropping the connection (MITM): Rerouting all IP packets to a certain machine makes it possible to eavesdrop on the connection by listening local network interface. Using tools like Wireshark, mitmproxy (see mitmproxy tutorial here) or SSLsplit (see SSLsplit tutorial here), this can be done without much effort — for both plain text protocols (HTTP, SMTP, etc.) as well as SSL-based requests (HTTPS, etc.).
2. Forge DNS entries with Dnsmasq
The scenario described in this tutorial uses the very tiny DNS server Dnsmasq to forge DNS entries. In short, the following steps will show you how to set up Dnsmasq and configure it to forward all DNS requests to Google’s DNS server — except the ones that you’d like to forge.
Once Dnsmasq is installed and running, clients must be told to use this DNS server to resolve IP addresses. This can be done by changing the router configuration or the network settings of the operating system or mobile device.
2.1. Download and install Dnsmasq
On some systems, Dnsmasq is already installed and running by default as a local DNS server (for caching puposes). If not, you first need to download and install Dnsmasq. You can do that in Ubuntu/Debian using apt-get like this.
1 |
apt-get install dnsmasq-base |
2.2. Configure Dnsmasq
Dnsmasq stores it’s configuration in /etc/dnsmasq.conf and reads the file on startup. By default, the file does not exist and Dnsmasq simply uses the default settings when run.
The first step is to create or modify this file and add the following lines:
1 2 3 4 5 |
no-dhcp-interface= server=8.8.8.8 no-hosts addn-hosts=/etc/dnsmasq.hosts |
These four config lines tell Dnsmasq to use Google’s DNS server (with IP address 8.8.8.8) as upstream server if a request cannot be answered and lookup local DNS entries in /etc/dnsmasq.hosts instead of the normal location at /etc/hosts. The first line tells Dnsmasq to not start a DHCP interface, because it’s simply not necessary for this example.
2.3. Add forged DNS entries
The above config file tells Dnsmasq to look in /etc/dnsmasq.hosts to check for all entries it is (or feels) responsible for. By default, this file does not exist and needs to be created:
1 2 3 |
192.168.1.99 www.facebook.com 192.168.1.98 www.microsoft.com microsoft.com 192.168.1.97 www.any.domain any.domain |
The format of the file is very simple and identical to the /etc/hosts file: Each line contains an IP address and (separated by spaces or tabs) one or many corresponding domains. Any request to “www.any.domain”, for instance, would be resolved to “192.168.1.97”.
2.4. Test and run server
Having created the two config files from above, Dnsmasq can now be run or restarted. The easiest way is to simply kill it, and then restart it. For test purposes, the options --no-daemon (debug mode, don’t fork to background) and --log-queries (log requests to STDOUT) are probably the best options:
1 2 |
killall -9 dnsmasq dnsmasq --no-daemon --log-queries |
To locally test that Dnsmasq returns the correct, i.e. the forged, result, you can either use the host utility or dig. Here is an example with dig.
1 2 3 4 5 6 7 8 9 10 |
$ dig @192.168.178.28 +short www.facebook.com 192.168.1.99 $ dig @192.168.178.28 +short www.google.com 173.194.70.99 173.194.70.105 173.194.70.147 173.194.70.106 173.194.70.103 173.194.70.104 |
The example above tells dig to use 192.168.178.28 as DNS server (the machine on which Dnsmasq is running) and only return a short response (+short option, no comments) for the domain “www.facebook.com”, and “www.google.com” in the second call.
As desired, Dnsmasq returns the IP address 192.168.1.99 for “www.facebook.com”, even though the real domain points to 31.13.81.33 (at least at the time of writing). The IP addresses for “www.google.com”, however, are real and come from the upstream DNS server specified in the Dnsmasq config (8.8.8.8).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
$ dnsmasq --no-daemon --log-queries dnsmasq: started, version 2.63rc6 cachesize 150 dnsmasq: compile time options: IPv6 GNU-getopt DBus i18n IDN DHCP DHCPv6 no-Lua TFTP conntrack dnsmasq: using nameserver 8.8.8.8#53 dnsmasq: read /etc/dnsmasq.hosts - 1 addresses dnsmasq: query[A] www.facebook.com from 192.168.178.20 dnsmasq: /etc/dnsmasq.hosts www.facebook.com is 192.168.1.99 dnsmasq: query[A] www.google.com from 192.168.178.20 dnsmasq: forwarded www.google.com to 8.8.8.8 dnsmasq: reply www.google.com is 173.194.70.99 dnsmasq: reply www.google.com is 173.194.70.105 dnsmasq: reply www.google.com is 173.194.70.147 dnsmasq: reply www.google.com is 173.194.70.106 dnsmasq: reply www.google.com is 173.194.70.103 dnsmasq: reply www.google.com is 173.194.70.104 ... |
The Dnsmasq STDOUT output resembles exactly that (see above). The first request is found locally in /etc/dnsmasq.hosts, but the second request is forwarded to the upstream server.
Once you are sure that your DNS server works, you can start it without any command line options (simply dnsmasq), and it will run in the background, answering DNS queries to any machine that asks.
2.5. Change router/client DNS server
For your local network clients (such as your phone or laptop) to use the DNS server, however, you can either change each individual device’s network settings, or simply adjust your local router’s settings.
3. Possible usages
DNS spoofing can be used in many possible ways — unfortunately none of them can be used for anything good. The following two of sections explain the two most common usages.
3.1. Phishing/malicious websites
DNS spoofing can be easily used to create phishing sites or any other kind of malicious websites. Especially for purely HTTP-based websites (not HTTPS, see below), a browser will not know the difference between the real site and the site delivered by any other web server.
All that needs to be done is to set up a web server on the machine with the IP address that answers to the target hostname. So, continuing the example from above, if the target hostname was “www.facebook.com” and the forged DNS entry returned “192.168.1.99”, the machine with this IP address needs to set up a virtual host to answer HTTP request for “www.facebook.com”. For the Apache web server, a virtual host configuration would look something like this:
1 2 3 4 5 |
<VirtualHost *:80> DocumentRoot "/srv/www/fakebook/public_html" ServerName www.facebook.com ... </VirtualHost> |
If a browser client now goes to “www.facebook.com”, the DNS response will say “192.168.1.99” and the browser will connect to that IP address, asking for “www.facebook.com” in the HTTP request:
1 2 3 |
GET / HTTP/1.1 Host: www.facebook.com ... |
And because the Apache configuration is set up to answer to that virtual host, the web site and scripts residing in “/srv/www/fakebook/public_html” will be delivered to the client. The Apache access log will say something like this:
1 2 3 |
www.facebook.com:80 192.168.178.20 - - [21/Jul/2013:20:53:12 +0200] "GET / HTTP/1.1" 200 315 "-" "Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.93 Safari/537.36" |
And for the client, it will look something like this:
This scenario obviously only works for HTTP and assumes that the DNS server with the spoofed entries is used. For HTTPS requests or any other SSL-based protocols, this method will not work, because the web server cannot deliver a valid CA-signed certificate to the client which will lead to a certificate error in the browser. To break HTTPS so that the client does not realize it, a man-in-the middle attack is necessary (see below, or my post about how to sniff into HTTPS connections).
3.2. Blocking content / Internet censorship
Another possible usage of DNS spoofing is the blocking/filtering/censoring of content for Internet users. From a technical perspective, the setup for DNS-based content filtering is exactly the same as for the phishing sites (see above), however, the intention is very different: While phishing/malicious sites typically try to trick to user by delivering a very similar site to the one expected, the strategy of DNS blocking aims to prevent users from accessing certain content, such as piracy sites, pornography or religious/political sites.
DNS blocking is typically used in large corporations or countries. And although it is very easy to circumvent by using a different DNS server, it is widely popular due to its easy setup.
3.3. Man-in-the-middle attacks
Being able to steer user communication in your directions makes it possible to listen in on the connections by using tools such as Wireshark (many protocols) or tcpdump for unencrypted connections, and mitmproxy (HTTPS only) or sslplit (any SSL/TCP) for encrypted connections.
Depending on what tool it is, it might be possible to either just monitor traffic on a specific network interface, or even alter requests and responses on the fly. If you’re interested, check out my tutorial on how to use mitmproxy to read and modify HTTPS traffic.
Very well put-together article, Keep it up, believe me it’s appreciated :)
Pretty good and detailed article. dnsmasq certainly looks interesting.
Here’s one ‘spoofing for good’ — redirecting smartphone clients to a development website for testing how well the new responsive theme works. Windows and Linux systems have a hosts file that can be edited by an administrator, but iPhones and Androids must be jailbroken or rooted to edit the hosts file.
Another benign usage is to redirect LAN clients to internal services (that also have an external name that would resolve to an external IP that might not be reachable from inside the network due to router/NAT issues, or that it would be inefficient to send out to the router only to turn it back to your servers) or to also resolve internal names only available in your Intranet or VPN (maybe if you have your AD tree as a subdomain of a public DNS).
What a superb and well written article! In recent weeks I have spent hours researching how to make a raspberrypi wireless server that will direct any and all user traffic to the index page of my website hosted on the raspberrypi.
While I have not yet fully achieved my goal I am very close and reading your article taught me more about dnsmasq in 20 mins than from the hours of reading other articles.
Written in a very concise yet easy to follow style your article is a pleasure to read.
Many thanks for posting.
Regards,
Des.
for this to actually be “malicious” you need to pose your DNS server as another DNS server, which the victim uses. else this is just child play. another way of providing making a positive use of this, on which i’m working on, is to set up dnsmasq on a ddwrt gateway router, to actually block a list of phishing/amlware domains by sending them to 127.0.0.1.
Is it possible to use dnsmasq to resolve various domain requests (fake) virtual “localhost” zones on a single computer where the requests are from clients on an Access Point that can rout to this server IP *.80. For example Like this: www.trump.com /var/www/html/trump.com | www.obama.com /var/www/html/obama.com/ | www.hillary.com /var/www/html/hillary.com ? I am using Ubuntu Server LTS 14.04. Thanks.
Is this an example of cache poisoning?
I have one question regarding dnsmasq. When i use dns masq for blocking all websites and allow few it just blocks my local network also. So no network browsing.. so please help me in this😅
I’d like to argue against “DNS spoofing can be used in many possible ways — unfortunately none of them can be used for anything good.” I’m using your technique on my DNSmasq system to intercept the multiple requests my iOS devices make on the Apple ntp server, re-directing them all to my own ntp server (a GPS-kitted Raspberry Pi). Saves bandwidth, less offset, less jitter – all good :-)
Hi, great article. Now I’m in trouble making iOS (tested on iPhone and iPad) to work with DnsMasq. Seems like it doesn’t query my “local” dns with (at least) Safari, nothing appear in the dnsmasq logs. I installed a DNS lookup app on my iPad and this one queries the local dns. I suspect Apple to use its own DNS. Any idea?
Hello it works for me great, but i have problem with facebook.com website it says connection error, but when i try to connect from other specified addresses it works, but it isn’t work for me especialy for facebook what’s wrong?
There are plenty of GOOD uses for dnsmasq;
– Block ads: send all known ad domains to a noop ip
– Intranet: serve requests for self-hosted domain names (you dont need to register them) and sub domains of any public or internal domain name
– Caching: great for connections that pay-per-quota in backwards countries like Australia and 3rd world countries where bandwidth is premium
– send some requests of known sites to a proxy (like squid) to potentially filter based on rules (think net nanny for children in your home or school network)
– threat detection: enable honeypot techniques for intrusion detection
And they’re just a few I came up with on the spot.. Imagine what a good conversation on the topic might uncover!
how can you do this configuration to return the same IP for ALL DNS requests?
Hi Philipp
It is a good article.
I am from a remote village in India, I travel frequently to my neighbouring countries for work (Nepal/SriLanka/Bangladesh etc)
The problem is that once I am out of my country, I can’t watch any Indian tv show/sports etc, so I have configured a linux server at my home and use wireguard vpn, but is does not give good streaming quality (my ISP is providing me 25 mbps plan). Can’t use data centre IP addresses as they all are blocked.
I came to know about DNS proxy, but don’t know how to configure it, can you help me do it with Dnsmasq ?
It’s a humble request .
Thanks.
Great piece of information, Thank you for sharing the updated one..