为何用Scapy扫描本地wlan0后断网且无法再次执行ARP ping扫描?
问题分析与解决:Scapy ARP扫描后wlan0断网且无法再次扫描
问题重现
首次执行Scapy ARP ping扫描可正常获取结果:
>>> from scapy.all import * >>> ans, unans = srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst="192.168.1.0/24"), iface="wlan0", timeout=2) Begin emission: Finished sending 256 packets. *****...... Received 11 packets, got 5 answers, remaining 251 packets >>> ans.summary(lambda s,r: r.sprintf("%Ether.src% %ARP.psrc%") ) 28:2e:a4:7f:d0:b6 192.168.1.1 cc:ff:a4:2a:5b:46 192.168.1.2 ce:ae:13:e6:7c:73 192.168.1.7 e0:56:cb:8f:5f:60 192.168.1.11 a0:d3:3a:3f:fa:1e 192.168.1.20
但扫描完成后wlan0失去内网及互联网连通性,再次执行扫描仅显示Begin emission:后无后续输出,虚拟接口无此异常。
核心原因分析
- 无线AP防护机制触发:多数家用/小型企业AP会检测短时间内的大量ARP广播包,判定为ARP洪水攻击,临时封禁发送设备的MAC地址,导致断网且无法继续发包。
- 无线接口模式异常:Scapy发送原始帧时,可能强制将wlan0切换到混杂/监控模式,扫描结束后未自动恢复为管理模式,导致接口无法正常处理常规流量。
- ARP缓存混乱:大量ARP请求可能冲垮本地ARP缓存,或导致路由器ARP表条目过载,暂时无法解析设备请求。
- Scapy接口资源泄漏:
srp函数在无线接口上可能存在资源未释放的情况,导致接口处于半阻塞状态,无法处理新的发包请求。
解决方案
1. 临时恢复网络连接
- 重启无线网卡:
sudo ip link set wlan0 down sudo ip link set wlan0 up - 若仍无法恢复,重启无线AP/路由器,等待1-2分钟后重新连接网络。
2. 避免触发AP防护
- 降低扫描发包速率,添加
inter参数控制间隔:ans, unans = srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst="192.168.1.0/24"), iface="wlan0", timeout=2, inter=0.1) # 每0.1秒发送一个包 - 缩小扫描范围,比如分段扫描
192.168.1.1-50,避免一次性发送256个广播包。
3. 确保扫描后恢复接口模式
- 扫描前记录接口原始模式,扫描后手动恢复:
from scapy.all import * import subprocess # 获取当前无线接口模式 def get_wlan_mode(iface): result = subprocess.check_output(f"iw {iface} info | grep type", shell=True).decode() return result.split(":")[1].strip() original_mode = get_wlan_mode("wlan0") # 执行扫描 ans, unans = srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst="192.168.1.0/24"), iface="wlan0", timeout=2, inter=0.1) # 恢复原始接口模式 subprocess.run(f"sudo iw wlan0 set type {original_mode}", shell=True)
4. 重置ARP缓存
- 清空本地ARP缓存:
sudo ip neigh flush all - 重新获取网关ARP条目:
ping -c 1 192.168.1.1
5. 优化Scapy扫描参数
- 添加
verbose=0减少输出干扰,同时确保Scapy正确释放接口资源:ans, unans = srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst="192.168.1.0/24"), iface="wlan0", timeout=2, inter=0.1, verbose=0) - 扫描后重置Scapy接口配置:
conf.iface = "wlan0" conf.iface.restart()
内容的提问来源于stack exchange,提问作者coder
相关产品推荐
相关产品推荐

