• python使用scapy模块实现ARP扫描


    前言

    上篇文章主要写了利用scapy实现ping扫描,这篇文章主要是利用scapy模块实现内网ARP扫描

    实现过程

    上篇文章中介绍了通过scapy来伪造包,那么ARP包的伪造过程这里不再详述,说一工具的简单整体流程

    1.首先,实现单个IP的ARP包的发送和接收

    2.其次,实现多进程同时多个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('用法:
     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)))
    

    运行结果

  • 相关阅读:
    添加多个tab,并循环修改tab样式
    00五大原则(转)
    win7 & IIS7.5 HTTP 错误 404.17 Not Found 请求的内容似乎是脚本,因而将无法由静态
    人类的奇怪之处
    创业公司CEO每天应该做的13件事(转),个人感觉,同样有几条也适合于自己,或部门领导。
    购物车功能分析
    ASP.NET中DataTable的用法
    jQuery插件列表
    jQuery灯箱插件lightBox使用方法
    一个黑客与电脑白痴的聊天纪录
  • 原文地址:https://www.cnblogs.com/Jleixin/p/14300063.html
Copyright © 2020-2023  润新知