什么是抓包?
简单说抓包就是截取网络中传输的数据包,然后对数据包进行重发、编辑、转存等操作。在此基础上可以对数据包进行安全分析安全检查等等,如果数据不安全,则可能被利用。
Fiddler的介紹
fiddler是常用的抓包工具之一。当浏览器访问服务器会形成一个请求,此时,fiddler就相当于一个中间商,当浏览器发送请求,会先经过fiddler,然后在转给服务器;当服务器有返回数据给浏览器显示时,也会先经过fiddler,然后再把数据返沪给客户端,在这样一个过程,fiddler就可以截取请求和响应。主要用来截取http和https请求。
1、 查看fiddler的界面,讲解说明
接下来我们实际操作下看看fiddler的界面
主要分为六块地方:
l 第一块区域是设置菜单
l 第二块区域是一些工具菜单,点下就能看到对应的功能
l 第三块左边是抓捕的请求会话列表,这里的会话指一次请求
l 四块右边上方区域是request请求的详细信息,可以查看Headers、Cookies、Raw、JSON等
l 第五块右边下方区域就是response信息,可以查看服务端返回的json数据或其它信息
l 第六块区域左下角黑色的那块小地方,虽然很不起眼,容易被忽略掉,这地方是命令行模式,可以输入简单的指令如:cls,执行清屏的作用等
常用页标签工具栏
看看右侧的标签页,通过Statistic可以看到请求和响应的字节数,以及时间消耗信息等等
Inspeactors检查标签,它提供headers、textview、hexview,Raw等多种方式查看单条http请求的请求报文的信息,它分为上下两部分:上部分为HTTP Request(请求)展示,下部分为HTTPResponse(响应)展示。
Auto Response自动响应标签,我觉得这个对前端用处更大些,它可以对服务端返回的数据进行修改,方便我们调试。
Composer标签
它跟我们熟悉的postman非常一样。支持手动构建和发送请求, 我们还可以从web session列表中拖曳session, 把它放到composer选项卡中, 当我们点击Execute按钮, 就可以把请求发送到服务器端。
Filters过滤标签
过滤器可以对左侧的数据流列表进行过滤, 我们可以标记、 修改或隐藏某些特征的数据流。
Fiddler命令行工具
1、 命令行清空
2、 命令行筛选
3、 打断点等等
打断点
断点的两种方式
Bpu
Bpafter
全局断点
单个断点
拦截网站的所有请求
其他命令
https://docs.telerik.com/fiddler/knowledge-base/quickexec
当然,我这里只是列举了比较基础常用的功能,还有更多的功能值得大家有兴趣去学习下,接下来我们看看wireshark工具。
Wireshark
Wireshark跟fiddler的主要区别就是,Wireshark主要用来帮助用户对网络行为有一个了解,而不能对网络内容做更改或是提示,也就是说只能查看不能修改或转发。
三次握手、四次挥手
在讲之前,我们先回顾下上学时学过的三次握手、四次挥手。
小写的ack代表的是头部的确认号Acknowledge number, 缩写ack,是对上一个包的序号进行确认的号,ack=seq+1。
大写的ACK,则是我们上面说的TCP首部的标志位,用于标志的TCP包是否对上一个包进行了确认操作,如果确认了,则把ACK标志位设置成1。
标志位(Flags):共 6 个,即 URG、ACK、PSH、RST、SYN、FIN 等。
六个标志位具体含义如下:
SYN:简写为S,同步标志位,用于建立会话连接,同步序列号;
ACK:简写为.,确认标志位,对已接收的数据包进行确认;
FIN:简写为F,完成标志位,表示我已经没有数据要发送了,即将关闭连接;
PSH:简写为P,推送标志位,表示该数据包被对方接收后应立即交给上层应用,而不在缓冲区排队;
RST:简写为R,重置标志位,用于连接复位、拒绝错误和非法的数据包;
URG:简写为U,紧急标志位,表示数据包的紧急指针域有效,用来保证连接不被阻断,并督促中间设备尽快处理;
需要注意的是:
- 不要将确认序号 Ack 与标志位中的 ACK 搞混了。
- 确认方 Ack=发起方 Seq+1,两端配对。
为什么需要三次握手?
我们假设client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。
假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。
所以,采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。
TCP 三次握手跟现实生活中的人与人打电话是很类似的:
- 三次握手:
- “喂,你听得到吗?”
- “我听得到呀,你听得到我吗?”
- “我能听到你,今天 balabala……“
经过三次的互相确认,大家就会认为对方对听的到自己说话,并且愿意下一步沟通,否则,对话就不一定能正常下去了。
挥手请求可以是Client端,也可以是Server端发起的,我们假设是Client端发起:
第一次挥手: Client端发起挥手请求,向Server端发送标志位是FIN报文段,设置序列号seq,此时,Client端进入FIN_WAIT_1状态,这表示Client端没有数据要发送给Server端了。
第二次挥手:Server端收到了Client端发送的FIN报文段,向Client端返回一个标志位是ACK的报文段,ack设为seq加1,Client端进入FIN_WAIT_2状态,Server端告诉Client端,我确认并同意你的关闭请求。
第三次挥手: Server端向Client端发送标志位是FIN的报文段,请求关闭连接,同时Client端进入LAST_ACK状态。
第四次挥手 : Client端收到Server端发送的FIN报文段,向Server端发送标志位是ACK的报文段,然后Client端进入TIME_WAIT状态。Server端收到Client端的ACK报文段以后,就关闭连接。此时,Client端等待2MSL的时间后依然没有收到回复,则证明Server端已正常关闭,那好,Client端也可以关闭连接了。
为什么连接的时候是三次握手,关闭的时候却是四次挥手?
建立连接时因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。所以建立连接只需要三次握手。
由于TCP协议是一种面向连接的、可靠的、基于字节流的运输层通信协议,TCP是全双工模式。这就意味着,关闭连接时,当Client端发出FIN报文段时,只是表示Client端告诉Server端数据已经发送完毕了。当Server端收到FIN报文并返回ACK报文段,表示它已经知道Client端没有数据发送了,但是Server端还是可以发送数据到Client端的,所以Server很可能并不会立即关闭SOCKET,直到Server端把数据也发送完毕。当Server端也发送了FIN报文段时,这个时候就表示Server端也没有数据要发送了,就会告诉Client端,我也没有数据要发送了,之后彼此就会愉快的中断这次TCP连接。
为什么要等待2MSL?
MSL:报文段最大生存时间,它是任何报文段被丢弃前在网络内的最长时间。有以下两个原因:
第一点:保证TCP协议的全双工连接能够可靠关闭:
由于IP协议的不可靠性或者是其它网络原因,导致了Server端没有收到Client端的ACK报文,那么Server端就会在超时之后重新发送FIN,如果此时Client端的连接已经关闭处于CLOESD状态,那么重发的FIN就找不到对应的连接了,从而导致连接错乱,所以,Client端发送完最后的ACK不能直接进入CLOSED状态,而要保持TIME_WAIT,当再次收到FIN的时候,能够保证对方收到ACK,最后正确关闭连接。
第二点:保证这次连接的重复数据段从网络中消失
如果Client端发送最后的ACK直接进入CLOSED状态,然后又再向Server端发起一个新连接,这时不能保证新连接的与刚关闭的连接的端口号是不同的,也就是新连接和老连接的端口号可能一样了,那么就可能出现问题:如果前一次的连接某些数据滞留在网络中,这些延迟数据在建立新连接后到达Client端,由于新老连接的端口号和IP都一样,TCP协议就认为延迟数据是属于新连接的,新连接就会接收到脏数据,这样就会导致数据包混乱。所以TCP连接需要在TIME_WAIT状态等待2倍MSL,才能保证本次连接的所有数据在网络中消失。
实际演示
接下来我们用wireshark来看看理论是不是符合实际情况。
我们打开wireshark分析,然后我筛选了ip地址跟端口号,得到了如图数据,这个其实就是一条完整的请求。我们可以很清楚的看到网络七层协议中的四层,如果是http请求的话,还会出现一层应用层的信息。
经过数据的拦截我们看看前三条数据,跟后四条数据。
首先是三次握手
首先是发送端发送给服务端,一个SYN同步标志,以及一个随机的序列号
然后服务端接收到了,将发送端的序列号加1变成确认号,然后将自己的序列号,确认号,以及大写的ACK确认标志位发回给客户端
客户端接收到了,又将服务端的序列号加1,变为自己的确认号,然后将确认号,序列号,确认标志位置1,发给服务端,至此就完成了三次握手的过程。
然后是四次挥手过程
服务端收到后,首先将确认位置1,ack=seq+1,以及一个随机的序列号发回给发起端
然后再发挥一个FIN标志位,ack确认号,ACK确认位,序列号,发回去,表示我也要结束了
最后发起端确认收到,再发回一个确认位给到服务端,同时等待两个生存时间就自动关闭连接,然后四次挥手就结束了。