如何创建存储ARP表的Python字典以检测ARP攻击?
ARP攻击检测脚本优化指南
核心问题修正思路
你的现有脚本每次检测都主动发送ARP请求获取原始MAC,效率低且冗余。正确的做法是维护本地可信MAC-IP映射字典,先初始化合法设备的映射关系,再对比捕获到的ARP响应包中的MAC是否与字典值一致,不一致则触发告警。
具体实现步骤
1. 初始化可信MAC-IP映射字典
提供两种初始化方式,按需选择:
方式一:主动扫描局域网获取映射
适合系统ARP表不全的场景:
def init_mac_table(network): # 示例network格式:"192.168.1.0/24" arp_req = ARP(pdst=network) broadcast = Ether(dst="ff:ff:ff:ff:ff:ff") arp_broadcast = broadcast / arp_req answered = srp(arp_broadcast, timeout=5, verbose=False)[0] mac_table = {} for item in answered: # 以IP为键,MAC为值存储 mac_table[item[1].psrc] = item[1].hwsrc return mac_table
方式二:读取系统ARP表获取映射
速度更快,适合已有稳定网络连接的场景:
import subprocess import re import os def init_mac_table_from_system(): mac_table = {} # Windows系统处理逻辑 if os.name == "nt": output = subprocess.check_output("arp -a", shell=True).decode() for line in output.split("\n"): match = re.search(r"([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\s+([0-9A-Fa-f-]+)", line) if match: ip = match.group(1) mac = match.group(2).replace("-", ":") mac_table[ip] = mac # Linux/macOS系统处理逻辑 else: output = subprocess.check_output("arp -n", shell=True).decode() for line in output.split("\n")[1:]: # 跳过表头行 parts = line.split() if len(parts) >= 3: mac_table[parts[0]] = parts[2] return mac_table
2. 修改检测逻辑,基于字典对比触发告警
整合初始化逻辑与pcap流量检测,实现异常告警:
from scapy.all import * import subprocess import re import os mac_table = {} def init_mac_table_from_system(): mac_table = {} if os.name == "nt": output = subprocess.check_output("arp -a", shell=True).decode() for line in output.split("\n"): match = re.search(r"([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\s+([0-9A-Fa-f-]+)", line) if match: ip = match.group(1) mac = match.group(2).replace("-", ":") mac_table[ip] = mac else: output = subprocess.check_output("arp -n", shell=True).decode() for line in output.split("\n")[1:]: parts = line.split() if len(parts) >= 3: mac_table[parts[0]] = parts[2] return mac_table def main(): # 初始化可信MAC-IP映射字典 global mac_table mac_table = init_mac_table_from_system() # 若用主动扫描,替换为:mac_table = init_mac_table("192.168.1.0/24") pkts = rdpcap('/root/Desktop/arp_capture.pcap') for packet in pkts: # 仅处理ARP响应包(op=2) if packet.haslayer(ARP) and packet[ARP].op == 2: src_ip = packet[ARP].psrc src_mac = packet[ARP].hwsrc # 检查IP是否在可信字典中 if src_ip in mac_table: # 对比MAC值,不一致则告警 if mac_table[src_ip] != src_mac: print(f"[**] ARP攻击告警!IP: {src_ip} 可信MAC: {mac_table[src_ip]} 异常MAC: {src_mac} [**]") else: # 可选:记录未知IP的MAC,或标记可疑 print(f"[!] 发现未知设备:IP={src_ip} MAC={src_mac}") mac_table[src_ip] = src_mac if __name__ == "__main__": main()
3. 关键逻辑说明
- 字典作用:
mac_table以IP为键、MAC为值,存储局域网内设备的合法映射,相当于本地可信ARP表。 - 告警触发:当捕获的ARP响应包中,源IP对应的MAC与字典中存储的可信MAC不一致时,立即输出攻击告警。
- 初始化选择:读取系统ARP表效率更高;主动扫描适合首次检测或系统ARP表缺失的场景。
额外优化建议
- 添加日志功能,将告警信息写入文件,便于后续排查。
- 增加频率检测:同一IP短时间内多次变更MAC,判定为攻击,减少误报。
- 对未知IP的ARP响应进行标记,避免遗漏新设备或攻击源。
内容的提问来源于stack exchange,提问作者koshila_dodan
相关产品推荐
相关产品推荐

