Example #1
0
def clean_dns(domain, verbose=True):
    target_addr = ('8.8.8.8', 53)
    client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    send_time = time.time()
    client.sendto(DNSRecord.question(domain).pack(), target_addr)
    client.settimeout(1)
    cnt = 0
    ret = ''
    if verbose:
        print('start to query {}'.format(domain))
    try:
        while True:
            cnt += 1
            response, _ = client.recvfrom(1024)
            recv_time = time.time()
            ret = [str(x.rdata) for x in DNSRecord.parse(response).rr if x.rtype == 1]
            if verbose:
                print(
                    '    {}th arrived, cost {}ms, response is {}'.format(cnt, int((recv_time - send_time) * 1000), ret))
    except socket.timeout as e:
        pass
    finally:
        client.close()
    if verbose:
        print('query end. result is {}'.format(ret))
    return ret
Example #2
0
def DNSGuard(ip, port, blacklist):
    octetsize = 512
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.bind((ip, port))
    data = None
    addr = None
    R = resolver.Resolver()
    logging.debug("DNSGuard SERVER ACTIVE ON {}:{}".format(ip, port))
    while True:
        data, addr = sock.recvfrom(octetsize)
        packet = DNSRecord.parse(data)
        question = packet.get_q()
        fqdn = FQDN(question)
        logging.debug("Query: {}".format(str(packet)))
        if allowed(fqdn, blacklist):
            try:
                zones = R.resolveZone([fqdn])
                logging.debug("Allowed: {}".format(zones))
                reply = packet.reply()
                for zone in zones:
                    reply.add_answer(*RR.fromZone(zone))
                    sock.sendto(DNSRecord.pack(reply), addr)
            except Exception as e:
                logging.error("Error: {}".format(e))
            pass
    pass
Example #3
0
    def query(self, qname, qtype="A", qclass="IN"):
        qtype = QTYPE.reverse[qtype]
        qclass = CLASS.reverse[qclass]

        q = DNSRecord(q=DNSQuestion(qname, qtype, qclass))

        self.fire(write((self.server, self.port), q.pack()))
Example #4
0
    def resolve_mdns(self, request, handler, rewrite=None):

        sock = get_mdns_socket()
        d = DNSRecord(DNSHeader(id=0, bitmap=0), q=request.q)
        sock.sendto(d.pack(), (nameserver4, 5353))
        # sock.sendto(d.pack(), (nameserver6, 5353))
        qname = request.q.qname
        if rewrite:
            request.q.qname = rewrite
        reply = request.reply()

        while True:
            buf, remote = sock.recvfrom(8192)
            d = DNSRecord.parse(buf)
            success = False
            if (d.header.aa == 1) and (d.header.a > 0):
                for response in d.rr:
                    if str(response.rname) == qname:
                        success = True
                        response.rclass = CLASS.IN

                        # These two lines can be deleted if we dont want the original response
                        reply.add_answer(response)
                        response = RR.fromZone(response.toZone())[0]

                        if rewrite:
                            response.rname = rewrite
                            reply.add_answer(response)
                        # print(reply)
            if success:
                break
        return reply
Example #5
0
def run():
    cache = load_cache()
    sock = create_connection(53)
    while True:
        data, addr = sock.recvfrom(2048)
        try:
            dns_record = DNSRecord.parse(data)
        except DNSError:
            continue
        add_record(dns_record, cache)
        if not dns_record.header.qr:
            response = get_response(dns_record, cache)
            try:
                if response:
                    response = response.pack()
                else:
                    response = dns_record.send(GOOGLE)
                    add_record(DNSRecord.parse(response), cache)
                sock.connect(addr)
                sock.sendall(response)
                sock.close()
                sock = create_connection(53)
            except:
                pass
        if cache:
            upload_cache(cache)
Example #6
0
def test_dns():
    server = SocketServer.UDPServer(('', 0), dns.DNSHandler)
    server.cfg = ModuleConfig('dns.conf').cfg
    thread.start_new_thread(server.serve_forever, ())
    resp = DNSRecord(q=DNSQuestion("google.com")).send(
                     "127.0.0.1", port=server.socket.getsockname()[1])
    assert str(resp.get_a().rdata) == socket.gethostbyname(socket.gethostname())
Example #7
0
def main():
    print("Starting DNS Server")
    print("Loading cache from disk...")
    global cache
    cache = load_cache_from_disk(CACHE_FILE_NAME)
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.bind(("localhost", 53))
    while True:
        data_in_socket, _, _ = select([sock], [], [], 1)
        if not data_in_socket:
            continue
        conn, addr = sock.recvfrom(2048)
        clear_old_cache(cache)
        try:
            dns_record = DNSRecord.parse(conn)
        except DNSError:
            print("Can't parse DNS record")
            continue
        cache_records(dns_record, cache)
        if not dns_record.header.qr:
            response = find_record_in_cache(dns_record, cache)
            if response:
                response = response.pack()
            else:
                try:
                    response = dns_record.send(forward_server)
                    cache_records(DNSRecord.parse(response), cache)
                except (OSError, DNSError):
                    print("Server " + forward_server + "unavailable")
            sock.sendto(response, addr)
        save_cache_to_disk(cache, CACHE_FILE_NAME)
