实验目的
目的:分析TCP和重要的应用层协议
内容:
实验内容与分析
任务1:DNS服务
任务要求
Solution
(1)
在配置完DNS环境后,首先要清空DNS缓存
1 | ipconfig /flushdns |
开启Wireshark进行抓包,笔者自己电脑的DNS服务器是172.16.9.1,首先将DNS服务器指向自己电脑,进行对自己配置的域名和邻居配置的域名的查询
观察一对DNS报文如下
DNS报文格式如下
0~15 | 16~31 |
---|---|
标识ID | 标志 |
问题数 | 资源记录数 |
授权资源记录数 | 额外资源记录数 |
查询问题 | |
回答 | |
授权信息 | |
额外信息 |
Transaction ID: 标识字段,客户通过标识字段来确定DNS响应是否与查询请求匹配,占16位。图中请求和回复报文该值均为0x2e15。
Flags: 标志,占16位,请求报文为0x0000,回复报文为0x8480,分为下面10个标志
Response: 占1位,操作类型:0:查询报文1:响应报文
Opcode: 占1位,查询类型:0:标准查询1:反向查询2:服务器状态查询3~15:保留未用 反向查询是客户端请求服务器根据回答生成导致此回答的问题,这个查询类型的使用并不多。
Authoritative: 占1位,若置位,则表示该域名解析服务器是授权回答该域的。
Truncated: 占1位,若置位,则表示报文被截断。 使用UDP传输时,应答的总长度超过512字节时,只返回报文的前512个字节内容。
Recursion desired: 占1位,客户端希望域名解析服务器采取的解析方式: 0:表示希望域名解析服务器采取迭代解析1:表示希望域名解析服务器采取递归解析
Recursion available: 占1位,域名解析服务器采取的解析方式: 0:表示域名解析服务器采取迭代解析1:表示域名解析服务器采取递归解析
Z: 占3位,全部置0,保留未用。
Answer authenticated: 占1位,应答认证:应答/权限部分未由服务器进行认证 ,0为应答服务器未验证了该查询相关的 DNSSEC 数字签名,1 为应答服务器已经验证了该查询相关的 DNSSEC 数字签名
Non-authenticated data: 占1位,非授权数据访问,0表示不可接受,1表示可接受
Reply code: 占4位,响应类型: 0:无差错1:查询格式错2:服务器失效3:域名不存在4:查询没有被执行5:查询被拒绝6-15: 保留未用
Questions:无符号16位整数表示报文请求段中的问题记录数,占16位。
Answer RRs:无符号16位整数表示报文回答段中的回答记录数,占16位
Authority RRs:无符号16位整数表示报文授权段中的授权记录数,占16位
Additional RRs:无符号16位整数表示报文附加段中的附加记录数,占16位
Queries:查询的问题
Anwers:问题的回答
Authoritative nameservers:授权信息
Additional records:额外信息
(2)
这些DNS报文的作用是用于标准查询或者反向查询域名。
从Recursion desired关键字可看出请求报文是迭代查询还是递归查询
从6161(递归查询),6162(迭代查询)可以看出,当用自己的主机作为域名服务器,查询邻居域名时,先进行递归查询(向本地DNS服务器询问),再进行迭代查询(本地DNS服务器向其他DNS服务器询问)
(3)
上述步骤中,当用域名查询IP时,nslookup返回的结果是非权威的,如果将DNS服务器指向该邻居,再查询域名,这时nslookup返回的结果是权威的。这是因为如果DNS服务器在自己的区域文件里找到了客户端需要查询的记录,就会返回一个权威性应答,否则是非权威性应答。
任务2: TCP协议分析
任务要求1
Solution1
在虚拟机内输入如下命令,同时开启Wireshark
1 | wget ischoolgu.xmu.edu.cn –-no-http-keep-alive |
抓到如下报文
1°分析报文
选取一TCP报文
TCP首部格式如下
图中:
Source Port:源端口,占16位,图中为62960
Destination Port:目的端口,占16位,图中为678
[Stream index]: 流索引,流索引是内部Wireshark映射到:[IP地址A,TCP端口A,IP地址B,TCP端口B],具有相同tcp.stream值的所有数据包对于这些字段应具有相同的值(尽管src/dest将针对A-> B和B-> A数据包进行切换),在Wireshark中的“统计信息/对话/ TCP”选项卡以显示这些流的摘要
[TCP Segment Len]:TCP报文段数据部分长度,点击这一项,其指向和Header Length同一字段,这是因为Wireshark根据IP层的数据总长度233减去IP首部长度20再减去TCP首部长度20计算得来的长度193字节
Sequence number(relative sequence number):序号,占16位,TCP报文每个字节都按顺序编号,这个序号指的是本报文段所发送数据的第一个字节序号,图中为168
[Next sequence number(relative sequence number)]:下一个序号,Wireshark根据Sequence number+TCP Segment Len=168+193=361算出来的结果,
Acknowledgment number(relative ack number):确认号,占16位,是期望收到对方下一个报文段的第一个数据字节的序号,若确认号为= N,则表明:到序号N-1为止的所有数据都已正确收到。图中为108
Header Length: 20 bytes:数据偏移,它指出TCP报文段的数据起始处距离TCP报文段的起始处有多远,这个字段实际上是指出TCP报文段的首部长度,占4位,其单位为32位字(4字节)图中为20bytes
Flags: 控制位,用来说明本报文段的性质,占12位,其中前6位是保留字段,后面6位代表以下6个控制位:
紧急URG(URGent):当URG=1时,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,应尽快发送(相当于高优先级的数据),而不要按原来的排队顺序来传送。例如,已经发送了很长的一个程序要在远地的主机上运行。但后来发现了一些问题,需要取消该程序的运行,因此用户从键盘发出中断命令。如果不使用紧急数据,那么这两个字符将存储在接收TCP的缓存末尾。只有在所有的数据被处理完毕后这两个字符才被交付接收方的应用进程。这样做就浪费了很多时间。
当URG置为1时,发送应用进程就告诉发送方的TCP有紧急数据要传送。于是发送方TCP就把紧急数据插入到本报文段数据的最前面,而在紧急数据后面的数据仍然是普通数据。这时要与首部中紧急指针(Urgent Pointer)字段配合使用,图中为0
确认ACK(ACKnowledgment):仅当ACK = 1时确认号字段才有效,当ACK = 0时确认号无效。TCP规定,在连接建立后所有的传送的报文段都必须把ACK置为1。图中为1
推送 PSH(PuSH):当两个应用进程进行交互式的通信时,有时在一端的应用进程希望在键入一个命令后立即就能收到对方的响应。在这种情况下,TCP就可以使用推送(push)操作。这时,发送方TCP把PSH置为1,并立即创建一个报文段发送出去。接收方TCP收到PSH=1的报文段,就尽快地(即“推送”向前)交付接收应用进程。而不用再等到整个缓存都填满了后再向上交付。图中为1
复位RST(ReSeT):当RST=1时,表名TCP连接中出现了严重错误(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立传输连接。RST置为1还用来拒绝一个非法的报文段或拒绝打开一个连接。图中为0
同步SYN(SYNchronization) 在连接建立时用来同步序号。当SYN=1而ACK=0时,表明这是一个连接请求报文段。对方若同意建立连接,则应在响应的报文段中使SYN=1和ACK=1,因此SYN置为1就表示这是一个连接请求或连接接受报文。图中为0
终止FIN(FINis,意思是“完”“终”) 用来释放一个连接。当FIN=1时,表明此报文段的发送发的数据已发送完毕,并要求释放运输连接。图中为0
Window size value:窗口大小,占2字节,窗口指的是发送本报文段的一方的接受窗口(而不是自己的发送窗口),以字节为单位,窗口值作为接收方让发送方设置其发送窗口的依据。图中为256
[Calculated window size]:窗口实际可用大小,由Window size value乘以Window size scaling factor计算而来图中为65536
[Window size scaling factor]:这是一个放大倍数,图中为256,实际上用16位表示窗口大小已经满足不了现在的需求。在TCP三次握手过程中,可以通过SYN包开启TCP选项Window Size Scaling,设计出这个选项是因为如今的带宽已经大规模提升,千兆到桌面也是一件常事儿,因此,65535长度的窗口大小已经显得有些小了,为了突破这个限制,便有了Window Size Scaling选项
打开一个另一个SNK报文,在选项发现如下字段:
可以看到这个字段的值为8,也就是要将Window Size的值左移8位,即乘以128,因此,在上面中我们看到window size值是256,但是真正选用的值却是65536(256*256)。
Checksum: 校验和,占2字节。检验和字段检验的范围包括首部和数据这两部分。和UDP用户数据报一样,在计算检验和时,要在TCP报文段的前面加上12字节的伪首部。伪首部的格式和UDP用户数据报的伪首部一样。但应把伪首部第4个字段中的17改为6(TCP的协议号是6);把第5字段中的UDP中的长度改为TCP长度。接收方收到此报文段后,仍要加上这个伪首部来计算检验和。若使用TPv6,则相应的伪首部也要改变。图中为0x843f [unverified]未验证状态
Urgent pointer: 紧急指针,占2字节。紧急指针仅在URG=1时才有意义,它指出本报文段中的紧急数据的字节数(紧急数据结束后就是普通数据) 。因此,在紧急指针指出了紧急数据的末尾在报文段中的位置。当所有紧急数据都处理完时,TCP就告诉应用程序恢复到正常操作。值得注意的是,即使窗口为0时也可以发送紧急数据,图中为0
Options:选项,长度可变,最长可达4字节。包括最大报文段长度MSS、窗口扩大选项、时间戳选项等。当没有使用“选项”时,TCP的首部长度是20字节。该TCP首部没有选项字段,因此仅有20字节
2°画出TCP的流图
利用右键追踪TCP流定位到 http://ischoolgu.xmu.edu.cn/ 网站html文件所在TCP流
根据流信息画出流程图
[TCP segment of a reassembled PDU]是Wireshark分析了其上层的HTTP协议而给出的摘要,为了便于分析,将其还原为可以直接读取的TCP信息,配置Wireshark不支持HTTP协议解析
转变为如下图
任务要求2
Solution2
定位所在流序号
得到以下图
依然对[TCP segment of a reassembled PDU]进行还原,得到以下图
任务3: HTTP协议分析
任务要求
Solution
(1)
访问http://stu.xmu.edu.cn/过滤HTTP报文得到如下图
分析其中一对HTTP请求/响应报文
HTTP请求报文格式如下:
HTTP响应报文格式如下:
HTTP请求报文首部:
GET /coremail/common/assets/login/js/blurImg_worker.js HTTP/1.1\r\n: GET 为请求方式,后面跟请求的内容及协议版本
Request Method: GET 请求方式
Request URI: /coremail/common/assets/login/js/blurImg_worker.js 请求内容
Request Version: HTTP/1.1 协议的版本
Host: stu.xmu.edu.cn\r\n 请求的主机名
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:71.0) Gecko/20100101 Firefox/71.0\r\n 发送请求的操作系统、及浏览器信息
Accept:*/*\r\n 客户端可识别的内容类型列表,用于指定客户端接受了哪些类型的信息
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2\r\n 浏览器所支持的语言类型
Accept-Encoding: gzip, deflate\r\n 客户端可识别的数据编码
Connection: close\r\n 客户端与服务端指定的请求,响应有关选项
Referer: http://stu.xmu.edu.cn/coremail/index.jsp?cus=1\r\n 客户端可识别的内容类型列表,用于指定客户端接受哪些类型的信息
Cookie: 类型为“小型文本文件”,是某些网站为了辨别用户身份,进行Session跟踪而储存在用户本地终端上的数据(通常经过加密),由用户客户端计算机暂时或永久保存的信息
HTTP响应报文首部:
HTTP/1.1 200 OK\r\n 状态行,200表示客户端请求成功
Request Version: HTTP/1.1 协议版本
Status Code: 200 状态码
Response Phrase: OK 响应短语
Server: nginx\r\n 服务器信息
Date: Fri, 27 Dec 2019 13:16:16 GMT\r\n 响应时间
Content-Type: application/javascript\r\n 告诉客户端实际返回的内容类型
Transfer-Encoding: chunked\r\n 消息主题的大小
Connection: close\r\n 连接状态
X-Protected-By: OpenRASP\r\n
X-Request-ID: 1040fe080fa5424da40cc11f29d4acec\r\n
ETag: W/“4603-1472555014000”\r\n 资源的特定版本的标识符
Last-Modified: Tue, 30 Aug 2016 11:03:34 GMT\r\n请求资源的最后修改时间
Content-Encoding: gzip\r\n 响应内容编码
HTTP chunked response 响应内容
Content-encoded entity body (gzip): 1560 bytes -> 4603 bytes 编码对应主体
File Data: 4603 bytes 文件数据大小
Media Type:文件类型
(2)
在首选项添加显示端口
可知这次的访问总共生成10个TCP流,传输双方的端口号和内容均可以从上图看出,可以发现远程主机的端口号均是80
任务4:FTP分析
任务要求
Solution
使用如下命令进入访问该ftp
1 | ftp |
1 | cd legal |
Linux Ftp命令下默认为被动模式,更改为主动的方法:
1 | passive |
但是这边有个巨坑!之后发现主动完全无法建立连接
捣鼓许久才知道需关闭windows防火墙
便成功抓到FTP PORT模式下的数据包
现比较两种模式
被动模式
从上面sequence图中可以看到,被动模式是FTP服务器返回数据传输需要的端口,FTP客户端去连接FTP服务端。绝大部分的互联网应用(比如Web/Http),都是客户端向服务端发起连接。换句话说,绝大部分互联网应用都是被动模式。
从上图可以看到,服务端(4.31.198.49)返回给客户端(192.168.2.29)数据端口(117,228)=117*256+128=30080,然后用这个端口进行数据传输
主动模式
从sequence图中可以看到,主动模式是FTP客户端向FTP服务器发送数据传输需要的端口,FTP服务端去连接FTP客户端的端口,与被动模式刚好相反。值得注意的是,需要注意的是,被动模式和主动模式的登录过程,都是FTP客户端去连接FTP服务器。
从上图可以看到,返回给客户端(192.168.2.29)主动将数据端口(195,76)=195*256+76=49996发给服务端(4.31.198.49),而服务端启用固定端口20和客户端的这个端口进行数据传输
因此从上面可以总结出:主动模式对便于FTP服务器的管理,不便于对客户端进行管理。因为FTP服务器企图与客户端的高位随机端口建立连接,而这个端口很有可能被客户端的防火墙所阻塞,从上面笔者将linux虚拟机外部的windows防火墙关掉才可使用FTP PORT模式可以看出。被动模式对FTP便于对客户端进行管理,不便于对服务器端进行管理。因为客户端要与服务器端建立两个连接,其中一个连到一个高位随机端口,而这个端口很有可能被服务器端的防火墙阻塞掉。
使用Windows下的firefox下载rfc811.txt
对比下图FTP被动模式,可以看出,使用web浏览器下载,其默认使用匿名(anonymous)登陆,密码自动使用mozilla@example.com,而实践证明用linux FTP在未开启匿名登陆方式时不能进行匿名登陆,然后会发送编码方式,使用被动模式进行传输,但在下载时,会下载该文件的属性(生成时间),这是与Windows的NTFS文件系统相匹配的。
实验小结
此次实验我进一步掌握了wireshark的各种使用技巧,分析了应用层的DNS、HTTP、FTP协议,对应用层有更深刻的认识和理解,并且学到了课本上所未提及到的知识。在切换FTP port模式时,我遇到了很大的困难,无论如何修改虚拟机配置都不能建立连接,最后了解主动模式和被动模式的区别,方知问题可能出在外部的Windows上,最后成功解决问题。学习就是不断经过思考和实践来克服困难的过程,知其难为而勉力为之,方为正道。