python基于线程池实现快速ARP扫描

import ipaddress
from scapy.all import ARP, Ether, srp1, conf, get_if_addr
from concurrent.futures import ThreadPoolExecutor

# 十进制地址转点分十进制
def bytes_2_Dotted_Decimal_Notation(bytes_network):
    if (bytes_network <= 0 or bytes_network >= 0xFFFFFFFF):
        raise ValueError("illegal network value", hex(bytes_network))
    ls = []
    for _ in range(4):
        ls.append(str(bytes_network & 0xFF))
        bytes_network = bytes_network >> 8
    ls.reverse()
    return ".".join(ls)

# 点分十进制掩码转长度
def decimal_2_bit_length(netmask: int):
    return sum([bin(int(i)).count('1') for i in bytes_2_Dotted_Decimal_Notation(netmask).split('.')])

# 获取本地网段
def get_local_network():
    interface = conf.iface
    ip = get_if_addr(interface)
    for _, netmask, _, interface, address, _ in conf.route.routes:
        if ip == address and netmask != 0:
            return f'{ip}/{decimal_2_bit_length(netmask)}'

def scan(ip):
    pkt = Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=ip)
    res = srp1(pkt, timeout=6, verbose=0)
    if res.psrc == ip:
        print(f'[+]{res.psrc}   {res.hwsrc}')
 
if __name__ == '__main__':
    default_net = get_local_network()
    input_net = input(f'请输入你要扫描的网段(默认:{default_net}):')
    if input_net:
        net = input_net
    else:
        net = default_net
    
    pool = ThreadPoolExecutor(max_workers=255)
    print("扫描开始...")
    for ip in ipaddress.ip_network(net, strict=False):
        pool.submit(scan, str(ip))
posted @ 2023-06-21 15:42  Désiré  阅读(62)  评论(0编辑  收藏  举报