-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathct-dns-resolver.py
124 lines (110 loc) · 4.1 KB
/
ct-dns-resolver.py
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#!/usr/bin/env python3.8
# -*- coding: utf-8 -*-
#
#
import redis
from M2Crypto import X509
import time
import base64
import os
import dns.resolver
import xxhash
import time
import json
#r = redis.Redis(host='localhost', port=6379, db=15, socket_keepalive=True, socket_timeout=300)
r = redis.Redis(unix_socket_path="/tmp/redis.sock")
p = r.pubsub()
p.subscribe('ct-certs', ignore_subscribe_messages=False)
m = False
common_names = ['www', 'mail', '', 'host', 'router', 'ns', 'gw', 'server', 'gateway']
resolver = dns.resolver.Resolver()
resolver.timeout = 0.2
resolver.lifetime = 0.2
resolver.nameservers = ['185.194.93.128']
time_to_expire = 3000
def cache(value = None, time_to_expire = time_to_expire):
if value is None:
return False
r.set(hash_to_query, to_query)
r.expire(hash_to_query, time_to_expire)
return True
while True:
try:
m = p.get_message()
except:
r = redis.Redis(unix_socket_path="/tmp/redis.sock")
p = r.pubsub()
p.subscribe('ct-certs', ignore_subscribe_messages=False)
m = p.get_message()
if m:
if type(m['data']) is int:
#print("Skip non-related pub-sub message")
continue
cert_der = base64.b64decode(m['data'].rstrip())
#decode(cert_der = cert_der)
x509 = X509.load_cert_string(cert_der, X509.FORMAT_DER)
try:
subject = x509.get_subject().as_text()
except:
pass
try:
cAltName = x509.get_ext('subjectAltName').get_value()
except LookupError:
cAltName = ""
dns_entry = str(subject).split("=")[1]
if dns_entry.startswith('*'):
for common_name in common_names:
dns_to_query = dns_entry.replace("*", common_name)
hash_dns_to_query = xxhash.xxh128_hexdigest(dns_to_query)
if r.exists(hash_dns_to_query):
continue
cache(value=hash_dns_to_query)
if dns_to_query.startswith('.'):
dns_to_query = dns_to_query.replace(".", "")
r.ping()
answers = None
try:
answers = resolver.resolve(dns_to_query, 'AAAA')
except:
pass
#print("-- NX {}".format(dns_to_query))
if answers is None: continue
for rdata in answers:
pdns_cof_record = {}
ts = time.time()
pdns_cof_record['time_first'] = ts
pdns_cof_record['time_last'] = ts
pdns_cof_record['rrtype'] = 'AAAA'
pdns_cof_record['rrname'] = dns_to_query
pdns_cof_record['rdata'] = str(rdata)
pdns_cof_record['sensor_id'] = 'circl-feed-ipv6-ct-newlyseen-aaaa'
r.publish('circl-feed-ipv6-ct-newlyseen-aaaa', json.dumps(pdns_cof_record))
print(json.dumps(pdns_cof_record))
for altname in cAltName.split(','):
try:
to_query = altname.split(":")[1]
except:
continue
r.ping()
hash_to_query = xxhash.xxh128_hexdigest(to_query)
if r.exists(hash_to_query):
continue
cache(value=hash_to_query)
answers = None
try:
answers = resolver.resolve(to_query, 'AAAA')
except:
pass
if answers is None: continue
for rdata in answers:
pdns_cof_record = {}
ts = time.time()
pdns_cof_record['time_first'] = ts
pdns_cof_record['time_last'] = ts
pdns_cof_record['rrtype'] = 'AAAA'
pdns_cof_record['rrname'] = to_query
pdns_cof_record['rdata'] = str(rdata)
pdns_cof_record['sensor_id'] = 'circl-feed-ipv6-ct-newlyseen-aaaa'
r.publish('circl-feed-ipv6-ct-newlyseen-aaaa', json.dumps(pdns_cof_record))
print(json.dumps(pdns_cof_record))
time.sleep(0.0001)