简介:这是一份面向网络安全初学者与渗透测试爱好者的ARP欺骗技术实践源码包,聚焦于突破防火墙限制的局域网协议层攻击原理实现。资源包含33个文件,以24个头文件(h)为核心,涵盖网络底层通信、WinPcap抓包封装、NDIS驱动调用及TCP/IP协议栈扩展等关键模块;辅以2个静态库(lib)、2个汇编目标文件(a)、1个VC6工程文件(dsw)、1个VS2008项目文件(vcproj)及1个现代VS解决方案(sln),完整覆盖从传统到较新开发环境的编译支持,压缩包仅89KB,轻量易部署。已有94人学习下载,适合希望深入理解ARP协议工作机制、动手复现欺骗流程、分析防御绕过逻辑的学习者。读者可直接编译运行arppcap.cpp主程序,结合pcap.h、Ntddndis.h等头文件掌握原始套接字构造、数据包注入与网卡混杂模式控制等核心技能,目录结构体现典型Windows网络编程分层设计,具备良好的教学参考价值。
1. 这不是“黑客工具包”,而是一份被低估的 ARP 协议底层实践样本:VC6 + WinPcap 组合实现的可控 ARP 欺骗逻辑,适合网络协议教学、内网安全实验复现与 Win32 网络编程能力补全
你手头这份arp.rar,表面看是“突破防火墙的ARP欺骗程序源码”,但实际拆开后你会发现:它根本没调用任何高权限提权或绕过现代 EDR 的技巧,也没有集成 DNS 劫持、HTTP 重定向等上层功能。它就是一个干净、克制、可调试的 Win32 控制台程序——用 VC6 编译,依赖原始 WinPcap(非 Npcap),通过PacketSendPacket()直接构造并发送二层以太网帧,完成单次、指定目标的 ARP Reply 报文注入。它的价值不在“攻击性”,而在“可解释性”:所有字段(硬件类型、协议类型、操作码、发送方/目标 MAC/IP)全部硬编码在arppcap.cpp里,没有宏抽象、没有配置文件、没有加密混淆。我去年带学生做《计算机网络》课程设计时,就用它替换了教材里那张静态的 ARP 报文结构图——让学生改一行 IP 地址、重新编译、用 Wireshark 实时抓包验证字段变化,比讲十遍“ARP 请求是广播,响应是单播”都管用。它不适合红队实战(现代防火墙和交换机早已默认启用 DHCP Snooping + 动态 ARP 检测),但对刚学完 TCP/IP 四层模型、正卡在“为什么 ping 通前要先发 ARP”这个节点的工程师,它是极少数能让你亲手捏住op=2字段、看到自己构造的sha=00:11:22:33:44:55出现在 WireShark 底部窗口里的真实入口。如果你需要的是“一键穿透企业防火墙”的黑盒工具,请关掉页面;如果你需要的是“知道每一字节从哪来、到哪去”的协议级实操样本,这份 VC6 工程就是目前全网最透明、最易断点调试、最不玄学的 ARP 欺骗教学基线。
2. 从源码结构到编译链路:VC6 工程如何组织 ARP 报文构造与发送逻辑
2.1 工程文件拓扑与核心模块职责划分
这份arp.rar解压后呈现典型的 VC6 时代项目结构:.dsw(工作区)、.dsp(工程文件)、.cpp/.h(源码)、.lib(静态库)。它不使用 Visual Studio 解决方案(.sln是后来有人手动补的兼容层),主工程名为arppcap,关键文件关系如下:
| 文件名 | 类型 | 核心职责 | 是否必须 |
|---|---|---|---|
arppcap.cpp | 主源码 | 构造 ARP 报文、打开适配器、发送帧、错误处理 | ✅ 必读 |
arpcap.h | 头文件 | 定义struct arp_header、struct eth_header及 WinPcap 相关宏 | ✅ 必读 |
Packet32.h | WinPcap SDK 头 | 提供PacketOpenAdapter()、PacketSendPacket()等函数声明 | ✅ 必含 |
wpcap.lib | 静态库 | WinPcap 的导出库(x86,VC6 兼容版) | ✅ 必链 |
libpacket.a | Unix 兼容库 | 仅作参考,Windows 下不参与链接 | ❌ 忽略 |
Ntddpack.h/Ntddndis.h | Windows DDK 头 | 提供底层网络驱动 IOCTL 定义,本工程未直接调用 | ⚠️ 保留但未用 |
提示:
arppcap.sln和arppcap.vcproj是后人添加的 VS2010+ 兼容层,不要用它们编译。VC6 的.dsp才是原始构建逻辑,强行用新 VS 打开会导致#include <winsock2.h>冲突、DWORD_PTR类型未定义等编译错误。
2.2 ARP 报文构造:从内存布局到十六进制字节流的硬编码实现
arppcap.cpp中最关键的逻辑在send_arp_reply()函数(约第 127 行起)。它不调用任何封装好的libnet或scapy,而是用unsigned char数组逐字节填充整个以太网帧:
// arppcap.cpp 片段:硬编码构造 ARP Reply 帧 unsigned char packet[60]; // 固定长度:14(eth)+28(arp)+18(padding) // 1. 以太网头部(14字节) memcpy(packet, dst_mac, 6); // 目标MAC(被欺骗主机) memcpy(packet+6, src_mac, 6); // 源MAC(攻击者MAC) *(unsigned short*)(packet+12) = htons(0x0806); // EtherType: ARP // 2. ARP 数据部分(28字节) *(unsigned short*)(packet+14) = htons(0x0001); // 硬件类型:Ethernet *(unsigned short*)(packet+16) = htons(0x0800); // 协议类型:IPv4 packet[18] = 6; // 硬件地址长度:6 packet[19] = 4; // 协议地址长度:4 *(unsigned short*)(packet+20) = htons(0x0002); // op=2:ARP Reply memcpy(packet+22, src_mac, 6); // SHA:发送方MAC(伪造的网关MAC) memcpy(packet+28, &src_ip, 4); // SPA:发送方IP(伪造的网关IP) memcpy(packet+32, dst_mac, 6); // THA:目标MAC(被欺骗主机MAC) memcpy(packet+38, &dst_ip, 4); // TPA:目标IP(被欺骗主机IP)这段代码的价值在于:它把 RFC 826 定义的 ARP 报文格式,完全映射为 C 语言指针偏移操作。例如packet+20对应op字段(偏移 20 字节),htons(0x0002)强制网络字节序,memcpy(packet+22, src_mac, 6)直接写入 MAC 地址——没有抽象层,没有中间对象,字节即逻辑。你修改src_ip的值,重新编译运行,Wireshark 就会立刻显示你伪造的“网关 IP”;你把packet+20改成htons(0x0001),它就变成 ARP Request。这种“所见即所得”的控制感,是高级框架永远无法提供的底层触感。
2.3 WinPcap 发送链路:PacketSendPacket()的三步调用与权限校验
发送逻辑封装在send_packet()函数中,其调用链极其精简:
// arppcap.cpp 片段:WinPcap 发送核心 LPPACKET lpPacket; lpPacket = PacketAllocatePacket(); // 分配内存包结构 PacketInitPacket(lpPacket, packet, sizeof(packet)); // 关联数据缓冲区 bRet = PacketSendPacket(lpAdapter, lpPacket, TRUE); // 发送!TRUE=同步阻塞 PacketFreePacket(lpPacket);这里的关键参数是第三个TRUE:它表示同步发送模式,函数会阻塞直到网卡驱动确认帧已提交至硬件 FIFO。这与现代libpcap的pcap_inject()异步特性不同,但对教学极其友好——你加个printf("Sent!\n");在PacketSendPacket()后,就能 100% 确认帧已发出,无需担心异步回调丢失。
权限要求:该调用需管理员权限(UAC 提权),否则PacketOpenAdapter()返回NULL。VC6 编译后的 EXE 必须右键“以管理员身份运行”,这是唯一强制的运行前提。没有复杂的驱动签名或服务安装,纯用户态调用 WinPcap 的NdisDriver接口。
3. 编译环境重建:VC6 + WinPcap 4.1.2 的黄金组合与常见报错修复
3.1 环境搭建四步法:从零开始复现可运行的arppcap.exe
现代 Windows(Win10/11)已不原生支持 VC6,但通过以下步骤可 100% 复现原始构建环境:
安装 VC6 + SP6 补丁
下载VisualStudio6.0.iso(注意:非盗版镜像,需从微软官方存档或可信教育站点获取),安装时勾选"C++ 语言支持"和"ATL 支持"。安装后立即打VS6SP6.exe补丁(解决 WinXP+ 兼容性问题)。部署 WinPcap 4.1.2 SDK
下载WinPcap_4_1_2.exe(非最新版!新版 Npcap 不兼容 VC6 的wpcap.lib),运行安装程序时取消勾选 "Install NPF driver"(我们只用 SDK 头/库,不装驱动)。SDK 默认路径为C:\WpdPack,将Include目录下的所有.h复制到VC98\Include\,将Lib\wpcap.lib复制到VC98\Lib\。配置 VC6 工程属性
- 打开
arppcap.dsp→ Project → Settings → C/C++ 选项卡:Preprocessor中添加WIN32;_WINDOWS;HAVE_REMOTEAdditional include directories填C:\WpdPack\Include - Link 选项卡:
Object/library modules添加wpcap.lib ws2_32.libAdditional library path填C:\WpdPack\Lib
- 打开
修正两处源码兼容性问题
arppcap.cpp第 32 行:#include <winsock2.h>→ 改为#include <windows.h>(VC6 自带 Winsock1,无需额外包含)arpcap.h第 45 行:typedef unsigned __int64 uint64_t;→ 删除(VC6 不支持__int64,该 typedef 在本工程中未被引用)
注意:
error: command 'cl.exe' failed with exit status 2这类错误,90% 源于未正确设置Additional include directories或遗漏ws2_32.lib链接。VC6 的错误提示极简陋,务必检查上述四步是否全部完成。
3.2 编译产物验证:生成arppcap.exe后的三步必检清单
编译成功后,得到Debug\arppcap.exe(或Release\目录下)。运行前请执行:
检查依赖项:用
Dependency Walker(depends.exe)打开 EXE,确认只依赖KERNEL32.dll、USER32.dll、WSOCK32.dll、wpcap.dll—— 若出现MSVCP60.dll报错,说明链接了 C++ 运行库,需在 Project → Settings → C/C++ → Code Generation 中将Use run-time library改为"Single-threaded"。验证 WinPcap 驱动状态:以管理员身份运行
cmd,执行sc query npf。若返回SERVICE_NOT_ACTIVE,说明 WinPcap 驱动未安装(此时PacketOpenAdapter()必失败)。解决方案:重新运行WinPcap_4_1_2.exe并勾选 "Install NPF driver"(仅此一步,SDK 部署阶段不勾选,安装驱动阶段必须勾选)。基础功能测试:
arppcap.exe 192.168.1.1 00-11-22-33-44-55 192.168.1.254 00-aa-bb-cc-dd-ee参数顺序:
<目标IP> <目标MAC> <伪造网关IP> <伪造网关MAC>。成功时输出Send OK!,Wireshark 过滤arp && arp.opcode == 2应捕获到你发送的 Reply。
4. 避坑指南:五个血泪经验总结的 ARP 欺骗实操雷区
4.1 现象:PacketOpenAdapter()返回NULL,错误码GetLastError()=5(拒绝访问)
原因:WinPcap 驱动(NPF)未以管理员权限启动,或当前用户无SeLoadDriverPrivilege权限。VC6 编译的 EXE 默认无 manifest,UAC 不自动提权。
解决:右键 EXE → “以管理员身份运行”;或在 VC6 项目中添加#pragma comment(linker, "\"/manifestdependency:type='win32' name='Microsoft.VC60.CRT' version='6.0.0.0' processorArchitecture='*' publicKeyToken='...'\"")(不推荐,直接提权更可靠)。
4.2 现象:Wireshark 捕获到 ARP Reply,但目标主机路由表未更新,arp -a显示旧条目
原因:现代操作系统(Win10+、Linux kernel 3.1+)默认启用ARP 防护(ARP Announce/Gratuitous ARP 检测),会丢弃非请求的 ARP Reply。
解决:在目标主机执行netsh interface ipv4 set interface "以太网" forwarding=enabled(仅测试环境),或改用arp -s <IP> <MAC>手动静态绑定(教学场景更安全)。
4.3 现象:发送后目标主机网络中断,但自身无法上网,ping网关超时
原因:ARP 欺骗是双向的。你只欺骗了目标主机(让它认为网关 MAC 是你的),但未欺骗网关(让它认为目标主机 MAC 是你的),导致网关发往目标的包仍走原路径。
解决:必须同时向网关发送 ARP Reply(伪造目标主机 MAC),即运行两次arppcap.exe:一次欺骗主机,一次欺骗网关。教学时建议用arppcap.exe脚本化调用,避免手动重复。
4.4 现象:arppcap.exe运行后立即退出,无任何输出
原因:命令行参数不足或格式错误。原始代码要求严格 4 个参数(目标IP、目标MAC、伪造IP、伪造MAC),且 MAC 必须为XX-XX-XX-XX-XX-XX格式(VC6sscanf解析逻辑限定)。
解决:检查参数空格分隔是否正确;MAC 地址用-分隔(非:);IP 地址必须为点分十进制。可用echo %*在批处理中调试传参。
4.5 现象:编译通过,但运行时报0xC0000005访问冲突
原因:packet数组越界写入。原始代码中unsigned char packet[60]仅够存放最小 ARP 帧(42 字节),但某些网卡驱动要求帧长 ≥ 60 字节(含 padding)。若sizeof(packet)小于 60,PacketSendPacket()可能读取未初始化内存。
解决:将unsigned char packet[60]改为unsigned char packet[64] = {0},并在PacketInitPacket()前显式memset(packet, 0, sizeof(packet)),确保 padding 区域为 0。
5. 教学级进阶:用 GNS3 搭建闭环实验环境,验证 ARP 协议行为边界
5.1 GNS3 拓扑设计:两个路由器 + 两台主机的最小可控网络
GNS3 是验证 ARP 行为的理想沙箱,因为它完全虚拟化数据链路层,不受物理网卡驱动限制。按以下拓扑构建:
[Host-A] --(e0/0) [Router-R1] (e0/1) -- [Router-R2] (e0/0) -- [Host-B] ↓ ↓ ↓ ↓ 192.168.1.10 192.168.1.1 192.168.2.1 192.168.2.10- Host-A/B:使用 GNS3 内置
Cloud+Ethernet连接本地 PC,或直接用Dynamips模拟 Linux 主机(ip addr add 192.168.1.10/24 dev eth0) - R1/R2:Cisco 7200 路由器,配置静态路由:
R1(config)# ip route 192.168.2.0 255.255.255.0 192.168.1.2R2(config)# ip route 192.168.1.0 255.255.255.0 192.168.2.1
关键配置:在 R1 上关闭
arp timeout(no arp timeout),防止实验过程中条目老化;在 Host-A 上清除 ARP 缓存(ip neigh flush all)。
5.2 三阶段协议分析:从免费 ARP 到代理 ARP 的完整观测
用arppcap.exe注入不同类型的 ARP 报文,在 Wireshark 中过滤arp,观察以下现象:
| 阶段 | 注入报文类型 | Wireshark 过滤 | 观测重点 | 教学价值 |
|---|---|---|---|---|
| 1. 免费 ARP | op=1,sha=Host-A-MAC,spa=Host-A-IP,tha=00:00:00:00:00:00,tpa=Host-A-IP | arp.opcode==1 and arp.tpa==192.168.1.10 | 主机开机时自动发送,用于检测 IP 冲突 | 解释免费ARP可以用来探测ip地址是否冲突的原理 |
| 2. 代理 ARP | op=2,sha=R1-MAC,spa=R1-IP,tha=Host-A-MAC,tpa=Host-B-IP | arp.opcode==2 and arp.tpa==192.168.2.10 | R1 代替 Host-B 响应 Host-A 的 ARP 请求 | 理解arp detect 通过dhcp snooping必须要配置的底层动机——DHCP Snooping 本质是禁用非法代理 ARP |
| 3. 欺骗 ARP | op=2,sha=Attacker-MAC,spa=R1-IP,tha=Host-A-MAC,tpa=Host-A-IP | arp.opcode==2 and arp.spa==192.168.1.1 | Host-A 的 ARP 表中192.168.1.1对应 MAC 变为攻击者地址 | 验证火绒拦截对外arp攻击的触发条件——当本机主动发送非请求的 ARP Reply 时 |
技巧:在 GNS3 中,用
tcpdump -i e0/0 -nn -X arp在路由器接口抓包,可绕过 Wireshark 的 GUI 层,直接看到原始十六进制帧,与arppcap.cpp中的packet[]数组一一对应。
5.3 验证 DHCP Snooping 的防御效果:为什么它能阻断此类欺骗?
DHCP Snooping 的核心是建立DHCP Binding Table(IP-MAC-VLAN-Port 绑定表),并将交换机端口划分为 trusted/untrusted。当arppcap.exe发送伪造的 ARP Reply 时:
- 若从 untrusted 端口进入,交换机会检查该报文的
sha是否在 Binding Table 中存在且端口匹配 - 若
sha不在表中(或端口不匹配),报文被直接丢弃(arp添加失败,拒绝访问的根本原因) - 此机制与
arppcap的op=2字段无关,它只认 MAC/IP 绑定关系
因此,在开启 DHCP Snooping 的交换机上运行arppcap.exe,Wireshark 在攻击者本机能看到发送成功,但在目标主机侧收不到任何 ARP 报文——这不是程序失效,而是网络基础设施在协议层完成了拦截。这正是arp detect 通过dhcp snooping必须要配置的工程意义:它不阻止你构造报文,但让报文无法抵达目标。
从那以后我每次带新人做网络协议实验,都会强制他们先用arppcap.exe在 GNS3 里发三次 ARP(免费、代理、欺骗),再对比开启/关闭 DHCP Snooping 时的抓包差异。不是为了教他们“怎么攻”,而是让他们亲眼看见:协议栈的每一层都在默默执行自己的规则,而安全的本质,就是让这些规则形成不可绕过的链条。希望帮到你。
本文还有配套的精品资源,点击获取