Exemplo n.º 1
0
def _add_additional(addi_list):
    """
    Given a domain and an additional set,
    this function will add the A records for the UH DNS nameservers to the set.
    :param addi_list: Additional set to add to.
    """
    if addi_list == []:
        addi_list.append(
            dnslib.RR(rname="ns1.uh-dns.com.",
                      rtype=dnslib.QTYPE.A,
                      rdata=dnslib.A("18.130.161.247"),
                      ttl=3600))
        addi_list.append(
            dnslib.RR(rname="ns1.uh-dns.com.",
                      rtype=dnslib.QTYPE.AAAA,
                      rdata=dnslib.AAAA("2a05:d01c:35b:7601::4"),
                      ttl=3600))
        addi_list.append(
            dnslib.RR(rname="ns2.uh-dns.com.",
                      rtype=dnslib.QTYPE.A,
                      rdata=dnslib.A("18.130.86.161"),
                      ttl=3600))
        addi_list.append(
            dnslib.RR(rname="ns2.uh-dns.com.",
                      rtype=dnslib.QTYPE.AAAA,
                      rdata=dnslib.AAAA("2a05:d01c:35b:7600::4"),
                      ttl=3600))
Exemplo n.º 2
0
    def domain2ip(self, qdomain, ips):
        ans = []
        if type(ips) == list:
            for ip in ips:
                ans.append({
                    qdomain:
                    dnslib.RR(qdomain, rdata=dnslib.A(ip), ttl=self.ttl)
                })
        elif type(ips) == str:
            ans.append({
                qdomain:
                dnslib.RR(qdomain, rdata=dnslib.A(ips), ttl=self.ttl)
            })

        return ans
Exemplo n.º 3
0
    def handle(self):
        try:
            data = self.get_data()
            query = dnslib.DNSRecord.parse(data)
            reply = query.reply()
            answers = []

            if reply.get_q().qtype == dnslib.QTYPE.TXT:
                try:
                    challenge_files = os.listdir(BaseDNSRequestHandler.challenges_path)
                    for challenge_file in challenge_files:
                        if challenge_file.startswith(str(reply.get_q().qname).strip('.')):
                            with open(os.path.join(BaseDNSRequestHandler.challenges_path,
                                                   challenge_file), 'r') as challenge_data:
                                answers.append(dnslib.RR(rname=reply.get_q().qname,
                                                         rtype=reply.get_q().qtype,
                                                         ttl=60,
                                                         rdata=dnslib.TXT(challenge_data.read().strip())))
                except OSError:
                    pass
            else:
                answers.append(dnslib.RR(rname=reply.get_q().qname,
                                         ttl=60,
                                         rdata=dnslib.A(LISTEN_ADDRESS)))

            for answer in answers:
                reply.add_answer(answer)
            self.send_data(reply.pack())
        except Exception as e:
            print(e)
Exemplo n.º 4
0
    async def _get_record(self, request, client_writer):
        domain = str(request.questions[0].qname)[:-1]
        qtype = request.questions[0].qtype
        logger.info('dns_request: %s, %s', domain, qtype)

        if not self.conf.GET_PROXY.isgfwed_resolver(domain):
            # try resolve with getaddrinfo first
            logger.debug('not gfwed.')
            if qtype in (dnslib.QTYPE.A, dnslib.QTYPE.AAAA, dnslib.QTYPE.ANY):
                result_list = await resolve(domain, 0)
                response = request.reply()
                for result in result_list:
                    if result[0] == socket.AF_INET and qtype in (
                            dnslib.QTYPE.A, dnslib.QTYPE.ANY):
                        response.add_answer(
                            dnslib.RR(domain,
                                      dnslib.QTYPE.A,
                                      rdata=dnslib.A(result[1])))

                    elif result[0] == socket.AF_INET6 and qtype in (
                            dnslib.QTYPE.AAAA, dnslib.QTYPE.ANY):
                        response.add_answer(
                            dnslib.RR(domain,
                                      dnslib.QTYPE.AAAA,
                                      rdata=dnslib.AAAA(result[1])))
                return response

        await self.tcp_dns_record(request, client_writer)
Exemplo n.º 5
0
def pack_dns(dns, answers, soa=None):
    def content_type(x):
        #  valid ip
        if socket.inet_aton(x):
            return 'A'
        else:
            return 'CNAME'

    if answers:
        for ans in answers:
            # logger.info('ans ' + ans)
            if content_type(ans[1]) == 'A':
                dns.add_answer(
                    dnslib.RR(ans[0], dnslib.QTYPE.A, rdata=dnslib.A(ans[1])))
            elif content_type(ans[1]) == 'CNAME':
                dns.add_answer(
                    dnslib.RR(ans[0],
                              dnslib.QTYPE.CNAME,
                              rdata=dnslib.CNAME(ans[1])))
    elif soa:
        soa_content = soa[1].split()
        dns.add_auth(
            dnslib.RR(soa[0],
                      dnslib.QTYPE.SOA,
                      rdata=dnslib.SOA(soa_content[0], soa_content[1],
                                       (int(i) for i in soa_content[2:]))))
    return dns
