def show_info(data, direction): try: from dns import message as m except ImportError: print "Install dnspython module will give you more response infomation." else: if direction == 0: print "query:\n\t", "\n\t".join(str(m.from_wire(data)).split("\n")) print "\n================" elif direction == 1: print "response:\n\t","\n\t".join(str(m.from_wire(data)).split("\n")) print "\n================"
def showInfo(self, data, direction): try: from dns import message as m except ImportError: print "Install dnspython module will give you more response infomation." else: if direction == 0: print "query:\n\t", "\n\t".join(str(m.from_wire(data)).split("\n")) print "\n================" elif direction == 1: print "response:\n\t", "\n\t".join(str(m.from_wire(data)).split("\n")) print "\n================"
def get_response(data, spoofs, spoof_all): message = from_wire(data) domain = str(message.question[0].name)[:-1] rrset = None response = make_response(message) if spoofs and message.question[ 0].rdtype == dns.rdatatype.A and domain in spoofs: print('Spoofing query for %s' % domain) rrset = from_text(message.question[0].name, 300, dns.rdataclass.IN, dns.rdatatype.A, spoofs[domain]) elif spoof_all and message.question[0].rdtype == dns.rdatatype.A: print('Spoofing query for %s due to spoof all' % domain) rrset = from_text(message.question[0].name, 300, dns.rdataclass.IN, dns.rdatatype.A, spoof_all) else: print('Not spoofing %s query for %s' % (dns.rdatatype.to_text(message.question[0].rdtype), domain)) resolver = Resolver() try: rrset = resolver.query(message.question[0].name, message.question[0].rdtype, message.question[0].rdclass).rrset except dns.resolver.NXDOMAIN: response.set_rcode(dns.rcode.NXDOMAIN) except dns.resolver.NoAnswer: response.set_rcode(dns.rcode.NOERROR) if rrset: response.answer.append(rrset) return response
def _actually_resolve(self, name, timeout): timeout = timeout / float(len(self.nameservers)) try: for server in self.nameservers: # Try each nameserver in succession. self.addr = server query = make_query(name, A) send(query.to_wire()) start = time.time() remaining = timeout while True: # Handle the possibility of responses that are not to our # original request - they are ignored and we wait for a # response that matches our query. item, data = first(datagram=True, sleep=remaining) if item == "datagram": response = from_wire(data) if query.is_response(response): if response.answer: a_records = [r for r in response.answer if r.rdtype == A] return [item.address for item in a_records[0].items] raise NotFound else: # Not a response to our query - continue waiting for # one that is. remaining = remaining - (time.time() - start) elif item == "sleep": break else: raise Timeout(name) finally: self.addr = self.primary
def _run(self): self._running = True while self._running: try: read, _, _ = select.select(self._socks, [], [], 1) etime = time.time() # Response is wait, stop the clock for sock in read: dgram, addr = sock.recvfrom(4096) dgram = dm.from_wire(dgram) # Ignore packets that are not responses if not dgram.flags & df.QR: continue # IPv6 will return additional details not needed for lookup addr = (addr[0], addr[1]) key = self._key(dgram, addr) with self._lock: callback, data, stime = self._callbacks[key] del self._callbacks[key] callback(dgram, data, etime - stime) except socket.timeout: pass except (KeyboardInterrupt, SystemExit): raise except Exception as e: print >>sys.stderr, 'Exception %s: %s' % (e, traceback.format_exc()) self.running = False
def handle(self, data, address): print("成功解析{}次, 共解析{}次".format(self.stats["success"], self.stats["total"])) self.stats["total"] += 1 query_msg = from_wire(data) assert len(query_msg.question) == 1 buffer = self.buffer.get(str(query_msg.question[0].name)) if buffer: response_msg = make_response(query_msg) response_msg.answer = buffer self.socket.sendto(response_msg.to_wire(), address) self.stats["success"] += 1 return client = DNSClient() for _ in range(2): server = self.get_server(query_msg.question) client.set_address(server) response_msg = client.query(query_msg) if response_msg and response_msg.answer: self.buffer[str( query_msg.question[0].name)] = response_msg.answer self.socket.sendto(response_msg.to_wire(), address) self.stats["success"] += 1 return server = self.get_server("") client.set_address(server) response_msg = client.query(query_msg) if response_msg and response_msg.answer: self.buffer[str(query_msg.question[0].name)] = response_msg.answer self.socket.sendto(response_msg.to_wire(), address) self.stats["success"] += 1 print("{}解析错误".format(str(query_msg.question[0].name)))
def _run(self): self._running = True while self._running: try: read, _, _ = select.select(self._socks, [], [], 1) etime = time.time() # Response is wait, stop the clock for sock in read: dgram, addr = sock.recvfrom(4096) dgram = dm.from_wire(dgram) # Ignore packets that are not responses if not dgram.flags & df.QR: continue # IPv6 will return additional details not needed for lookup addr = (addr[0], addr[1]) key = self._key(dgram, addr) with self._lock: callback, data, stime = self._callbacks[key] del self._callbacks[key] callback(dgram, data, etime - stime) except socket.timeout: pass except (KeyboardInterrupt, SystemExit): raise except Exception as e: print >> sys.stderr, 'Exception %s: %s' % ( e, traceback.format_exc()) self.running = False
def data_process(self,data_get): data_message = message.from_wire(data_get).to_text() # print(data_message) data_list = data_message.split('\n') data_dic = {} Question = [] Answer = [] data_dic['id'] = data_list[0][2:] for index in range(len(data_list)): if index > data_list.index(';QUESTION') and index < data_list.index(';ANSWER'): #question data_temp = data_list[index].split(' ') Question.append(data_temp) # # question : name,class,type for example: www.baidu.com. IN A # elif index > data_list.index(';ANSWER') and index < data_list.index(';AUTHORITY'): #answer data_temp = data_list[index].split(' ') if data_temp[3] == 'MX': #对于MX类型 省略优先级 data_temp.remove(data_temp[4]) Answer.append(data_temp) # # answer : name,ttl,class,type,value for example :www.baidu.com. 168 IN A 39.156.66.18 # data_dic['QUESTION'] = Question data_dic['ANSWER'] = Answer return data_dic
def handle(self, data, addr): logging.info("Handling request for %s" % str(addr)) request = message.from_wire(data) name = self._name_from_message(request) if name in self.config['mapping']: logging.debug("Found %s in config file" % name) return self._make_response_for(request, name, self.config['mapping'][name]) else: logging.debug("Resolved %s from real dns" % name) return query.udp(request, self.config['general']['nameserver'])
def _handle_raw(self, wire): # pass stime = 0 etime = time.time() q = None address = None try: r = message.from_wire(wire) self.rcount += 1 (q, stime, address) = self.outstanding_queries[r.id] if q.is_response(r): del self.outstanding_queries[q.id] except Exception, e: print >>sys.stderr, "err", type(e), e
async def query_worker(self, host, q_type): try: if q_type == 'A': mq_type = 1 elif q_type == 'AAAA': mq_type = 28 query = message.make_query(host.decode('utf-8'), mq_type) query = query.to_wire() s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) await self.loop.sock_connect(s, (self.config['dns'], 53)) await self.loop.sock_sendall(s, query) result = await asyncio.wait_for(self.loop.sock_recv(s, 1024), 4) await self.clean_up(s, None) result = message.from_wire(result) return self.decode(str(result), q_type) except Exception as error: traceback.clear_frames(error.__traceback__) error.__traceback__ = None await self.clean_up(s, None)
def get_name_and_type_from_dns_question(request: Request) -> Message: logger = logging.getLogger("doh-server") accept_header = request.headers.get("Accept") if request.method == "GET": if accept_header == DOH_JSON_CONTENT_TYPE: qname = request.args.get(DOH_DNS_JSON_PARAM["name"], None) rdtype = request.args.get(DOH_DNS_JSON_PARAM["type"], None) if qname and rdtype: return dns.message.make_query(qname=qname, rdtype=rdtype) else: dns_request = request.args.get(DOH_DNS_PARAM, None) if dns_request: return extract_from_params(dns_request) elif request.method == "POST" and request.content_type == DOH_CONTENT_TYPE: body = await request.get_data() if body: try: return message.from_wire(body) except Exception as ex: logger.info(str(ex))
def handle(self): data = self.request.recv(1024) dlen, = unpack('>H', data[:2]) while dlen > len(data[2:]): data += self.request.recv(1024) dnsp = data[2:dlen + 2] LOG.info('DNS: Client sent authorization') pckt = from_wire(dnsp) LOG.debug(str(pckt)) nti = None for rd in pckt.additional[0]: nti = rd.key if not nti: return if self.server.config.mode == 'RELAY': authdata = get_auth_data(nti, self.server.config) self.do_relay(authdata) else: # Unconstrained delegation mode authdata = get_kerberos_loot(token, self.server.config) self.do_attack(authdata)
def _handle_query(self, metadata, data, fz, pz): try: dns_msg = message_parser.from_wire(data) except (message_parser.ShortHeader, message_parser.TrailingJunk, dns.name.BadLabelType): self._view.error( 'Error while parsing DNS message. Pass Thru policy applied.') self.DECISION_DICT[self.PASSTHRU_POLICY](self, fz, metadata=metadata, raw=data) return # Figuring out which policy to apply verdict = self._find_policy(pz, dns_msg.question[0]) if verdict is None: self._view.error('Could not determine a verdict. Dropping.') return self.DECISION_DICT[verdict](self, fz, metadata=metadata, parsed=dns_msg)
async def _process(sock, resolve, data, addr): try: msg = message.from_wire(data) except: print(f'[Serve53] invalid message from {addr}') return try: do = "1" if msg.flags & flags.DO else "0" rr = msg.question[0] res = await resolve(name=rr.name, type=rr.rdtype, do=do) want_nsid = edns.NSID in (o.otype for o in msg.options) msg = message.make_response(msg) msg.set_rcode(res.get('Status', rcode.NOERROR)) msg.question, msg.answer = [], [] msg.flags |= flags.from_text(" ".join(k for k, v in res.items() if len(k) == 2 and v is True)) for m, n in ((msg.question, "Question"), (msg.answer, "Answer"), (msg.authority, "Authority"), (msg.additional, "Additional")): for a in res.get(n, []): data = [a['data']] if 'data' in a else [] m.append( rrset.from_text(a['name'], a.get('TTL'), "IN", a['type'], *data)) if want_nsid: comment = res.get("Comment") nsid = f"named1/{res['NameClient']}{': ' + comment if comment else ''}" msg.options.append(edns.GenericOption(edns.NSID, nsid.encode())) except Exception as e: # Don't die on errors/timeouts but report back a failure if not isinstance(e, trio.TooSlowError): print(f"{e!r}\n{msg}") msg.flags = flags.QR msg.set_rcode(rcode.SERVFAIL) try: await sock.sendto(msg.to_wire(origin=origin), addr) except Exception as e: raise Exception( f"Malformed output with answer:\n{res}\n\nand msg:\n{msg}") from e
def udp_timing(qname, where, rdtype=rdatatype.A, rdclass=rdataclass.IN, timeout=5.0, port=53, af=None, source=None, source_port=0, ignore_unexpected=False, one_rr_per_rrset=False): rc = 'FAIL' q = message.make_query(qname, rdtype, rdclass) wire = q.to_wire() (af, destination, source) = query._destination_and_source(af, where, port, source, source_port) s = socket.socket(af, socket.SOCK_DGRAM, 0) try: expiration = query._compute_expiration(timeout) s.setblocking(0) if source is not None: s.bind(source) query._wait_for_writable(s, expiration) t1 = time() s.sendto(wire, destination) while 1: query._wait_for_readable(s, expiration) (wire, from_address) = s.recvfrom(65535) t2 = time() if from_address == destination or \ (dns.inet.is_multicast(where) and \ from_address[1] == destination[1]): rc = 'OK' if not ignore_unexpected: rc = 'UnexpectedSource' break finally: s.close() r = message.from_wire(wire, keyring=q.keyring, request_mac=q.mac, one_rr_per_rrset=one_rr_per_rrset) if not q.is_response(r): rc = 'BadResponse' return (r, q, t1, t2), rc
def doh_query(domain, dnsname, detected): message = dns.make_query(domain, 1) dns_req = base64.urlsafe_b64encode(message.to_wire()).\ decode("UTF8").rstrip("=") try: resp = requests.get( dnssec[dnsname]['url'], params={"dns": dns_req}, headers={"Content-type": "application/dns-message"}) except requests.RequestException as reqerror: detected[dnsname] = dict(report_DoH='Error with DNSSec Service', domain=domain) return detected if "application/dns-message" not in resp.headers["Content-Type"]: detected[dnsname] = dict(report_DoH='DNS is not response', domain=domain, A='') return detected answers = [ response.to_text().split("\n") for response in dns.from_wire(resp.content).answer ] ips = [answer.split()[4] for answer in answers[0]] if not ips: detected[dnsname] = dict(report_DoH='Domain does not exist', domain=domain, A='') elif dnssec[dnsname]['malware_ip'] in ips: detected[dnsname] = dict(report_DoH='Malware', domain=domain, A='') else: detected[dnsname] = dict(report_DoH='Good', domain=domain, A=ips) return detected
def _actually_resolve(self, name, timeout): timeout = timeout / float(len(self.nameservers)) try: for server in self.nameservers: # Try each nameserver in succession. self.addr = server query = make_query(name, A) send(query.to_wire()) start = time.time() remaining = timeout while True: # Handle the possibility of responses that are not to our # original request - they are ignored and we wait for a # response that matches our query. item, data = first(datagram=True, sleep=remaining) if item == 'datagram': response = from_wire(data) if query.is_response(response): if response.answer: a_records = [ r for r in response.answer if r.rdtype == A ] return [ item.address for item in a_records[0].items ] raise NotFound else: # Not a response to our query - continue waiting for # one that is. remaining = remaining - (time.time() - start) elif item == 'sleep': break else: raise Timeout(name) finally: self.addr = self.primary
def handle_read(self): data = self.recv(4096) answer = message.from_wire(data) print answer.answer[0].items[0].target.to_text(True)
def run(self): flag = False data_dic = self.data_process(self.c_data) #查询数据库 # print(data_dic) db = DBFacade() _name , _type = data_dic['QUESTION'][0][0],data_dic['QUESTION'][0][2] #原始请求 answer = db.query(_name , _type) flag = (answer == []) #answer = [['www.shifen.com.','222','IN','A','39.20.1.1'],['www.shifen.com.','222','IN','A','25.69.6.3']] # print("---------------ans-----------") # print("answer: ",answer) if flag == False: #用数据库查到的数据向客户端发送 # print("---------------") # print("send case 1") # print("----------------") remark = 'Local' if answer[0][4] == '0.0.0.0' or answer[0][4] == '0:0:0:0:0:0:0:0': #拦截不良网站 print('拦截不良网站:', _name) remark = 'Rejected' elif answer[0][3] == 'MX': #answer 的处理 (MX) for i in range(len(answer)): answer[i].insert(4,'5') temp_message = message.from_wire(self.c_data) temp_message = message.make_response(temp_message).to_text() temp_list = temp_message.split("\n") index = temp_list.index(";ANSWER") for ret in answer: temp_list.insert(index+1,' '.join(ret)) index += 1 data_send = '\n'.join(temp_list) data_send = message.from_text(data_send) data_send = data_send.to_wire() self.c_socket.sendto(data_send, self.c_addr) #向客户端发回 else: #请求DNS服务器 self.s_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 与DNS服务器通信的套接字 # print("---------------") # print("send case 2") # print("----------------") self.s_socket.sendto(self.c_data, (self.send_ip, self.send_port)) #向服务器发送 self.s_socket.settimeout(self.timeout_time) #设置超时时间 try: data, addr = self.s_socket.recvfrom(1024) #读回DNS服务器的返回 remark = 'Remote' # print(data) # print(message.from_wire(data)) data_dic = self.data_process(data) # 存数据库 data_dic['ANSWER'] db = DBFacade() db.insert_records(data_dic["ANSWER"]) #发回到客户端 self.c_socket.sendto(data, self.c_addr) except socket.timeout: #DNS超时 print('请求超时:', _name) remark = 'TimeOut' self.s_socket.close() #获取DNS的返回后(或超时)关闭与服务器通信的socket #handler做完了一项工作,插入日志,退出 logger.info('%s:%s %s %s %s'%(self.c_addr[0], self.c_addr[1], _name , _type, remark))
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
async def _get_dns_response(qname, record_type): query_bytes = message.make_query(qname, record_type).to_wire() response_bytes = await dns_c2.handler.generate_dns_tunneling_response_bytes( query_bytes) return message.from_wire(response_bytes)
def handle(self, data, address): query_msg = from_wire(data) assert len(query_msg.question) == 1 client = DNSClient('192.168.6.2') response_msg = client.query(query_msg) self.socket.sendto(response_msg.to_wire(), address)
def main(): s = Socket(AF_INET, SOCK_DGRAM) s.bind(("", 53)) while True: message = s.recv(1500) print repr(from_wire(message))
def _get_dns_response(qname, record_type): query_bytes = message.make_query(qname, record_type).to_wire() response_bytes = loop.run_until_complete( dns_c2.handler.generate_dns_tunneling_response_bytes(query_bytes)) return message.from_wire(response_bytes)
def dns_doh(domain, threat): detected = {} message = doh.make_query(domain, 'A') dns_req = base64.urlsafe_b64encode(message.to_wire()).\ decode("UTF8").rstrip("=") try: resp = requests.get(dnssec['elevenpaths']['url'], params={"dns": dns_req}, headers={"Content-type": ct}) except requests.RequestException: return detected if ct not in resp.headers["Content-Type"]: detected = {} return detected ips = [] answers = [] for response in doh.from_wire(resp.content).answer: answers = response.to_text().split("\n") for answer in answers: output = answer.split() ips.append(output[len(output) - 1]) if dnssec['elevenpaths']['malware_ip'] in ips: detected[threat] = {} detected[threat]['report_DoH'] = 'Malware' detected[threat]['domain'] = domain detected[threat]['A'] = '' detected[threat]['MX'] = '' elif not ips: detected = () else: detected[threat] = {} detected[threat]['report_DoH'] = 'Good' detected[threat]['domain'] = domain detected[threat]['A'] = ips mess_mx = doh.make_query(domain, 'MX') dns_mx = base64.urlsafe_b64encode(mess_mx.to_wire()).\ decode("UTF8").rstrip("=") try: res_mx = requests.get(dnssec['elevenpaths']['url'], params={"dns": dns_mx}, headers={"Content-type": ct}) except requests.RequestException: detected[threat]['MX'] = '' return detected if ct not in res_mx.headers["Content-Type"]: detected[threat]['MX'] = '' return detected detected[threat]['MX'] = [] ans = [] for response in doh.from_wire(res_mx.content).answer: ans = response.to_text().split("\n") for ans_mx in ans: output = ans_mx.split() detected[threat]['MX'].append(output[len(output) - 1]) return detected
def handle_read(self): data = self.recv(4096) answer = message.from_wire(data) print answer.answer[0].to_text()