如何在python使用scapy模块实现一个ARP扫描功能

这篇文章给大家介绍如何在python使用scapy模块实现一个ARP扫描功能,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

单进程ARP包

包的构造:

def scapy_arp_one(ip_address, queue=None):  Packet = Ether(dst='FF:FF:FF:FF:FF:FF') / ARP(op=1, hwdst='00:00:00:00:00:00:', pdst=ip_address)

请求包的发送:

arp = srp(Packet, timeout=0.2, verbose=False)

返回包的接收

try:   reply_list = arp[0].res   if queue is None:    return reply_list[0][1].getlayer(ARP).fields['hwsrc']   else:    queue.out((ip_address, reply_list[0][1].getlayer(ARP).fields['hwsrc']))  except:   return

这里采用队列的模式,主要是为了后面多进程同时发送做准备,涉及到ARP包的接受。这里我简单描述一下ARP包接受的情况,当我们发送ARP广播包的之后,我们就会接受到一个返回包。所以正确的情况就是,一个发送包一个接收包,一个发送包一个接收包,所以这里采用队列的方式,一个一个IP地址的接收,并使用列表进行存储,然后过滤ARP把内容,接收ARP中的硬件MAC地址

完整代码:

#!/usr/bin/env python3 # -*- coding:utf-8 -*- # Author:Ameng, jlx-love.com from scapy.all import * import sys def scapy_arp_one(ip_address, queue=None):  Packet = Ether(dst='FF:FF:FF:FF:FF:FF') / ARP(op=1, hwdst='00:00:00:00:00:00:', pdst=ip_address)  arp = srp(Packet, timeout=0.2, verbose=False)  try:   reply_list = arp[0].res   if queue is None:    return reply_list[0][1].getlayer(ARP).fields['hwsrc']   else:    queue.out((ip_address, reply_list[0][1].getlayer(ARP).fields['hwsrc']))  except:   return if __name__ == '__main__':  scapy_arp_one(sys.argv[1])

进一步完善

那么既然我们已经了解了使用ARP进行基本的发包和收包,那么我们接下来就来编写一个能够扫描整个网段的ARP检测

理一下思路,首先,我们需要将ip地址编程一个网段中的所有ip,可以借助ipaddress模块实现,其次我们知道我们接收响应包是一对的,所以我们可以从一对一对的响应包中接收我们需要的目标IP和源MAC地址,其次就是优化代码,输出结果,这里我不再采用sys模块进行传参,而是采用一个新的模块optparse,具体使用方法可以百度百科

完整代码:

#!/usr/bin/env python3 # -*- coding:utf-8 -*- # Author:Ameng, jlx-love.com import time from scapy.all import * import ipaddress import optparse def scapy_arp_scan(network, ifname):  net = ipaddress.ip_network(network)  ip_addr = []  for ip in net:   ip = str(ip)   ip_addr.append(ip)  time.sleep(1)  Packet = Ether(dst='FF:FF:FF:FF:FF:FF')/ARP(op=1, hwdst='00:00:00:00:00:00', pdst=ip_addr)  arp = srp(Packet, iface = ifname, timeout = 1, verbose = False)  arp_list = arp[0].res  IP_MAC_LIST = []  for n in range(len(arp_list)):     IP = arp_list[n][1][1].fields['psrc']   MAC = arp_list[n][1][1].fields['hwsrc']   IP_MAC = [IP, MAC]   IP_MAC_LIST.append(IP_MAC)  return IP_MAC_LIST if __name__ == '__main__':  t1 = time.time()  parser = optparse.OptionParser('用法:\n python3 scapy_arp_scan.py --network 扫描网段 --ifname 网卡名称')  parser.add_option('--network', dest = 'network', type = 'string', help = '扫描网段')  parser.add_option('--ifname', dest = 'ifname', type = 'string', help = '网卡名称')  (options, args) = parser.parse_args()  network = options.network  ifname = options.ifname  if network == None or ifname == None:  print(parser.usage)  else:   active_ip_mac = scapy_arp_scan(network, ifname)   print('存活的IP地址及对应MAC:')   for ip, mac in active_ip_mac:    print(ip, mac)  t2 = time.time()  print('所用时间为:{}'.format(int(t2 - t1)))

运行结果

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。