Giter Club home page Giter Club logo

polardns's Introduction

PolarDNS logo

PolarDNS is a specialized authoritative DNS server written in Python 3.x, which allows the operator to produce fully custom DNS responses, suitable for DNS protocol testing purposes.

_

See the attached BlackHat MEA 2023 presentations (including BONUS slides) for a detailed information.

PolarDNS can be used for testing of:

  • DNS resolvers (server-side)
  • DNS clients
  • DNS libraries
  • DNS parsers and dissectors
  • any software handling DNS information

It supports both UDP and TCP protocols, and it gives the operator full control over the DNS protocol layer.

PolarDNS server can produce variety of non-standard and non-compliant DNS responses, DNS responses violating the RFC specifications, including highly abnormal and malformed DNS responses.

This can be useful for:

  • Functional testing
  • RFC compliance
  • Vulnerability research

Installation

  1. Install Python 3.11 or newer.
  2. (Optional) Edit the polardns.toml configuration file and add your domain and nameserver IP addresses.

Running PolarDNS

Make sure you are using Python 3.11 or newer to run the PolarDNS server:

python polardns.py

Alternatively, you can also deploy PolarDNS as a Docker image for which you can use the following steps.

Building and running PolarDNS Docker image

  1. To build the Docker image for PolarDNS:
docker build -t polar_dns .
  1. To run the PolarDNS container:
docker run -d --name polar_dns_container -p 53:53/tcp -p 53:53/udp polar_dns

Working with PolarDNS

By default, the server starts listening on all interfaces on UDP and TCP port 53 (0.0.0.0:53), ready to answer DNS queries.

You can test it locally by asking the following sample query, which should always resolve to something.

Ask in UDP mode:

dig always.yourdomain.com @127.0.0.1

Ask in TCP mode:

dig always.yourdomain.com @127.0.0.1 +tcp

You should receive A record with the 2.3.4.5 IP address, similarly like in this screenshot:

PolarDNS example usage

This indicates that the server is working properly.

Main concept

By asking the PolarDNS server to resolve something, you are essentially giving it instructions how it should respond to you. This means that you, the client, dictate the PolarDNS server what kind of response it should produce for you.

For instance, consider the following query:

dig always.ttl2000000000.slp1500.yourdomain.com @127.0.0.1

You should, again, receive A record with the 2.3.4.5 IP address, but this time with TTL of 2,000,000,000 (63.4 years) and after a delay of 1.5 seconds:

PolarDNS custom TTL and latency

In the above example, we have used the always basic feature (which always resolves to something), and combined it with the ttl modifier to adjust the TTL value and the slp modifier to wait before sending the response out.

Main functionalities (features and response modifiers)

PolarDNS has the following main functionalities:

  1. Features: These can produce various DNS responses. Most features have parameters, meaning that it is possible to adjust their behavior to produce variety of different DNS responses.
  2. Response modifiers: These can further modify the DNS responses coming out from the PolarDNS server. Modifiers are independent on the selected feature and can be combined freely.

There are around 60 different features and 11 response modifiers currently implemented. By using different features and combining them together with different response modifiers, it is possible to produce countless variants of given response.

See the included catalogue of all implemented features and response modifiers.

This gives PolarDNS capacity to produce highly unusual, abnormal, and even malformed DNS responses, allowing the operator to see how the receiving side handles such situations and whether the receiving side is technically robust and mature.

Some examples of DNS responses which PolarDNS can produce contain:

  • Alias (CNAME) chains and alias loops
  • DNS header malformations (ID, Flags, number of sections)
  • Injection of unsolicited records (cache poisoning)
  • Injection of arbitrary bytes of arbitrary lengths
  • Incomplete / empty / NULL byte(s) responses
  • Compression issues (loops, invalid pointers)
  • Slowly transmitted chunked responses
  • Illegal labels or domain name lengths
  • Arbitrary number of TXT records of arbitrary size
  • Packet length manipulations (TCP)
  • Etc.

These can lead to discovery of various vulnerabilities such as:

  • Sloth domain attacks
  • Phantom domain attacks
  • Domain lock-up attacks
  • Cache poisoning
  • Resource exhaustion
  • Crashes, DoS

See the BlackHat MEA 2023 presentations (including BONUS slides) for more details, many more examples and use-cases.

Testing of recursive DNS resolvers

Here's a high-level overview of what you need in order to start testing recursive DNS servers.

  1. Purchase a domain for your tests e.g., example123.com
  2. Get 2 Linux VPS instances with public and static IP addresses - these will be your nameservers.
  3. Deploy the PolarDNS server on both of your VPS instances (nameservers)
  4. Make sure to edit the polardns.toml configuration file and change your domain name and nameserver IP addresses
  5. In the domain registrar, select to manage the domain using your own nameservers (you will need to specify 2 public IPs of your servers - primary and secondary NS)

Now your infrastructure should be ready for testing of any recursive DNS resolver of your choice.

Testing process breakdown

In order to start testing a target DNS recursive resolver, you have to target your queries to the target DNS resolver, e.g.