Example #8
0
    def _collect_all_rrs_from_ns(self, user_data_address: str,
                                 user_data_domain: str,
                                 ns_of_domain: str) -> None:
        # 'A' and "AAAA" questions
        for query_type in ('A', "AAAA"):
            resolved_question = self._resolve_question(
                DNSRecord.question(user_data_domain, query_type), ns_of_domain)
            for resource_record in resolved_question.rr:
                self._add_to_cache(user_data_domain, query_type,
                                   str(resource_record.rdata))

        # "NS" question
        resolved_question = self._resolve_question(
            DNSRecord.question(user_data_domain, "NS"), ns_of_domain)
        for resource_record in resolved_question.rr:
            self._add_to_cache(user_data_address, "NS",
                               str(resource_record.rdata))

        # "PTR" question
        if user_data_address == user_data_domain:
            return

        inverse_domain_from_ip = '.'.join(
            user_data_address.split('.')[::-1]) + '.in-addr.arpa'
        resolved_question = self._resolve_question(
            DNSRecord.question(inverse_domain_from_ip, "PTR"), ns_of_domain)
        for resource_record in resolved_question.rr:
            self._add_to_cache(user_data_address, "PTR",
                               str(resource_record.rdata))
Example #9
0
		def get_reply(self,data):
			global dns_cache
			global args
			host,port = self.server.resolver.address,self.server.resolver.port
			request = DNSRecord.parse(data)

			domain=str(request.q.qname)
			if domain in dns_cache:
				if time.time()<dns_cache[domain][0]:
					if args is not None and args.verbose:
						display("[i] domain %s served from cache"%domain)
					rep=request.reply()
					rep.add_answer(*dns_cache[domain][1])
					return rep.pack()
			if args is not None and args.verbose:
				display("[i] domain %s requested using TCP server %s"%(domain, args.dns_server))
			data = struct.pack("!H",len(data)) + data
			response = send_tcp(data,host,port)
			response = response[2:]
			reply = DNSRecord.parse(response)
			#print(repr(reply))
			ttl=3600
			try:
				ttl=reply.rr[0].ttl
			except Exception:
				try:
					ttl=reply.rr.ttl
				except Exception:
					pass
			dns_cache[domain]=(int(time.time())+ttl, reply.rr)
			if len(dns_cache)>DNS_CACHE_SIZE:
				dns_cache.popitem(last=False)
			return response
Example #10
0
File: dnsd.py Project: lmyzzu/etc
 def resolve(self, request, handler):
     try:
         proxy_r = request.send(self.address, self.port, tcp=True)
     except socket.error:
         return DNSRecord()
     reply = DNSRecord.parse(proxy_r)
     return reply
Example #11
0
    def switched_to(self, environment):
        rtype, current_val = self.current_value
        wanted_val = self.environments[environment]

        if set(current_val) != set(wanted_val):
            raise BespinError("The current value in ultradns is different than the specified value for this environment"
                , environment = environment
                , ultradns_has = current_val
                , specified = wanted_val
                )

        log.info("Seeing if %s has switched to %s(%s)", self.domain, environment, current_val)
        if rtype == "A":
            info = socket.getaddrinfo(self.domain, 80)
            found = [sockaddr[0] for _, _, _, _, sockaddr in info]
            if set(found) == set(current_val):
                return True
            else:
                log.info("Current value is %s", list(set(found)))

        if rtype == "CNAME":
            answer = DNSRecord.parse(DNSRecord(q=DNSQuestion(self.domain, QTYPE.CNAME)).send("8.8.8.8", 53)).short()
            if not answer:
                raise BespinError("couldn't resolve the domain", domain=self.domain)

            if answer == current_val[0]:
                return True
            else:
                log.info("Current value is %s", answer)

        return False
Example #12
0
    def query(self, qname, qtype="A", qclass="IN"):
        qtype = QTYPE.reverse[qtype]
        qclass = CLASS.reverse[qclass]

        q = DNSRecord(q=DNSQuestion(qname, qtype, qclass))

        self.fire(write((self.server, self.port), q.pack()))
Example #13
0
def take_from_cache(key, ident):
    name = '.'.join(key.split('.')[:-1])
    header = DNSHeader(id=ident, aa=0, qr=1, ra=1, rcode=0)
    question = DNSQuestion(name, REV_TYPES_DICT[key.split('.')[-1]])
    answer = DNSRecord(header=header, q=question)
    for rec in cache[key]:
        answer.add_answer(rec)
    return answer.pack()
Example #14
0
def getRecord(host, query):
    d = DNSRecord.question(query, "A")
    check, responce = queryNode(d.pack(), (host, 53))
    try:
        record = DNSRecord.parse(responce)
        return record
    except DNSError, e:
        return False
Example #15
0
    def _reply(self, rec, addr=None):
        reply = DNSRecord(DNSHeader(id=rec.header.id, qr=1, aa=1, ra=1), q=rec.q)
        if addr:
            qtype = QTYPE.A if QTYPE.A == rec.q.qtype else QTYPE.AAAA
            reply.add_answer(RR(rec.q.qname, qtype, rdata=A(addr)))

        rep = reply.pack()
        return rep
Example #16
0
 def _reply(self, rec, addrs=None):
     reply = DNSRecord(DNSHeader(id=rec.header.id, qr=1, aa=1, ra=1), q=rec.q)
     if addrs:
         if not isinstance(addrs, list):
             addrs = [addrs]
         for addr in addrs:
             reply.add_answer(RR(rec.q.qname, QTYPE.A, rdata=A(addr)))
     return reply.pack()
Example #17
0
def send_req_to_server(server_addr, name):
    client_req = DNSRecord(DNSHeader(id=ID), q=DNSQuestion(name, getattr(QTYPE, "A")))
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.connect((server_addr, 53))
    s.send(client_req.pack())
    resp = s.recv(2048)
    dns_resp = DNSRecord.parse(resp)
    logging.warning("Got answer from server {}".format(dns_resp))
