CherieLi Student

基于ARP的主机发现

2021-09-28
CherieLi

ARP协议(地址解析协议)属于数据链路层的协议,主要负责根据网络层地址(IP)来获取数据链路层地址(MAC)。   

借助Scapy来编写ARP主机发现脚本,通过脚本对以太网内的每个主机都进行ARP请求。若主机存活,则会响应我们的ARP请求,否则不会响应。   

Scapy中的ARP参数如下所示:

image

op代表消息类型:1为ARP请求,2为ARP响应 hwsrc代表源MAC地址 psrc代表源IP地址 hwdst代表目的MAC地址 pdst代表目的IP地址

Scapy中的Ether参数如下所示:

image

src表示源MAC地址

dst表示目的MAC地址

	#!/usr/bin/python3
	#-*- coding: utf-8 -*-
	import os
	import re
	import optparse
	from scapy.all import *
	#取IP地址和MAC地址获取函数
	def HostAddress(iface):
	        #os.popen执行后返回执行结果
	        ipData = os.popen('ifconfig '+iface)
	        #对ipData进行类型转换,再用正则进行匹配
	        dataLine = ipData.readlines()
	        #re.search利用正则匹配返回第一个成功匹配的结果,存在结果则为true
	        #取MAC地址
	        global MAC
	        global IP
	        if re.search('\w\w:\w\w:\w\w:\w\w:\w\w:\w\w',str(dataLine)):
	                #取出匹配的结果
	                MAC = re.search('\w\w:\w\w:\w\w:\w\w:\w\w:\w\w',str(dataLine)).group(0)
	        #取IP地址
	        if re.search(r'((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)',str(dataLine)):
	                IP = re.search(r'((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)',str(dataLine)).group(0)
	        #将IP和MAC通过元组的形式返回
	        addressInfo = (IP,MAC)
	        return addressInfo
	 
	#ARP扫描函数
	def ArpScan(iface='eth0'):
	        # 通过HostAddres返回的元组取出MAC地址
	        mac = HostAddress(iface)[1]
	        #取出本机IP地址
	        ip = HostAddress(iface)[0]
	        #对本机IP地址进行分割并作为依据元素,用于生成需要扫描的IP地址
	        ipSplit = ip.split('.')
	        #需要扫描的IP地址列表
	        ipList = []
	        for i in range(1,255):
	                ipItem = ipSplit[0] + '.' + ipSplit[1] + '.' + ipSplit[2] + '.' + str(i)
	                ipList.append(ipItem)
	        '''
	        发送ARP包
	        因为要用到OSI的二层和三层,所以要写成Ether/ARP。
	        因为最底层用到了二层,所以要用srp()发包
	        '''
	        result=srp(Ether(src=mac,dst='FF:FF:FF:FF:FF:FF')/ARP(op=1,hwsrc=mac,hwdst='00:00:00:00:00:00',pdst=ipList),iface=iface,timeout=2,verbose=False)
	        #读取result中的应答包和应答包内容
	        resultAns = result[0].res
	        #存活主机列表
	        liveHost = []
	        #number为接收到应答包的总数
	        number = len(resultAns)
	        print("=========================")
	        print("ARP 探测结果")
	        print("本机IP地址:" + ip)
	        print("本机MAC地址:" + mac)
	        print("=========================")
	        for x in range(number):
	                IP = resultAns[x][1][1].fields['psrc']
	                MAC = resultAns[x][1][1].fields['hwsrc']
	                liveHost.append([IP,MAC])
	                print("IP:" + IP + "\n\n" + "MAC:" + MAC )
	                print("============================")
	        # 把存活主机IP写入文件
	        resultFile = open("result","w")
	        for i in range(len(liveHost)):
	                resultFile.write(liveHost[i][0] + "\n")
	        resultFile.close()
	 
	if __name__ == '__main__':
	     parser = optparse.OptionParser('usage: python %prog -i interfaces \n\n' 'Example: python %prog -i eth0\n')
	     #添加网卡参数 -i
	     parser.add_option('-i','--iface',dest='iface',default='eth0',type='string', help='interfaces name')
	     (options,args) = parser.parse_args()
	     ArpScan(options.iface)

脚本测试结果如下: 3

查看结果文件如下所示:

4


下一篇 netstat

Comments

Content