Abusing DNS, Part 1: How does DNS do what it do?
DNS is one of the protocols that make the internet possible. In many ways DNS is the phone book of the internet. DNS turns the domain you are trying to get to into the IP address your computer needs to get there. DNS is robust network of inter connected systems used to translate human readable domains into the IP address, but it can be much more.
In this series we will use rust to build a key-value store that uses DNS to transfer data between our custom DNS server and client. Future code will be available on Github.
Let's start by looking at the protocol, we will then build a simple DNS server/client application and finally take advantage of what we know to build a key value store.
DNS requests, how do they work?

It is important to know that computers don't think in strings like people (www.google.com) they think in binary 10001110111110100100100000100100
. Humans are really bad at thinking in binary so we make computers to backflips to manage all of that for us.
$ dig +short @1.1.1.1 www.google.com
142.250.69.228
Astute readers like yourself probably notice that isn't binary. We humans are so bad at binary we have computers encode
the numbers (we wont remember) into more human readable forms, thus 142.250.69.228
.
>>> socket.gethostbyname('www.google.com')
>>> socket.inet_aton('142.250.69.228')
b'\x8e\xfaE\xe4'
>>> struct.unpack('>I', b'\x8e\xfaE\xe4')
(2398767140,)
>>> bin(2398767140)
'0b10001110111110100100100000100100'
We will utilize data encodings to our advantage later in this series. Back to DNS...
What is happening when you make a DNS request?
$ dig www.google.com
; <<>> DiG 9.18.28-1~deb12u2-Debian <<>> www.google.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5248
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;www.google.com. IN A
;; ANSWER SECTION:
www.google.com. 300 IN A 142.250.72.36
;; Query time: 28 msec
;; SERVER: 192.168.0.1#53(192.168.0.1) (UDP)
;; WHEN: Thu Feb 20 09:10:07 MST 2025
;; MSG SIZE rcvd: 59
The above dig
command asked "what is the IPv4 address for www.google.com".
While a very simple command on its face, a very complex set of things just happened.
First my system looked at it's local resolver settings and found 192.168.0.1
as my local DNS server. Next a UDP request with an A
question was sent to 192.168.0.1
. From here the server checked to see if it knew an IP for www.google.com
and if that IP address was still valid by checking the TTL
. If 192.168.0.1
did not know the answer it then looked for it's own resolver and sent a request asking the same question. I'm simplifying here, but that continues until we get an answer or don't have any other server to ask. Finally the answers are sent all the way back and my system has the IP.

Well that is pretty cool. We ask a server we don't control to send requests for us and get responses from our own servers... Wait, what else can we ask for?
Glad you asked! There are many different questions you can ask. The server responds with records. We already saw the most common A
query which will return an A
record. The A
query is so common, in fact, dig
assumes that is what you meant. If you want to be more explicit you can specify the record type. Let's look at a few different query types.
Later in the series we will be going further into query and record types, for now, know that there are multiple record types that contain different data types. A
records are IPv4, AAAA
(quad A) records contain IPv6 addresses. TXT
records have text data. MX
(Mail Exchanger) have the mail server. These are the most common, there are a whole bunch (go read the wiki pages and donate to wiki foundation while you are there).
That is it for now. Up next we will start our rust project and build a UDP DNS server that can respond to various query types with our own DNS records.
Subscribe, follow, etc if you want to see more.