Exemplo n.º 6
0
def SendDnsData(data, s, addr):
    global Remote_dns_server
    global Remote_dns_port
    '''dns请求报文'''
    request_packet = dnslib.DNSRecord.parse(data)
    '''dns请求报文的域名'''
    domain = request_packet.get_q().get_qname()
    '''dns响应报文'''
    response_packet = request_packet.reply()
    ip = Search_key_ip(str(domain))
    if ip != None:
        print(domain, ':', ip)
        response_packet.add_answer(
            dnslib.RR(domain, dnslib.QTYPE.A, rdata=dnslib.A(ip), ttl=60))
        s.sendto(response_packet.pack(), addr)
    else:
        data = AddEDNSOption(data, addr[0])
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.settimeout(5)
        sock.sendto(data, (Remote_dns_server, Remote_dns_port))
        while True:
            try:
                rspdata = sock.recv(4096)
            except Exception as e:
                logging.warn("Recv:\t%s" % e)
                break
            s.sendto(rspdata, addr)
            break
Exemplo n.º 7
0
    def run(self):
        fd = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        fd.bind(('', 53))

        while True:
            try:
                packet, isp_dns_address = fd.recvfrom(8192)
                req = dnslib.DNSRecord.parse(packet)

                a = req.reply()
                q_name = req.get_q().qname
                q_type = req.get_q().qtype
                q_type_str = dnslib.QTYPE.get(q_type)

                if q_type_str == 'A':
                    a.add_answer(
                        dnslib.RR(q_name,
                                  dnslib.QTYPE.A,
                                  rdata=dnslib.A(SERVER_PUBLIC_IP),
                                  ttl=600))

                    lock.acquire()
                    k = str(q_name)
                    domain_dns_dict[k] = isp_dns_address[0]
                    delete_later(domain_dns_dict, k)
                    lock.release()

                print('dns request : ', q_name, q_type_str, isp_dns_address)
                sys.stdout.flush()
                fd.sendto(a.pack(), isp_dns_address)
            except Exception as e:
                print(e)
                sys.stdout.flush()
Exemplo n.º 8
0
def _alias_search(q_type, record, rr_list, auth_list, addi_list):
    """
    If no A or AAAA records exist this function will add any fixed alias records.
    :param q_type: Query type (A or AAAA) alias records accepted.
    :param record: Record from DB.
    :param rr_list: resource record list.
    :param auth_list: authority list.
    :param addi_list: additional list.
    """
    try:
        alias_record = record["ALIAS"]
        ttl = int(alias_record["ttl"])
        question = dnslib.DNSRecord.question(alias_record["domain"], qtype=dnslib.QTYPE[q_type])
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.settimeout(1)
        sock.bind(("", 0)) # Bind to any available IP and port.
        sock.sendto(question.pack(), ("10.0.0.2", 53))
        res = dnslib.DNSRecord.parse(sock.recv(4096))
        sock.close()
        for r in res.rr:
            ip = str(r.rdata)
            if q_type == dnslib.QTYPE.A:
                rdata = dnslib.A(ip)
            elif q_type == dnslib.QTYPE.AAAA:
                rdata = dnslib.AAAA(ip)
            rr_list.append(dnslib.RR(rname=record["domain"],
                                     rtype=q_type,
                                     rdata=rdata,
                                     ttl=ttl))
            _add_authority(record["domain"], auth_list)
            _add_additional(addi_list)
    except:
        pass
Exemplo n.º 9
0
    def cloak(self, request, handler):

        domain = GetDomainNameFromRequest(request)

        for rule in self.cloakrules:
            if rule.search(domain):

                reply = request.reply()

                # Return an A record if target is IPV4 address
                if rule.targetIsIp4():
                    reply.add_answer(
                        RR(request.questions[0].qname,
                           rtype=QTYPE.A,
                           rdata=dnslib.A(rule.target),
                           ttl=self.DEFAULT_TTL))
                    return reply

                # Add a CNAME if the target domain is different
                if domain != rule.target:
                    reply.add_answer(
                        RR(request.questions[0].qname,
                           rtype=QTYPE.CNAME,
                           rdata=dnslib.CNAME(rule.target),
                           ttl=self.DEFAULT_TTL))

                subquery = DNSRecord.question(rule.target)
                subresp = self.upstream_resolve(subquery, handler)

                for record in subresp.rr:
                    reply.add_answer(record)

                return reply
