# ICMP Redirect 与 MITM 实验演示手册 本文档按“实际演示”来写,不只解释原理,还给出每个容器要执行的具体命令。 当前仓库已经包含可用脚本: - `Labsetup/volumes/task1.py` - `Labsetup/volumes/task1_improved.py` - `Labsetup/volumes/task1_sniff_and_redirect.py` - `Labsetup/volumes/mitm_attack.py` 其中: - `task1.py` 是当前更适合展示的 ICMP Redirect 发送脚本 - `task1_sniff_and_redirect.py` 只在攻击者容器能看到 victim 单播流量时才适用 - `mitm_attack.py` 已修复死循环重发问题,可以直接用于 MITM 展示 --- ## 1. 实验目标 本实验分两部分: 1. 演示 ICMP Redirect 攻击,尝试让 `victim` 把发往 `192.168.60.5` 的流量改走恶意路由器 `10.9.0.111` 2. 演示 MITM 篡改,在恶意路由器上把 `hello seedlabs` 改成 `hello AAAAAAAA` --- ## 2. 拓扑与角色 | 容器 | IP | 作用 | | :--- | :--- | :--- | | `victim-10.9.0.5` | `10.9.0.5` | 受害者 | | `attacker-10.9.0.105` | `10.9.0.105` | 发送 ICMP Redirect 的攻击机 | | `malicious-router-10.9.0.111` | `10.9.0.111` | 恶意路由器,负责 MITM | | `router` | `10.9.0.11 / 192.168.60.11` | 合法路由器 | | `host-192.168.60.5` | `192.168.60.5` | 目标主机 | --- ## 3. 启动环境 在宿主机的项目根目录执行: ```bash cd /home/gh0s7/project/netsecurity2026/ICMP_Directing/Labsetup docker-compose up -d docker ps ``` 建议先确认容器都起来了: ```bash docker ps --format 'table {{.Names}}\t{{.Status}}' ``` --- ## 4. 打开 5 个终端 建议分别打开以下终端,便于课堂展示: ### 终端 1: victim ```bash docker exec -it victim-10.9.0.5 bash ``` ### 终端 2: attacker ```bash docker exec -it attacker-10.9.0.105 bash ``` ### 终端 3: malicious-router ```bash docker exec -it malicious-router-10.9.0.111 bash ``` ### 终端 4: target host ```bash docker exec -it host-192.168.60.5 bash ``` ### 终端 5: router ```bash docker exec -it router bash ``` `router` 终端不是必须,但展示路径时有帮助。 --- ## 5. 演示前检查 ### 在 victim 容器执行 先确认默认到目标网段的路由仍然指向合法网关: ```bash ip route ``` 你应该看到类似结果: ```bash 192.168.60.0/24 via 10.9.0.11 dev eth0 ``` 再清理路由缓存: ```bash ip route flush cache ``` 再查看当前 redirect 相关内核参数: ```bash sysctl net.ipv4.conf.all.accept_redirects sysctl net.ipv4.conf.eth0.accept_redirects sysctl net.ipv4.conf.all.secure_redirects sysctl net.ipv4.conf.eth0.secure_redirects ``` ### 在 malicious-router 容器执行 先看恶意路由器的默认路由: ```bash ip route ``` ### 在 attacker 容器执行 确认脚本在共享目录里: ```bash ls -l /volumes ``` --- ## 6. 第一阶段: ICMP Redirect 展示 这一阶段分为两种情况: 1. 理想情况:当前内核接受 redirect,victim 会真的改路由 2. 当前环境常见情况:victim 能收到 redirect,但不会真的安装这条重定向路由 ### 6.1 在 attacker 容器执行 先运行静态 redirect 脚本: ```bash python3 /volumes/task1.py ``` 这个脚本会: - 伪造源 IP 为合法网关 `10.9.0.11` - 伪造源 MAC 为合法网关的 MAC - 发送 ICMP Type 5 Redirect - 引用一个最小合法长度的“原始触发包”片段 如果你想把发送次数调大一点,可以这样运行: ```bash python3 /volumes/task1.py --count 50 --interval 0.2 ``` ### 6.2 在 victim 容器执行 在 attacker 正在发包时,触发 victim 访问目标主机: ```bash ping -c 3 192.168.60.5 ``` 然后检查缓存和路径: ```bash ip route show cache ip route get 192.168.60.5 mtr -n -r -c 2 192.168.60.5 ``` ### 6.3 成功时你应看到什么 理想情况下,`mtr` 第一跳会变成: ```bash 10.9.0.111 ``` `ip route show cache` 可能出现类似: ```bash 192.168.60.5 via 10.9.0.111 dev eth0 cache ``` ### 6.4 如果没有成功,这在当前环境是正常的 我在当前环境里实际验证过: - victim 能收到大量 ICMP Redirect - 但路由没有真正切换到 `10.9.0.111` 原因不是脚本完全没工作,而是当前容器共享宿主机较新的 Linux 内核,对 redirect 的接受条件比实验 PDF 对应的旧环境更严格。 你可以在 victim 容器里用下面命令说明“包确实收到了”: ```bash nstat -az | grep Redirect ``` 如果 `IcmpInRedirects` 持续增加,就说明 redirect 已到达 victim 内核。 ### 6.5 关于 `task1_sniff_and_redirect.py` 这个脚本只在攻击者能嗅探到 victim 发往 router 的单播 ICMP 时才适合使用: ```bash python3 /volumes/task1_sniff_and_redirect.py ``` 在当前 Docker bridge 拓扑里,`attacker` 通常看不到 `victim -> router` 的单播流量,所以这个脚本经常抓不到包。这不是代码语法问题,而是网络可见性问题。 --- ## 7. 第二阶段: MITM 篡改展示 因为第一阶段在当前环境下可能不会真的完成“自动改路由”,所以演示时推荐手工把 victim 的目标网段路由改到恶意路由器。这一步相当于“模拟第一阶段已经成功”。 这能稳定完成第二阶段展示,而且可以清楚证明 MITM 篡改逻辑是正确的。 ### 7.1 在 victim 容器执行 先把发往目标网段的路由改到恶意路由器: ```bash ip route replace 192.168.60.0/24 via 10.9.0.111 ``` 验证: ```bash ip route mtr -n -r -c 2 192.168.60.5 ``` 此时 `mtr` 应该看到类似三跳: ```bash 10.9.0.111 10.9.0.11 192.168.60.5 ``` 说明流量已经先进入恶意路由器,再被转发到真实路由器和目标主机。 ### 7.2 在 malicious-router 容器执行 关闭内核自动转发: ```bash sysctl -w net.ipv4.ip_forward=0 ``` 然后启动 MITM 脚本: ```bash python3 /volumes/mitm_attack.py ``` 这个脚本只拦截: - 源 IP 是 `10.9.0.5` - 目的 IP 是 `192.168.60.5` - 二层目的 MAC 真正发给恶意路由器本机 因此不会再把自己重发的包抓回来无限循环。 ### 7.3 在 target host 容器执行 启动 netcat 监听: ```bash nc -lp 9090 ``` 这个终端要保持打开。 ### 7.4 在 victim 容器执行 发起 TCP 连接并发送测试字符串: ```bash printf 'hello seedlabs\n' | nc -N 192.168.60.5 9090 ``` ### 7.5 在 target host 容器观察结果 如果 MITM 成功,目标主机终端不会看到: ```bash hello seedlabs ``` 而是会看到: ```bash hello AAAAAAAA ``` ### 7.6 在 malicious-router 容器观察结果 MITM 脚本终端会打印出它截获的原始载荷,例如: ```bash Original data: b'hello seedlabs\n' ``` 如果脚本是错误的,常见现象是会重复打印多次同一条已经修改过的数据,说明它抓到了自己重发的包。当前仓库中的 `mitm_attack.py` 已修复这个问题。 --- ## 8. 一次完整展示时,各容器该执行什么命令 下面是一套可以直接照着走的顺序。 ### 宿主机执行 ```bash cd /home/gh0s7/project/netsecurity2026/ICMP_Directing/Labsetup docker-compose up -d ``` ### victim 容器执行 ```bash ip route ip route flush cache sysctl net.ipv4.conf.all.accept_redirects sysctl net.ipv4.conf.eth0.accept_redirects ping -c 3 192.168.60.5 ip route show cache ip route get 192.168.60.5 mtr -n -r -c 2 192.168.60.5 ``` 如果第一阶段未成功,继续执行: ```bash ip route replace 192.168.60.0/24 via 10.9.0.111 mtr -n -r -c 2 192.168.60.5 printf 'hello seedlabs\n' | nc -N 192.168.60.5 9090 ``` ### attacker 容器执行 ```bash python3 /volumes/task1.py --count 50 --interval 0.2 ``` 可选: ```bash python3 /volumes/task1_sniff_and_redirect.py ``` ### malicious-router 容器执行 先在第一阶段前可只查看路由: ```bash ip route ``` 第二阶段执行: ```bash sysctl -w net.ipv4.ip_forward=0 python3 /volumes/mitm_attack.py ``` ### target host 容器执行 ```bash nc -lp 9090 ``` ### router 容器可选执行 如果老师想看正常路由器是否还在链路中,可以执行: ```bash ip route ip neigh ``` --- ## 9. 现场讲解时可以这样解释 ### Q1: 为什么第一阶段可能失败,但第二阶段还能演示成功? 答: - 第一阶段依赖受害者内核真正接受 ICMP Redirect - 当前环境下 victim 容器共享宿主机较新的 Linux 内核,检查更严格 - Redirect 包能到达 victim,但内核未安装重定向缓存 - 为了继续展示 MITM 的核心思想,可以手工把 victim 的路由改到恶意路由器,相当于模拟第一阶段已经成功 ### Q2: 为什么 `task1_sniff_and_redirect.py` 在当前环境未必好用? 答: - 它要求 attacker 能看见 victim 发往 router 的单播包 - 当前 Docker bridge 网络通常不会把这类单播复制给 attacker - 所以这个脚本在当前环境里常常抓不到包 ### Q3: 为什么 `mitm_attack.py` 之前会重复打印很多次? 答: - 因为原脚本只按 IP 层过滤 - 它把自己重发出去的包又抓回来处理了 - 现在脚本额外检查二层目的 MAC 是否真的是恶意路由器本机,从而避免死循环 ### Q4: 为什么要关闭 `ip_forward`? 答: - 如果不关,内核会直接把原始包转发出去 - 应用层脚本来不及修改内容 - 关闭后,脚本才能接管“抓包、改包、重发”的过程 --- ## 10. 恢复环境 展示完成后,建议把 victim 的路由恢复,避免后续混淆。 ### 在 victim 容器执行 ```bash ip route replace 192.168.60.0/24 via 10.9.0.11 ip route flush cache ``` ### 在 malicious-router 容器执行 ```bash sysctl -w net.ipv4.ip_forward=1 ``` --- ## 11. 最终建议 如果你要“稳定展示给老师看”,推荐这样安排: 1. 先演示第一阶段理论流程:attacker 发 redirect,victim ping,检查路径 2. 如果当前环境没有真的安装 redirect,就用 `nstat -az | grep Redirect` 证明 victim 已收到 redirect 3. 然后说明由于当前内核更严格,手工把 victim 路由切到 `10.9.0.111` 4. 继续演示第二阶段 MITM,把 `hello seedlabs` 成功改成 `hello AAAAAAAA` 这样展示是完整的,逻辑也是自洽的。