0

我想创建脚本以从 ARP 协议(​​被动扫描)中提取 IP 和 MAC 地址,我在 debian 上使用了 python3.8 和 scapy 2.4.4。我使用的代码返回所有地址,但我希望它打印出 IP/MAC 而不重复,所以我创建了一个列表,以检查 MAC 之前是否已注册,如果未注册,它将添加到列表并出现在输出中。但是 for 循环停留在列表中的第一个项目上,然后所有 MAC 都被打印出来了。

编码:

from scapy.all import *
print("-"*33,"\nIP\t\tMac Address\n","-"*33)
mac_list = [1]
def arp_display(pkt):
    if ((pkt[ARP].op == 2 ) or (pkt[ARP].op == 1 )):
        new_mac = pkt[ARP].hwsrc
        for i in mac_list :
            if ( i != new_mac):
            mac_list.append(new_mac)
            return f"{pkt[ARP].psrc}    {pkt[ARP].hwsrc} "
sniff(prn=arp_display, filter="arp", store=0, iface='eth0')

我尝试使用以下代码打印 (i) 值、新 MAC 和列表值:

from scapy.all import *
print("-"*33,"\nIP\t\tMac Address\n","-"*33)
mac_list = [1]
def arp_display(pkt):
    if ((pkt[ARP].op == 2 ) or (pkt[ARP].op == 1 )): #is-at (response)
        new_mac = pkt[ARP].hwsrc
        for i in mac_list :
            print("i=",i)
            print("New MAC", new_mac)
            print("List=", mac_list)
            if ( i != new_mac):
                mac_list.append(new_mac)
                return f"{pkt[ARP].psrc}    {pkt[ARP].hwsrc} "
sniff(prn=arp_display, filter="arp", store=0, iface='eth0')

输出是这样的:

---------------------------------
IP              Mac Address
 ---------------------------------
i= 1
New MAC 3c:95:09:77:86:01
List= [1]
192.168.60.2    3c:95:09:77:86:01
i= 1
New MAC 00:0c:29:de:7b:39
List= [1, '3c:95:09:77:86:01']
192.168.60.3    00:0c:29:de:7b:39
i= 1
New MAC 3c:47:11:bf:84:f2
List= [1, '3c:95:09:77:86:01', '00:0c:29:de:7b:39']
192.168.60.1    3c:47:11:bf:84:f2
i= 1
New MAC 00:0c:29:de:7b:39
List= [1, '3c:95:09:77:86:01', '00:0c:29:de:7b:39', '3c:47:11:bf:84:f2']
192.168.60.3    00:0c:29:de:7b:39

如您所见,列表中有项目,但 for 循环卡在第一个项目上。

4

2 回答 2

0

1永远不会等于 MAC 地址,所以每次迭代if (i != new_mac):都是真的,然后你return从那个身体开始,这将阻止进一步的迭代。

只需使用 aset代替。Sets 不能包含重复项,因此您无需担心重复条目:

mac_set = set()  # A set instead of a list
def arp_display(pkt):
    if ((pkt[ARP].op == 2) or (pkt[ARP].op == 1)): #is-at (response)
        new_mac = pkt[ARP].hwsrc
        mac_set.add(new_mac)  # add instead of append
        return f"{pkt[ARP].psrc}    {pkt[ARP].hwsrc} "

但是,这不会保持顺序,因为集合是无序的。

于 2020-11-23T21:14:09.917 回答
0

@BatWannaBe你是对的,return在错误的地方,我试图把它写出for循环然后我做对了。

第二个错误是 Loop 函数单独传递所有元素,然后添加新项目的值 ( new_mac) 如果它与 Loop 函数传递给 ( ) 的元素不匹配mac_list,为了避免这个问题我添加了Double变量,所以当循环函数通过列表项(mac_list)时,0如果不匹配则添加值,否则将添加值1然后中断循环函数。

因此,我们确定了新的 MAC 地址是否在列表中。

最终代码如下:

from scapy.all import *
print("-"*33,"\nIP\t\tMac Address\n","-"*33)
mac_list = ['1']
output = ""
def arp_display(pkt):
    if ((pkt[ARP].op == 2 ) or (pkt[ARP].op == 1 )): #is-at (response)
        new_mac = str(pkt[ARP].hwsrc)
        double = 0
        for i in mac_list :
            if ( i != new_mac ):
                double = 0
            else:
                double = 1
                break
        if(double == 0):
            mac_list.append(new_mac)
            output = f"{pkt[ARP].psrc}    {pkt[ARP].hwsrc} "
        else:
            output = None
    return output
sniff(prn=arp_display, filter="arp", store=0, iface='eth0')
于 2020-11-23T23:23:26.030 回答