DOT/DOH service detection and recognition

No return, Acacia is sent to Shanhai!

Due to compliance requirements, I need to detect which hosts run DOT and DOH services on the host, and nmap can’t identify the fingerprints of these two services temporarily, but I can only do it myself. DOT (DNS over TLS), DOH (DNS over HTTPS), both of which are DNS encryption services, because I was also the first to contact them, so it took some time to access the information, recorded here.

Why do I need DNS encryption?

DNS is the most basic protocol in the Internet. It can resolve domain names into IP addresses and has a wide range of uses. If the dns parsing request process is not encrypted, after the intermediary intercepts the dns request traffic, it can hijack, phish, and monitor the user’s browsing site.

DOH VS DOT

The two are somewhat similar and are used to encrypt dns request traffic. The IETF has defined DNS on HTTPS as RFC8484 and defines it as RFC7858 and RFC8310 via TLS. DOT uses TCP as the basic connection protocol and is layered through TLS encryption and authentication. The default port for DOH is 443, based on the HTTPS protocol; the default port for DOT is 853, based on the tcp protocol.

How to identify DOT and DOH services

As mentioned earlier, DOT defaults to port 853, so just scan the host to open port 853, or scan the full port to identify which ports are domain services. However, DOH defaults to port 443. The nmap probe returns the https service fingerprint, so it is difficult to judge and identify. The only way is to simulate the dns request of the DOH standard protocol and see if the parsing result can be returned normally. However, it is very difficult to construct a standard request package to study specific protocols and principles. Fortunately, someone has written a library in this area in python.

doh-proxy

Official PYPI: https://pypi.org/project/doh-proxy/#doh-client
Doh-proxy is a library dedicated to proxy doh. It is divided into server tools and client tools. After installation, it comes with doh-proxy and doh-client. Focus on doh-client, you can simulate using doh. Encrypted dns request. Currently only supports >python3.5, you can install it directly with pip.

1
$ pip install doh-proxy

Use command

1
$ doh-client --domain 1.1.1.1 --qname thief.one --dnssec


If no error is reported, the port 443 of 1.1.1.1 supports the doh service. If 1.1.1.1 is replaced with the host IP to be identified, it can be identified whether the port 443 of the host provides the DOH service. If you want to scan the host in batches, you can modify the client.py file in the site-packages/dohproxy directory, like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import asyncio
import dns.message
import time
import signal
from dohproxy import client_protocol, utils
class Client(client_protocol.StubServerProtocol):
def on_answer(self, addr, msg):
try:
print(dns.message.from_wire(msg))
except Exception:
self.logger.exception(msg)
def parse_args():
parser = utils.client_parser_base()
parser.add_argument(
'--qname',
default='example.com',
help='Name to query for. Default [%(default)s]',
)
parser.add_argument(
'--qtype',
default='AAAA',
help='Type of query. Default [%(default)s]',
)
parser.add_argument(
'--dnssec',
action='store_true',
help='Enable DNSSEC validation.'
)
return parser.parse_args()
def build_query(args):
dnsq = dns.message.make_query(
qname=args.qname,
rdtype=args.qtype,
want_dnssec=args.dnssec,
)
dnsq.id = 0
return dnsq
def func_time(timeout=10):
def run_func(func):
def handler(signum, frame):
raise AssertionError
def wrapper(*args,**kwargs):
try:
signal.signal(signal.SIGALRM, handler)
signal.alarm(timeout)
return func(*args,**kwargs)
except AssertionError:
print(func.__name__+" Function run Timeout","Warning")
return wrapper
return run_func
def main_sync(args):
logger = utils.configure_logger('doh-client', level=args.level)
client = Client(args=args, logger=logger)
loop = asyncio.get_event_loop()
loop.run_until_complete(client.make_request(None, build_query(args)))
class test():
domain = "1.1.1.1"
qname = "thief.one"
port = 443
level = "DEBUG"
qtype = "AAAA"
dnssec = True
insecure = False
cafile = None
remote_address = None
uri = "/dns-query"
post = False
debug = False
@func_time(timeout=10)
def main(domain):
args = test()
args.domain = domain
try:
main_sync(args)
return True
except Exception as e:
print (e)
return False
if __name__ == '__main__':
domain_list = ["1.1.1.1","2.2.2.2"]
for domain in domain_list:
print(main(domain))

Then run the python client.py file.

Reference article

https://www.racent.com/blog/dns-over-tls-vs-dns-over-https/
https://program-think.blogspot.com/2018/10/Comparison-of-DNS-Protocols.html
https://zhuanlan.zhihu.com/p/47170371

本文标题:DOT/DOH service detection and recognition

文章作者:nmask

发布时间:2019年07月09日 - 17:07

最后更新:2019年07月11日 - 17:07

原始链接:https://thief.one/2019/07/09/1/en/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

nmask wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客!
坚持原创技术分享,您的支持将鼓励我继续创作!

热门文章推荐: