<导航

Wireshark抓包工具使用

文章整理自网络资源。

一、先来个案例

相对于火狐或谷歌浏览器中使用调试工具抓取HTTP数据包,使用wireshark要显得复杂些,但是也可以达到最终效果。这些操作分为两步,第一步设置合理的过滤条件,第二步在任意数据包中选择Follow TCP Stream。

假设在8080端口运行一个HTTP服务器,本例中使用Python Flask运行一个HTTP服务并侦听8080端口,实现一个简单的加法运算,网页中通过ajax提交两个数据,例如a=2&b=3,Flask处理之后返回一个json数据包,格式如{"result":5}。

1.设置过滤条件

【1】http and ip.addr == 192.168.1.106 and tcp.port == 8080
【a】http:指定网络协议
【b】ip.addr == 192.168.1.106:指定服务器ip地址,请根据实际情况替换。
【c】tcp.port == 8080,指定端口号,请根据实际情况替换。
 

【2】点击apply

    点击apply之后可过滤得到两个数据包,分别是HTTP请求和HTTP响应。
 

2.查看TCP数据流——Follow TCP Stream

【1】在任意数据包上右击,选择Follow TCP Stream

 该步骤可以过滤出和该HTTP数据包有关的TCP数据包,包括TCP 3次握手,TCP分片和组装等。
 

【2】最终得到HTTP请求和响应

【a】红色背景字体为HTTP请求,蓝色背景字体为HTTP响应
【b】从User-Agent中可以看出,360浏览器兼容模式使用了IE8内核(该台计算机操作系统为XP,IE浏览器版本为8),这说明360浏览器使用了系统中的IE核。
 

二、wireshark过滤规则

 

使用好wireshark一个关键是如何从抓到的众多的包中找到我们想要的那一个。这里就要说filter过滤规则了。如上图,在过滤器方框,我们加上了ip.src==192.168.1.102 or ip.dst==192.168.1.102的过滤规则,意思是在封包列表中,只显示源ip地址为192.168.1.102或者目的ip地址为192.168.1.102的包。 
下面列举一些常用的过滤规则:

1、过滤IP,如来源IP或者目标IP等于某个IP 

如前面说的例子: ip.src==192.168.1.102 or ip.dst==192.168.1.102 
比如TCP,只显示TCP协议。

2、过滤端口 

tcp.dstport == 80 // 只显tcp协议的目标端口80 

tcp.srcport == 80 // 只显tcp协议的来源端口80 
也可以写成tcp.port eq 80 or udp.port eq 80 这样的模式

3、过滤协议 

单独写上tcp、udp、xml、http就可以过滤出具体协议的报文。你也可以用tcp or xml这样格式来过滤。 
我们还可以更加具体过滤协议的内容,如tcp.flags.syn == 0x02 表示显示包含TCP SYN标志的封包。

4、过滤mac地址 

eth.src eq A0:00:00:04:C5:84 // 过滤来源mac地址 
eth.dst==A0:00:00:04:C5:84 // 过滤目的mac地址

5、http模式过滤 

http.request.method == “GET” 
http.request.method == “POST” 
http.request.uri == “/img/logo-edu.gif” 
http contains “GET” 
http contains “HTTP/1.”
 // GET包 
http.request.method == “GET” && http contains “Host: ” 
http.request.method == “GET” && http contains “User-Agent: ” 
// POST包 
http.request.method == “POST” && http contains “Host: ” 
http.request.method == “POST” && http contains “User-Agent: ” 
// 响应包 
http contains “HTTP/1.1 200 OK” && http contains “Content-Type: ” 
http contains “HTTP/1.0 200 OK” && http contains “Content-Type: “

6、过滤内容 

contains:包含某字符串 
ip.src==192.168.1.107 and udp contains 02:12:21:00:22 
ip.src==192.168.1.107 and tcp contains “GET” 
前面也有例子,http contains “HTTP/1.0 200 OK” && http contains “Content-Type: “

三、osi模型简述

OSI定义了网络互连的七层框架(物理层、数据链路层、网络层、传输层、会话层、表示层、应用层),即ISO开放互连系统参考模型。如下图左边部分。在每个分层中,都会对所发送的数据附加一个首部,在这个首部中包含了该层必要的信息,如源ip地址和目的ip地址等。

 

osi模型中,在下一层的角度看,当收到上一层的包时,全部会被认为是本层的数据,然后在本层中加上自己本层的首部,继续往下传递。一个数据包格式如下: 

 

