Exemple #1
0
    def spoof_devices(ip, devs, logger):
        tgt = (ip.gateway,
               ip.dns_servers[0]) if util.is_spoof_dns(ip) else (ip.gateway, )

        for entry in devs:
            dev_ip = util.get_device_ip(entry)
            dev_hw = ip.redis.get_device_mac(
                dev_ip, network=util.get_device_net(entry))

            for source in tgt:
                if util.get_device_enabled(entry) == "1":
                    # sendp(Ether(dst=dev_hw) / ARP(op=2, psrc=ip.gateway, pdst=dev_ip, hwdst=dev_hw))
                    sendp([
                        Ether(dst=dev_hw) / IPv6(src=source, dst=dev_ip) /
                        ICMPv6ND_NA(tgt=source, R=0, S=1) /
                        ICMPv6NDOptDstLLAddr(lladdr=ip.mac)
                    ])
                    # sendp(Ether(dst=ip.gate_mac) / ARP(op=2, psrc=dev_ip, pdst=ip.gateway, hwdst=ip.gate_mac))
                else:
                    # sendp(Ether(dst=dev_hw) / ARP(op=2, psrc=ip.gateway, pdst=dev_ip, hwdst=dev_hw, hwsrc=ip.gate_mac))
                    # sendp(Ether(dst=ip.gate_mac) / ARP(op=2, psrc=dev_ip, pdst=ip.gateway, hwsrc=dev_hw))
                    sendp([
                        Ether(dst=dev_hw) / IPv6(src=source, dst=dev_ip) /
                        ICMPv6ND_NA(tgt=source, R=0, S=1) /
                        ICMPv6NDOptDstLLAddr(lladdr=ip.gate_mac)
                    ])
    def _icmpv6_handler(self, pkt):
        """"This method is called for each ICMPv6 echo reply packet or multicast listener report packet
        received through scapy's sniff function.
        Incoming packets are used to spoof involved devices and add new devices
        to the redis db.

        Args:
            pkt (str): Received packet via scapy's sniff (through socket.recv).
        """
        # add transmitting device to redis db
        self.ip.redis.add_device(pkt[IPv6].src, pkt[Ether].src)
        # impersonate gateway
        if not self.ip.redis.check_device_disabled(pkt[Ether].src):
            sendp(
                Ether(dst=pkt[Ether].src) /
                IPv6(src=self.ip.gateway, dst=pkt[IPv6].src) /
                ICMPv6ND_NA(tgt=self.ip.gateway, R=0, S=1) /
                ICMPv6NDOptDstLLAddr(lladdr=self.ip.mac))

        # impersonate DNS server if necessary
        if util.is_spoof_dns(self.ip):
            if not self.ip.redis.check_device_disabled(pkt[Ether].src):
                sendp(
                    Ether(dst=pkt[Ether].src) /
                    IPv6(src=self.ip.dns_servers[0], dst=pkt[IPv6].src) /
                    ICMPv6ND_NA(tgt=self.ip.dns_servers[0], R=0, S=1) /
                    ICMPv6NDOptDstLLAddr(lladdr=self.ip.mac))
    def run(self):
        """Starts multiple threads sends out packets to spoof
        all existing clients on the network and the gateway. This packets are sent every __SLEEP seconds.
        The existing clients (device entries) are read from the redis database.

        Threads:
            A SniffThread, which sniffs for incoming ARP packets and adds new devices to the redis db.
            Several HostDiscoveryThread, which are searching for existing devices on the network.
            A PubSubThread, which is listening for redis expiry messages.

        Note:
            First, ARP replies to spoof the gateway entry of existing clients arp cache are generated.
            ARP relpies to spoof the entries of the gateway are generated next.
            Unlike the holistic mode only packets for existing clients are generated.

        """
        try:
            for worker in self.threads:
                self.threads[worker].start()

            # check if the impersonation of the DNS server is necessary
            tgt = (self.ipv6.gateway,
                   self.ipv6.dns_servers[0]) if util.is_spoof_dns(
                       self.ipv6) else (self.ipv6.gateway, )

            while not self.exit.is_set():
                packets = []

                for source in tgt:
                    packets.extend([
                        Ether(dst=dev[1]) / IPv6(src=source, dst=dev[0]) /
                        ICMPv6ND_NA(tgt=source, R=1, S=1, O=1) /
                        ICMPv6NDOptDstLLAddr(lladdr=self.ipv6.mac)
                        for dev in self.ipv6.redis.get_devices_values(
                            filter_values=True)
                    ])

                sendp(packets)
                try:
                    with self.sleeper:
                        self.sleeper.wait(timeout=self.__SLEEP)
                except RuntimeError as e:
                    # this error is thrown by the with-statement when the thread is stopped
                    if len(e.args) > 0 and e.args[
                            0] == "cannot release un-acquired lock":
                        return
                    else:
                        raise e
            self._return_to_normal()
        except Exception as e:
            self.logger.error("Process IPv6")
            self.logger.exception(e)
Exemple #4
0
def packets_for_test(request, ptfadapter, duthost, config_facts, tbinfo,
                     ip_and_intf_info):
    ip_version = request.param
    src_addr_v4, src_addr_v6, ptf_intf = ip_and_intf_info
    ptf_intf_index = int(ptf_intf.replace('eth', ''))
    ptf_intf_mac = ptfadapter.dataplane.get_mac(0, ptf_intf_index)
    vlans = config_facts['VLAN']
    topology = tbinfo['topo']['name']
    dut_mac = ''
    for vlan_details in vlans.values():
        if 'dualtor' in topology:
            dut_mac = vlan_details['mac'].lower()
        else:
            dut_mac = duthost.shell(
                'sonic-cfggen -d -v \'DEVICE_METADATA.localhost.mac\''
            )["stdout_lines"][0].decode("utf-8")
        break

    if ip_version == 'v4':
        tgt_addr = increment_ipv4_addr(src_addr_v4)
        out_pkt = testutils.simple_arp_packet(eth_dst='ff:ff:ff:ff:ff:ff',
                                              eth_src=ptf_intf_mac,
                                              ip_snd=src_addr_v4,
                                              ip_tgt=tgt_addr,
                                              arp_op=1,
                                              hw_snd=ptf_intf_mac)
        exp_pkt = testutils.simple_arp_packet(eth_dst=ptf_intf_mac,
                                              eth_src=dut_mac,
                                              ip_snd=tgt_addr,
                                              ip_tgt=src_addr_v4,
                                              arp_op=2,
                                              hw_snd=dut_mac,
                                              hw_tgt=ptf_intf_mac)
    elif ip_version == 'v6':
        tgt_addr = increment_ipv6_addr(src_addr_v6)
        ll_src_addr = generate_link_local_addr(ptf_intf_mac)
        multicast_tgt_addr = in6_getnsma(inet_pton(socket.AF_INET6, tgt_addr))
        multicast_tgt_mac = in6_getnsmac(multicast_tgt_addr)
        out_pkt = Ether(src=ptf_intf_mac, dst=multicast_tgt_mac)
        out_pkt /= IPv6(dst=inet_ntop(socket.AF_INET6, multicast_tgt_addr),
                        src=ll_src_addr)
        out_pkt /= ICMPv6ND_NS(tgt=tgt_addr)
        out_pkt /= ICMPv6NDOptSrcLLAddr(lladdr=ptf_intf_mac)

        exp_pkt = Ether(src=dut_mac, dst=ptf_intf_mac)
        exp_pkt /= IPv6(dst=ll_src_addr, src=generate_link_local_addr(dut_mac))
        exp_pkt /= ICMPv6ND_NA(tgt=tgt_addr, S=1, R=1, O=0)
        exp_pkt /= ICMPv6NDOptSrcLLAddr(type=2, lladdr=dut_mac)
        exp_pkt = mask.Mask(exp_pkt)
        exp_pkt.set_do_not_care_scapy(packet.IPv6, 'fl')

    return ip_version, out_pkt, exp_pkt
    def spoof_devices(ip, devs, logger):
        tgt = (ip.gateway,
               ip.dns_servers[0]) if util.is_spoof_dns(ip) else (ip.gateway, )

        for entry in devs:
            dev_hw = util.get_device_mac(entry)
            dev_ip = devs[entry]

            for source in tgt:
                if not ip.redis.check_device_disabled(
                        util.get_device_mac(entry)):
                    sendp([
                        Ether(dst=dev_hw) / IPv6(src=source, dst=dev_ip) /
                        ICMPv6ND_NA(tgt=source, R=1, S=1) /
                        ICMPv6NDOptDstLLAddr(lladdr=ip.mac)
                    ])
                else:
                    sendp([
                        Ether(dst=dev_hw) / IPv6(src=source, dst=dev_ip) /
                        ICMPv6ND_NA(tgt=source, R=1, S=1) /
                        ICMPv6NDOptDstLLAddr(lladdr=ip.gate_mac)
                    ])
