当前位置: 首页 > 科技观察

30分钟掌握tcpdump

时间:2023-03-12 02:46:30 科技观察

这是一篇关于tcpdump的文章,分为两部分:使用tcpdump和解释输出。其中,“解释输出”部分关于分片的解释是我认为最有价值的。当然,如果你愿意花30分钟自己抓一个包,并尝试通过本文介绍的方法来恢复IP和TCP头,那一定会帮你调试网络的。程序很有帮助(想想成为专治各种网络疑难杂症的老司机是不是很激动?)。使用tcpdump格式:tcpdump[option][expression]我常用的option-n禁用域名解析,tcpdump会对每个接收到的数据包尝试域名解析,有时会造成“延迟输出”。添加此选项使tcpdump直接输出IP地址。-X以十六进制输出完整的数据包,没有这个选项tcpdump只会输出ip,tcp/udp头信息。添加此选项将导致tcpdump打印出整个数据包。-i指定网卡,如果没有指定网卡,tcpdump将使用第一个网卡。-vvvv是两个选项的组合-v会输出稍微更详细的信息,包括checksumttl等;-vvv会尝试解析应用层协议并输出详细信息。两者结合可以得到完整的详细信息表达式来过滤数据包,特别是带X选项(输出数据包的详细内容会让你的屏幕飞的飞快~~),如果不指定表达式,基本上面是刷新屏幕的速度。我通常限制协议类型、主机地址或端口。比如抓HTTP包,我会tcpdump-X-ieth0-vvvv-nport80,指定在80端口(peer80和localmachine80)抓数据。要解释tcpdump输出并提及网络,您必须提及ISO分数。层模型,TCP/IP分层模型,这两部分教材太多,就不啰嗦了。在实际意义上,网络只有三层。物理层和数据链路层是指网卡,我们不需要关心;IP层、TCP/UDP、应用层这三部分是我们最常接触到的三部分,但实际上指的是一个东西。例如,查看HTTPGET请求。这是tcpdump捕获的GET请求,line***,12:53:07.156463IP(tos0x2,ECT(0),ttl64,id22767,offset0,flags[DF],protoTCP(6),长度577)输出当前时间(本机),IP头信息;第二行,192.168.200.1.59222>192.168.200.10.80:Flags[P.],cksum0x98a6(correct),seq966819399:966819924,ack3158680476,win4096,options[nop,nop,TSval3206ecr278】,长度525表示这个数据包是从192.168.200.1的59222端口发送到192.168.200.10的80端口,后面是TCP头信息。第三行不是“实际内容”,它是整个数据包和对应的ASCII(包括IP头和TCP头)的十六进制输出。所以网络分层其实就是一个数据包有不同的包头。这种设计是一种封装,通过划分“层”让应用更容易开发。我们来分析一下IP头和TCP头。如果你掌握了这部分内容,你就可以算是“精通网络”了(我没看错,是精通~~)。IP头盗用wiki的图(这种图到处都是,我不会自己画)。IP头最小为20字节(不含options),上图中每行4字节(32位),一共6行(***一行大小不固定,最多40字节。)。结合我们的例子,tcpdump其实已经帮我们输出了关键的IP信息。我们直接看十六进制数据(验证tcpdump输出的IP信息是否与十六进制表示的数据包匹配),每组16位。4502024158ef40004006ce68c0a8c801前4表示是IPv4(占4位);5表示包头长度为5个32位(这个IP包头一共有20个字节,说明这个数据包不包含“options”);后一个字段需要特别注意,有些资料直接解释为TOS,并不完全正确。它有两个含义。DSCP就是传统意义上的TOS。这里02是一个字节(8个二进制位)。前6位用来表示TOS,这里为0(很多设备忽略TOS字段);后2位显式拥塞通知(ECN)是一个新特性(即使Windows7不支持)显示并告知对方是否支持拥塞控制(如果另一端发生拥塞,它会自动通知你通过这两个领域-我太忙了兄弟,请慢点~~)。二进制10(十进制为2)表示支持ECN特性。(tcpdumpip头输出tos0x2,ECT(0)表示支持ECT,不支持会显示为Not-ECT)0241是数据的总长度,这里是十六进制,它的十进制值是577(和tcpdumpIP头输出的长度577匹配)58ef是数据包的唯一标识。一般约定在TCP三次握手时,双方会随机生成一个ID,每发送一个数据包,都会互相递增。它的主要目的是为了重传,但实际上IP协议从来没有实现过“重传”(后述)。(和tcpdumpIPheader输出的id22767匹配)4是分片标志,基本上所有的IP包都是4。因为IP包不会被分片重传。下面这段推翻了网上很多传闻(嗯,好像包括维基),每块以太网卡都有一个MTU(最大传输单元)限制,也就是说网卡一次只能接收一个包大小。所以即使IP数据包能达到2^32=65535字节,也不能一次性发送这么大的数据包。每个IP数据包的大小限制为1500字节(最常见的MTU大小),去掉最小的IP报头(20)和最小的TCP报头(20)后还剩下1460字节。这是一个IP数据包可以携带的确切数据。如果超过这个设置,就必须“分段”。如果使用UDP协议,基本是自己考虑分片,UDP协议本身不会重传,也不会重新组装。因此,UDP协议一般用作“一次性交易”——将所有信息包含在一个数据包中,不分片。(如果使用UDP协议传输数据一般不要使用1380,否则程序要考虑处理分片-即MTU-***IP头60字节-***TCP头60字节)如果是TCP,非常幸运的是,TCP会帮你做分片和重组。(后面会讲到)因为TCP已经考虑了分片,所以IP数据包不需要再分片,“flag”字段基本都是-4(不分片)。(可以抓取163之类的网站,看HTML分段传输时***行有没有4000)因为没有考虑段后面的offset,没用——0004006,存活时间为40十进制64,这是一个常用的值,一个数据包如果路由了64次就可以丢弃(与Tcpdump输出一致);06表示这是TCP协议(如果是01表示ICMP,UDP是0x11)ce68校验和,不管它c0a8c801源IP地址,c0a8c80a目的地址用一段代码表达如何构造IP自己包数据对于同一个TCP会话,IP头是很固定的。TCPheader最小的TCPheader是20字节(不含options),上图中每行4字节(32位),一共6行(***一行大小不固定,最多40个字符节.).结合我们的例子,tcpdump其实已经帮我们输出了关键的IP信息。注意这里的长度是指数据的大小,不包括IP头和TCP头。我们直接看十六进制数据,每组16bit。e756005039a07e47bc45a39ce756源端口5922,0050是目标端口8039a07e47=966819399,是seq号(序列号)bc45a39c=3158680476,是ack号TCP同意发送方会随机生成一个seq,当双方握手三次号码通过第一个SYN协议发送给对端,对端会随机生成一个seq号并设置ack+1回应对端。发件人回复seq=selfseq+1,ack=peerseq+1。通俗地说,seq就是你自己的序列号,ack就是你期望从另一端发送的数据,所以如果你得到一个数据包seq=1024,ack=522;那么你只需要回复一个seq=522,ack=1025就可以实现“TCP会话劫持”(很可怕吗?相当于不仅检测你的通话内容,还可以“无缝介入”你的通话,假装对方毫无违和感)。第三行8018100098a600000101080a14558表示8个32bits(这个TCP头的大小是8*4=32字节)0是保留的,18是一个flag,对应tcpdump中的flag。FIN=0x01,代表数据发送完毕,可以释放连接了。它用于关闭TCP连接。SYN=0x02,很流行。它用于TCP握手。RST=0x04,直接关闭TCP连接(不带FIN)PUSH=0x08,官方的解释是“尽快交付给应用程序,不等待缓冲区满”,其实这个flag会一直存在。只要你传输数据,就一定有这个标志。ACK=0x10,确认数据tcpdump会在Flags选项中使用大写字母输出,例如例子中的“P”表示设置push位,因为有ack3158680476,所以肯定有ACK标志少量。不难计算出PUSH+ACK=8+10=181000就是数据窗口的大小(十进制4096),这是TCP流量控制的关键技术手段。包括最近流行的“GoogleBBR”,其实就是找一个算法,可以尽可能准确的调整这个窗口的大小。(其实ECN更好,不需要“计算”直接通知你,只是很多操作系统和硬件不支持。)98a6Checksum,不管0000,通常与“标志位”,标志位设置为URG(0x20)表示开启“紧急数据”,该字段为“紧急数据序号”。比如你正在看一个视频,你可以只用一个数据包播放5分钟,但是现在网络正在传输下面的数据,你可以利用这个标志“紧急”获取关键数据包。但是这个功能基本没什么用,设备会忽略这些东西。这个TCP包是32个字节,上面介绍了20个字节,所以有12个字节(6组),用来表示TCP选项。0101080a14555dea00031f5d,选项的格式是一个TLV结构(类型,长度,值)。简单的说,第一个字节代表数据类型,不同的类型会有不同的长度和内容。TCP的常用选项包括0(1字节)无,1(1字节)无,常用于“填充”。以上两个其实是一个意思。2***报文段的长度(4字节)一般出现在三次握手的SYN包中,用来说明你能收到的***报文的长度(一般是MTU-40,即Ethernet***Transmissionunit-minimumIP-minimumTCP。这也印证了前面的说法——IP永远不会分片,TCP负责分片。)3窗口扩展因子(4字节),取值0-14。滑动窗口的最大值为2^16(65535)。如果这个值在一个“高延迟高带宽”(也叫长胖管道)网络(所有的广域网甚至整个互联网都是这样的网络)中特别小。因此,新增加的扩展因子用于扩展窗口的大小,表示TCP窗口向左移动的位数(实际窗口大小=窗口*2^窗口多扩展因子)。8:Timestamp(10bytes)peer'stimestamp(4bytes)owntimestamp(4bytes).该选项主要用于测量往返时间(RTT),这也是TCP作为流量控制的一个关键手段。例子中0101没有意义,08表示这是一个时间戳选项(类型),后面0a是值占用的字节(选项的整个长度,包括1个字节表示类型和一个字节表示length),14555dea(341138922这四个字节)表示发送方的时间戳,00031f5d(204637)这四个字节表示回显的时间戳。(对应tcpdump输出中的选项[nop,nop,TS...])一段代码说明了如何构造一个TCP数据包。对于一个TCP会话来说,response、control、seq、ack是变化的,滑动窗口的大小会随着网络拥塞是否变化而变化。后者是实际HTTP协议的内容,47455420,0x47是G的ASCII,0x45是E的ASCII,0x54是T的ASCII,0x20是一个空格。....以后自己看总结《TCP/IP协议详解》大部分章节都是tcpdump的输出,IP头,TCP头(甚至可以说三卷都是这个),掌握tcpdump对我们来说很重要对网络分析或系统调试很有帮助。大家玩得开心。高能预警小哥下篇聊聊tcpdump——《手把手教你做ARP病毒》。史上最难缠的ARP病毒,横行数十年,依然所向披靡。作为一个老司机,教你做一个病毒,分分钟瘫痪你的网络(让你“精准”打击网络中的任何一个人——让她无法上网,然后假装上网)做个修电脑的老司机)。【本文为专栏作家邢森原创文章,转载请联系作者获得授权】点此阅读更多该作者好文