def addRecord(self, domain, host, ip, klass, type, ttl): host = "%s." % host records = [x for x in self.zones if x.domain == domain] if not records: raise RuntimeError("Invalid domain") record = records[0] file = record.file zone = dns.zone.from_file(file, os.path.basename(file), relativize=False) node = zone.get_node(host, create=True) if type == "A": t = dns.rdatatype.A if klass == "IN": k = dns.rdataclass.IN ds = node.get_rdataset(t, k, covers=dns.rdatatype.NONE, create=True) ds.ttl = ttl if type == "A" and klass == "IN": item = A(k, t, ip) ds.items.append(item) # update version for k, v in zone.nodes.iteritems(): for ds in v.rdatasets: if ds.rdtype == dns.rdatatype.SOA: for item in ds.items: item.serial += 1 zone.to_file(file, relativize=False) self.restart()
def fake_srv_(qname, rdtype): try: ans = fake_hosts[qname, rdtype] except KeyError: raise DNSException(f"unknown test host: {qname} {rdtype}") rv: List[Union[A, SRV]] = [] if rdtype == "A": for entry in ans: rv.append(A("IN", "A", entry)) else: for entry in ans: pri, w, port, target = entry.split() rv.append(SRV("IN", "SRV", int(pri), int(w), int(port), target)) return rv
class hostinfo(object): """Host information class""" A_type = dns.rdatatype.from_text('A') AAAA_type = dns.rdatatype.from_text('AAAA') NS_type = dns.rdatatype.from_text('NS') NAME_CLASH = A(1, 1, "127.0.53.53") def __init__(self): self._resolver = dns.resolver.Resolver() self._resolver.Timeout = 2.0 self._resolver.lifetime = 6.0 #self._resolver.cache = dns.resolver.LRUCache() self._resolver.search = list() #Ensure no search suffixes self._gi = pygeoip.GeoIP('datasources/GeoIP.dat') self._giv6 = pygeoip.GeoIP('datasources/GeoIPv6.dat') def do_query(self, prefix, sHostname, rdatatype): try: if prefix: domainname = dns.name.from_text(prefix + '.' + sHostname, origin=dns.name.root) else: domainname = dns.name.from_text(sHostname, origin=dns.name.root) dnsAnswers = self._resolver.query(domainname, rdatatype) if self.NAME_CLASH in dnsAnswers.rrset: raise dns.resolver.NXDOMAIN #Fake NX record for name clashes else: return dnsAnswers except dns.exception.Timeout: return None except dns.resolver.NoAnswer: return None except dns.resolver.NoNameservers: return None def getWWW(self, sHostname): return self.do_query('www', sHostname, self.A_type) def getWWWv6(self, sHostname): return self.do_query('www', sHostname, self.AAAA_type) def getM(self, sHostname): return self.do_query('m', sHostname, self.A_type) def getMv6(self, sHostname): return self.do_query('m', sHostname, self.AAAA_type) def getWEBMail(self, sHostname): return self.do_query('webmail', sHostname, self.A_type) def getWEBMailv6(self, sHostname): return self.do_query('webmail', sHostname, self.AAAA_type) def getMX(self, sHostname): # MX try: return self.do_query(None, sHostname, dns.rdatatype.from_text('MX')) except dns.resolver.NXDOMAIN: #Special case, return None rather than throwing NXDOMAIN (TODO figure out why!) return None def getNS(self, sHostname): return self.do_query(None, sHostname, self.NS_type) def getSOA(self, sHostname): return None def getNSServers(self, sHostname): nameservers = self._resolver.query(sHostname,'NS') ns = [] for rdata in nameservers: server = str(rdata) ns.append(server) return ns def getIPv4(self, sHostname): return self.do_query(None, sHostname, self.A_type) def getIPv6(self, sHostname): return self.do_query(None, sHostname, self.AAAA_type) def getGeobyIP(self, sIP): try: # Geo Location return self._gi.country_code_by_addr(sIP) except Exception: pass def getGeobyIPv6(self, sIP): try: # Geo Location return self._giv6.country_code_by_addr(sIP) except Exception: pass # # these are used by the v2 AJAX API # def getGeoImagebyIPv4new(self, sIP): try: countrycode = self.getGeobyIP(sIP) if countrycode: return "/flags/flags-iso/shiny/16/"+ countrycode + ".png" except Exception: pass return "/flags/flags-iso/shiny/16/_unknown.png" def getGeoImagebyIPv6new(self, sIP): try: countrycode = self.getGeobyIPv6(sIP) if countrycode: return "/flags/flags-iso/shiny/16/"+ countrycode + ".png" except Exception: pass return "/flags/flags-iso/shiny/16/_unknown.png"
from dns.rdtypes.ANY.MX import MX from dns.rdtypes.ANY.TXT import TXT from dns.resolver import NXDOMAIN, NoAnswer, NoNameservers, Timeout class RRset(object): def __init__(self): self.address = "192.0.2.1" class RRsetInvalid(object): def __init__(self): self.address = "000.0.0.0" _A_RECORD = A("IN", "A", "1.2.3.4") _MX_RECORD_1 = MX("IN", "MX", 10, Name("mx.example.com".split("."))) _MX_RECORD_2 = MX("IN", "MX", 10, Name("mx2.example.com".split("."))) _MX_RECORD_3 = MX("IN", "MX", 10, Name("mx3.example.com".split("."))) _SPF_RECORD = TXT("IN", "TXT", ["v=spf1 mx -all"]) _DMARC_RECORD = TXT("IN", "TXT", ["v=DMARC1 p=reject"]) _DKIM_RECORD = TXT("IN", "TXT", ["v=DKIM1 p=XXXXX"]) _BAD_MX_RECORD = MX("IN", "MX", 10, Name("bad-response.example.com".split("."))) _DNE_MX_RECORD = MX("IN", "MX", 10, Name("does-not-exist.example.com".split("."))) _MX_RECORDS = [_MX_RECORD_1] _IP_SET_RECORDS = [RRset()] _IPV4_RECORD_1 = (socket.AF_INET, socket.SOCK_STREAM, 6, "", ("192.0.2.1", 25)) _IPV4_RECORD_2 = (socket.AF_INET, socket.SOCK_STREAM, 6, "", ("192.0.2.2", 25))
def collector(self, packet): packetdata = None try: eth = ImpactDecoder.EthDecoder().decode(packet) off = eth.get_header_size() if eth.get_ether_type() == ImpactPacket.IP.ethertype: ip_decoder = ImpactDecoder.IPDecoder() ip = ip_decoder.decode(packet[off:]) dst = ip.get_ip_dst() src = ip.get_ip_src() if ip.get_ip_p() == ImpactPacket.UDP.protocol: udp = ip.child() payload = udp.child().get_bytes().tostring() try: import hexdump try: msg = message.from_wire(payload) except Exception as e: # Not an acceptable DNS packet return None if len(msg.answer) > 0: # Packet should not have an answer section return None if len(msg.question) > 0: for q in msg.question: #if hasattr(q, 'name'): if q.rdtype == rdatatype.A: if self.PROPERTIES['subdomain']['Value']: prefix = '.%s.%s.' % ( self.PROPERTIES['subdomain'] ['Value'], self.PROPERTIES['domain']['Value']) else: prefix = '.%s.' % ( self.PROPERTIES['domain']['Value']) if prefix == q.name.to_text( )[-len(prefix):]: # Send a reply to the DNS packet try: r = message.make_response(msg) a = A(rdataclass.IN, rdatatype.A, '79.70.84.71' ) # OFTG in dotted-decimal rrs = rrset.from_rdata( q.name.to_text(), 30, a) r.answer.append(rrs) data = ImpactPacket.Data( r.to_wire()) rudp = ImpactPacket.UDP() rudp.set_uh_sport(53) rudp.set_uh_dport(12345) rudp.contains(data) rip = ImpactPacket.IP() rip.set_ip_dst(src) rip.set_ip_src(self.getlocaladdr()) rip.contains(rudp) s = socket.socket( socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_UDP) s.setsockopt( socket.IPPROTO_IP, socket.IP_HDRINCL, 1) s.sendto(rip.get_packet(), (src, 12345)) except Exception as e: self.logger.error( 'Failed to send reply packet with %s: %s' % (self.__class__.__name__, e)) dnsdata = q.name.to_text( )[:-len(prefix)] dnsdata = self.dnsb64unescape(dnsdata) payload = self.decoder(dnsdata) result = payload # TODO: Fix results result['Source Host'] = src result['Protocol Subtype'] = 'Port' result[ 'Subtype'] = 53 #str(ip.child().get_uh_sport()) return result except DNSException: pass except Exception as e: if e: print 'Error %s' % e.message raise elif eth.get_ether_type() == IP6.IP6.ethertype: ip6_decoder = ImpactDecoder.IP6Decoder() ip6 = ip6_decoder.decode(packet[off:]) src = ip6.get_source_address() packetdata = ip6.get_data_as_string() self.logger.debug( 'Skipping IPv6 packet (not supported for this plugin)') if not packetdata: return None return None except Exception as e: raise return None
def dns_ns_query_response(): answer = [] answer.append(A(1, 1, '216.239.32.10')) return answer