You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建存储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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 22:54:18