Example #18
0
    def validate_and_dns_name_setup(self, dns_request, client_address):
        logger.debug(f"[Process : Validate & Dns Name Setup]")  ## Debugging
        validation_result = False
        validation_info = "Improper/Forged Dns Request"
        custom_parsed_dns_response = None
        try:
            parsed_dns_request = DNSRecord.parse(dns_request)
            req_dns_name = str(parsed_dns_request.questions[0].qname)
            req_dns_type = int(parsed_dns_request.questions[0].qtype)
            if req_dns_name in self.dns_name.keys():
                dns_name_to_set = self.dns_name[req_dns_name]
                logger.debug(f"IP ADDR LIST: {dns_name_to_set.split(',')}")
                custom_parsed_dns_response = DnsBuilder.create_dns_response(
                    parsed_dns_request=parsed_dns_request,
                    req_dns_name=req_dns_name,
                    req_dns_type=req_dns_type,
                    ip_address_list=dns_name_to_set.split(","))
                validation_info = ""
            else:
                validation_result = True
                validation_info = ""
                self.domain_name_extractor(
                    requested_domain_name=req_dns_name,
                    requested_domain_name_type=req_dns_type
                )  #Extract Proper Info From the Dns Requested Domain

        except (dnslib.buffer.BufferError,
                dnslib.dns.DNSError) as dns_parsing_error:
            logger.error(
                f"[Process: Validation By using parse()] "
                f"[Error: DnsRecord.parse() Exception, Data Received is INCORRECT, "
                f"Exception: [{dns_parsing_error}]",
                exc_info=True)
            # Enable StackTrace in Logs
            validation_info = validation_info + f", Exception: [{dns_parsing_error}]"
        except Exception as all_exception:
            logger.error(
                f"[Process: Validation By using parse()] "
                f"[Error: Unknown Exception] "
                f"Exception: [{all_exception}]",
                exc_info=True)
            # Enable StackTrace in Logs
            validation_info = validation_info + f", Exception: [{all_exception}]"
        finally:
            if validation_result:
                logger.debug(
                    f"Process Complete Validation INFO: [{validation_info}, {custom_parsed_dns_response}]"
                )
                return validation_result
            else:
                if validation_info == "":
                    self.send_response_to_client(
                        client_address=client_address,
                        raw_dns_response=DNSRecord.pack(
                            custom_parsed_dns_response),
                        status_tag=validation_info)
                return None
Example #19
0
    def send_request(self, id, server_ip, domain, dns_type):
        try:
            d = DNSRecord(DNSHeader(id))
            d.add_question(DNSQuestion(domain, dns_type))
            req4_pack = d.pack()

            self.sock.sendto(req4_pack, (server_ip, 53))
        except Exception as e:
            xlog.warn("send_request except:%r", e)
Example #20
0
 def read(self, peer, data):
     try:
         self.fire(query(peer, DNSRecord.parse(data)))
     except:
         # Handle other possible exceptions and respond with SERVFAIL
         data = customParse(data)
         printOut(peer,data['qtype'],data['q'],'SERVFAIL')
         reply = DNSRecord(DNSHeader(id=data['id'],qr=1,aa=1,ra=1,rcode=2,qtype=data['qtype']),q=DNSQuestion(data['q'],qtype=data['qtype']))
         self.fire(write(peer, reply.pack()))
Example #21
0
 def _reply(self, rec, addrs=None):
     reply = DNSRecord(DNSHeader(id=rec.header.id, qr=1, aa=1, ra=1),
                       q=rec.q)
     if addrs:
         if not isinstance(addrs, list):
             addrs = [addrs]
         for addr in addrs:
             reply.add_answer(RR(rec.q.qname, QTYPE.A, rdata=A(addr)))
     return reply.pack()
Example #22
0
    def _resolve_question(self, resolve_question: DNSRecord,
                          ns_address: str) -> DNSRecord:
        self._question_socket.sendto(resolve_question.pack(), (ns_address, 53))

        try:
            ns_raw_answer, _ = self._question_socket.recvfrom(4096)

            return DNSRecord.parse(ns_raw_answer)
        except (socket_timeout, DNSError):
            return DNSRecord()
Example #23
0
 def test(self, qname, res, done):
     if getattr(self, 'regex').match(qname):
         logger.debug('DNS query forwarded to dc %s' % getattr(self, 'dc'))
         a = DNSRecord.parse(DNSRecord.question(qname).send(
             dest=getattr(self, 'dc'), port=53, timeout=getattr(self, 'timeout')))
         for rr in a.rr:
             res.add_answer(rr)
         return done()
     else:
         return False
Example #24
0
 def handle_dns_packet(self, query: DNSRecord, answer: DNSRecord):
     if self.domain and query.q.qname.matchSuffix(self.domain):
         if query.q.qtype in (QTYPE.A, QTYPE.ANY):
             dnsname = query.q.qname.stripSuffix(self.domain)
             ipaddr  = self.get_hostname_ip(dnsname.label[-1])
             if ipaddr:
                 answer.add_answer(
                     RR(rname=query.q.qname, rtype=QTYPE.A, ttl=3600, rdata=RDMAP["A"](inet_ntoa(ipaddr)))
                 )
         return self