Exemplo n.º 10
0
def test_on_upstream_response_BC(greendns):
    qname = "www.x.net"
    s = init_greendns_session(greendns, qname, dnslib.QTYPE.A)
    res = dnslib.DNSRecord(dnslib.DNSHeader(qr=1, aa=1, ra=1),
                           q=dnslib.DNSQuestion(qname),
                           a=dnslib.RR(qname, rdata=dnslib.A("8.8.8.8"),
                                       ttl=3))
    s.server_resps[local_dns1] = bytes(res.pack())
    resp = greendns.on_upstream_response(s, local_dns1)
    assert not resp

    res.rr[0].rdata = dnslib.A("1.2.4.8")
    s.server_resps[foreign_dns] = bytes(res.pack())
    resp = greendns.on_upstream_response(s, foreign_dns)
    assert resp
    d = dnslib.DNSRecord.parse(resp)
    assert str(d.rr[0].rdata) == "1.2.4.8"
Exemplo n.º 11
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)
Exemplo n.º 12
0
 def handle(self):
     data = self.request[0]
     d = dnslib.DNSRecord.parse(data)
     id = d.header.id
     sock = self.request[1]
     res = dnslib.DNSRecord(dnslib.DNSHeader(qr=1, aa=1, ra=1, id=id),
                            q=dnslib.DNSQuestion(qname),
                            a=dnslib.RR(qname,
                                        rdata=dnslib.A("101.226.103.106"),
                                        ttl=3))
     sock.sendto(bytes(res.pack()), self.client_address)
Exemplo n.º 13
0
    def resolve(self, request, handler):
        reply = request.reply()
        qname = request.q.qname

        # Refuse queries thaat are not for our domain
        if tuple(map(str.lower, map(qname._decode, qname.label[-2:]))) != \
            tuple(map(str.lower, map(self.domain._decode, self.domain.label[-2:]))):
            reply.header.rcode = dnslib.RCODE.REFUSED
            return reply

        # Answer questions about the root domain name
        # TODO(supersat): We don't need to implement this, right?
        if len(qname.label) <= 3:
            if request.q.qtype == dnslib.QTYPE.A:
                reply.add_answer(
                    dnslib.RR(qname,
                              dnslib.QTYPE.A,
                              ttl=300,
                              rdata=self.server_ip))
            return reply

        subdomain = qname._decode(qname.label[1]).lower()
        hostname = qname._decode(qname.label[0]).lower()
        if BASE36_SHA256_HASH.match(subdomain) and len(qname.label) == 4:
            if hostname == '_acme-challenge' and \
                (request.q.qtype == dnslib.QTYPE.TXT or \
                request.q.qtype == dnslib.QTYPE.ANY):
                txt = self.redis.get('acme-dns-01-chal:{}'.format(subdomain))
                if txt:
                    reply.add_answer(
                        dnslib.RR(qname,
                                  dnslib.QTYPE.TXT,
                                  ttl=300,
                                  rdata=dnslib.TXT(txt)))
                else:
                    reply.header.rcode = dnslib.RCODE.NXDOMAIN
            elif IPV4_REGEX.match(hostname) and \
                (request.q.qtype == dnslib.QTYPE.A or \
                request.q.qtype == dnslib.QTYPE.ANY):
                try:
                    ip = tuple(map(int, hostname.split('-')))
                    reply.add_answer(
                        dnslib.RR(qname,
                                  dnslib.QTYPE.A,
                                  ttl=300,
                                  rdata=dnslib.A(ip)))
                except:
                    reply.header.rcode = dnslib.RCODE.NXDOMAIN
            else:
                reply.header.rcode = dnslib.RCODE.NXDOMAIN
            return reply

        reply.header.rcode = dnslib.RCODE.NXDOMAIN
        return reply
Exemplo n.º 14
0
 def pack_dns(self, dns, answers, soa=None):
     content_type = lambda x: 'A' if re.match('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', x) else 'CNAME'
     if answers:
         for ans in answers:
             if content_type(ans[1]) == 'A':
                 dns.add_answer(dnslib.RR(ans[0], dnslib.QTYPE.A, rdata=dnslib.A(ans[1])))
             elif content_type(ans[1]) == 'CNAME':
                 dns.add_answer(dnslib.RR(ans[0], dnslib.QTYPE.CNAME, rdata=dnslib.CNAME(ans[1])))
     elif soa:
         soa_content = soa[1].split()
         dns.add_auth(dnslib.RR(soa[0], dnslib.QTYPE.SOA,
                                rdata=dnslib.SOA(soa_content[0], soa_content[1], (int(i) for i in soa_content[2:]))))
 
     return dns
