1,在直连的设备上进行ARP扫描,可以准确的判断出主机的状态,比PING扫描来的更块更准确,
因为现在大多数的设备都已经禁止PING技术了。
2,ARP数据包分析
ARP_Request包:
因为是个ARP包,所以以太二层的dst是广播(FF:FF:FF:FF:FF:FF),源地址是出接口的mac地址。
arp_request的操作码是1,arp_reply的操作码是2
arp协议的源mac和ip是出接口的mac和ip,目的mac是00:00:00:00:00:00(这就是问题),目的ip就
是要查询的ip,如果找到,则在回复包中就会作为源mac地址发送回来。
ARP_Reply包:
arp_reply包就回答了arp_request包的问题,所以以太二层的源mac就成功回复方的mac地址,目标mac
就是给谁回的mac地址,arp协议中操作码为2,代表arp_reply,以及发送方的mac和ip,目的地址的mac
和IP。
3,使用scapy铸造ARP数据包
arp_request=Ether(dst='FF:FF:FF:FF:FF:FF')/ARP(op=1,hwdst='00:00:00:00:00:00',pdst='192.168.219.180')
arp_request.show()可以查看铸造的包的信息。
根据实际情况对包的数据进行填写,已达到所需要的要求。
4,发送3铸造的数据包
应为这里铸造的包是一个以太二层的数据包,所以在发送该数据包的时候,应该使用srp()函数,
srp()可以发送一个以太二层的数据包并等待回复,这里的回复是一个复杂的数据结构,这里对
这个回复做简单的解释。
这里srp函数的返回值是一个特殊的类,分为收到结果的包,和未收到结果的包。这里可以看到,
srp将返回值做成了一个元组。arp[0]就是收到的数据包,在收到的数据包中,又是列表,列表
中的每一元素都是有发送的数据包和接收到的数据包组成,arp[0].res可以产生这个列表作为一
个清单。清单的第一个元素(就是第一个响应的数据包)的第二个位置就是保存的接收到的数据包。
在此位置查看此包的hwsrc字段,就是问题的答案,就是目标的mac地址。
5,实现arp数据包铸造和发送的程序代码
#--------------------------------------------------------------------------------------------------------------------------------
#!/usr/bin/python3.4
# _*_ coding=utf-8 _*_
# 清除报错
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
#构造发送数据包并接受响应函数,两个参数,一个IP地址,一个队列,默认为None
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=ipaddress,timeout=1,verbose=False)
try:
#把响应的数据包对,产生清单
result_list=result_raw[0].res
#[0]第一组响应数据包
#[1]接收到的包,[0]为发送的数据包
#[1]ARP头部字段中的['hwsrc']字段,作为返回值返回
if queue==None:
return result_list[0][1].getlayer(ARP).fields['hwsrc']
else:
queue.put((ip_address,result_list[0][1].getlayer(ARP).fields['hwsrc']))
except:
return
if __name_=='__main__':
import sys
print(arp_request(sys.argv[1]))
#--------------------------------------------------------------------------------------------------------------------------------
这里使用队列是为了进程间的通信,在这个进程中将所有响应的ip地址和mac放入队列中
,然后再另外一个进程将其都出来,以此实现进程间的通信。
6,实现arp扫描
#!/usr/bin/python3.4
# _*_ coding=utf-8 _*_
import logging
logging.getLogger(''scapy.runtime'').setLevel(logging.ERROR)
import ipaddress
import time
from arp_request import arp_request
from multiprocessing import Process,Queue
def arp_scan(network):
queue=Queue()
net=ipaddress.ip_network(network)
for ip in net:
ip_addr=str(ip)
arp_one=Process(target=arp_request,args=(ip_addr,queue))
arp_one.start()
time.sleep(2)
ip_mac_list=[]
while True:
if queue.empty():
break;
else:
ip,mac=queue.get()
ip_mac_list.append((ip,mac))
return ip_mac_list
if __name__=='__main__':
import sys
active_ip_mac=arp_scan(sys.argv[1])
print('活动IP与MAC地址如下:')
for ip,mac in active_ip_mac:
print(ip,mac)
print('总个数为:'+str(len(active_ip_mac))