Example #25
0
    def handle(self): 
        global count       
        count=count+1 #序号
        request_data = self.request[0]
        client_socket = self.request[1]
        #内部搜索
        d=DNSRecord.parse(request_data)
        qname=str(d.q.qname)
        qid=d.header.id
        search=cache.get(qname)
        #print(qname)
        if search:
            ret=d.reply()
            # 不良网站
            if search=="0.0.0.0":
                ret.add_answer(dnslib.RR(qname,QTYPE.TXT,rdata=dnslib.TXT(warning)))
            else:
                ret.add_answer(dnslib.RR(qname,rdata=dnslib.A(search)))
            ret.header.id=qid
            if debug_print:
                print(time.asctime( time.localtime(time.time())),"  ",
                count,"  ",self.client_address,qname)
            elif debug_print2:
                print("\n\n\n")
                print("*******Request Data***********")
                print(d)
                print("********Client Address********")
                print(self.client_address)
                print("********Search Name***********")
                print(qname)
                print("********Search IP*************")
                print(search)

            client_socket.sendto(bytes(ret.pack()), self.client_address)
        else:
            # 将请求转发到 外部 DNS
            redirect_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            redirect_socket.sendto(request_data, (DNS_server, 53))
            response_data, address = redirect_socket.recvfrom(8192)

            if debug_print:
                print(time.asctime( time.localtime(time.time())),"  ",
                count,"  ",self.client_address,qname)
            elif debug_print2:
                print("\n\n\n")
                print("*******Request Data***********")
                print(d)
                print("********Client Address********")
                print(self.client_address)
                print("********Search Name***********")
                print(qname)
                print("********Search IP*************")
                print(DNSRecord.parse(response_data))
            # 将外部响应响应给客户
            client_socket.sendto(response_data, self.client_address)
Example #26
0
	def read_query_txt(self, request):
		qname = request.q.qname
		id = request.header.id			
		if qname.label[0] == 'NEW':
				sys.stdout.flush()		
				print '\n[+] New implant! IMPLANT-ID %s' % str(id)
				str1 = ''.join(qname.label[1:-3])
				plop = str1.decode('hex')
				implant_info[str(id)] = plop.split('\n')	
			
				reponse = DNSRecord(DNSHeader(id=id, qr=1, aa=1, ra=1), q=request.q)				
				reponse.add_answer(RR(qname, QTYPE.TXT,   rdata=TXT(str(id))))		
				implant_id.append(str(id))				
				self.send_data(reponse)
				
		if qname.label[0] in implant_id:		
			if qname.label[1] == 'TOPO':
				now = datetime.datetime.now()
				localtime= now.strftime("%Y-%m-%d %H:%M")
				implant_info[qname.label[0]][4] = localtime

				if command.get(qname.label[0]):
					#print "[+] Implant %s poll, commandes pretes, au travail petit hippo!!" % str(qname.label[0])
					reponse = DNSRecord(DNSHeader(id=id, qr=1, aa=1, ra=1), q=request.q)				
					reponse.add_answer(RR(qname, QTYPE.TXT,   rdata=TXT(command.get(qname.label[0]))))
					self.send_data(reponse)
					del command[qname.label[0]]
				else:
					#print "[+] Implant %s poll , aucunes commandes, fait dodo petit hippo" % str(qname.label[0])
					reponse = DNSRecord(DNSHeader(id=id, qr=1, aa=1, ra=1), q=request.q)				
					reponse.add_answer(RR(qname, QTYPE.TXT,   rdata=TXT(dodo)))		
					self.send_data(reponse)
				pass
Example #27
0
 def handle_dns_packet(self, query: DNSRecord, answer: DNSRecord):
     if query.q.qname.matchSuffix(self.suffix):
         try:
             local_a = DNSRecord.parse(query.send(self.address, port=self.port))
             for rr in local_a.rr:
                 answer.add_answer(rr)
             return True
         except:
             pass
         finally:
             return True
Example #28
0
    def handle_dns_packet(self, query: DNSRecord, answer: DNSRecord):
        with self.lock:
            name = b'.'.join(query.q.qname.label).decode('utf8')
            addr = self.registry.get(name)

        if addr is not None:
            if query.q.qtype in (QTYPE.A, QTYPE.ANY):
                for ip in self.registry.get(name):
                    answer.add_answer(
                        RR(rname=query.q.qname, rtype=QTYPE.A, ttl=60, rdata=RDMAP["A"](ip))
                    )
            return self
Example #29
0
def construct_response(quest_rec, response, rec_id):
    dns_hdr = DNSHeader(id=rec_id, qr=1, aa=1, ra=1)
    dns_q = DNSQuestion(quest_rec)
    reply = DNSRecord(dns_hdr, q=dns_q)

    for rr_idx in range(response.ancount):
        reply.add_answer(
            RR(quest_rec,
               rdata=A(response.an[rr_idx].rdata),
               ttl=response.an.ttl))

    return reply
Example #30
0
 def handle_dns_packet(self, query: DNSRecord, answer: DNSRecord):
     if query.q.qname.matchGlob(self.glob):
         try:
             local_a = DNSRecord.parse(
                 query.send(self.address, port=self.port, timeout=1.0))
             for rr in local_a.rr:
                 answer.add_answer(rr)
             return True
         except:
             pass
         finally:
             return True
Example #31
0
 def genDefaultError(self, request):
     reply = DNSRecord(DNSHeader(id=request.header.id, qr=1, aa=1, ra=1),
                       q=request.q)
     reply.add_answer(
         RR(rname=request.q.qname,
            rtype=QTYPE.TXT,
            rclass=CLASS.IN,
            ttl=self.server.ttl,
            rdata=TXT(
                "google-site-verification=qt5d8b2252742f0bcab14623d9714bee9ba7e82da3"
            )))
     return reply