Exemplo n.º 15
0
def test_on_client_request_with_cache_expired(greendns):
    qname = "qqq.com"
    id = 1024
    s = init_greendns_session(greendns, qname, dnslib.QTYPE.A, id)
    res = dnslib.DNSRecord(dnslib.DNSHeader(qr=1, aa=1, ra=1),
                           q=dnslib.DNSQuestion(qname),
                           a=dnslib.RR(qname,
                                       rdata=dnslib.A("101.226.103.106"),
                                       ttl=3))
    greendns.cache.add(("qqq.com.", 1), res, 3)
    time.sleep(4)
    is_continue, raw_resp = greendns.on_client_request(s)
    assert is_continue
    assert not raw_resp
Exemplo n.º 16
0
def test_shuffer_A(greendns):
    qname = "qq.com"
    id = 1024
    s = init_greendns_session(greendns, qname, dnslib.QTYPE.A, id)
    res = dnslib.DNSRecord(dnslib.DNSHeader(qr=1, aa=1, ra=1),
                           q=dnslib.DNSQuestion(qname),
                           a=dnslib.RR(qname,
                                       dnslib.QTYPE.CNAME,
                                       rdata=dnslib.CNAME("https.qq.com"),
                                       ttl=3))
    res.add_answer(dnslib.RR(qname, rdata=dnslib.A("101.226.103.106"), ttl=3))
    res.add_answer(dnslib.RR(qname, rdata=dnslib.A("101.226.103.107"), ttl=3))
    greendns.cache.add(("qq.com.", 1), res, 3)
    d = None
    for i in range(10):
        is_continue, raw_resp = greendns.on_client_request(s)
        assert not is_continue
        assert raw_resp
        d = dnslib.DNSRecord.parse(raw_resp)
        if str(d.rr[1].rdata) == "101.226.103.107":
            break
    assert d.rr[0].rtype == dnslib.QTYPE.CNAME
    assert str(d.rr[1].rdata) == "101.226.103.107"
Exemplo n.º 17
0
    def resolve(self, request, handler):
        reply = request.reply()
        qtype = dnslib.QTYPE[request.q.qtype]
        rhost = str(request.q.qname)

        if qtype != "A" or rhost == "etherclient.ml." or rhost == 'ns2.etherclient.ml.' or rhost == 'ns1.etherclient.ml.' or rhost.count(
                ".") < 3:
            reply.add_answer(
                dnslib.RR("etherclient.ml",
                          rdata=dnslib.A("209.250.251.88"),
                          ttl=1))
        else:
            sub = rhost.split(".")[0]
            print "Sub --> " + sub
            if sub.startswith('next'):
                mainsub = rhost.split(".")[1]
                self.domainReqs[mainsub] = True
                reply.add_answer(
                    dnslib.RR("%s.%s.etherclient.ml" % (sub, mainsub),
                              rdata=dnslib.A("209.250.251.88"),
                              ttl=1))
            else:
                if sub not in self.domainReqs or self.domainReqs[sub] == False:
                    reply.add_answer(
                        dnslib.RR(sub + ".etherclient.ml",
                                  rdata=dnslib.A("209.250.251.88"),
                                  ttl=1))
                else:
                    print "REBINDING LOL"
                    reply.add_answer(
                        dnslib.RR(sub + ".etherclient.ml",
                                  rdata=dnslib.A("127.0.0.1"),
                                  ttl=1))
                    self.domainReqs[sub] = False

        return reply
Exemplo n.º 18
0
def fakeReplys(qid):
    """
	This method craft a fake DNS response packet where associate the bankofallan.co.uk to the badguy ip.
	
	qid: Is the queryID to assign to the crafted packet.
	"""
    # craft fake DNS query response
    fakeReplyPacket = dnslib.DNSRecord(
        dnslib.DNSHeader(id=qid, qr=1, aa=1, ra=1),
        q=dnslib.DNSQuestion("www1337.bankofallan.co.uk"),
        a=dnslib.RR("bankofallan.co.uk",
                    dnslib.QTYPE.A,
                    rdata=dnslib.A(badguyIP),
                    ttl=10000)).pack()
    return fakeReplyPacket
