├── README.md
├── old_attempts
├── requirements.txt
├── dns_server.py
└── dns_server_rebind.py
└── index.php
/README.md:
--------------------------------------------------------------------------------
1 | # HM-DNS
--------------------------------------------------------------------------------
/old_attempts/requirements.txt:
--------------------------------------------------------------------------------
1 | dnslib==0.9.6
--------------------------------------------------------------------------------
/index.php:
--------------------------------------------------------------------------------
1 |
2 |
3 | DNS Rebinding demo
4 |
5 |
15 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/old_attempts/dns_server.py:
--------------------------------------------------------------------------------
1 | # coding=utf-8
2 | """
3 | LICENSE http://www.apache.org/licenses/LICENSE-2.0
4 | Source: https://gist.github.com/andreif/6069838
5 | """
6 | import datetime
7 | import sys
8 | import time
9 | import threading
10 | import traceback
11 | import SocketServer
12 | from dnslib import *
13 |
14 | class DomainName(str):
15 | def __getattr__(self, item):
16 | return DomainName(item + '.' + self)
17 |
18 |
19 | D = DomainName('example.com')
20 | IP = '127.0.0.1'
21 | TTL = 60 * 1 #one minute
22 | PORT = 5053
23 |
24 | soa_record = SOA(
25 | mname=D.ns1, # primary name server
26 | rname=D.andrei, # email of the domain administrator
27 | times=(
28 | 201307231, # serial number
29 | 60 * 60 * 1, # refresh
30 | 60 * 60 * 3, # retry
31 | 60 * 60 * 24, # expire
32 | 60 * 60 * 1, # minimum
33 | )
34 | )
35 | ns_records = [NS(D.ns1), NS(D.ns2)]
36 | records = {
37 | D: [A(IP), AAAA((0,) * 16), MX(D.mail), soa_record] + ns_records,
38 | D.ns1: [A(IP)], # MX and NS records must never point to a CNAME alias (RFC 2181 section 10.3)
39 | D.ns2: [A(IP)],
40 | D.mail: [A(IP)],
41 | D.andrei: [CNAME(D)],
42 | }
43 |
44 |
45 | def dns_response(data):
46 | request = DNSRecord.parse(data)
47 |
48 | print request
49 |
50 | reply = DNSRecord(DNSHeader(id=request.header.id, qr=1, aa=1, ra=1), q=request.q)
51 |
52 | qname = request.q.qname
53 | qn = str(qname)
54 | qtype = request.q.qtype
55 | qt = QTYPE[qtype]
56 |
57 | if qn == D or qn.endswith('.' + D):
58 |
59 | for name, rrs in records.iteritems():
60 | if name == qn:
61 | for rdata in rrs:
62 | rqt = rdata.__class__.__name__
63 | if qt in ['*', rqt]:
64 | reply.add_answer(RR(rname=qname, rtype=QTYPE[rqt], rclass=1, ttl=TTL, rdata=rdata))
65 |
66 | for rdata in ns_records:
67 | reply.add_ns(RR(rname=D, rtype=QTYPE.NS, rclass=1, ttl=TTL, rdata=rdata))
68 |
69 | reply.add_ns(RR(rname=D, rtype=QTYPE.SOA, rclass=1, ttl=TTL, rdata=soa_record))
70 |
71 | print "---- Reply:\n", reply
72 |
73 | return reply.pack()
74 |
75 |
76 | class BaseRequestHandler(SocketServer.BaseRequestHandler):
77 |
78 | def get_data(self):
79 | raise NotImplementedError
80 |
81 | def send_data(self, data):
82 | raise NotImplementedError
83 |
84 | def handle(self):
85 | now = datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')
86 | print "\n\n%s request %s (%s %s):" % (self.__class__.__name__[:3], now, self.client_address[0],
87 | self.client_address[1])
88 | try:
89 | data = self.get_data()
90 | print len(data), data.encode('hex') # repr(data).replace('\\x', '')[1:-1]
91 | self.send_data(dns_response(data))
92 | except Exception:
93 | traceback.print_exc(file=sys.stderr)
94 |
95 |
96 | class TCPRequestHandler(BaseRequestHandler):
97 |
98 | def get_data(self):
99 | data = self.request.recv(8192).strip()
100 | sz = int(data[:2].encode('hex'), 16)
101 | if sz < len(data) - 2:
102 | raise Exception("Wrong size of TCP packet")
103 | elif sz > len(data) - 2:
104 | raise Exception("Too big TCP packet")
105 | return data[2:]
106 |
107 | def send_data(self, data):
108 | sz = hex(len(data))[2:].zfill(4).decode('hex')
109 | return self.request.sendall(sz + data)
110 |
111 |
112 | class UDPRequestHandler(BaseRequestHandler):
113 |
114 | def get_data(self):
115 | return self.request[0].strip()
116 |
117 | def send_data(self, data):
118 | return self.request[1].sendto(data, self.client_address)
119 |
120 |
121 | if __name__ == '__main__':
122 | print "Starting nameserver..."
123 |
124 | servers = [
125 | SocketServer.ThreadingUDPServer(('', PORT), UDPRequestHandler),
126 | SocketServer.ThreadingTCPServer(('', PORT), TCPRequestHandler),
127 | ]
128 | for s in servers:
129 | thread = threading.Thread(target=s.serve_forever) # that thread will start one more thread for each request
130 | thread.daemon = True # exit the server thread when the main thread terminates
131 | thread.start()
132 | print "%s server loop running in thread: %s" % (s.RequestHandlerClass.__name__[:3], thread.name)
133 |
134 | try:
135 | while 1:
136 | time.sleep(1)
137 | sys.stderr.flush()
138 | sys.stdout.flush()
139 |
140 | except KeyboardInterrupt:
141 | pass
142 | finally:
143 | for s in servers:
144 | s.shutdown()
--------------------------------------------------------------------------------
/old_attempts/dns_server_rebind.py:
--------------------------------------------------------------------------------
1 | """
2 | Source: https://github.com/marksteward/rebind
3 | """
4 | import datetime
5 | import sys
6 | import ConfigParser
7 | import time
8 | import threading
9 | import traceback
10 | import SocketServer
11 | from dnslib import *
12 | import socket
13 | import dns.resolver
14 |
15 |
16 | class DomainName(str):
17 | def __getattr__(self, item):
18 | return DomainName(item + '.' + self)
19 |
20 |
21 | defaults = {
22 | 'root': 'localhost',
23 | 'ttl': '60',
24 | 'ip': '',
25 | 'port': '5053',
26 | 'serialsuffix': '1',
27 | 'resolver': '8.8.8.8',
28 | }
29 | config = ConfigParser.ConfigParser(defaults)
30 | config.read(['rebind.conf'])
31 |
32 | D = DomainName(config.get('rebind', 'root'))
33 | if config.get('rebind', 'ip') == '':
34 | IP = socket.gethostbyname(D)
35 | else:
36 | IP = config.get('rebind', 'ip')
37 | TTL = config.getint('rebind', 'ttl')
38 | PORT = config.getint('rebind', 'port')
39 | SERIALSUFFIX = config.get('rebind', 'serialsuffix')
40 | RESOLVER = config.get('rebind', 'resolver')
41 |
42 | soa_record = SOA(
43 | mname=D.ns1, # primary name server
44 | rname=D.hostmaster, # email of the domain administrator
45 | times=(
46 | int(datetime.datetime.utcnow().strftime('%Y%m%d') + SERIALSUFFIX), # serial number
47 | 60 * 60 * 1, # refresh
48 | 60 * 60 * 3, # retry
49 | 60 * 60 * 24, # expire
50 | 60 * 60 * 1, # minimum
51 | )
52 | )
53 | ns_records = [NS(D.ns1), NS(D.ns2)]
54 | records = {
55 | D: [A(IP), AAAA((0,) * 16), MX(D.mail), soa_record] + ns_records,
56 | D.ns1: [A(IP)], # MX and NS records must never point to a CNAME alias (RFC 2181 section 10.3)
57 | D.ns2: [A(IP)],
58 | D.mail: [A(IP)],
59 | D.hostmaster: [CNAME(D)],
60 | }
61 |
62 | clients = {}
63 |
64 | def rchop(string, ending):
65 | if string.endswith(ending):
66 | return string[:-len(ending)]
67 | return string
68 |
69 | def dns_response(data):
70 | request = DNSRecord.parse(data)
71 |
72 | print request
73 |
74 | reply = DNSRecord(DNSHeader(id=request.header.id, qr=1, aa=1, ra=1), q=request.q)
75 |
76 | qname = request.q.qname
77 | qn = rchop(str(qname), '.')
78 |
79 | qtype = request.q.qtype
80 | qt = QTYPE[qtype]
81 |
82 | if qn in records:
83 | for rdata in records[qn]:
84 | rqt = rdata.__class__.__name__
85 | if qt in ['ANY', rqt]:
86 | reply.add_answer(RR(rname=qname, rtype=getattr(QTYPE, rqt), rclass=1, ttl=TTL, rdata=rdata))
87 |
88 | if qt in ['ANY']:
89 | for rdata in ns_records:
90 | reply.add_ar(RR(rname=D, rtype=QTYPE.NS, rclass=1, ttl=TTL, rdata=rdata))
91 |
92 | reply.add_auth(RR(rname=D, rtype=QTYPE.SOA, rclass=1, ttl=TTL, rdata=soa_record))
93 |
94 | elif not qn.endswith('.' + D):
95 | pass
96 |
97 | else:
98 | data = rchop(qn, '.' + D)
99 | if '.' not in data:
100 | # Main page - not rebound
101 | reply.add_answer(RR(rname=qname, rtype=QTYPE.A, rclass=1, ttl=TTL, rdata=A(IP)))
102 | else:
103 | target, client = data.rsplit('.', 1)
104 | if '-' in client:
105 | op, client = client.split('-', 1)
106 | op = op.upper()
107 |
108 | if op in ['N', 'R']:
109 | clients[client] = op
110 |
111 | if client not in clients:
112 | clients[client] = 'N' # normal
113 |
114 | print 'Client %s is currently %s' % (client, clients[client])
115 | if clients[client] == 'N':
116 | reply.add_answer(RR(rname=qname, rtype=QTYPE.A, rclass=1, ttl=15, rdata=A(IP)))
117 | else:
118 | try:
119 | print 'Looking up %s' % target
120 | for rdata in dns.resolver.query(target, 'A'):
121 | reply.add_answer(RR(rname=qname, rtype=QTYPE.A, rclass=1, ttl=15, rdata=A(rdata.address)))
122 | except Exception:
123 | pass
124 |
125 | print "---- Reply:\n", reply
126 |
127 | return reply.pack()
128 |
129 |
130 | class BaseRequestHandler(SocketServer.BaseRequestHandler):
131 |
132 | def get_data(self):
133 | raise NotImplementedError
134 |
135 | def send_data(self, data):
136 | raise NotImplementedError
137 |
138 | def handle(self):
139 | now = datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')
140 | print "\n\n%s request %s (%s %s):" % (self.__class__.__name__[:3], now, self.client_address[0],
141 | self.client_address[1])
142 | try:
143 | data = self.get_data()
144 | print len(data), data.encode('hex')
145 | self.send_data(dns_response(data))
146 | except Exception:
147 | traceback.print_exc(file=sys.stderr)
148 |
149 |
150 | class TCPRequestHandler(BaseRequestHandler):
151 |
152 | def get_data(self):
153 | data = self.request.recv(8192)
154 | sz = int(data[:2].encode('hex'), 16)
155 | if sz < len(data) - 2:
156 | raise Exception("Wrong size of TCP packet")
157 | elif sz > len(data) - 2:
158 | raise Exception("Too big TCP packet")
159 | return data[2:]
160 |
161 | def send_data(self, data):
162 | sz = ('%04x' % len(data)).decode('hex')
163 | return self.request.sendall(sz + data)
164 |
165 |
166 | class UDPRequestHandler(BaseRequestHandler):
167 |
168 | def get_data(self):
169 | return self.request[0]
170 |
171 | def send_data(self, data):
172 | return self.request[1].sendto(data, self.client_address)
173 |
174 |
175 | if __name__ == '__main__':
176 | print "Starting nameserver..."
177 |
178 | servers = [
179 | SocketServer.ThreadingUDPServer(('', PORT), UDPRequestHandler),
180 | SocketServer.ThreadingTCPServer(('', PORT), TCPRequestHandler),
181 | ]
182 | for s in servers:
183 | thread = threading.Thread(target=s.serve_forever) # that thread will start one more thread for each request
184 | thread.daemon = True # exit the server thread when the main thread terminates
185 | thread.start()
186 | print "%s server loop running in thread: %s" % (s.RequestHandlerClass.__name__[:3], thread.name)
187 |
188 | try:
189 | while 1:
190 | time.sleep(1)
191 | sys.stderr.flush()
192 | sys.stdout.flush()
193 |
194 | except KeyboardInterrupt:
195 | pass
196 | finally:
197 | for s in servers:
198 | s.shutdown()
--------------------------------------------------------------------------------