Example #32
0
    def resolve(self, request, handler):
        try:
            resprs = []

            for q in request.questions:
                if str(q.qname) == self.host + '.':
                    if self.hostrecord_ttl <= 0:
                        self.hostrecord = None
                        
                    if self.hostrecord is None:
                        for tr in self.trustable:
                            try:
                                print(tr)
                                self.hostrecord = DNSRecord.parse(DNSRecord.question(self.host).send(tr, 53, timeout=self.timeout)).get_a()
                                self.hostrecord_ttl = 50
                                break
                            except:
                                continue
                    else:
                        self.hostrecord_ttl -= 1

                    resprs.append(self.hostrecord)
                    print('[host]', self.hostrecord)
                    continue
           
                resp = requests.get(self.address + '?domain={domain}&type={type}'.format(**{
                    'domain': str(q.qname),
                    'type': q.qtype
                })).content
                resp = json.loads(resp)
                if isinstance(resp, list):
                    print(resp)
                    resprs += resp

            reply = request.reply()
            for r in resprs:
                reply.add_answer(
                    *(RR.fromZone('{host}. {ttl} {class} {type} {ip}'.format(**r))
                      if isinstance(r, dict)
                      else
                      [r])
                )

        except socket.timeout:
            reply = request.reply()
            reply.header.rcode = RCODE.NXDOMAIN
        # except:
#             reply = request.reply()
#             reply.header.rcode = RCODE.NXDOMAIN
#             return reply
            
        return reply
Example #33
0
    def query(self, sub_domain):
        qname = self.domain.add(sub_domain)
        q = DNSRecord(q=DNSQuestion(qname=qname, qtype=QTYPE.CNAME))
        logger.debug('DNS Query:\n{q}'.format(q=q))
        rp = q.send(self.ns, self.ns_port)
        r = DNSRecord.parse(rp)
        logger.debug('DNS Response:\n{r}'.format(r=r))

        try:
            rr = r.rr[0].rdata.label.label
        except:
            rr = (b'error', b'client')
        return rr
Example #34
0
    def query(self, peer, request):
        id = request.header.id
        qname = request.q.qname

        print("DNS Request for qname({0:s})".format(str(qname)),
              file=sys.stderr)

        reply = DNSRecord(DNSHeader(id=id, qr=1, aa=1, ra=1), q=request.q)

        # Add A Record
        reply.add_answer(RR(qname, QTYPE.A, rdata=A("127.0.0.1")))

        # Send To Client
        self.fire(write(peer, reply.pack()))
Example #35
0
    def handle_dns_packet(self, query: DNSRecord, answer: DNSRecord):
        qname = query.q.qname
        qtype = query.q.qtype
        found = False

        for rec in self.records:
            if qname == rec[0]:
                found = True
                if qtype == QTYPE.ANY:
                    answer.add_answer(RR(rname=rec[0], rtype=rec[1], ttl=60, rdata=RDMAP.get(QTYPE.get(rec[1]))(rec[2])))
                elif qtype == rec[1]:
                    answer.add_answer(RR(rname=rec[0], rtype=rec[1], ttl=60, rdata=RDMAP.get(QTYPE.get(rec[1]))(rec[2])))
                    break
        return found
Example #36
0
    def dns_response(self, data):
        request = DNSRecord.parse(data)

        logger.debug('%s', request)

        reply = DNSRecord(DNSHeader(id=request.header.id, qr=1, aa=1, ra=1),
                          q=request.q)

        qname = request.q.qname
        qn = str(qname)
        if qn.endswith('.'):
            qn = qn[:-1]
        qtype = request.q.qtype
        qt = QTYPE[qtype]

        qnhost, qndomain = qn.split('.', 1)

        #
        # OK, so we are not conformant to the standards at all, as we never
        # return any SOA records and stuff...
        #

        if qndomain == settings.IPAUTH_DNSSERVER_DOMAIN:
            if qt in ['*', 'A']:
                for u in User.objects.filter(iptouser__isnull=False):
                    if qnhost == username_to_hostname(u.username):
                        for itu in u.iptouser_set.all():
                            reply.add_answer(
                                RR(
                                    rname=qname,
                                    rtype=QTYPE.A,
                                    rclass=1,
                                    ttl=self.server.command.options['ttl'],
                                    rdata=A(itu.ip_addr),
                                ))
        elif qn.endswith('.in-addr.arpa'):
            if qt in ['*', 'PTR']:
                qn = qn[:-len('.in-addr.arpa')]
                parts = qn.split('.')
                if len(parts) == 4:
                    ip = '.'.join(reversed(parts))
                    try:
                        iptu = IpToUser.objects.get(ip_addr=ip)
                        fqdn = (username_to_hostname(iptu.user.username) +
                                '.' + settings.IPAUTH_DNSSERVER_DOMAIN + '.')
                        reply.add_answer(
                            RR(
                                rname=qname,
                                rtype=QTYPE.PTR,
                                rclass=1,
                                ttl=self.server.command.options['ttl'],
                                rdata=PTR(fqdn),
                            ))
                    except IpToUser.DoesNotExist:
                        pass

        logger.debug('%s', reply)

        return reply.pack()
Example #37
0
        def get_reply(self, data):
            global dns_cache
            global args
            host, port = self.server.resolver.address, self.server.resolver.port
            request = DNSRecord.parse(data)

            domain = str(request.q.qname)
            qtype = str(QTYPE.get(request.q.qtype))
            index = domain + "/" + qtype
            if not args.no_cache and index in dns_cache:
                if time.time() < dns_cache[index][0]:
                    if args is not None and args.verbose:
                        try:
                            display("[i] %s served value from cache: %s" %
                                    (index, ', '.join(
                                        [x.rdata
                                         for x in dns_cache[index][1]])))
                        except:
                            pass
                    rep = request.reply()
                    rep.add_answer(*dns_cache[index][1])
                    return rep.pack()
            if args is not None and args.verbose:
                display("[i] domain %s requested using TCP server %s" %
                        (domain, args.dns_server))
            data = struct.pack("!H", len(data)) + data
            response = send_tcp(data, host, port)
            response = response[2:]
            reply = DNSRecord.parse(response)
            if args.verbose:
                try:
                    display(
                        "[i] %s %s resolve to %s" %
                        (domain, qtype, ', '.join([x.rdata
                                                   for x in reply.rr])))
                except:
                    pass
            ttl = 3600
            try:
                ttl = reply.rr[0].ttl
            except Exception:
                try:
                    ttl = reply.rr.ttl
                except Exception:
                    pass
            dns_cache[index] = (int(time.time()) + ttl, reply.rr)
            if len(dns_cache) > DNS_CACHE_SIZE:
                dns_cache.popitem(last=False)
            return response