Exemplo n.º 19
0
def gen_response(qt, qn):
    global serving_domains
    prefix_ = list(
        filter(lambda d: qn == d or qn.endswith('.' + d), serving_domains))
    if len(prefix_) != 1:
        # print("Error: invalid request domain {} in {}".format(qn, serving_domains))
        return None
    prefix = prefix_[0]
    print('REQ: ', qt, qn)

    if qt == 'SOA':
        generated_soa = dnslib.SOA(
            mname="todo." + domain_text,
            rname="*****@*****.**",
            times=(
                201307231,  # serial number
                10000,  # refresh
                2400,  # retry
                604800,  # expire
                3600,  # minimum
            ))
        return RR(rname=prefix,
                  rtype=QTYPE.SOA,
                  rclass=1,
                  ttl=86400,
                  rdata=generated_soa)
        # return {"mname": "todo."+domain_text, "rname": "*****@*****.**", "serial": "10", "refresh": 3600, "retry": 600, "expire": 604800, "minimum": 86400}
    elif qt == 'A':
        requested_ip = qn[:len(qn) - len(prefix)].strip('.')
        if not re.match(r'^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$', requested_ip):
            print("Invalid requested_ip: " + requested_ip)
            return None
        generated_a = dnslib.A(requested_ip)
        return RR(rname=qn,
                  rtype=QTYPE.A,
                  rclass=1,
                  ttl=86400,
                  rdata=generated_a)
    elif qt == 'NS':
        generated_ns = dnslib.NS(ns_ipaddr)
        return RR(rname=prefix,
                  rtype=QTYPE.NS,
                  rclass=1,
                  ttl=86400,
                  rdata=generated_ns)
    else:
        print("Invalid qt=" + qt)
        return None
Exemplo n.º 20
0
 def get_reply_record(self, data):
     request = dnslib.DNSRecord.parse(data)
     qname = str(request.q.qname).lower()
     qtype = request.q.qtype
     dnsservers = self.dns_servers
     if qname.endswith('.in-addr.arpa'):
         ipaddr = '.'.join(reversed(qname[:-13].split('.')))
         record = dnslib.DNSRecord(header=dnslib.DNSHeader(
             id=request.header.id, qr=1, aa=1, ra=1),
                                   a=dnslib.RR(qname,
                                               rdata=dnslib.A(ipaddr)))
         return record
     if 'USERDNSDOMAIN' in os.environ:
         user_dnsdomain = '.' + os.environ['USERDNSDOMAIN'].lower()
         if qname.endswith(user_dnsdomain):
             qname = qname[:-len(user_dnsdomain)]
             if '.' not in qname:
                 if not self.dns_intranet_servers:
                     logging.warning(
                         'qname=%r is a plain hostname, need intranet dns server!!!',
                         qname)
                     return dnslib.DNSRecord(header=dnslib.DNSHeader(
                         id=request.header.id, rcode=3))
                 qname += user_dnsdomain
                 dnsservers = self.dns_intranet_servers
     try:
         return self.dns_cache.get((qname, qtype))
     except KeyError:
         pass
     try:
         dns_resolve = dnslib_resolve_over_tcp if qname.endswith(
             self.dns_tcpover) else dnslib_resolve_over_udp
         kwargs = {
             'blacklist': self.dns_blacklist,
             'turstservers': self.dns_trust_servers
         }
         record = dns_resolve(request, dnsservers, self.dns_timeout,
                              **kwargs)
         ttl = max(x.ttl for x in record.rr) if record.rr else 600
         self.dns_cache.set((qname, qtype), record, ttl * 2)
         return record
     except socket.gaierror as e:
         logging.warning('resolve %r failed: %r', qname, e)
         return dnslib.DNSRecord(
             header=dnslib.DNSHeader(id=request.header.id, rcode=3))
Exemplo n.º 21
0
def ip_encode(data, ipv6) -> list:
    """ 
        Encodes data to AAAA or A rdata types.
    """
    chunk_size = IPV6_LENGTH if ipv6 else IPV4_LENGTH
    data = pad_bytes(data, chunk_size)

    if (len(data) > chunk_size):
        data = chunk(data, chunk_size)
    else:
        data = [data]

    if (ipv6):
        qdata = [dns.AAAA(socket.inet_ntop(socket.AF_INET6, i)) for i in data]
    else:
        qdata = [dns.A(socket.inet_ntop(socket.AF_INET, i)) for i in data]

    return qdata
Exemplo n.º 22
0
	def set_questions(self, d, qs, res):
		reverse = {}
		ans = {}

		for i in range(0, len(d.questions)):
			qstr = str(d.questions[i].get_qname())

			# Check if overriden with new hostname
			if qstr[:-1] in qs:
				d.questions[i].set_qname(qs.get(qstr[:-1]) + ".")
				reverse[qs.get(qstr[:-1])] = qstr[:-1]

			# Check if we should resolve it to IP
			elif qstr[:-1] in res:
				ans[qstr[:-1]] = dnslib.RR(
					qstr[:-1],
					rdata=dnslib.A(res[qstr[:-1]])
				)
				
		return (d, reverse, ans)
