简述
采用Python编程语言,利用Scapy库实现了一个基于ICMP协议的网络扫描工具。该工具能够通过发送ping请求探测指定IP地址范围内的存活主机,并以多线程方式并发执行以提高扫描效率。用户可通过命令行参数指定要扫描的IP地址或地址范围。
步骤
- 引入所需库:包括scapy、random、time、ipaddress、threading和argparse,为实现网络扫描功能提供支持。
- 定义ICMP_Ping函数,用于构造并发送ICMP ping包到指定地址,同时接收并处理响应,若收到响应则输出存活的IP地址。
- 在主程序中设置日志级别以过滤Scapy运行时信息,然后创建命令行参数解析器以接收用户输入的IP地址或范围。
- 根据用户提供的IP地址或范围信息,将其转换为IP网络对象,并遍历其中的每个IP地址。
- 对于每一个待探测的IP地址,创建一个新的线程调用ICMP_Ping函数进行ping探测。
- 若用户未提供任何IP地址或范围,则打印帮助信息。
实现代码
from scapy.all import *
from random import randint
import time,ipaddress,threading
import argparse
import logging
# import asyncio
# from concurrent.futures import ThreadPoolExecutor
# 使用scapy库发送ICMP ping包
def ICMP_Ping(addr):
RandomID=randint(1,65534) # 生成一个随机ID
packet = IP(dst=addr, ttl=64, id=RandomID) / ICMP(id=RandomID, seq=RandomID) / "hello lyshark" # 构造ICMP ping包
respon = sr1(packet,timeout=3,verbose=0) # 发送ping包并等待响应
if respon: # 如果有响应
print("[+] 存活地址: {}".format(str(respon[IP].src))) # 打印存活的IP地址
if __name__ == "__main__":
logging.getLogger("scapy.runtime").setLevel(logging.ERROR) # 设置日志级别
#net = ipaddress.ip_network("192.168.1.0/24") # 设置要扫描的IP地址范围
parser = argparse.ArgumentParser() # 创建参数解析器
parser.add_argument("-a","--addr",dest="addr",help="指定一个IP地址或范围") # 添加参数选项
args = parser.parse_args() # 解析命令行参数
if args.addr: # 如果有指定的IP地址或范围
net = ipaddress.ip_network(str(args.addr)) # 将IP地址或范围转换为IP网络对象
for item in net: # 遍历IP网络中的每个IP地址
t = threading.Thread(target=ICMP_Ping,args=(str(item),)) # 创建一个线程来发送ping包
t.start() # 启动线程
else: # 如果没有指定IP地址或范围
parser.print_help() # 打印帮助信息
优化建议
- 异步化改进:虽然当前使用了多线程并发发送ping请求,但可以进一步考虑采用异步I/O模型(如asyncio)替代线程池,减少系统资源消耗并提升扫描性能。
- 速率控制:在并发发送ping包时加入速率控制机制,防止短时间内发送过多数据包导致网络拥塞或被目标网络设备视为攻击而丢弃数据包。
- 错误处理与日志记录:增强错误处理能力,例如在网络异常或超时时增加重试机制;同时完善日志记录,包括记录发送及接收的数据包详情以及可能遇到的异常情况。
- 性能优化:针对大规模IP地址段的扫描,可尝试使用CIDR块分片策略,分批次进行扫描,以减少内存占用并提高扫描效率。
如何防御ICMP扫描
防御ICMP扫描的措施主要包括以下几个方面:
- 防火墙策略:
- 在网络边缘设备(如路由器或防火墙)上配置规则,限制或禁止外部对内部网络发起的ICMP请求。例如,可以只允许必要的ICMP类型和代码通过,比如回应请求(echo reply),而过滤掉其他类型的ICMP数据包,包括ping请求(echo request)。
- ICMP筛选与限速:
- 对于服务器或主机,可以在操作系统级别设置安全策略来阻止或限制ICMP流量。如前所述,可以通过在Windows系统中管理IP安全策略,或者在Linux系统中编辑iptables规则,来过滤不必要的ICMP通信。
- 带宽控制:
- 如果是针对大规模的ICMP Flood攻击,可以在边界路由器或负载均衡器上设置带宽限制,确保ICMP协议占用的带宽不会影响正常服务。
- 关闭响应:
- 关闭服务器或主机对外部ICMP Echo Request(Ping)的响应,这虽然不能阻止扫描本身,但能避免暴露服务器的存在性信息。
- 深度包检测( DPI ):
- 使用深度包检测技术对进出的数据包进行检查,识别并丢弃异常或恶意的ICMP流量。
- 日志记录与监控:
- 监控ICMP流量,及时发现扫描迹象,并结合入侵检测系统(IDS)和入侵防御系统(IPS)来分析和应对潜在威胁。
- 网络分割与访问控制:
- 根据最小权限原则,将网络划分为不同区域,并严格控制每个区域之间的ICMP通信。