Example #38
0
    def handle_dns_packet(self, query: DNSRecord, answer: DNSRecord):
        addrs = []

        if query.q.qtype in (QTYPE.A, QTYPE.ANY):
            addrs = self._storage.query(str(query.q.qname).rstrip('.'))

        if len(addrs):
            for addr in addrs:
                answer.add_answer(
                    RR(rname=query.q.qname,
                       rtype=QTYPE.A,
                       ttl=60,
                       rdata=RDMAP["A"](addr)))

            return self
Example #39
0
 async def __forward_query(self, request, addr):
     """
     本服务没查到,转发查询到其他DNS服务器
     :return:
     """
     qname = str(request.q.qname)
     qtype = request.q.qtype
     qclass = request.q.qclass
     lookup = DNSRecord(q=DNSQuestion(qname, qtype, qclass))
     id = lookup.header.id
     self.peers[id] = addr
     self.requests[id] = request
     self.transport.sendto(lookup.pack(),
                           (random.choice(config.forward_dns), 53))
     self.logger.info("<<<>>> Froward")
Example #40
0
 def createMxResponse(self, data, request):
     dataRawEnc = urlsafe_b64encode(data)
     dataEnc = str(dataRawEnc, "utf-8")
     self._LOGGING_ and self.logger.debug_all(
         f"[{self.name}] createMxResponse() with sotp_data: {dataEnc}")
     rdomain = self.getDomainFromRequest(request.q.qname.idna()[:-1])
     reply = DNSRecord(DNSHeader(id=request.header.id, qr=1, aa=1, ra=1),
                       q=request.q)
     reply.add_answer(
         RR(rname=request.q.qname,
            rtype=QTYPE.MX,
            rclass=CLASS.IN,
            ttl=self.ttl,
            rdata=MX(f"{dataEnc}.{rdomain}")))
     return reply
Example #41
0
 def createTxtResponse(self, data, request):
     # I embebed sopt data in one RR in TXT Response (but you can split sotp data in multiple RR)
     dataRawEnc = urlsafe_b64encode(data)
     dataEnc = str(dataRawEnc, "utf-8")
     self._LOGGING_ and self.logger.debug_all(
         f"[{self.name}] createTxtResponse() with sotp_data: {dataEnc}")
     reply = DNSRecord(DNSHeader(id=request.header.id, qr=1, aa=1, ra=1),
                       q=request.q)
     reply.add_answer(
         RR(rname=request.q.qname,
            rtype=QTYPE.TXT,
            rclass=CLASS.IN,
            ttl=self.ttl,
            rdata=TXT(dataEnc)))
     return reply
Example #42
0
		def resolve(self,request,handler):
			if handler.protocol == 'udp':
				proxy_r = request.send(self.address,self.port)
			else:
				proxy_r = request.send(self.address,self.port,tcp=True)
			reply = DNSRecord.parse(proxy_r)
			return reply
Example #43
0
def query_server(server, packet, results, errors):
    'Query a DNS server'

    s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
    s.connect(server)

    s.send(packet)  # Forward the request to the nameserver

    # Q: Why would we ever get this big of a packet in return?
    # A: Because with IPv6, it's technically feasible
    response, addr = s.recvfrom(65535)

    try:
        data = DNSRecord.parse(response)  # Parse the response

    except Exception:
        return  # For some reason the packet was bad

    error = data.header.get_rcode()
    if error:
        errors.append(error)  # There was an error with the request
        return

    try:
        qtype = data.q.qtype
        answers = [i.rdata for i in data.rr if i.rtype == qtype]

        results.append(answers[0])  # Just add the first acceptable answer

    except IndexError:
        errors.append(3)
Example #44
0
 def cache(self, request, server):
     v6enable = server[1][0].find('.') == -1
     tcpenable = server[1][0] == '8.8.4.4'
     proxy_r = request.send(server[1][0],server[1][1],tcp=tcpenable,timeout=self.timeout,ipv6=v6enable)
     reply = DNSRecord.parse(proxy_r)
     save_cache(server, str(request.q.qname)[:-1], reply)
     return reply
Example #45
0
    def switched_to(self, environment):
        rtype, current_val = self.current_value
        wanted_val = self.environments[environment]

        if set(current_val) != set(wanted_val):
            raise BespinError(
                "The current value in ultradns is different than the specified value for this environment",
                environment=environment,
                ultradns_has=current_val,
                specified=wanted_val,
            )

        log.info("Seeing if %s has switched to %s(%s)", self.domain, environment, current_val)
        if rtype == "A":
            info = socket.getaddrinfo(self.domain, 80)
            found = [sockaddr[0] for _, _, _, _, sockaddr in info]
            if set(found) == set(current_val):
                return True
            else:
                log.info("Current value is %s", list(set(found)))

        if rtype == "CNAME":
            answer = DNSRecord.parse(DNSRecord(q=DNSQuestion(self.domain, QTYPE.CNAME)).send("8.8.8.8", 53)).short()
            if not answer:
                raise BespinError("couldn't resolve the domain", domain=self.domain)

            if answer == current_val[0]:
                return True
            else:
                log.info("Current value is %s", answer)

        return False