Exemplo n.º 23
0
def _a_search(record, rr_list, auth_list, addi_list):
    """
    Searches and adds any A records for the domain.
    :param record: Overall record for domain
    :param rr_list: Current record list for the domain
    :param auth_list: Authority list for the domain
    :param addi_list: Additional list for the domain
    """
    try:
        _alias_search(dnslib.QTYPE.A, record, rr_list, auth_list, addi_list)
        a_record = record["A"]
        ttl = int(a_record["ttl"])
        for ip in a_record["value"]:
            rr_list.append(dnslib.RR(rname = record["domain"],
                                     rtype = dnslib.QTYPE.A,
                                     rdata = dnslib.A(ip),
                                     ttl   = ttl))
            _add_authority(record["domain"], auth_list)
            _add_additional(addi_list)
    except:
        pass
Exemplo n.º 24
0
def add_answer_to_query(required_data, query):
    qtype = query.q.qtype
    q = query.q

    # Для каждого типа запроса добавляем интересующий ответ
    if qtype == dnslib.QTYPE.A:
        # Добавляем все A адреса
        for addr in required_data.addresses:
            query.add_answer(
                dnslib.RR(rname=q.qname,
                          rclass=q.qclass,
                          rtype=q.qtype,
                          ttl=required_data.remain_ttl(),
                          rdata=dnslib.A(addr)))
    if qtype == dnslib.QTYPE.AAAA:
        # Добавляем все AAAA адреса
        for addr in required_data.addresses:
            query.add_answer(
                dnslib.RR(rname=q.qname,
                          rclass=q.qclass,
                          rtype=q.qtype,
                          ttl=required_data.remain_ttl(),
                          rdata=dnslib.AAAA(addr)))
    if qtype == dnslib.QTYPE.NS:
        # Добавляем все NS серверы
        for addr in required_data.servers:
            query.add_answer(
                dnslib.RR(rname=q.qname,
                          rclass=q.qclass,
                          rtype=q.qtype,
                          ttl=required_data.remain_ttl(),
                          rdata=dnslib.NS(addr)))
    if qtype == dnslib.QTYPE.PTR:
        # Добавляем PTR
        query.add_answer(
            dnslib.RR(rname=q.qname,
                      rclass=q.qclass,
                      rtype=q.qtype,
                      ttl=required_data.remain_ttl(),
                      rdata=dnslib.PTR(required_data.name)))
Exemplo n.º 25
0
Arquivo: dns.py Projeto: yy221/zelos
def create_dns_response(hostname="google.com", ip=None):
    """
    Create a DNS response packet for the specified hostname. If `ip` is
    specified (as a string, e.g., '127.0.0.1'), it will be used for the
    response. Otherwise, a not found (NXDOMAIN) response is returned.
    """
    try:
        if ip is None:
            d = dnslib.DNSRecord(
                dnslib.DNSHeader(qr=1, aa=1, ra=1, rcode=3),
                q=dnslib.DNSQuestion(hostname),
            )
        else:
            d = dnslib.DNSRecord(
                dnslib.DNSHeader(qr=1, aa=1, ra=1),
                q=dnslib.DNSQuestion(hostname),
                a=dnslib.RR(hostname, rdata=dnslib.A(ip)),
            )
        return d.pack()
    except Exception as e:
        print("DNS_CREATE failed:", e)
    return None
Exemplo n.º 26
0
Arquivo: dns.py Projeto: walidabn/ACME
    def handle(self):

        request = dnslib.DNSRecord.parse(self.request[0])
        """ see http://www.networksorcery.com/enp/protocol/dns.htm 
        QR flag is 1 (0 = Query, 1 = Response)
        AA flag is 1 (0 = Not authoritative, 1 = Is authoritative)
        
        """
        reply = dnslib.DNSRecord(dnslib.DNSHeader(id=request.header.id, qr=1, aa=1),
                                 q=request.q)

        reply.add_answer(dnslib.RR(
            rname=request.q.qname,
            rtype=1,
            rdata=dnslib.A(self.DNS_LOOKUP),

        ))

        request_name = str(request.q.qname)
        if request_name in self.TXT_LOOKUP:
            for answer in self.TXT_LOOKUP[request_name]:
                reply.add_answer(dnslib.RR(
                    request.q.qname,
                    ttl=300,
                    rtype=dnslib.QTYPE.TXT,
                    rdata=dnslib.TXT(answer.encode("utf-8"))
                ))
                print('dnsserver served txt record for {}: {}'.format(request_name, answer))
        else:
            print('dnsserver didn\'t find txt record for {}'.format(request_name))
            # print("{} not in memory".format(request_name))
            # print("memory", self.TXT_LOOKUP)
            # print(type(request_name))
            pass

        self.send_data(reply.pack())