举一个例子,比如客户端应用程序A向远端服务器应用程序B发送“早上好”的数据,那么大致流程是这样的:

  1. 应用程序A把数据发送给下一层的TCP模块。
  2. TCP模块属于传输层。TCP在应用层数据的前端加上一个TCP首部。TCP首部中包含源端口号和目标端口号等信息。然后将包发送给IP模块。
  3. IP模块属于网络层。IP将TCP传过来的TCP首部和TCP数据合起来当做自己的数据,并且在TCP首部的前面加上自己的IP首部。IP首部包含了源ip地址和目的ip地址。然后,IP包将被发送给数据链路层,也就是以太网驱动程序。
  4. 从IP传过来的包,对于以太网驱动程序来说不过就是数据。给这些数据加上以太网首部,里面包含了源MAC地址和目的MAC地址。然后再通过物理层把数据发送给目的MAC地址。
  5. 服务器物理层接收到来自客户端的数据包时,首先从以太网的包首部找到MAC地址,判断是否为发给自己的包,如果不是就丢弃,如果是就向上转移给IP模块解析。
  6. IP模块收到IP包首部和后面的数据以后,判断包首部的目的ip地址与自己的ip地址是否匹配,如果匹配,就接收数据并传给TCP模块处理。
  7. TCP模块会检查端口号确定接收数据的应用程序是哪一个。
  8. 应用程序接收到数据包之后也会根据自己的规则判断做出一系列的处理。

通过上面例子大致的过程,可以体会到从上而下发包再到从下而上收包的过程。

讲述一下看懂报文的方法。想要读懂tcp报文,头部至关重要,对着下图去看wireshark tcp报文,并且找到tcp首部各个字段代表的意思,你就能读懂tcp报文了。其他像以太网报文、ip报文、http报文等同样如此。
 

四、TCP:传输控制协议

 TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议。 

  面向连接: 面向连接意味着使用tcp的应用程序在传输数据前必须先建立连接,就如打电话一样,要先进行拨号,等待对方响应才能开始说话。 
  可靠性:tcp协议通过下列方式来提高可靠性: 

  • 应用数据被分割成TCP认为最适合发送的数据块。这和UDP完全不同,应用程序产生的数据报长度将保持不变。由TCP传递给I P的信息单位称为报文段或段
  • 当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。
  • 当TCP收到发自TCP连接另一端的数据,它将发送一个确认。这个确认不是立即发送,通常将推迟几分之一秒。
  • TCP将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP将丢弃这个报文段和不确认收到此报文段(希望发端超时并重发)。
  • 既然TCP报文段作为IP数据报来传输,而IP数据报的到达可能会失序,因此TCP报文段的到达也可能会失序。如果必要,TCP将对收到的数据进行重新排序,将收到的数据以正确的顺序交给应用层。
  • 既然I P数据报会发生重复,TCP的接收端必须丢弃重复的数据。
  • TCP还能提供流量控制。TCP连接的每一方都有固定大小的缓冲空间。TCP的接收端只允许另一端发送接收端缓冲区所能接纳的数据。这将防止较快主机致使较慢主机的缓冲 
    区溢出。

    字节流:两个应用程序通过TCP连接交换8 bit字节构成的字节流。

      另外,TCP对字节流的内容不作任何解释。TCP不知道传输的数据字节流是二进制数据,还是ASCII字符或者其他类型数据。对字节流的解释由TCP连接双方的应用层解释。

TCP首部格式

  tcp数据是被封装在IP数据包中的,和udp类似,在IP数据包的数据部分。tcp数据包的格式如下:

 

源端口号和目的端口号与udp中类似,用于寻找发端和收端应用进程。这两个值加上IP首部中的源端IP地址和目的端IP地址唯一确定一个TCP连接,在网络编程中,一般一个IP地址和一个端口号组合称为一个套接字(socket)。 
  序号:用来标识从TCP发端向TCP收端发送的数据字节流,它表示在这个报文段中的的第一个数据字节。在tcp中tcp用序号对每个字节进行计数(这个值与发送的帧数没有关系,而是与发送的数据字节数有关系,后面会有说明)。 
  确认序号:包含发送确认的一端所期望收到的下一个序号。因此,确认序号应当是上次已成功收到数据字节序号加 1(不是单纯的序号加1,还包括数据字节数)。 
  首部长度:用于记录tcp数据报首部的长度,一般为20字节,实际值为首部长度除以4。 
  URG: 紧急指针( urgent pointer)有效。 
  ACK: 确认序号有效。 
  PSH: 接收方应该尽快将这个报文段交给应用层。 
  RST: 重建连接。 
  SYN: 同步序号用来发起一个连接。 
  FIN: 发端完成发送任务。 
  窗口大小:用于流量控制。 
  检验和:检验和覆盖了整个的 TCP报文段: TCP首部和TCP数据,与udp相似需要计算伪首部。

