Descubrimiento de host basado en ARP

Cómo funciona ARP

El protocolo ARP pertenece al protocolo de la capa de enlace de datos y es el principal responsable de obtener la dirección de la capa de enlace de datos (MAC) de acuerdo con la dirección de la capa de red (IP). El protocolo Ethernet estipula que si un host en la misma LAN se comunica directamente con otro host, debe conocer la dirección MAC del host de destino. En TCP / IP, la capa de red solo presta atención a la dirección IP del host de destino. Esto da como resultado que cuando se usa el protocolo IP en Ethernet, los datos proporcionados por el protocolo IP de la capa de red recibidos por el protocolo Ethernet de la capa de enlace de datos solo contienen la dirección IP del host de destino. Por lo tanto, se necesita el protocolo ARP para completar la conversión de la dirección IP a la dirección MAC.

Inserte la descripción de la imagen aquí
La comunicación anterior es probablemente si la PC1 conoce la dirección IP de la PC3 pero no conoce su dirección MAC, enviará una solicitud ARP a Ethernet para su consulta. Cuando cada host recibe esta solicitud, verificará su propia dirección IP. no corresponde, descarte el paquete de datos Cuando la PC3 recibe el paquete de datos, se comunica con la PC1, y luego la PC1 almacena la dirección MAC de la PC3 en la tabla de caché. Debido a que la tabla de caché está involucrada, la velocidad de consulta es muy rápida.En la misma Ethernet, usar ARP para el descubrimiento de host es la mejor opción.

Esta es una explicación detallada de los parámetros de scapy.
Inserte la descripción de la imagen aquí
Aquí op representa el tipo de mensaje, hwsrc representa la dirección MAC de origen, psrc representa la dirección IP de origen y pdst representa la dirección IP de destino.

Visualización de código

En primer lugar, los módulos relevantes todavía se importan primero

import os
import re
import optparse
from scapy.all import *

Utilice expresiones regulares para hacer coincidir la dirección MAC y la dirección IP correspondientes

#取IP地址和MAC地址函数
def HostAddress(iface):
    #os.popen执行后返回执行结果
    ipData = os.popen('ifconfig '+iface)
    #对ipData进行类型转换,再用正则进行匹配
    dataLine = ipData.readlines()
    #re.search利用正则匹配返回第一个成功匹配的结果,存在结果则为true
    #取MAC地址
    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]|[1]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[1]?\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

Permítanme hablar sobre lo \wque es la MACdirección coincidente . La popenfunción python ejecuta el comando en la línea de comando y devuelve el valor correspondiente.

Las siguientes son algunas de las reglas de las expresiones regulares

personaje descripción
[A B C] Coincide con todos los caracteres en […], por ejemplo, [aeiou] coincide con todas las letras eoua en la cadena "google runoob taobao"
[ARIZONA] [AZ] significa un rango, que coincide con todas las letras mayúsculas, [az] significa todas las letras minúsculas
\ w Haga coincidir letras, números y guiones bajos. Equivalente a [A-Za-z0-9_]
* Coincide con la subexpresión anterior cero o más veces. Por ejemplo, zo * puede coincidir con "z" y con "zoo". * Equivalente a {0,}
+ Coincide con la subexpresión anterior una o más veces. Por ejemplo, 'zo +' puede coincidir con "zo" y "zoo", pero no con "z". + Equivalente a {1,}
Coincide con la subexpresión anterior cero o una vez. Por ejemplo, "do (s)?" Puede coincidir con "do" en "do", "does" en "does" y "do" en "doxy". ? Equivalente a {0,1}
{norte} n es un número entero no negativo. Coincide con ciertas n veces. Por ejemplo, 'o {2}' no puede coincidir con la 'o' en "Bob", pero puede coincidir con dos o en "comida".
{norte,} n es un número entero no negativo. Coincidir al menos n veces. Por ejemplo, 'o {2,}' no puede coincidir con la 'o' en "Bob", pero puede coincidir con todas las o en "foooood". 'o {1,}' es equivalente a 'o +'. 'o {0,}' es equivalente a 'o *'
{Nuevo Méjico} Tanto myn son números enteros no negativos, donde n <= m. Coincidencias al menos n veces y como máximo m coincidencias. Por ejemplo, "o {1,3}" coincidirá con las primeras tres o en "fooooood". 'o {0,1}' es equivalente a 'o?'. Tenga en cuenta que no puede haber espacios entre la coma y los dos números

Escriba la función de detección de ARP, genere automáticamente objetivos para la detección y escriba los resultados en un archivo

#ARP扫描函数
def ArpScan(iface='eth0'):
    #通过HostAddress返回的元组取出MAC地址
    mac = HostAddress(iface)[1]
    #取出本机IP地址
    ip = HostAddress(iface)[0]
    #对本机IP地址进行分隔并作为依据元素,用于生成需要扫描的IP地址
    ipSplit = ip.split('.')
    #需要扫描的IP地址列表
    ipList = []
    #根据本机IP生成IP扫描范围
    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()

Definir la función principal

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)

El efecto de ejecución es como se muestra en la figura
Inserte la descripción de la imagen aquí
siguiente . El siguiente es nmapel código escrito por el módulo de llamada . El código no ha cambiado mucho. Es similar al host ICMP anterior y el código es mucho más simple.

#!/usr/bin/python3
# -*- coding: utf-8 -*-

import nmap
import optparse


def NmapScan(targetIP):
	# 实例化PortScanner对象
	nm = nmap.PortScanner()
	try:
		# hosts为目标IP地址,argusments为Nmap的扫描参数
		# -PR:使用ARP进行扫描
		result = nm.scan(hosts=targetIP, arguments='-PR')
		# 对结果进行切片,提取主机状态信息
		state = result['scan'][targetIP]['status']['state']
		print("[{}] is [{}]".format(targetIP, state))
	except Exception  as e:
		pass


if __name__ == '__main__':
	parser = optparse.OptionParser('usage: python %prog -i ip \n\n'
                                    'Example: python %prog -i 192.168.1.1[192.168.1.1-100]\n')
	# 添加目标IP参数-i
	parser.add_option('-i','--ip',dest='targetIP',default='192.168.1.1',type='string',help='target ip address')
	options,args = parser.parse_args()
	# 判断是单台主机还是多台主机
	# ip中存在-,说明是要扫描多台主机
	if '-' in options.targetIP:
		# 代码意思举例:192.168.1.1-120
		# 通过'-'进行分割,把192.168.1.1和120进行分离
		# 把192.168.1.1通过','进行分割,取最后一个数作为range函数的start,然后把120+1作为range函数的stop
		# 这样循环遍历出需要扫描的IP地址
		for i in range(int(options.targetIP.split('-')[0].split('.')[3]),int(options.targetIP.split('-')[1])+1): 
			NmapScan(options.targetIP.split('.')[0] + '.' + options.targetIP.split('.')[1] + '.' + options.targetIP.split('.')[2] + '.' + str(i))
	else:	
		NmapScan(options.targetIP)

El efecto de ejecución es como se muestra en la figura siguiente.
Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/weixin_45007073/article/details/113437355
Recomendado
Clasificación