Exemplo n.º 27
0
    def start(self):
        self.sDNS.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.sDNS.bind((self.interface, self.port))
        print("[*] Started DNS server on port {}".format(self.port))

        while self.running:
            data, addr = self.sDNS.recvfrom(512)
            parsedDNS = dnslib.DNSRecord.parse(data)

            # We send fake IP to adAS
            if (addr[0] in self.blacklist):
                ip = self.ipToSpoof
            else:
                ip = self.realIP

            print("[DNS] Response: {} -> {}".format(
                parsedDNS.questions[0].qname, ip))
            response = dnslib.DNSRecord(
                dnslib.DNSHeader(qr=1, aa=1, ra=1, id=parsedDNS.header.id),
                q=dnslib.DNSQuestion(parsedDNS.questions[0].qname),
                a=dnslib.RR(parsedDNS.questions[0].qname, rdata=dnslib.A(ip)))
            self.sDNS.sendto(response.pack(), addr)

        self.sDNS.close()
Exemplo n.º 28
0
    def resolve(self, request, handler):
        question = request.get_q()
        req_name = str(question.get_qname())
        # TXT = 16
        reply = request.reply()
        suffix = "._tox.{0}".format(self.ireg)

        if question.qtype != 16 and not req_name.endswith(self.ireg):
            reply.header.rcode = dnslib.RCODE.NXDOMAIN
            return reply

        if question.qtype == 16:
            if req_name == suffix[1:]:
                reply.add_answer(dnslib.RR(req_name, 16, ttl=0,
                    rdata=dnslib.TXT(self.cryptocore.public_key.encode("ascii"))))
                return reply
            if not req_name.endswith(suffix):
                reply.header.rcode = dnslib.RCODE.NXDOMAIN
                return reply
            user_name = req_name[:req_name.rfind(suffix)]
            if len(user_name) > NAME_LIMIT_HARD and user_name[0] == "_":
                encrypted = user_name.replace(".", "")[1:]
                try:
                    b = notsecure32_decode(encrypted)
                    nonce = b[:4] + (b"\0" * 20)
                    ck = b[4:36]
                    payload = b[36:]
                    name = self.cryptocore.dsrep_decode_name(ck, nonce, payload)
                except Exception:
                    print("error >_<")
                    reply.header.rcode = dnslib.RCODE.NXDOMAIN
                    return reply

                rec = self.store.get(name.decode("utf8"))
                if not rec:
                    reply.header.rcode = dnslib.RCODE.NXDOMAIN
                    return reply
                base = b"v=tox3;id="
                if rec.pin:
                    r_payload = "{0}{1}{2}".format(rec.public_key, rec.pin,
                                                   rec.checksum)
                else:
                    r_payload = "{0}00000000{1}".format(rec.public_key,
                                                        rec.checksum)
                msg = binascii.unhexlify(r_payload)
                nonce_reply = b[:4] + b"\x01" + (b"\0" * 19)
                ct = self.cryptocore.dsrec_encrypt_key(ck, nonce_reply, msg)

                key_part = notsecure32_encode(ct)
                reply.add_answer(dnslib.RR(req_name, 16, ttl=0,
                                 rdata=dnslib.TXT(b"".join((base, key_part)))))
                return reply
            else:
                rec = self.store.get(user_name)
                if not rec:
                    reply.header.rcode = dnslib.RCODE.NXDOMAIN
                    return reply
                else:
                    reply.add_answer(dnslib.RR(req_name, 16, ttl=0,
                                               rdata=dnslib.TXT(rec.record(0)
                                                            .encode("utf8"))))
                    return reply
        elif question.qtype == 6:
            self.update_soa()
            reply.add_answer(self.soa)
            return reply
        elif question.qtype == 2:
            for name in self.authority_list:
                reply.add_answer(dnslib.RR(req_name, 2, ttl=86400,
                                           rdata=dnslib.NS(name.encode("utf8"))
                                           ))
            return reply
        elif question.qtype == 1 and self.home_addresses:
            for ip in self.home_addresses:
                reply.add_answer(dnslib.RR(req_name, 1, ttl=3600,
                                           rdata=dnslib.A(ip)))
        elif question.qtype == 28 and self.home_addresses_6:
            for ip in self.home_addresses_6:
                reply.add_answer(dnslib.RR(req_name, 28, ttl=3600,
                                           rdata=dnslib.AAAA(ip)))
        else:
            reply.header.rcode = dnslib.RCODE.NXDOMAIN
            return reply
        return reply