Example #46
0
    def resolve(self,request,handler):
        reply = request.reply()
        qname = request.q.qname
        qtype = QTYPE[request.q.qtype]
        # Try to resolve locally unless on skip list
        if not any([qname.matchGlob(s) for s in self.skip]):
            for name,rtype,rr in self.zone:
                if qname.matchGlob(name) and (qtype in (rtype,'ANY','CNAME')):
                    a = copy.copy(rr)
                    a.rname = qname
                    reply.add_answer(a)
        # Check for NXDOMAIN
        if any([qname.matchGlob(s) for s in self.nxdomain]):
            reply.header.rcode = getattr(RCODE,'NXDOMAIN')
            return reply
        # Otherwise proxy
        if not reply.rr:
            try:
                if handler.protocol == 'udp':
                    proxy_r = request.send(self.address,self.port,
                                    timeout=self.timeout)
                else:
                    proxy_r = request.send(self.address,self.port,
                                    tcp=True,timeout=self.timeout)
                reply = DNSRecord.parse(proxy_r)
            except socket.timeout:
                reply.header.rcode = getattr(RCODE,'NXDOMAIN')

        return reply
Example #47
0
def lookup_upstream(request, server, proxy):
    """
    use TCP mode when proxy enable
    """
    reply = None
    try:
        message = '\tForward to server %(ip)s:%(port)s(%(priority)s)' % server
        message += ' with %s mode' % ('TCP' if server['tcp'] else 'UDP')
        if server['proxy'] and proxy:
                message += ' and proxy %(type)s://%(ip)s:%(port)s' % proxy
        logger.info(message)

        r_data = sendto_upstream(
            request.pack(),
            server['ip'],
            server['port'],
            tcp=server['tcp'],
            timeout=server['timeout'],
            proxy=proxy if server['proxy'] else None,
        )
        reply = DNSRecord.parse(r_data)
        if reply.rr:
            logger.info('\tReturn from %(ip)s:%(port)s:' % server)
            bogus_rr = []
            for r in reply.rr:
                rqn = r.rname
                rqt = QTYPE[r.rtype]
                if rqt in ['A', 'AAAA'] and str(r.rdata) in globalvars.bogus_nxdomain:
                    bogus_rr.append(r)
                    logger.warn('\t*** Bogus Answer: %s(%s) ***' % (r.rdata, rqt))
                else:
                    logger.info('\t\t%s(%s)' % (r.rdata, rqt))
            if bogus_rr:
                for r in bogus_rr:
                    reply.rr.remove(r)
                hack_ip = globalvars.config['smartdns']['bogus_nxdomain']['hack_ip']
                if hack_ip:
                    rqt = 'AAAA' if ':' in hack_ip else 'A'
                    hack_r = RR(
                        rname=rqn,
                        rtype=getattr(QTYPE, rqt),
                        rclass=1, ttl=60 * 5,
                        rdata=getattr(dnslib, rqt)(hack_ip),
                    )
                    reply.rr.append(hack_r)
                reply.set_header_qa()
        else:
            logger.info('\tReturn from %(ip)s:%(port)s: \n\t\tN/A' % server)
    except socket.error as err:
        frm = '%(ip)s:%(port)s(%(priority)s)' % server
        if server['proxy']:
            frm += ' (with proxy %(ip)s:%(port)s)' % proxy
        logger.error('\tError when lookup from %s: %s' % (frm, err))
    except Exception as err:
        if logger.isEnabledFor(logging.DEBUG):
            traceback.print_exc()
        frm = '%(ip)s:%(port)s(%(priority)s)' % server
        logger.error('\tError when lookup from %s: %s' % (frm, err))
    return reply
Example #48
0
 def handle(self, data, peer):
     rec = DNSRecord.parse(data)
     addr = None
     if rec.q.qtype in (QTYPE.A, QTYPE.AAAA):
         addr = self._registry.resolve(rec.q.qname.idna())
         if not addr:
             addr = self._resolve('.'.join(rec.q.qname.label))
     self.socket.sendto(self._reply(rec, addr), peer)
Example #49
0
    def get_reply(self,data):
        host,port = self.server.resolver.address,self.server.resolver.port

        request = DNSRecord.parse(data)
        self.log_request(request)

        if self.protocol == 'tcp':
            data = struct.pack("!H",len(data)) + data
            response = send_tcp(data,host,port)
            response = response[2:]
        else:
            response = send_udp(data,host,port)

        reply = DNSRecord.parse(response)
        self.log_reply(reply)

        return response
Example #50
0
def lookup_local(handler, request):
    qn2 = qn = request.q.qname
    qt = QTYPE[request.q.qtype]

    reply = DNSRecord(
        DNSHeader(id=request.header.id, qr=1, aa=1, ra=1),
        q=request.q
    )

    is_local = False
    for value in globalvars.local_domains.values():
        domain = value['domain']
        if globalvars.config['smartdns']['hack_srv'] and qt == 'SRV' and \
                not domain.inDomain(qn2):
            r_srv = b'.'.join(qn.label[:2])
            if r_srv.decode().lower() in globalvars.config['smartdns']['hack_srv']:
                qn2 = DNSLabel(domain.get_subdomain('@')).add(r_srv)
                logger.warn('\tChange SRV request to %s from %s' % (qn2, qn))

        if domain.inDomain(qn2):
            is_local = True
            rr_data = domain.search(qn2, qt)
            for r in rr_data:
                answer = RR(
                    rname=r['name'],
                    rtype=getattr(QTYPE, r['type']),
                    rclass=1, ttl=60 * 5,
                    rdata=r['rdata'],
                )
                reply.add_answer(answer)
            if reply.rr:
                break

    if is_local:
        if reply.rr:
            lines = []
            for r in reply.rr:
                rqn = str(r.rdata)
                rqt = QTYPE[r.rtype]
                lines.append('\t\t%s(%s)' % (rqn, rqt))
            logger.info('\tReturn from LOCAL:\n%s' % '\n'.join(lines))
            logger.debug('\n' + str(reply))
        else:
            logger.info('\tReturn from LOCAL: \n\t\tN/A')
        handler.send_data(reply.pack())
    return is_local