Exemple #6
0
    def respond_to_neighbour_solicitation(self, packet, iface):
        if not self.is_performing_nd(): return

        try:
            if packet.haslayer(ICMPv6ND_NS):
                src = IPv6Address(packet.getlayer(IPv6).src)
                dst = IPv6Address(packet.getlayer(IPv6).dst)
                tgt = IPv6Address(packet.getlayer(ICMPv6ND_NS).tgt)

                if iface.has_ip(tgt) and (iface.has_ip(dst) or str(
                        dst).startswith("ff02:0000:0000:0000:0000:0001:ff")):
                    iface.send(
                        IPv6(src=str(tgt), dst=str(src)) /
                        ICMPv6ND_NA(tgt=str(tgt), R=True, S=True, O=True) /
                        ICMPv6NDOptDstLLAddr(lladdr=iface.ll_addr))
        except AttributeError:
            pass
    def _return_to_normal(self):
        """This method is called when the daemon is stopping.
        Apate tells the clients the real gateway via neighbor advertisements.
        """
        # spoof clients with nd advertisements
        with self.sleeper:
            # check if the impersonation of the DNS server is necessary
            tgt = (self.ipv6.gateway,
                   self.ipv6.dns_servers[0]) if util.is_spoof_dns(
                       self.ipv6) else (self.ipv6.gateway, )

            for source in tgt:
                sendp(
                    Ether(dst=ETHER_BROADCAST) /
                    IPv6(src=source,
                         dst=MulticastPingDiscoveryThread._MULTICAST_DEST) /
                    ICMPv6ND_NA(tgt=source, R=1, S=0, O=1) /
                    ICMPv6NDOptDstLLAddr(lladdr=self.ipv6.gate_mac))
Exemple #8
0
    def _return_to_normal(self):
        """This method is called when the daemon is stopping.
        First, sends a GARP broadcast request to all clients to tell them the real gateway.
        Then ARP replies for existing clients are sent to the gateway.
        If IPv6 is enabled, Apate tells the clients the real gateway via neighbor advertisements.
        """
        # spoof clients with GARP broadcast request
        with self.sleeper:
            # check if the impersonation of the DNS server is necessary
            tgt = (self.ipv6.gateway,
                   self.ipv6.dns_servers[0]) if util.is_spoof_dns(
                       self.ipv6) else (self.ipv6.gateway, )

            for source in tgt:
                sendp(
                    Ether(dst=ETHER_BROADCAST) /
                    IPv6(src=source,
                         dst=MulticastPingDiscoveryThread._MULTICAST_DEST) /
                    ICMPv6ND_NA(tgt=source, R=0, S=0) /
                    ICMPv6NDOptDstLLAddr(lladdr=self.ipv6.gate_mac))
Exemple #9
0
from scapy.all import sendp, Ether, IPv6, ICMPv6ND_NA, ICMPv6NDOptSrcLLAddr
print("start")
sendp(Ether(src="5e:6c:c9:a5:6a:4e") \
        /IPv6(src="fe80::5c6c:c9ff:fea5:6a4e",dst="fe80::25a4:1eab:bba8:77eb") \
        /ICMPv6ND_NA(tgt="3333:db8:1:0:227c:8fff:fe79:2580",R=1,S=1,O=1) \
        /ICMPv6NDOptSrcLLAddr(lladdr="5e:6c:c9:a5:6a:4e",type=2),loop=1, inter=1, iface="br0")
Exemple #10
0
    return ':'.join(['%02x' % ord(char) for char in info[18:24]])


try:
    scriptname, myif, myip = sys.argv
except ValueError:
    print __doc__
    sys.exit(1)

if os.geteuid() != 0:
    print "Must be run as root."
    sys.exit(1)

# Get MAC address of interface to use as source MAC
myll = get_hw_address(myif)

# Dest MAC is all-nodes multicast MAC
e = Ether(dst="33:33:00:00:00:01", src=myll, type=0x86dd)

# Dest IP is all-nodes multicast address
ip6 = IPv6(src=myip, dst="ff02::1", nh=58)

# Set Flags and Target Addr as per RFC-4861 Section 4.4
nd_na = ICMPv6ND_NA(R=0, S=0, O=1, tgt=myip)

# Target Link Layer Address option, not required but helpful
ndo_lladdr = ICMPv6NDOptDstLLAddr(lladdr=myll)

# Send constructed frame
sendp(e / ip6 / nd_na / ndo_lladdr, iface=myif)