def etherleak(target, **kargs): """Exploit Etherleak flaw""" return srp(Ether() / ARP(pdst=target), prn=lambda s_r: conf.padding_layer in s_r[1] and hexstr(s_r[1][ conf.padding_layer].load), filter="arp", **kargs)
def arp_request(ip_address, queue=None): # 发送二层数据帧 result_raw = srp(Ether(dst='FF:FF:FF:FF:FF:FF') / ARP(op=1, hwdst='00:00:00:00:00:00', pdst=ip_address), timeout=1, verbose=False) try: # 把响应的数据包对,产生清单 result_list = result_raw[0].res # [0]第一组响应数据包 # [1]接收到的包,[0]为发送的数据包 # [1]ARP头部字段中的['hwsrc']字段,作为返回值返回 hwsrc = result_list[0][1].getlayer(ARP).fields['hwsrc'] if queue is None: print("MAC", hwsrc) return hwsrc else: print("MAC", hwsrc) queue.put({"ip": ip_address, "mac": hwsrc}) except: return
def send_request(self, options=None): assert self.yiaddr, "No client address(yiaddr) to request, start discover process" status = None default_options = [('message-type', 'request'), ("server_id", self.siaddr), ("requested_addr", self.yiaddr), ("hostname", self.hostname)] options = self.expand_options(default_options, options) msg = self._construct_dhcp_msg(options=options) self.log.debug("Request(mac=%s, ip=%s)", self.mac, self.yiaddr) ans, _unans = srp(msg, retry=0, iface=self.interface) ack = self.filter_ack(ans) if ack: rcvd_addr = ack[0][BOOTP].yiaddr self.log.debug("ACK recieved for ip=%s", rcvd_addr) if self.yiaddr != rcvd_addr: msg = "Requested={}, Got={}".format(self.yiaddr, rcvd_addr) raise RequestedAddrException(msg) status = DHCP_PACKET.ACK self.lease_start_time = int(ack[0].time) else: # check for NACK nack = self.filter_nack(ans) if nack: self.log.debug("NACK recieved for ip=%s", self.yiaddr) status = DHCP_PACKET.NACK return status
def _get_mac_ip_mapping(ips: list, interface: str, mac_names: dict): logger.info("Starting MAC search") ip_dns_mapping = {} count = 1 for ip in ips: logger.debug(f"Sending ARP broadcast for IP {ip} ({count}/{len(ips)})") if len(ip_dns_mapping) == len(mac_names): break broadcast = Ether(dst="FF:FF:FF:FF:FF:FF") arp_request = ARP(pdst=str(ip)) package = broadcast / arp_request ans, uans = srp(package, iface=interface, timeout=0.1, verbose=False) for snd, rcv in ans: if rcv: ip = rcv[ARP].psrc mac = rcv[Ether].src if mac in mac_names: ip_dns_mapping[ip] = mac_names[mac] logger.info( f"({len(ip_dns_mapping)}/{len(mac_names)}) Found IP {ip} for name: {mac_names[mac]} " ) logger.debug(f"Found MACs: {len(ip_dns_mapping)} / {len(mac_names)}") count += 1 if len(ip_dns_mapping) != len(mac_names): logger.warning( f"All names not found, ignoring:{set(mac_names.values()) - set(ip_dns_mapping.values())}" ) return ip_dns_mapping
def run_ping_checks_scapy(target, ret, checks, interval, timeout, source, timestamp, group, alert, **kwargs): check_result = { "success": 0, "checks": checks, "rtt": [], "comment": "", "target": target, "check_type": "PING", "source": source, # add minion id "@timestamp": timestamp, "group": group, } # try to resolve target name to IP: try: target_address = socket.gethostbyname(target) except socket.gaierror: check_result[ "comment"] += "ERROR, PING connection check, DNS resolution failed for target - {}".format( target) ret["out"].append(check_result) return # do ICMP checks for i in range(checks): try: packet = Ether() / IP(dst=target_address) / ICMP() ans, unans = srp(packet, filter="icmp", verbose=0, timeout=timeout) if len(ans) != 0: rx = ans[0][1] tx = ans[0][0] check_result["rtt"].append(abs(rx.time - tx.sent_time)) check_result["success"] += 1 elif len(unans) != 0: check_result[ "comment"] += "Check {}, ERROR, no ICMP reply, timeout - {}s, target - {}, address - {}\n".format( i, timeout, target, target_address) except: exc_type, exc_value, exc_traceback = sys.exc_info() check_result[ "comment"] += "Check {}, ERROR: Unhandled scapy error, target - {}, target_address - {}\n\n{}\n".format( i, target, target_address, "".join( traceback.format_exception(exc_type, exc_value, exc_traceback)), ) time.sleep(interval) # add check stats check_result = _calculate_stats(check_result) # sent alert on failure if requested to do so if check_result["success"] == 0 and alert is True: _send_alert(check_type="PING", target=target, data=check_result) # save thread run results ret["out"].append(check_result)
def get_mac_addr(target, timeout=2, verbose=None): ans, _ = srp(Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(pdst=target), verbose=verbose, timeout=timeout, iface_hint=target) # for send, received in answered for _, recv in ans: if Ether in recv: return recv[Ether].src
def etherleak(target, **kargs): # type: (str, **Any) -> Tuple[SndRcvList, PacketList] """Exploit Etherleak flaw""" return srp( Ether() / ARP(pdst=target), prn=lambda s_r: conf.padding_layer in s_r[1] and hexstr(s_r[1][ conf.padding_layer].load), # noqa: E501 filter="arp", **kargs)
def promiscping(net, timeout=2, fake_bcast="ff:ff:ff:ff:ff:fe", **kargs): """Send ARP who-has requests to determine which hosts are in promiscuous mode promiscping(net, iface=conf.iface)""" ans,unans = srp(Ether(dst=fake_bcast)/ARP(pdst=net), filter="arp and arp[7] = 2", timeout=timeout, iface_hint=net, **kargs) ans = ARPingResult(ans.res, name="PROMISCPing") ans.display() return ans,unans
def get_mac_with_arp(ip_address): """ restituisce il MAC con ARP Request """ responses, unanswered = srp(Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(pdst=ip_address), timeout=2, retry=4) for s, r in responses: return r[Ether].src return None
def scan_ip(ip): res1, res2 = srp(Ether(dst=UNKNOWN_MAC) / ARP(pdst=ip), timeout=1, verbose=False, iface=NETWORK) print('Processing: ' + str(ip_list.index(ip)) + '/' + str(len(ip_list))) if res1: for r in res1.res: mac_list.append(r[1].getlayer(ARP).fields['hwsrc']) living_ip.append(ip)
def arp_request(iface: str, dst: str, retry=2, timeout=1) -> Optional[str]: """ Sends an ARP request and attempts to return target's MAC address """ local_ip, local_mac = unpack_iface(iface) rsp = srp(l2.Ether(dst='ff:ff:ff:ff:ff:ff', src=local_mac) / l2.ARP( hwsrc=local_mac, psrc=local_ip, hwdst='ff:ff:ff:ff:ff:ff', pdst=dst), timeout=timeout, retry=retry, verbose=False) if not rsp[0]: return return rsp[0][0][1]['ARP'].hwsrc
def broadcast_arp(target): sep = '-' * 33 arp_broadcast = Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(op="who-has", pdst=target) answered = srp(arp_broadcast, timeout=2, verbose=False)[0] # The 'answered' list contains tuples of size 2 where each tuple contains the # sent and received packet. We only care about the received packets. print("{}\n{:15} {:18}\n{}".format(sep, "Host IP", "MAC Address", sep)) for _, recv in answered: arp = recv.getlayer(ARP) print_found_host(arp) print("Scan is done: {} hosts found".format(len(answered)))
def arp_scan(queue, subnet, interface): conf.verb = 0 ans, uan = srp(Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(pdst=subnet), timeout=10, iface=interface, retry=3) for snd, rcv in ans: mac_addr = rcv.sprintf("%Ether.src%") ip_addr = rcv.sprintf("%ARP.psrc%") queue.put((mac_addr, ip_addr))
def get_hosts_macs_and_ips(self): """ Method used to get a list of tuple containing mac addresses and ips of each host present on the network in a specific interface. """ conf.verb = 0 ans, unans = srp(Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(pdst=self.ips), timeout=2, iface=self.interface, inter=0.1) hosts = [] for snd, rcv in ans: mac, ip = str(rcv.sprintf(r'%Ether.src%-%ARP.psrc%')).split('-') # mac-ip hosts.append((mac, ip)) return hosts
def scan(self, ip): arp_request = ARP(pdst=ip) broadcast = Ether(dst="ff:ff:ff:ff:ff:ff") arp_request_broadcast = broadcast / arp_request answered_list = srp(arp_request_broadcast, timeout=1, verbose=False)[0] clients_list = [] for element in answered_list: client_dict = {"ip": element[1].psrc, "mac": element[1].hwsrc} clients_list.append(client_dict) return clients_list
def arpleak(target, plen=255, hwlen=255, **kargs): # type: (str, int, int, **Any) -> Tuple[SndRcvList, PacketList] """Exploit ARP leak flaws, like NetBSD-SA2017-002. https://ftp.netbsd.org/pub/NetBSD/security/advisories/NetBSD-SA2017-002.txt.asc """ # We want explicit packets pkts_iface = {} # type: Dict[str, List[Ether]] for pkt in ARP(pdst=target): # We have to do some of Scapy's work since we mess with # important values iface = conf.route.route(pkt.pdst)[0] psrc = get_if_addr(iface) hwsrc = get_if_hwaddr(iface) pkt.plen = plen pkt.hwlen = hwlen if plen == 4: pkt.psrc = psrc else: pkt.psrc = inet_aton(psrc)[:plen] pkt.pdst = inet_aton(pkt.pdst)[:plen] if hwlen == 6: pkt.hwsrc = hwsrc else: pkt.hwsrc = mac2str(hwsrc)[:hwlen] pkts_iface.setdefault(iface, []).append( Ether(src=hwsrc, dst=ETHER_BROADCAST) / pkt ) ans, unans = SndRcvList(), PacketList(name="Unanswered") for iface, pkts in viewitems(pkts_iface): ans_new, unans_new = srp(pkts, iface=iface, filter="arp", **kargs) ans += ans_new unans += unans_new ans.listname = "Results" unans.listname = "Unanswered" for _, rcv in ans: if ARP not in rcv: continue rcv = rcv[ARP] psrc = rcv.get_field('psrc').i2m(rcv, rcv.psrc) if plen > 4 and len(psrc) > 4: print("psrc") hexdump(psrc[4:]) print() hwsrc = rcv.get_field('hwsrc').i2m(rcv, rcv.hwsrc) if hwlen > 6 and len(hwsrc) > 6: print("hwsrc") hexdump(hwsrc[6:]) print() return ans, unans
def get_mac(ip_address): #srp sends and receives #srp returns packets and associated answer in the first arg #srp returns unanswered packets response, unanswered = srp(Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(pdst=ip_address), timeout=100, retry=1000) for s, r in response: #print s, r[ARP].hwsrc return r[Ether].src return None # in case of argument IP address is not found
def get_mac(self, ip_address): arp_request = ARP(pdst=ip_address) broadcast = Ether(dst="ff:ff:ff:ff:ff:ff") arp_request_broadcast = broadcast / arp_request retries = 4 for i in range(retries): answered_list = srp(arp_request_broadcast, timeout=1, verbose=False)[0] if answered_list: return answered_list[0][1].hwsrc return ""
def arpleak(target, plen=255, hwlen=255, **kargs): """Exploit ARP leak flaws, like NetBSD-SA2017-002. https://ftp.netbsd.org/pub/NetBSD/security/advisories/NetBSD-SA2017-002.txt.asc """ # We want explicit packets pkts_iface = {} for pkt in ARP(pdst=target): # We have to do some of Scapy's work since we mess with # important values iface = conf.route.route(pkt.pdst)[0] psrc = get_if_addr(iface) hwsrc = get_if_hwaddr(iface) pkt.plen = plen pkt.hwlen = hwlen if plen == 4: pkt.psrc = psrc else: pkt.psrc = inet_aton(psrc)[:plen] pkt.pdst = inet_aton(pkt.pdst)[:plen] if hwlen == 6: pkt.hwsrc = hwsrc else: pkt.hwsrc = mac2str(hwsrc)[:hwlen] pkts_iface.setdefault(iface, []).append( Ether(src=hwsrc, dst=ETHER_BROADCAST) / pkt ) ans, unans = SndRcvList(), PacketList(name="Unanswered") for iface, pkts in viewitems(pkts_iface): ans_new, unans_new = srp(pkts, iface=iface, filter="arp", **kargs) ans += ans_new unans += unans_new ans.listname = "Results" unans.listname = "Unanswered" for _, rcv in ans: if ARP not in rcv: continue rcv = rcv[ARP] psrc = rcv.get_field('psrc').i2m(rcv, rcv.psrc) if plen > 4 and len(psrc) > 4: print("psrc") hexdump(psrc[4:]) print() hwsrc = rcv.get_field('hwsrc').i2m(rcv, rcv.hwsrc) if hwlen > 6 and len(hwsrc) > 6: print("hwsrc") hexdump(hwsrc[6:]) print() return ans, unans
def get_mac_from_ip(ip, network='eth0'): local_ip = get_ip_address(network) ip_list = local_ip + '/24' temp = srp(Ether(dst=UNKNOWN_MAC) / ARP(pdst=ip_list), timeout=3, verbose=False, iface=network) result = temp[0].res for item in result: target_mac = item[1].getlayer(ARP).fields['hwsrc'] target_ip = item[1].getlayer(ARP).fields['psrc'] if str(target_ip) == str(ip): return target_mac return UNKNOWN_MAC
def arping(net, timeout=2, cache=0, verbose=None, **kargs): """Send ARP who-has requests to determine which hosts are up arping(net, [cache=0,] [iface=conf.iface,] [verbose=conf.verb]) -> None Set cache=True if you want arping to modify internal ARP-Cache""" if verbose is None: verbose = conf.verb ans,unans = srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=net), verbose=verbose, filter="arp and arp[7] = 2", timeout=timeout, iface_hint=net, **kargs) ans = ARPingResult(ans.res) if cache and ans is not None: for pair in ans: arp_cache[pair[1].psrc] = (pair[1].hwsrc, time.time()) if verbose: ans.show() return ans,unans
def arping(net, timeout=2, cache=0, verbose=None, **kargs): """Send ARP who-has requests to determine which hosts are up arping(net, [cache=0,] [iface=conf.iface,] [verbose=conf.verb]) -> None Set cache=True if you want arping to modify internal ARP-Cache""" if verbose is None: verbose = conf.verb ans,unans = srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=net), verbose=verbose, filter="arp and arp[7] = 2", timeout=timeout, iface_hint=net, **kargs) ans = ARPingResult(ans.res) if cache and ans is not None: for pair in ans: conf.netcache.arp_cache[pair[1].psrc] = (pair[1].hwsrc, time.time()) if verbose: ans.show() return ans,unans
def arping(net, timeout=2, cache=0, verbose=None, **kargs): # type: (str, int, int, Optional[int], **Any) -> Tuple[ARPingResult, PacketList] # noqa: E501 """Send ARP who-has requests to determine which hosts are up arping(net, [cache=0,] [iface=conf.iface,] [verbose=conf.verb]) -> None Set cache=True if you want arping to modify internal ARP-Cache""" if verbose is None: verbose = conf.verb ans, unans = srp(Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(pdst=net), verbose=verbose, # noqa: E501 filter="arp and arp[7] = 2", timeout=timeout, iface_hint=net, **kargs) # noqa: E501 ans = ARPingResult(ans.res) if cache and ans is not None: for pair in ans: _arp_cache[pair[1].psrc] = pair[1].hwsrc if ans is not None and verbose: ans.show() return ans, unans
def send_and_recv(interface, packet): """ Send packet and return array of received packets array (wait 0.5 sec for answers!) :param interface: Client interface :param packet: Packet to send :return: packets """ packets = [] response, unanswered = srp(packet, iface=interface, multi=True, timeout=0.5, verbose=0) for s, r in response: if (r[Ether].type == 0x8863 or r[Ether].type == 0x8864): packets.append(r) return packets
def chkIsPromiscuousByIP(ip): # Validamos IP. if not isValidIP(ip): raise InvalidIPv4Exception(ip) try: # Send ARP packet to host by IP with an practically not existant MAC resp = srp(Ether(dst='ff:ff:ff:ff:ff:fe') / ARP(pdst=ip), timeout=3, verbose=False, iface=programMgr.mainNICName)[0] except: raise NetworkException() # If there's a response, promisc mode is active if resp: return True else: return False
def discover(): ether_layer = Ether( src=DHCP_CLIENT_MAC_ADDRESS, dst=BROADCAST_MAC_ADDRESS, ) ip_layer = IP( src=DHCP_DISCOVER_HOST_IP_ADDRESS, dst=LIMITED_BROADCAST_IP_ADDRESS, ) udp_layer = UDP( sport=DHCP_CLIENT_PORT, dport=DHCP_SERVER_PORT, ) # BOOTPの引数chaddrについて: # Scapyを使った他の実装を見たところ # (https://github.com/david415/dhcptakeover/blob/master/dhcptakeover.py)、 # scapy.all.get_if_raw_hwaddr()を使っていた # scapy.all.get_if_raw_hwaddr()の中で `mac = mac2str(str(link_addr))` しており # mac2str()関数にて、規則に従いMACアドレスを文字列化してた # コメントに「dumbnet module」とあったので、使用モジュールの関係上、このロジックとなっているのかもしれない chaddr = mac2str(DHCP_CLIENT_MAC_ADDRESS) # なお、単にMACアドレスそのものを渡してもOKだが、その場合には同一のDHCPサーバから複数レスポンスが返ってくる # chaddr = DHCP_CLIENT_MAC_ADDRESS bootp_layer = BOOTP(chaddr=chaddr) dhcp_layer = DHCP(options=[('message-type', 'discover'), 'end']) discover_packet = ether_layer / ip_layer / udp_layer / bootp_layer / dhcp_layer # 作成したパケットを念のため確認 discover_packet.show() # Scapyのドキュメント通りに設定して送信 # http://scapy.readthedocs.io/en/latest/usage.html#identifying-rogue-dhcp-servers-on-your-lan conf.checkIPaddr = False answers, _ = srp(discover_packet, iface=USB_INTERFACE_NAME, multi=True) for send_packet, recv_packet in answers: print 'DHCP Server - MAC: {}, IP: {}'.format(recv_packet[Ether].src, recv_packet[IP].src)
def __arp_ping(ip): """ Performs ARP-ping on L2. http://www.aviran.org/arp-ping-with-python-and-scapy/ :returns: True if ARP-ping succeeds, False if fails :rtype: bool """ ret = False ifaces = SIPpNetwork.get_interfaces() for iface in ifaces: answered, unanswered = srp( Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(pdst=ip), timeout=0.1, # seconds verbose=False, iface=iface) if answered: ret = True break return ret
def send_discover(self, options=None, retry=3, timeout=5): # start discovering for new ip address self.use_ip_addr(ip=None) default_options = [('message-type', 'discover')] options = self.expand_options(default_options, options) msg = self._construct_dhcp_msg(options=options) for attempt in range(1, retry): self.log.debug("Attempt %d: Discover(mac=%s) ...", attempt, self.mac) ans, _unans = srp(msg, retry=0, timeout=timeout, iface=self.interface) offer_msg = self.filter_offer(ans) if offer_msg: self.log.debug("Attempt %d: Offer(mac=%s, ip=%s)", attempt, self.mac, offer_msg[0][BOOTP].yiaddr) self._extract_info_from_response(offer_msg[0]) break else: self.log.warning("Attempt %d: No offers recieved", attempt)
def arp_request(ip_address, ifname='eth0'): # 获取本机IP地址 localip = get_ip_address(ifname) # 获取本机MAC地址 localmac = get_mac_address(ifname) try: # 发送ARP请求并等待响应 result_raw = srp(Ether(src=localmac, dst='FF:FF:FF:FF:FF:FF') / ARP(op=1, hwsrc=localmac, hwdst='00:00:00:00:00:00', psrc=localip, pdst=ip_address), iface=ifname, timeout=1, verbose=False) # 把响应的数据包对,产生为清单 result_list = result_raw[0].res # [0]第一组响应数据包 # [1]接受到的包,[0]为发送的数据包 # 获取ARP头部字段中的['hwsrc']字段,作为返回值返回 return ip_address, result_list[0][1].getlayer(ARP).fields['hwsrc'] except IndexError: return ip_address, None
def srp(self, frame, timeout=1): """ *** WARNING *** This method exists primarily to assist unit testing of the IIERCT framework. Under normal operation the send() method should be invoked, rather than directly calling srp(). Wraps the srp() command from scapy.sendrecv, adding arguments to specify the interface to use, and any filters to be applied when packets are received. Expected Attributes: frame a Layer 2 frame to send on the network interface Optional Attributes: timeout the amount of time to wait for the frame to be answered before declaring it as unanswered, in seconds Returns: [PacketList, PacketList], the answered and unanswered packets """ return sendrecv.srp(frame, iface=self.__interface, timeout=timeout, verbose=0)
def arp_scan_network_for_devices(self): """ Returns a list of devices which are currently active on the network """ devices = [] default_gateway = getNetworkScanner().get_default_gateway() ip = getDatabase().get_config("home_cidr") logging.info("[*] Scanning network (" + str(ip) + ") for devices (this takes up to 30 seconds)") answered_list = srp(Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(pdst=ip), timeout=2, retry=10)[0] for element in answered_list: if element[1].psrc != default_gateway: device = {} device["ip"] = element[1].psrc device["mac"] = element[1].hwsrc.upper() device["name"] = "" device["scanning"] = 0 devices.append(device) #self.save_device_list() getDatabase().save_network_scan(devices) return devices
def get_mac(ip_address): res, un = srp(Ether(dst='ff:ff:ff:ff:ff:ff')/ARP(pdst=ip_address), \ timeout=2, retry=10) for s, r in res: return r[Ether].src return None
""" Sample script to send an ARP who-is to an IP range """ import scapy from scapy.sendrecv import sendp, sniff, srp from scapy.all import Ether, ARP # broadcast message eth = Ether(dst="ff:ff:ff:ff:ff:ff") # IP range in prefix notation - first 24 bits are left unchanged arp = ARP(pdst="192.168.0.0/16") # send and recieve multiple packets answered, unanswered = srp(eth / arp) for pkt in answered: print pkt
def etherleak(target, **kargs): """Exploit Etherleak flaw""" return srp(Ether() / ARP(pdst=target), prn=lambda s_r: conf.padding_layer in s_r[1] and hexstr(s_r[1][conf.padding_layer].load), # noqa: E501 filter="arp", **kargs)
def get_mac(ip): arp_broadcast = Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(op="who-has", pdst=ip) arp_broadcast_response = srp(arp_broadcast) return arp_broadcast_response[0][0][1].hwsrc