五、Wireshark抓包分析TCP结构

1、利用wireshark抓取一个tcp数据包,查看其具体数据结构和实际的数据:

这里写图片描述

这里写图片描述

2、TCP连接的建立

 利用TCP传输数据前,需要建立tcp连接,tcp连接的建立有3个主要过程,叫做3次握手,具体过程如下图所示: 
  这里写图片描述 
  

过程: 
   1. 首先客户端发送一个SYN包给服务器(SYN=1,Seq为主机选择的这个连接的初始序号),然后等待应答。 
   2. 服务器端收到SYN包,回应给客户端一个ACK =x+1、SYN=1的TCP数据段(ACK表示确认序号有效,即收到上一个包,这里加1并不是ACK的值加1,ACK是一个标志位,这里会变成1,而x+1则是希望收到的下一个包的序列号,这个值放在包的确认序列号字段中,而只有ACK=1时,确认序列号才有效)。 
   3. 客户必须再次回应服务器端一个ACK确认数据段(这里的Seq为x+1)。 
   
   经过上面3个过程就建立了一个tcp连接,接着就可以发送数据了,因为建立连接使用了一个序列号x,所以发送数据的第一个字节序号为x+1。 
   
   注意:这里tcp为应用层提供全双工服务,意味数据能在两个方向上独立地进行传输,因此连接的每一段都有各自的传输数据序号(对应于上图中的x和y,这两个值是没有必然联系的)。

3、Wireshark抓包分析TCP3次握手

 下面通过利用http应用层连接一个网络,实现tcp的3次握手和简单的数据交换过程,下面通过抓包来实际观察这个过程,首先我们先看看抓到的包: 

  这里写图片描述

  从第一行的tcp往下看,前面3个tcp包为3次握手的过程,接着http包说明成功建立连接,主机向服务器发送一个http应用请求,服务器收到请求后,返回一个tcp确认帧,接着发送一个http应答给主机,主机收到服务器的http应答数据后,又发送一个tcp确认帧,确认收到了数据。这样图中的前7个包实现了主机和服务器建立连接,并实现一次简单的数据请求应答过程。即下图所示的交互按键回显过程:

这里写图片描述

接下来是按照顺序的7个数据帧的数据结构。数据帧顺序分别为: 

  1. 主机发起一个tcp连接请求(tcp), 
  2. 服务器响应连接请求(tcp), 
  3. 主机返回ACK完成3次握手成功建立连接(tcp), 
  4. 主机发送一个http网页请求(http), 
  5. 服务器收到请求返回一个ACK帧(tcp), 
  6. 服务器根据请求发送数据到主机(http), 
  7. 主机收到服务器数据返回一个ACK帧(tcp),具体帧细节见下图:

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

4、TCP连接的释放

当通信双方完成数据传输,需要进行TCP连接的释放,由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这个原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。因为正常关闭过程需要发送4个TCP帧,因此这个过程也叫作4次挥手。具体过程如下图: 

  这里写图片描述 
  


过程(默认客户端发起关闭): 
  1. TCP客户端发送一个FIN,关闭客户端到服务器端的数据传送。(客户端不再发送报文给服务器端,但可接受服务器端报文) 
  2. 服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。 
  3.服务器关闭客户端的连接,发送一个FIN给客户端。(服务器端关闭到客户端的数据传送) 
  4.客户段发回ACK报文确认,并将确认序号设置为收到序号加1。

下面通过wireshark抓包了解具体的释放连接过程,通过断开一个连接,抓取到4个TCP帧,帧顺序依次为: 

  1. 主动关闭放发送一个FIN帧给被动方 
  2. 被动方收到关闭信息返回一个确认ACK帧 
  3. 被动方发送一个FIN帧给主动方 
  4. 主动方收到被动方的FIN关闭信息返回一个ACK帧,连接释放

下面为按照顺序的帧数据结构详细信息:

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

 六、RST标志位

1、tcp报文

TCP是在IP网络层之上的传输层协议,用于提供port到port面向连接的可靠的字节流传输。我来用土语解释下上面的几个关键字:

port到port:IP层只管数据包从一个IP到另一个IP的传输,IP层之上的TCP层加上端口后,就是面向进程了,每个port都可以对应到用户进程。

标志位共有六个,其中RST位就在TCP异常时出现。

发送的数据TCP包都有一个序号。它是这么得来的:最初发送SYN时,有一个初始序号,根据RFC的定义,各个操作系统的实现都是与系统时间相关的。之后,序号的值会不断的增加,比如原来的序号是100,如果这个TCP包的数据有10个字节,那么下次的TCP包序号会变成110。

2、滑动窗口