dig always.example123.com @<TARGET-RESOLVER-IP>

For example, to test the CloudFlare public DNS:

dig always.example123.com @1.1.1.1

During the resolution, the target DNS resolver will contact your authoritative PolarDNS nameservers (managing your example123.com testing domain) to resolve the query.

One of your PolarDNS servers will respond to the target DNS resolver. The target DNS resolver will obtain the response from PolarDNS and will parse it and process it. Afterwards, the resolver will send you (the client) the answer.

By instructing the DNS resolver to resolve various subdomains under your example123.com domain, you can effectively test the behavior of the DNS resolver and see how it handles various unexpected situations (responses).

For instance, how does it handle a situation when it obtains a malformed DNS response, a response with an injected record, or a record containing illegal characters, and what kind of answer does it ultimately send to you, the client?

Adding new features

Adding new features to PolarDNS is essential.

PolarDNS allows you to relatively easily implement a new idea, a test case, a feature or a PoC, without a need of implementing your own DNS server.

All you need is a basic / intermediate Python knowledge and knowing a bit of DNS protocol too.

Both can be learned on the go by looking on the PolarDNS code and by simply copying and modifying some of the existing features.

Testing locally using dig / host / nlsookup and Wireshark is of essence here.

The test/test.sh script has been tested on a machine running dig 9.18.10.

Plus, the links below can help with the DNS protocol.

Links

Here are some great resources which can aid in the testing process.

DNS Protocol related links:

DNS servers:

polardns's People

Contributors

ivan-jedek avatar jrihds avatar mpdevilleres avatar stakelovelace avatar turroks avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

polardns's Issues

Proposal: Replace yaml with toml

as of python 3.11 toml parser is part of standard library.

what does it mean for the project is as follow.

  • remove third party dependency (PyYAML)
  • improve readability of configuration reference

current yaml

#########################
# main settings

domain: yourdomain.com
ns1: 127.0.0.1
ns2: 127.0.0.1

#########################
# other configurables

# server address
listen_addr: 0.0.0.0:53

# debug (0 or 1)
debug: 0

# default TTL
ttl: 60

# default latency (in ms)
sleep: 0

# a 3rdparty domain which we don't own
a3rdparty_domain: whatever.com

# known DNS resolvers / clients connecting to us
known_servers:
  127.0.0.1:      localhost
  1.2.3.4:        powerdns1
  1.2.3.5:        powerdns2
  2.3.4.5:        bind-test1
  4.5.6.7:        msdns-test1

#########################

will look like with toml

[main]
domain = 'yourdomain.com'
ns1 = '127.0.0.1'
ns2 = '127.0.0.1'

# server address
listen_addr = '0.0.0.0:53'

# debug (0 or 1)
debug = 0

# default TTL
ttl = 60

# default latency (in ms)
sleep = 0

# a 3rdparty domain which we don't own
a3rdparty_domain = 'whatever.com'

known_servers = """
127.0.0.1   localhost
1.2.3.4     powerdns1
1.2.3.5     powerdns2
2.3.4.5     bind-test1
4.5.6.7     msdns-test1
"""

just a little caveat this will not work to python 3.10 below. so it will be a good idea to update the readme stating this only works with python 3.11 and above.

PR: #3

Ethernet Padding Bug for empty1 test

Hello
I think I have found an Ethernet padding test bug. For me, the dig command for the 'empty1.yourdomain.com' test returns a Warning banner for queries sent across the internet to a remote instance of PolarDNS, but not for queries to a localhost instance of PolarDNS.

Internet bound query:

$ dig empty1.yourdomain.com @<remote-ip> +tries=1 +timeout=3 -p 53
;; Warning: short (< header size) message received
;; communications error to <remote-ip>#53: timed out

; <<>> DiG 9.18.10 <<>> empty1.yourdomain.com @<remote-ip> +tries=1 +timeout=3 -p 53
;; global options: +cmd
;; no servers could be reached

Local query:

$ dig empty1.yourdomain.com @127.0.0.1 +tries=1 +timeout=3 -p 53
;; communications error to 127.0.0.1#53: timed out

; <<>> DiG 9.18.10 <<>> empty1.yourdomain.com @127.0.0.1 +tries=1 +timeout=3 -p 53
;; global options: +cmd
;; no servers could be reached

This means the md5sum is different so the test might fail. I've checked this difference in Wireshark and I think it is due to extra Ethernet frame padding on the internet query which isn't present on the loopback query. The Warning could be stripped off using the grep -v command in test.sh but the hashes for other 'empty' tests would need to be adjusted to accommodate this.

test md5sum

Hello
Firstly, this is a cool project thank you for making it!
I am trying to run the tests but the md5sum produced by my dig is different than the md5sum that is specified in the test file. For example:
runtest "cgena.1.${domain}"
is supposed to produce the md5sum:
"8bee2a94ebe12cee620a8bfa18169b1d"
but I get something different.
Are you able to run this test in debug mode on your system and share the /tmp/ text file output that produces the target hash? I can then use this to help me troubleshoot why my system is different.
Thank you

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.