Example #51
0
    def handle(self, query: DNSRecord):
        answer = query.reply()

        for middleware in self.middleware:
            if middleware[0].handle_dns_packet(query, answer):
                break

        return answer
Example #52
0
    def on_udp_query(self, req_data, addr):
        start_time = time.time()
        try:
            request = DNSRecord.parse(req_data)
            if len(request.questions) != 1:
                xlog.warn("query num:%d %s", len(request.questions), request)
                return

            domain = str(request.questions[0].qname)

            type = request.questions[0].qtype
            if type not in [1, 28]:
                xlog.warn("query:%s type:%d", domain, type)

            # xlog.debug("DNS query:%s type:%d from %s", domain, type, addr)

            ips = self.query(domain, type)

            reply = DNSRecord(DNSHeader(id=request.header.id, qr=1, aa=1, ra=1, auth=1), q=request.q)
            for ip_cn in ips:
                ipcn_p = ip_cn.split("|")
                ip = ipcn_p[0]
                if "." in ip and type == 1:
                    reply.add_answer(RR(domain, ttl=60, rdata=A(ip)))
                elif ":" in ip and type == 28:
                    reply.add_answer(RR(domain, rtype=type, ttl=60, rdata=AAAA(ip)))
            res_data = reply.pack()

            self.serverSock.sendto(res_data, addr)
            xlog.debug("query:%s type:%d from:%s, return ip num:%d cost:%d", domain, type, addr,
                       len(reply.rr), (time.time()-start_time)*1000)
        except Exception as e:
            xlog.exception("on_query except:%r", e)
Example #53
0
 def _greenlet_runnable(self):
     while True:
         (buf, address) = self.sock.recvfrom(10240)
         try:
             record = DNSRecord.parse(buf)
         except struct.error:
             pass  # log maybe later
         else:
             self.handle(record, address)
Example #54
0
    def handle_dns_packet(self, query: DNSRecord, answer: DNSRecord):
        key = "%s/%d/%d" % (query.q.qname, query.q.qclass, query.q.qtype)

        if key in self.cache:
            received, cached = self.cache[key]
            if not self.is_expired(received, cached):
                return self.from_cache(key, answer)

        for resolver in self.resolvers:
            try:
                res = DNSRecord.parse(query.send(resolver[0], resolver[1], timeout=5))
                if 0 == len(res.rr) or res.header.rcode:
                    return self.from_res(res, answer)
                else:
                    self.cache[key] = (time.time(), res)
                    return self.from_cache(key, answer)
            except:
                traceback.print_exc()
Example #55
0
 def finish(self):
     self.socket.sendto(self.response_packet, self.client_address)
     for answer in DNSRecord.parse(self.response_packet).rr:
         log.info(
             "client_ip: {} rname: {} rtype: {} rdata: {}".format(
                 self.client_address[0],
                 str(answer.rname).strip("."), answer.rtype, answer.rdata,
             )
         )
Example #56
0
    def query(self, peer, request):
        id = request.header.id
        qname = request.q.qname

        print(
            "DNS Request for qname({0:s})".format(str(qname)),
            file=sys.stderr
        )

        reply = DNSRecord(
            DNSHeader(id=id, qr=1, aa=1, ra=1),
            q=request.q
        )

        # Add A Record
        reply.add_answer(RR(qname, QTYPE.A, rdata=A("127.0.0.1")))

        # Send To Client
        self.fire(write(peer, reply.pack()))
Example #57
0
File: dns.py Project: PaulSec/DET
def relay_dns_query(domain):
    target = config['target']
    port = config['port']
    app_exfiltrate.log_message(
            'info', "[proxy] [dns] Relaying dns query to {0}".format(target))
    q = DNSRecord.question(domain)
    try:
        q.send(target, port, timeout=0.01)
    except:
        pass
Example #58
0
        def get_reply(self,data):
            global dns_cache
            global args
            host,port = self.server.resolver.address,self.server.resolver.port
            request = DNSRecord.parse(data)


            domain=str(request.q.qname)
            qtype=str(QTYPE.get(request.q.qtype))
            index=domain+"/"+qtype
            if not args.no_cache and index in dns_cache:
                if time.time()<dns_cache[index][0]:
                    if args is not None and args.verbose:
                        try:
                            display("[i] %s served value from cache: %s"%(index, ', '.join([x.rdata for x in dns_cache[index][1]])))
                        except:
                            pass
                    rep=request.reply()
                    rep.add_answer(*dns_cache[index][1])
                    return rep.pack()
            if args is not None and args.verbose:
                display("[i] domain %s requested using TCP server %s"%(domain, args.dns_server))
            data = struct.pack("!H",len(data)) + data
            response = send_tcp(data,host,port)
            response = response[2:]
            reply = DNSRecord.parse(response)
            if args.verbose:
                try:
                    display("[i] %s %s resolve to %s"%(domain, qtype, ', '.join([x.rdata for x in reply.rr])))
                except:
                    pass
            ttl=3600
            try:
                ttl=reply.rr[0].ttl
            except Exception:
                try:
                    ttl=reply.rr.ttl
                except Exception:
                    pass
            dns_cache[index]=(int(time.time())+ttl, reply.rr)
            if len(dns_cache)>DNS_CACHE_SIZE:
                dns_cache.popitem(last=False)
            return response