滑动窗口用于加速传输,比如发了一个seq=100的包,理应收到这个包的确认ack=101后再继续发下一个包,但有了滑动窗口,只要新包的seq与没有得到确认的最小seq之差小于滑动窗口大小,就可以继续发。

滑动窗口毫无疑问是用来加速数据传输的。TCP要保证“可靠”,就需要对一个数据包进行ack确认表示接收端收到。有了滑动窗口,接收端就可以等收到许多包后只发一个ack包,确认之前已经收到过的多个数据包。有了滑动窗口,发送端在发送完一个数据包后不用等待它的ack,在滑动窗口大小内可以继续发送其他数据包。

3、四次握手的正常TCP连接关闭示意图:

FIN标志位也看到了,它用来表示正常关闭连接。图的左边是主动关闭连接方,右边是被动关闭连接方,用netstat命令可以看到标出的连接状态。

FIN是正常关闭,它会根据缓冲区的顺序来发的,就是说缓冲区FIN之前的包都发出去后再发FIN包,这与RST不同。

4、RST表示复位

RST表示复位,用来异常的关闭连接,在TCP的设计中它是不可或缺的。就像上面说的一样,发送RST包关闭连接时,不必等缓冲区的包都发出去(不像上面的FIN包),直接就丢弃缓存区的包发送RST包。而接收端收到RST包后,也不必发送ACK包来确认。

TCP处理程序会在自己认为的异常时刻发送RST包。例如,A向B发起连接,但B之上并未监听相应的端口,这时B操作系统上的TCP处理程序会发RST包。

又比如,AB正常建立连接了,正在通讯时,A向B发送了FIN包要求关连接,B发送ACK后,网断了,A通过若干原因放弃了这个连接(例如进程重启)。网通了后,B又开始发数据包,A收到后表示压力很大,不知道这野连接哪来的,就发了个RST包强制把连接关了,B收到后会出现connect reset by peer错误。

5、tcp连接中几种出现rst情况

1.端口未打开
比如主机A向主机B发送一个SYN请求,表示想要连接主机B的8000端口。但是主机B根本没有打开8000这个端口。于是向主机A发送了一个RST。
在某些操作系统的主机上未必是这样的表现。比如向一台win7主机发送一个端口不存在的请求,这台主机就不会响应。
 2.请求超时

3.提前关闭

 打开一个socket然后连接一个服务器并发送5000个字节,而服务端设置的每次只接收4996个字节。那么客户端剩下的四个字节服务端没有接收到,服务端的socket就被关闭掉。这时服务端会先向客户端发送一个ack确认包,然后发送RST断开连接。
4.在一个已关闭的socket上收到数据。
如果某个socket已经关闭,但依然收到数据也会产生RST。客户端在服务端已经关闭掉socket后仍然在发送数据,这时服务端会产生RST。

七、常用的捕获过滤

1、只(不)捕获某主机的HTTP流量 

host 192.168.5.231 and port 80 and http 只捕获主机192.168.5.231 的http流量。注意如果你的HTTP端口为8080,把80 改为8080。

port 80 and http 捕获所有经过该接口的http流量。注意如果你的HTTP端口为8080,把80 改为8080。

host 192.168.5.231 and not port 80 捕获主机192.168.5.231除 http 之外的其他所有流量,注意如果你的HTTP端口为8080,把80 改为8080。

not port 80 捕获除http之外的其他所有流量,注意如果你的HTTP端口为8080,把80 改为8080。

not port 80 and !http  捕获除 http 之外的其他所有流量,注意如果你的HTTP端口为8080,把80 改为8080。

 

2、只捕获某主机的所有流量 

host 192.168.5.231 捕获源目主机均为192.168.5.231

dst 192.168.5.231  捕获目的主机均为192.168.5.231

src 192.168.5.231  捕获来源主机均为192.168.5.231

net 192.168.5.0/24 捕获网段为d192.168.5的所有主机的所有流量

3、只捕获某主机的DNS流量 

host 192.168.5.231 and port 53  只捕获主机192.168.5.231 的dns流量。

src 192.168.5.231 and port 53    只捕获主机192.168.5.231 对外的dns 的流量。

dst 192.168.5.231 and port 53    只捕获dns服务器相应主机192.168.5.231的dns流量。

port 53          捕获接口中的所有主机的dns流量

4、捕获电子邮件的流量 

host 192.168.5.231 and port 25       捕获主机192.168.5.231 的POP3协议的流量。

port 25 and portrange 110-143        因为电子邮件的协议:SMTP、POP3、IMAP4,所以捕获端口的流量。

 

 
 
 
 
 
posted @ 2018-06-12 11:42  字节悦动  阅读(4013)  评论(0编辑  收藏  举报