简介:这是一份面向高校网络安全实验课开发的地址解析协议与域名系统欺骗演示工具包,基于Go语言实现,用于在受控教学环境中模拟中间人攻击、域名劫持等典型攻击过程,帮助学习者直观理解协议层漏洞与防御思路,适合网络安全初学者和实验指导教师使用。压缩包共6个文件,核心为两个Go语言源码文件,另辅以YAML配置模板、Markdown说明文档、开源许可与Git忽略文件,整体仅10KB,轻量且便于部署和代码阅读。目前已有99人学习。工具代码量小但攻击链路完整,学习者可结合课程实验对照阅读,快速掌握地址解析协议报文伪造、域名系统响应篡改的基本实现方式,同时深刻认识此类技术的法律边界与实验室使用的必要性,为后续开展网络安全防护研究打下基础。
1. 一次"攻击自己人"的课堂实验,到底在练什么
第一次在实验网络里敲下arpspoof命令并按下回车时,我盯着终端里不断滚动的 ARP 应答包,心里其实比谁都紧张。老师站在讲台上把要求说得非常清楚:实验目标就是同一局域网里那台指定的"受害者"虚拟机,通过 ARP 欺骗拿到中间人位置,再配合 DNS 劫持,让受害者在浏览器里访问任意域名时都被引导到我们预设的页面。整个过程必须在课堂模拟网络内完成,严禁对任何真实网络和真实用户发起同样操作。
这门"网络安全第三次实验"之所以让人印象深刻,并不是因为命令有多难记,而是它把教材里那些抽象的协议漏洞变成了眼前可见的事实。你亲眼看到目标机器的 ARP 缓存被篡改,亲眼看到它发出的 DNS 查询请求被你的攻击机截获并返回了伪造应答,那种"原来漏洞是这样被利用的"的冲击感,比任何课本例题都来得直接。
这个实验真正练的有三件事:第一是理解 ARP 协议和 DNS 解析的底层工作机制,第二是掌握中间人攻击的完整攻击链——从网络层到应用层如何逐级渗透,第三也是最重要的,是建立防守视角。一个合格的网络工程师如果不清楚 ARP 欺骗是怎么发生的,就很难真正理解为什么交换机上要开 DHCP Snooping、为什么服务器要配置静态 ARP、为什么终端上要部署异常流量检测。攻击实验的价值从来不在攻击本身,而在它逼着你去想清楚"我该怎么挡"。
我们的实验环境极其简单:三台虚拟机,一台当攻击者,一台当受害者,网关是虚拟网络自带的虚拟路由器。整场演示从开始到结束不到二十分钟,但背后涉及的知识密度非常高。下面我按照从原理到实操再到防御的顺序,把这次实验完整还原一遍,所有命令均仅限于课堂虚拟环境复现,请务必在合法授权的实验网络内操作。
2. 原理拆解:ARP缓存投毒与DNS劫持的两个信任缺陷
2.1 ARP协议的工作方式与天生的"不设防"
ARP(Address Resolution Protocol)解决的是一个非常朴素的问题:在以太网这样的广播式局域网络里,两个主机要通信,发送方必须知道对方的 MAC 地址,但应用层和网络层只知道 IP 地址。ARP 的解决办法简单粗暴——发一个广播请求,问"谁是这个 IP 地址,请把你的 MAC 告诉我",目标主机听到后回复自己的 MAC 地址,请求方收到后写进自己的 ARP 缓存表,之后一段时间内再通信就直接用缓存里的条目,不再重复询问。
问题恰恰出在这个"简单粗暴"上。ARP 协议从设计之初就没有考虑身份认证,任何一个收到 ARP 请求的主机都可以回一个应答包,即使它根本不是请求中问的那个 IP 地址的持有者。更致命的是,很多操作系统采用的机制是"无请求应答也接受"——也就是说,哪怕你没有主动发出 ARP 请求,只要网络上有人主动发来一个 ARP 应答包,声称"我是 192.168.1.1",系统也会乖乖把这个映射关系写入 ARP 缓存表,覆盖掉原来的正确条目。
这就给了攻击者一个绝佳的漏洞。攻击者只要向受害者发送伪造的 ARP 应答,声称自己就是网关,受害者的数据包就会全部发往攻击机。同理,再向网关发送伪造的应答,声称自己就是受害者,网关发往受害者的数据包也会经过攻击机。两个方向的欺骗同时完成后,攻击者就成了受害者与网关之间的"中间人",这就是教科书里反复强调的 ARP 缓存投毒,也叫 ARP 欺骗或 ARP Spoofing。
用一个生活化的类比来解释:ARP 缓存就像一个小区物业登记册,正常情况下住户入住时会登记"302 室,张三"。但门卫没有任何验证手段,任何人打电话来说"我是 302 室,我改叫李四了",物业就直接把登记册改掉。于是所有寄给 302 室的快递都先交给冒名顶替的人过一手,拆开看完再转交过去——你毫无察觉,但所有东西都被别人看过一遍,甚至被换过。
2.2 DNS请求劫持:拿到中间人位置之后的"借力打力"
ARP 欺骗解决的是"流量经过我"的问题,而 DNS 欺骗解决的是"流量被我篡改"的问题。两者叠加,就构成了完整的攻击链。
DNS(Domain Name System)解析是终端访问网站的第一步:浏览器输入www.example.com,系统会向配置好的 DNS 服务器发起查询,拿到对应的 IP 地址,然后才建立 TCP 连接、发起 HTTP 请求。整个过程同样建立在"信任"之上——终端信任 DNS 服务器的应答,DNS 服务器信任上一级权威服务器,层层递归,每一环都没有对响应内容做真实性校验。
当攻击者通过 ARP 欺骗拿到中间人位置后,受害者的所有网络流量都会先到达攻击机。如果攻击机只做"就地转发"而不做任何干预,受害者不会有任何感知,通信照常进行。但攻击者显然不会这么安分——他可以在这一层做很多事情:记录流量、篡改内容、或者把 DNS 查询的请求截住,直接返回一个自己伪造的 IP 地址。
这就是 dnsspoof 这类工具的用途。攻击者在自己的机器上配置好规则文件,比如把www.baidu.com映射到自己的 IP 地址上,然后启动 dnsspoof 监听 53 端口。受害者发出 DNS 查询时,这个查询请求本来应该被转发到真实的 DNS 服务器,但在中间人场景下,攻击机可以直接抢答,返回一条伪造的 DNS 响应,告诉受害者"www.baidu.com 的 IP 是 192.168.1.50"。受害者无从分辨真假,浏览器就会连接到攻击者预设的页面,一个钓鱼页面就此生效。
从这个角度理解,ARP 欺骗和 DNS 劫持其实是"网络层漏洞 + 应用层漏洞"的组合拳。前者给了你一个可以站在路中间而不被人发现的位置,后者利用了应用层协议对 DNS 应答天然的信任,两者缺一不可。这也是为什么这个实验要从 ARP 做起,而不是直接讲 DNS——没有中间人位置,在同一个局域网里裸发 DNS 伪造应答的成功率很低,现代操作系统和浏览器都有一定的基础校验,而有了中间人位置后一切就顺理成章了。
3. 实验环境搭建:攻击机、受害者与网关的三方关系
3.1 网络拓扑与角色分工
实验拓扑非常清晰,就是典型的"三角关系":攻击者、受害者、网关三者同处一个局域网段,攻击者位于受害者与网关的数据通路上。
我在 VMware 里创建了全虚拟化的实验环境,具体分工如下:
| 角色 | 系统 | IP 地址 | 承担任务 |
|---|---|---|---|
| 攻击者 | Kali Linux | 192.168.1.50 | 运行 arpspoof 与 dnsspoof |
| 受害者 | Windows 10 / Ubuntu | 192.168.1.100 | 被欺骗方,演示浏览器异常行为 |
| 网关 | VMware 虚拟 NAT 网关 | 192.168.1.1 | 正常通信出口,被伪造对象 |
三个节点的虚拟网络适配器都设置为 NAT 模式,确保它们处于同一个虚拟局域网。这里有个细节值得注意:NAT 模式下的 VMware 虚拟网关本身也是一个软件路由器,它的 ARP 行为与实体路由器几乎一致,因此完全能够复现真实场景下的欺骗效果,不需要额外配置实体设备。
攻击机选择 Kali Linux 是最省事的选择,因为它自带大量渗透测试工具,dsniff 工具包默认安装,省去编译源码的环节。如果没有 Kali,用任何 Debian/Ubuntu 发行版也可以,只需要执行apt install dsniff安装工具包。受害者那台机器建议用 Windows 或 Ubuntu 这种有图形界面的系统,方便演示时直接打开浏览器观察效果。
3.2 工具安装与连通性预检
攻击机上需要用到三个核心工具:arpspoof、dnsspoof,以及可选的wireshark用于抓包验证。它们都来自 dsniff 工具包,Kali 自带,其他系统按需安装:
sudo apt update sudo apt install dsniff wireshark工具装好后,先做一轮连通性预检,这一步非常关键,能避免后面演示时因为环境问题而"翻车":
# 攻击机 ping 网关与受害者 ping -c 3 192.168.1.1 ping -c 3 192.168.1.100 # 查看网关的真实 MAC 地址 arp -a正常情况下,攻击机的 ARP 缓存表中应该有网关 192.168.1.1 对应的 MAC 地址记录。这个 MAC 地址要记下来,后续核对 ARP 缓存是否被成功篡改时需要用。预检的另一个目的是确认三台机器之间二层链路通畅——如果连 ping 网关都不通,说明虚拟网络配置有问题,得先排查 VMware 的网络模式,而不是急着开实验。
我还习惯在受害者机器上先访问一次目标网站,确认它的 DNS 解析和网页加载都正常。这一步是为了建立"基线行为"——只有先确认正常情况下的表现,后面演示时出现的变化才具有说服力。
4. 实操全流程:从 arpspoof 到 dnsspoof 的完整命令链路
4.1 开启IP转发,先当个"透明中转站"
拿到中间人位置之后,攻击机必须做一件事:把收到的、原本不属于自己的数据包转发出去。如果不做这一步,受害者的流量会在攻击机这里断掉,表现就是"全网断网",动静太大,受害者立刻就会发现异常,中间人也就"暴露"了。
Linux 内核默认不开启 IP 转发,需要手动打开:
sudo sysctl -w net.ipv4.ip_forward=1也可以直接写/proc/sys/net/ipv4/ip_forward:
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward这一步的操作意图很明确:让攻击机成为"透明路由器",只转发不干预。我的建议是把sysctl -w net.ipv4.ip_forward=1写在演示脚本的第一行,养成习惯,否则后面开了欺骗但没开转发,受害者网络一断,整个实验就白费了。
值得一提的是,IP 转发开启后,攻击机就完成了"窃听但不断线"的基础条件。此时流量虽然经过攻击机,但内容没有被修改,受害者不会有任何感知。这本身就是一种隐蔽的窃听手段,也是后续一切篡改动作的"地基"。
4.2 双向ARP欺骗:网关和受害者同时被"带节奏"
接下来是核心操作。arpspoof 的语法是arpspoof -i <网卡接口> -t <目标IP> <要冒充的IP>,它的作用是向目标 IP 发送伪造的 ARP 应答,声称"我是那个 IP"。要实现完整的中间人效果,需要开两个终端,分别欺骗受害者和网关。
第一个终端,欺骗受害者,让受害者以为攻击机就是网关:
sudo arpspoof -i eth0 -t 192.168.1.100 192.168.1.1第二个终端,欺骗网关,让网关以为攻击机就是受害者:
sudo arpspoof -i eth0 -t 192.168.1.1 192.168.1.100两条命令同时运行,效果是:受害者发往网关的数据包(目标 MAC 是网关的 MAC,但现在被篡改成了攻击机的 MAC)会到达攻击机;网关发往受害者的数据包也会到达攻击机。IP 转发开启后,这些数据包会被攻击机原样转发,通信不中断,但每一对数据包都经过了攻击机这个"夹层"。
有个容易踩坑的地方:-t参数后面先写谁,语义完全不同。第一条命令中的-t 192.168.1.100表示目标受害者是 192.168.1.100,要冒充的是 192.168.1.1;第二条命令相反,目标变成了网关,冒充的是受害者。两条都不能少,只做单向欺骗的话,流量只会"半程经过"攻击机,无法实现完整监听与篡改。
运行 arpspoof 后,终端会持续滚动输出发送的 ARP 应答包。此时可以在受害者机器上执行arp -a查看网关条目,如果欺骗成功,网关的 MAC 地址已经变成了攻击机的 MAC 地址。这一步验证很直观,建议在演示时保留这个画面作为证据。
4.3 编辑劫持规则并启动 dnsspoof
中间人链路打通后,DNS 劫持就变得非常简单。先准备一个域名劫持规则文件,格式是"IP 地址 + 域名",一行一条:
192.168.1.50 www.example.com 192.168.1.50 mail.example.com 192.168.1.50 *.test.org文件名随意,我习惯叫hosts.txt。注意这里的目标 IP 要写攻击机的 IP,也就是攻击者自己搭建的假网站所在的位置。如果想偷懒,也可以不指定规则文件直接运行dnsspoof -i eth0,这样它会默认把所有 DNS 查询请求都解析到攻击机的 IP 上,但这样动静太大,课堂上还是用精确匹配的规则文件更有演示价值。
启动 dnsspoof:
sudo dnsspoof -i eth0 -f hosts.txt运行后,dnsspoof 开始监听 53 端口,等待受害者的 DNS 查询包。一旦命中规则文件中的域名,就会立即返回一条伪造的 DNS 应答,把域名解析到攻击机 IP。终端会把每一次劫持记录打印出来,包括受害者的 IP、查询的域名和伪造的应答内容,这些日志也是实验报告里的好素材。
4.4 一整场演示的命令回顾
把完整命令串起来,大概是这样:
# 终端 1:开启 IP 转发 echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward # 终端 2:欺骗受害者(让受害者以为攻击机是网关) sudo arpspoof -i eth0 -t 192.168.1.100 192.168.1.1 # 终端 3:欺骗网关(让网关以为攻击机是受害者) sudo arpspoof -i eth0 -t 192.168.1.1 192.168.1.100 # 终端 4:启动 DNS 劫持 sudo dnsspoof -i eth0 -f hosts.txt实际操作时建议把四个终端窗口横向或纵向排列,同时运行,这样便于观察不同进程的输出信息。演示结束后,先按Ctrl+C停止 dnsspoof,再停止两个 arpspoof 进程。停止 arpspoof 后,受害者的 ARP 缓存不会立刻恢复,需要等缓存条目超时或手动执行arp -d清空后重新获取,这个"尾巴"也要在实验报告里说明,因为真实攻击结束后,受害者也需要一段时间才能恢复正常通信。
5. 效果验证与数据取证:攻击结果要"看得见、留得下"
5.1 受害者浏览器里的"见证时刻"
整场实验最有冲击力的环节,就是在受害者机器上打开浏览器输入目标域名,看到的却是攻击者预设的页面。
我在受害者机器上访问www.example.com,正常情况下应该打开真实网站,但实验开始后,浏览器地址栏输入这个域名,加载出来的却是攻击机上的一个简单 HTML 页面。这个页面上写着"这是一个 DNS 欺骗测试页面",用来区分布局,效果一目了然。
这里补充一个很重要的细节:浏览器的地址栏显示仍然是www.example.com,而不是攻击机的 IP 地址。因为 DNS 欺骗发生在域名解析阶段,浏览器并不知道自己连接的是假服务器,它以为域名就是解析到了这个 IP。只有用户主动查看证书信息或者通过nslookup手动查询,才会发现解析结果异常。这也是为什么钓鱼网站配合 DNS 劫持后很难被普通用户识别——地址栏的域名是真的,内容却是假的。
在受害者机器上运行nslookup www.example.com,会看到解析结果直接指向 192.168.1.50,这就是垮掉的铁证。
5.2 Wireshark里的攻击痕迹
作为网络安全实验,只看到表象是不够的,必须抓包留证。我在攻击机上启动 Wireshark,监听 eth0 接口,然后用两个过滤器分别查看 ARP 和 DNS 的数据包。
ARP 过滤器直接写arp:你会看到大量来自攻击机 MAC 地址的 ARP 应答包,这些包的类型是reply,而正常情况下网络上不会有这么高频的主动 ARP 应答。正常网络里 ARP 应答是"一问一答"的,攻击场景下则是攻击机单方面疯狂发送应答包,重复宣称自己是网关 IP。这个特征非常明显,几乎是 ARP 欺骗的代名词。
DNS 过滤器用dns:关注 UDP 端口 53 的通信。正常情况下,受害者的 DNS 查询会发给配置的 DNS 服务器,但在攻击场景下,响应来自攻击机的 IP,而且攻击机的 DNS 响应包往往比真实 DNS 服务器的响应更快返回。因为攻击机和受害者同处一个局域网,物理距离近,抢答成功的概率极高。Wireshark 里可以清楚地看到请求的目标地址和响应的源地址不一致,这正是 DNS 欺骗的特征。
建议在实验报告里附上两张截图:一张是 ARP 应答包风暴的抓包图,一张是 DNS 伪造应答的抓包图,再配一段文字说明攻击原理,这份实验报告的质量就非常扎实了。
6. 防御对策与实验踩坑心得
6.1 防守方工具箱:从终端到交换机再到DNS
实验做完,真正的重头戏是防守。这次实验让我深刻体会到,理解一种攻击方式最好的结果,就是能够把它对应的防御措施讲清楚。我整理了一下,针对 ARP+DNS 欺骗至少有这么几层防护可以部署。
第一层是终端侧的静态 ARP 绑定。对于关键服务器和网关,可以在终端上手动配置静态 ARP 条目,让系统不再接受来自网络的动态 ARP 更新。Windows 下用arp -s命令,Linux 下用arp -s或写/etc/ethers配合arpon这类工具。静态绑定的问题在于运维成本高,适合保护网关和少量核心设备,不适合全网络推广。
第二层是交换机层面的防护,这是企业网络最常用的方案。开启 DHCP Snooping 后,交换机可以建立一张"IP + MAC + 端口 + VLAN"的绑定关系表,再配合 Dynamic ARP Inspection(DAI),交换机就会校验每个 ARP 包是不是与绑定表匹配,不匹配的直接丢弃。这个机制专门针对 ARP 欺骗设计,效果非常好。华三、华为、思科的交换机基本都支持,配置命令略有不同,但原理一致。实验里我虽然没有真实交换机,但这一部分作为防御章节写进实验报告,老师给的评价很高。
第三层是 DNS 层面的防护。部署 DNSSEC 可以对 DNS 应答做数字签名校验,让伪造应答无法通过验证。同时,企业内部 DNS 服务器要配置递归查询限制,只对内部用户开放,避免被外部利用。对于普通用户来说,配置使用可信的公共 DNS 也能在一定程度上降低被劫持的风险,但要注意,在 ARP 欺骗已经成功的中间人场景下,DNS 服务器地址本身也是可以被篡改的,所以 DNS 防护必须与网络层防护配合使用。
第四层是异常流量监测。部署 arpwatch 这类工具,可以持续监听局域网内的 ARP 流量,当发现某个 IP 的 MAC 地址发生变化或者出现异常高频的 ARP 应答时,自动发出告警。企业级方案里,入侵检测系统(IDS)也能识别这类行为特征。对于课堂环境,用 Wireshark 手动检查也能达到同样的教学目的,关键是让学生学会看数据包特征。
6.2 实验过程中踩过的坑
这次实验我前前后后跑了三遍,踩了几个非常典型的坑,写出来给大家避雷。
第一个坑是没有开 IP 转发就直接跑 arpspoof,结果受害者全网断线。当时还以为是命令参数写错了,排查了半天才发现是/proc/sys/net/ipv4/ip_forward还是 0。这个错误几乎是所有新手第一次做 ARP 欺骗实验时都会遇到的,原因在于 arpspoof 只是负责"发伪造包",它不负责"转包",转包是内核的职责。所以把开启 IP 转发放在第一步,永远不要省略。
第二个坑是只做了单向欺骗。我只开了arpspoof -i eth0 -t 192.168.1.100 192.168.1.1,也就是只欺骗了受害者,没欺骗网关。结果受害者的上游流量确实到了攻击机,但网关回给受害者的流量还是直接到达受害者,攻击机只能看到一半流量,DNS 劫持自然不生效。因为在 DNS 查询的场景里,受害者发出查询请求后会等待响应,如果我只能看到请求但看不到响应通道,无法完成抢答。双向欺骗一定要两条命令同时运行。
第三个坑是 VMware 的虚拟网络隔离问题。如果虚拟机的网络模式配置不对,三台机器可能不在同一个二层网段,arpspoof 根本找不到目标。我的排查方法是先看三台机器的 IP 是否在同一网段,再互 ping 一遍,最后用arp -a确认能解析到对方的 MAC 地址。二层通不了,三层就一定通不了,这个顺序逻辑一定要理清。
第四个坑相对隐蔽:受害者的操作系统如果开启了 ARP 协议栈加固功能(某些 Linux 发行版默认开启),对异常 ARP 应答的接受度会降低,欺骗效果可能不稳定。课堂演示遇到这种情况不用慌,换一个操作系统的虚拟机,或者手动调整内核参数即可。Windows 系统在这方面比较"配合",演示效果更稳定。
6.3 一点真实的教学体会
实验结束后老师问了我们一个问题:"你们觉得这个攻击最容易防的一点是什么?"很多人说是 DNSSEC,也有人说是交换机上的 DAI,但老师的答案是:最容易防的是"人"——如果每个使用网络的人都保持警惕,发现页面异常就立刻停止输入敏感信息,攻击者精心搭建的钓鱼页面就失去了意义。技术防御可以做得很完善,但人的安全意识永远是最基础也最有效的一环。
我个人最大的收获是建立了一种"攻击链路思维"。以前学 ARP 和 DNS 是割裂的,各是各的章节,做完这个实验才真正明白它们是怎么串联起来的:网络层的漏洞给了攻击者"位置",应用层的信任给了攻击者"手段"。这种思维方式对以后做网络排障也有帮助,遇到异常现象时,我会下意识地沿着数据链路从二层到七层逐层排查,而不是只盯着某一个协议的报错。
另外还想提醒一句:这类工具在真实网络环境中的使用必须严格遵守法律法规,只能在实验网络、授权测试环境或者自己的设备上进行教学验证。课堂上老师反复强调这一点,我也希望大家把这些技术当作理解网络安全的窗户,而不是当作攻击他人网络的工具。只有先弄清楚攻击者是怎么想的,防守方才能真正做到未雨绸缪。
本文还有配套的精品资源,点击获取