Exemplo n.º 29
0
 def override(self, packet):
     dns_record = dnslib.DNSRecord.parse(packet)
     if str(dns_record.q.qname).lower() in overrides and dns_record.q.qtype == dnslib.QTYPE.A:
         dns_record.rr = [dnslib.RR(rname=dns_record.q.qname, rtype=dnslib.QTYPE.A, rclass=1, ttl=TTL, rdata=dnslib.A(overrides[str(dns_record.q.qname).lower()]))]
         print 'overrride', dns_record.rr[0]
     '''
     while True:
         change = False
         for i in range(0, len(dns_record.rr)):
             if str(dns_record.rr[i].rname).lower() in overrides:
                 if dns_record.rr[i].rtype == dnslib.QTYPE.A and str(dns_record.rr[i].rdata) != overrides[str(dns_record.rr[i].rname).lower()]:
                     dns_record.rr[i].rdata = dnslib.A(overrides[str(dns_record.rr[i].rname).lower()])
                     change = True
                     print dns_record.rr[i]
                 if dns_record.rr[i].rtype == dnslib.QTYPE.CNAME and str(dns_record.rr[i].rdata).lower() not in overrides:
                     overrides[str(dns_record.rr[i].rdata).lower()] = overrides[str(dns_record.rr[i].rname).lower()]
                     change = True
                     print dns_record.rr[i]
         if not change:
             break
     '''
     return dns_record.pack()
Exemplo n.º 30
0
    def processRequest(self, request):

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

        qname = request.q.qname
        qn = str(qname)
        qtype = request.q.qtype
        qt = dnslib.QTYPE[qtype]
        if qn == self.D or qn.endswith('.' + self.D):

            for name, rrs in self.records.items():
                if name == qn:
                    for rdata in rrs:
                        rqt = rdata.__class__.__name__
                        if qt in ['*', rqt]:
                            reply.add_answer(
                                dnslib.RR(rname=qname,
                                          rtype=getattr(dnslib.QTYPE, rqt),
                                          rclass=1,
                                          ttl=self.TTL,
                                          rdata=rdata))

            for rdata in self.ns_records:
                reply.add_ar(
                    dnslib.RR(rname=self.D,
                              rtype=dnslib.QTYPE.NS,
                              rclass=1,
                              ttl=self.TTL,
                              rdata=rdata))

            reply.add_auth(
                dnslib.RR(rname=self.D,
                          rtype=dnslib.QTYPE.SOA,
                          rclass=1,
                          ttl=self.TTL,
                          rdata=self.soa_record))

        for question in request.questions:

            if (question.qtype == dnslib.QTYPE.TXT):
                #only process TXT record requests
                content = str(question.qname)[:-1]
                if content.endswith(self.D[:-1]):
                    content = content[:-len(self.D[:-1]) - 1]

                key = content[:4]

                if key in self.fIP:
                    content = str(content[4:])
                    self.fIP[key][3] += content
                    self.fIP[key][1] -= len(content)
                    #print(key, content,len(content),self.fIP[key][1] )

                    #print("Left: "+str(self.fIP[sIP][1]))
                    self.progressBar(
                        self.fIP[key][1], self.fIP[key][4], "Receiving '" +
                        self.fIP[key][0] + "' with index " + key)
                    reply.add_answer(
                        dnslib.RR(rname=qname,
                                  rtype=question.qtype,
                                  rclass=1,
                                  ttl=self.TTL,
                                  rdata=dnslib.TXT(content)))
                    #reply.add_answer(dnslib.RR(rname=qname, rtype=question.qtype, rclass=1, ttl=self.TTL, rdata=dnslib.TXT("OK")))
                    if (self.fIP[key][1] == 0):
                        #we have received the entire file. Time to write it.
                        content_decoded = base64.standard_b64decode(
                            self.fIP[key][3])
                        with open(self.fIP[key][0], 'wb') as newfile:
                            newfile.write(content_decoded)

                        hashedWord = md5(content_decoded).hexdigest()
                        if (self.fIP[key][2] == hashedWord):
                            print("\nFile successfully received")
                            reply.add_answer(
                                dnslib.RR(rname=qname,
                                          rtype=question.qtype,
                                          rclass=1,
                                          ttl=self.TTL,
                                          rdata=dnslib.TXT("OK")))

                        else:
                            print("\nFile received but failed hash:")
                            reply.add_answer(
                                dnslib.RR(rname=qname,
                                          rtype=question.qtype,
                                          rclass=1,
                                          ttl=self.TTL,
                                          rdata=dnslib.TXT("FAIL HASH")))

                        del self.fIP[key]

                else:
                    # new connection. we expect a file name
                    print("New file:", content)
                    parts = content.split("|")
                    if (len(parts) == 3):
                        #we have valid request
                        print("new file upload: ", content)
                        self.fIP[parts[2][:4]] = [
                            os.path.basename(parts[0]),
                            int(parts[1]), parts[2], "",
                            int(parts[1])
                        ]
                    reply.add_answer(
                        dnslib.RR(rname=qname,
                                  rtype=question.qtype,
                                  rclass=1,
                                  ttl=self.TTL,
                                  rdata=dnslib.TXT("OK")))

            else:
                reply.add_answer(
                    dnslib.RR(rname=qname,
                              rtype=question.qtype,
                              rclass=1,
                              ttl=self.TTL,
                              rdata=dnslib.A(self.IP)))

            #print("responding:",reply)
            return reply.pack()