def action(self, packet): targetip = utils.bin_to_ip(packet.data.src) targetport = 137 nbns_response = packet.data.data.data nbns_response.op = 0x8500 # For each question, add an answer for query in nbns_response.qd: name = decode_name(query.name).rstrip() address = self.getAddress(name) if not address: out.debug("%s: Skipped Query from %s for %s" % (self.getName(), targetip, name), 0) continue answer = NS.RR() answer.name = query.name # We reinsert in encoded format answer.type = query.type answer.cls = query.cls answer.ttl = 120 # Not very long TTL answer.rlen = 6 answer.rdata = '\x00\x00' + utils.ip_to_bin(address) # 0x0000 is flags for Unique name + B-Node nbns_response.an.append(answer) nbns_response.qd = [] if len(nbns_response.an) == 0: return False # Response is a UDP packet with 137 source port and Query's IP+Port as destination sock = socket(AF_INET, SOCK_DGRAM) sock.bind(('0.0.0.0', targetport)) sock.sendto(str(nbns_response), (targetip, packet.data.data.sport)) sock.close() for answer in nbns_response.an: out.verbose("%s: \tResponse: %s - %s" % (self.getName(), decode_name(answer.name).rstrip(), utils.bin_to_ip(answer.rdata[2:]))) return True
def condition(self, packet): # Should be an IPv4 packet if packet.type != ETH_TYPE_IP: return False # Should be a broadcast request dstip = utils.bin_to_ip(packet.data.dst) if dstip != utils.get_iface_bcast(self.interface) and dstip != "255.255.255.255": return False # Should be a UDP packet if packet.data.p != IP_PROTO_UDP: return False # Should be from port 137 to port 137 if packet.data.data.dport != 137 or packet.data.data.dport != 137: return False # Must be a Name Query # bit 1 = Message is a Query # bit 2-5 = Opcode: Name Query # We check this so we don't reply to Registration Queries if packet.data.data.data.op & 0xf800 != 0: return False out.verbose("%s: Request from %s" % (self.getName(), utils.bin_to_ip(packet.data.src))) out.verbose("%s: \tQueries: %s" % (self.getName(), ' '.join([decode_name(x.name).rstrip() for x in packet.data.data.data.qd]))) return True
def action(self, packet): ifname = self.interface[0] targetip = utils.bin_to_ip(packet.data.tpa) srcip = utils.bin_to_ip(packet.data.spa) # Determine what mac address to use targetmac = self.getAddress(targetip) if not targetmac: return False # Ethernet: # We set source address as destination packet.dst = packet.src # And we set source address as our address packet.src = utils.mac_to_bin(targetmac) # ARP: # change OP to ARP Reply packet.data.op = dpkt.arp.ARP_OP_REPLY # Set target mac as sender mac packet.data.tha = packet.data.sha # Flip target IP and sender IP packet.data.tpa, packet.data.spa= packet.data.spa, packet.data.tpa # Set sender mac as our own mac packet.data.sha = utils.mac_to_bin(targetmac) # Time to send! utils.send_raw(ifname, str(packet)) # Log action out.verbose("%s module: ARP response to %s: %s at %s " % (self.getName(), srcip, targetip, targetmac)) return True
def startListener(self): p = pcap.pcapObject() p.open_live(self.getInterfaceName(), 1600, 0, 100) out.verbose("legitHost listener started") try: while True: p.dispatch(1, self.handlePackets) except KeyboardInterrupt: out.error("Got keyboard interrupt.") self.stop()
def condition(self, packet): # Should be an ARP packet if packet.type != dpkt.ethernet.ETH_TYPE_ARP: return False # Check that ARP type == Request if packet.data.op != dpkt.arp.ARP_OP_REQUEST: return False targetip = utils.bin_to_ip(packet.data.tpa) srcip = utils.bin_to_ip(packet.data.spa) out.verbose("%s: Request for %s from %s" % (self.getName(), targetip, srcip)) return True
def condition(self, packet): # Should be an IPv4 packet if packet.type != dpkt.ethernet.ETH_TYPE_IP: return False # Should be a UDP packet if packet.data.p != dpkt.ip.IP_PROTO_UDP: return False # Should have a 224.0.0.252:5355 destination if packet.data.dst != utils.ip_to_bin("224.0.0.252"): return False if packet.data.data.dport != 5355: return False # And is a LLMNR Request if packet.data.data.data.op & 0x8000 != 0: return False out.verbose("%s: LLMNR request from %s" % (self.getName(), utils.bin_to_ip(packet.data.src))) out.verbose("%s: \tQueries: %s" % (self.getName(), ' '.join([x.name for x in packet.data.data.data.qd]))) return True
def action(self, packet): targetip = utils.bin_to_ip(packet.data.src) targetport = 5355 llmnr_response = packet.data.data.data llmnr_response.op = 0x8000 # For each question, add an answer for query in llmnr_response.qd: address = self.getAddress(query.name, query.type) if not address: out.debug("%s: Skipped query from %s for %s" % (self.getName(), targetip, query.name), 0) continue answer = dpkt.dns.DNS.RR() answer.name = query.name answer.type = query.type answer.cls = query.cls answer.ttl = 30 if answer.type == dpkt.dns.DNS_A: answer.rlen = 4 answer.rdata = utils.ip_to_bin(address) elif answer.type == dpkt.dns.DNS_AAAA: answer.rlen = 16 answer.rdata = utils.ip6_to_bin(address) llmnr_response.an.append(answer) if len(llmnr_response.an) == 0: return False # Response is a UDP packet with 5355 source port and Query's source port # as destination port. sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.bind(('0.0.0.0', targetport)) sock.sendto(str(llmnr_response), (targetip, packet.data.data.sport)) sock.close() for answer in llmnr_response.an: if answer.type == dpkt.dns.DNS_A: out.verbose("%s: \tResponse: %s - %s" % (self.getName(), answer.name, utils.bin_to_ip(answer.rdata))) elif answer.type == dpkt.dns.DNS_AAAA: out.verbose("%s: \tResponse: %s - %s" % (self.getName(), answer.name, utils.bin_to_ip6(answer.rdata))) return True
def stop(self): # Anything to clean before exiting out.verbose("Exiting.") exit()