实验环境
我使用的是 Ubuntu 24.04.4,基本环境配置见ARP攻击原理学习
启动实验前先清理容器环境,防止被之前的网络配置干扰
|
|
进入实验目录并启动
|
|
遇到问题:报错
Error response from daemon: interface specific sysctl setting "net.ipv4.conf.eth0.send_redirects" must be supplied using driver option 'com.docker.network.endpoint.sysctls'![]()
编辑
docker-compose.yml,删除这一行
1- net.ipv4.conf.eth0.send_redirects=0
网络结构包括受害者、攻击者、真实网关、恶意路由器以及目标主机
| 节点 | IP 地址 | 作用说明 |
|---|---|---|
| 受害者主机 | 10.9.0.5 |
攻击目标。初始路由指向 .11 |
| 真实路由器 | 10.9.0.11 |
连接两个网段的实际节点。它同时拥有 10.9.0.11 和 192.168.60.11 两个 IP |
| 恶意路由器 | 10.9.0.111 |
攻击者诱导流量去往的中间人节点 |
| 攻击者主机 | 10.9.0.105 |
发送伪造 ICMP 重定向报文的节点 |
| 目标主机 | 192.168.60.5 |
位于另一个网段的通信目标 |
| Docker 网关 | 10.9.0.1 |
Docker 虚拟网络的默认出口,不参与实验 |
ICMP 重定向攻击
ICMP Redirect 用于局域网优化路径。主机将数据包发送给网关时,如果网关发现存在更优的路径,会返回一个重定向报文来让主机更新路由缓存,之后的数据包就会经过新的网关。这个机制缺少认证,只要报文结构合法而且来源看似可信,就有可能被内核接受,因此可以伪造重定向来进行攻击
攻击目标是修改受害者的路由缓存,让受害者发往目标主机的流量途经恶意路由器
受害者
ICMP 重定向并不是无条件生效,需要存在对应的通信流量,否则内核可能直接忽略报文,因此必须让受害者与目标主机保持通信,这样重定向才有机会实行
进入受害者容器,执行ping命令且不中断
|
|
攻击者
攻击者需要伪造来自网关的 ICMP Type 5 Redirect 报文,告诉受害者访问目标时改走新的路由。需要满足两个条件:重定向报文必须伪装成网关发送,以及报文中必须包含受害者当前正在进行的通信信息。一般通过抓包监听,ARP 欺骗,局域网嗅探等获取此信息
进入攻击者容器
|
|
首先写一个脚本icmp_redirect.py
|
|
发送伪造的 ICMP 重定向报文
|
|
验证
原本受害者访问目标主机时的路径为
受害者>网关>目标主机,攻击成功后会变成受害者>攻击者>目标主机
攻击完成后,停止受害者机器上的 ping 命令,在受害者容器查看路由缓存
|
|
可以看到以下输出
|
|
- 第一行说明默认网关是10.9.0.1
- 第二行说明10.9.0.x 网段就在本地,不需要经过网关,可以直接发送
- 第三行说明访问 192.168.60.x 网段时走静态路由10.9.0.11
如果攻击成功,第三行应该显示的是10.9.0.111。攻击失败了,这是Docker中复杂的网络环境,以及现代Linux对ICMP重定向更严格的校验所导致,即使攻击报文成功发送,受害者也不一定更新缓存。因此手动添加路由进行模拟即可
|
|
附:排查过程
容器
查看容器信息,并没有问题
|
|
在发包的时候进行抓包,可以看到0a09006f中6f对应111,这里也没有问题
|
|
修改脚本中的攻击者ip为10.9.0.100,删除路由缓存后重新进行攻击,发现路由缓存没有变化,说明这个路由并不是更新的动态缓存,而是写在Docker配置里的静态路由
|
|
查看docker-compose.yml,发现这一行,这说明受害者的默认路由被指向10.9.0.11,也就是刚刚输出的地址
|
|
这里说明真正的路由器其实是10.9.0.11,而不是我最初以为的10.9.0.1。修改脚本中的路由器ip为10.9.0.11,重新发包后还是没有用
|
|
发包
再次进行抓包,tcpdump -i eth0 -nn -vvv icmp
|
|
这句话表示攻击报文中嵌套的原始数据包片段,声明受害者10.9.0.5正在向目标192.168.60.5发送一个8字节的Ping请求,内核通过核对这段嵌套信息与自身发出的真实流量是否一致,来决定是否接受路由重定向。这里说明发出的攻击包中确实附带了受害者最近的通信信息
删除受害者的静态路由,ping直接断掉,尝试发包依旧没有用
|
|
验证攻击包到底有没有真的作用在受害者的网卡上,受害者执行tcpdump -i eth0 icmp -nn,输出如下,说明一切正常
|
|
查看受害者内核计数器,ICMP messages failed为0,ICMP redirects received数量很多,说明大概率是内核拒绝了请求
内核
Linux 内核还有一个反向路径过滤的防御机制,内核收到 .1 发来的重定向包,但它会检查如果向这个地址发包,路径是否是收到包的网口,如果不符合或者路由不通就不更改,在受害者容器内进行关闭
|
|
还是失败了,又把最开始的.11添加回去,依旧不行,说明实验确实无法正常完成,只能进行模拟
中间人攻击
攻击的核心并不是重定向本身,而是通过重定向使流量经过攻击者,实现对流量的控制。此时攻击者已经处于通信路径中间,但默认情况下数据仍然是直接转发的,需要对数据进行拦截和修改。路由缓存有时间限制,中间人攻击需要在有效期内完成,否则需要重新进行重定向攻击
通信
在目标主机上开启监听
|
|
受害者发起连接
|
|
通信建立后,在恶意路由器上关闭内核转发,这是为了防止数据包在被脚本篡改之前就被系统转发走
|
|
攻击
进入脚本目录
|
|
在恶意路由器写一个中间人脚本mitm_nc.py
|
|
运行中间人脚本
|
|
验证
在受害者端发送任意字符串,目标主机接收到的内容被替换为相同长度的A,这说明数据已在传输过程中被修改