Python实现ARP的扫描

Zss 发表于:

通过操作scapy来构造一个arp请求,将输入的网段中的254个ip扫描一次,若响应请求则存在此ip的设备

并获取这些设备的ip和mac地址输出,首先发送一个数据包来获取发包网卡的mac和ip地址,在linux中可以通过

ifconfig + 接口来获取这些信息,使用grep和正则表达式很方便的获取到这些信息,但是在win下面不方便是,所以

在win下面使用的发一个数据包来获取ip和mac,再抓取这个数据包来获取系统自动填充的mac和ip

#coding:utf-8
from scapy.all import *
from subprocess import PIPE,Popen
from socket import *
from threading import Thread

def sniff_win_pack():
    global ip_mac
    result = sniff(timeout=1)
    for i in result:
        if i.payload.name == 'IP':
            if i['IP'].dst == '8.8.8.8':
                ip_mac = [i['IP'].src,i['Ether'].src]


def send_arp(user_iface='eth0'):
    try:
        send(IP(dst='8.8.8.8'),iface=user_iface,verbose=False)
    except Exception as e:
        print '错误信息:%s' % e

def get_mac_ip(user_iface='eth0'):
    system_name = os.name
    global ip_mac
    if system_name == 'posix':#获取linux下的网卡ip和mac
        cmd1 = "ifconfig %s|grep -Eo '\w\w:\w\w:\w\w:\w\w:\w\w:\w\w'"%user_iface
        result1 = Popen(cmd1,shell=True,stdout=PIPE)
        result1 = result1.stdout.read()
        cmd2 = "ifconfig %s|grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'|awk 'NR==1{print}'"%user_iface
        result2 = Popen(cmd2,shell=True,stdout=PIPE)
        result2 = result2.stdout.read()
        ip_mac = [result2.strip(),result1.strip()]
    elif system_name == 'nt':  #获取win下的网卡的ip和mac
        T_list = []
        T_1 = Thread(target=sniff_win_pack)
        T_1.start()
        T_list.append(T_1)
        T_2 = Thread(target=send_arp, args=(user_iface,))
        T_2.start()
        T_list.append(T_2)
        for i in T_list:
            i.join()
    else:
        print '未知的操作系统!'
        exit()

def arp_scan(user_network):
    ip_list = []
    for i in range(1,255):
        ip = user_network.split('.')[0] + '.' + user_network.split('.')[1] + '.' + user_network.split('.')[2] + '.' + str(i)
        ip_list.append(ip)
    pack = Ether(dst='ff:ff:ff:ff:ff:ff',src=ip_mac[1])/ARP(hwsrc=ip_mac[1],pdst=ip_list)
    result = srp(pack,iface=user_iface,timeout=4,verbose=False)
    for t in result[0].res:
        print t[1]['ARP'].hwsrc,t[1]['ARP'].psrc

if __name__ == '__main__':
    ip_mac = []
    print '-------->>>     欢迎使用ARP扫描工具      <<<--------\n'
    user_iface = raw_input('请输入你的网卡名称用来扫描,linux为接口名,win为网卡描述名\n').decode('utf-8').encode('gbk')
    get_mac_ip(user_iface)
    print '网卡名称为:%s,网卡ip为:%s,网卡mac为:%s\n'%(user_iface,ip_mac[0],ip_mac[1])
    user_network = raw_input('请输入你的需要扫描的网段,譬如:192.168.0.1\n')
    arp_scan(user_network)