tcpdump 抓包总结
tcpdump (dump traffic on a network)。主要来对协议,主机,端口结合and(&&)、or(||)、not(!)逻辑进行网络层数据包的获取及分析。
tcpdump命令可使用的参数很多:
-A:以ASCII编码打印每个报文(不包括链路层的头),这对分析网页来说很方便;
-a:将网络地址和广播地址转变成名字;
-c:在收到指定的包的数目后,tcpdump就会停止;
-C:该选项使得tcpdump 在把原始数据包直接保存到文件中之前, 检查此文件大小是否超过file-size. 如果超过了, 将关闭此文件,另创一个文件继续用于原始数据包的记录. 新创建的文件名与-w 选项指定的文件名一致, 但文件名后多了一个数字.该数字会从1开始随着新创建文件的增多而增加. file-size的单位是百万字节(nt: 这里指1,000,000个字节,并非1,048,576个字节, 后者是以1024字节为1k, 1024k字节为1M计算所得, 即1M=1024 * 1024 = 1,048,576)
-d:将匹配信息包的代码以人们能够理解的汇编格式给出;
-dd:将匹配信息包的代码以c语言程序段的格式给出;
-ddd:将匹配信息包的代码以十进制的形式给出;
-D:列出当前主机的所有网卡编号和名称,可以用于选项-i;
-e:在输出行打印出数据链路层的头部信息,
-f: 将外部的Internet地址以数字的形式打印出来;
-F:从指定的文件中读取表达式,忽略其它的表达式;
-i:监听主机的该网卡上的数据流,如果没有指定,就会使用最小网卡编号的网卡(在选项-D可知道,但是不包括环路接口),1inux 2.2内核及之后的版本支持any网卡,用于指代任意网卡;
-l:对标准输出进行行缓冲(nt: 使标准输出设备遇到一个换行符就马上把这行的内容打印出来).在需要同时观察抓包打印以及保存抓包记录的时候很有用. 比如, 可通过以下命令组合来达到此目的:``tcpdump -l | tee dat'' 或者 ``tcpdump -l > dat & tail -f dat''.(nt: 前者使用tee来把tcpdump 的输出同时放到文件dat和标准输出中, 而后者通过重定向操作'>', 把tcpdump的输出放到dat 文件中, 同时通过tail把dat文件中的内容放到标准输出中)
-L:列出指定网络接口所支持的数据链路层的类型后退出.
-n:显示ip,而不是主机名;
-nn:直接以 IP 及 port number 显示,而非主机名及服务名称
-N:不列出域名;
-O:不将数据包编码最佳化;
-p:不让网络界面进入混杂模式;
-q:快速输出,仅列出少数的传输协议信息,
-r:从指定的文件中读取包这些包一般通过-w选项产生);
-s:指定抓包显示行的宽度,-s0表示可按包长显示完整的包,经常和-A一起用,默认截取长度为60个字节,但一般ethernet MTU都是1500字节。所以,要抓取大于60字节的包时,使用默认参数就会导致包数据丢失;
-S:用绝对而非相对数值列出TCP关联数;
-t:在输出的每一行不打印时间戳;
-tt:在输出的每一行显示未经格式化的时间戳记;
-ttt:tcpdump 输出时, 每两行打印之间会延迟一个段时间(以毫秒为单位);
-tttt:在每行打印的时间戳之前添加日期的打印;
-T:将监听到的包直接解释为指定的类型的报文,常见的类型有rpc (远程过程调用) 和snmp (简单网络管理协议) ;
-v:输出一个稍微详细的信息,例如在ip包中可以包括tt1和服务类型的信息;
-vv:产生比-v更详细的输出. 比如, NFS回应包中的附加域将会被打印, SMB数据包也会被完全解码;
-vvv:产生比-vv更详细的输出. 比如, telent 时所使用的SB, SE 选项将会被打印, 如果telnet同时使用的是图形界面,其相应的图形选项将会以16进制的方式打印出来;
-w:把包数据直接写入文件而不进行分析和打印输出. 这些包数据可在随后通过-r 选项来重新读入并进行分析和打印.
-W:filecount.此选项与-C 选项配合使用, 这将限制可打开的文件数目, 并且当文件数据超过这里设置的限制时, 依次循环替代之前的文件, 这相当于一个拥有filecount 个文件的文件缓冲池. 同时, 该选项会使得每个文件名的开头会出现足够多并用来占位的0, 这可以方便这些文件被正确的排序.
-x:当分析和打印时, tcpdump 会打印每个包的头部数据, 同时会以16进制打印出每个包的数据(但不包括连接层的头部).总共打印的数据大小不会超过整个数据包的大小与snaplen 中的最小值. 必须要注意的是, 如果高层协议数据没有snaplen 这么长,并且数据链路层(比如, Ethernet层)有填充数据, 则这些填充数据也会被打印;
-xx:tcpdump 会打印每个包的头部数据, 同时会以16进制打印出每个包的数据, 其中包括数据链路层的头部.
-X:当分析和打印时, tcpdump 会打印每个包的头部数据, 同时会以16进制和ASCII码形式打印出每个包的数据(但不包括连接层的头部).这对于分析一些新协议的数据包很方便.
-XX:当分析和打印时, tcpdump 会打印每个包的头部数据, 同时会以16进制和ASCII码形式打印出每个包的数据, 其中包括数据链路层的头部.这对于分析一些新协议的数据包很方便.
一.查看机器上面哪些端口可以用来抓包:
tcpdump -D
1.eth0
2.bond0
3.nflog (Linux netfilter log (NFLOG) interface)
4.nfqueue (Linux netfilter queue (NFQUEUE) interface)
5.eth1
6.usbmon1 (USB bus number 1)
7.usbmon2 (USB bus number 2)
8.any (Pseudo-device that captures on all interfaces)
9.lo
二.指定对应的端口进行抓包(如果不指定,那么抓取tcpdump -D 的第一个端口)。对于抓包,除非要 -w保存,否则我一般都会加上 -n 参数,可以即时显示出来抓取的内容。
抓取bond0上面的3个包:
tcpdump -i bond0 -c 3 -n
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on bond0, link-type EN10MB (Ethernet), capture size 65535 bytes
14:31:00.990209 IP 221.208.191.21.62081 > 36.42.73.7.http: Flags [.], ack 500646323, win 1026, options [nop,nop,TS val 1097193525 ecr 4194330317], length 0
14:31:00.990216 IP 221.208.191.21.62081 > 36.42.73.7.http: Flags [.], ack 1, win 1026, options [nop,nop,TS val 1097193525 ecr 4194330317], length 0
14:31:00.990685 IP 221.208.191.21.62081 > 36.42.73.7.http: Flags [P.], seq 0:512, ack 1, win 1026, options [nop,nop,TS val 1097193525 ecr 4194330317], length 512
3 packets captured
18 packets received by filter
0 packets dropped by kernel
三. 指定网络层或传输层协议进行抓包,常用的有:ip,arp,icmp,vrrp,tcp,udp
抓取bond0上面的三个arp包:
tcpdump -i bond0 arp -c 3 -n
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on bond0, link-type EN10MB (Ethernet), capture size 65535 bytes
15:08:27.407443 ARP, Request who-has 113.141.164.57 tell 113.141.164.33, length 46
15:08:28.599637 ARP, Request who-has 36.42.73.12 tell 36.42.73.1, length 46
15:08:29.580988 ARP, Request who-has 113.141.164.47 tell 113.141.164.33, length 46
3 packets captured
7 packets received by filter
0 packets dropped by kernel
抓取bond0上面的三个vrrp组播包:
tcpdump -i bond0 vrrp -c 3 -n
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on bond0, link-type EN10MB (Ethernet), capture size 65535 bytes
15:09:57.344708 IP 36.42.73.2 > 224.0.0.18: VRRPv2, Advertisement, vrid 37, prio 100, authtype simple, intvl 3s, length 28
15:10:00.345779 IP 36.42.73.2 > 224.0.0.18: VRRPv2, Advertisement, vrid 37, prio 100, authtype simple, intvl 3s, length 28
15:10:03.346832 IP 36.42.73.2 > 224.0.0.18: VRRPv2, Advertisement, vrid 37, prio 100, authtype simple, intvl 3s, length 28
3 packets captured
11 packets received by filter
0 packets dropped by kernel
抓取bond0上面的三个UDP包:
tcpdump -i bond0 udp -c 3 -n
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on bond0, link-type EN10MB (Ethernet), capture size 65535 bytes
15:42:32.281446 IP 139.215.138.141.8302 > 36.42.73.2.8302: UDP, length 691
15:42:32.304079 IP 124.239.247.193.8302 > 36.42.73.2.8302: UDP, length 790
15:42:32.343396 IP 61.151.131.6.8302 > 36.42.73.2.8302: UDP, length 936
3 packets captured
6 packets received by filter
0 packets dropped by kernel
或者
tcpdump -i bond0 ip and udp -c 3 -n
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on bond0, link-type EN10MB (Ethernet), capture size 65535 bytes
15:43:53.493484 IP 36.42.73.2.8302 > 36.42.73.6.8302: UDP, length 305
15:43:53.493522 IP 36.42.73.2.8302 > 112.13.174.9.8302: UDP, length 305
15:43:53.493555 IP 36.42.73.2.8302 > 120.220.40.42.8302: UDP, length 305
3 packets captured
43 packets received by filter
9 packets dropped by kernel
或者
tcpdump -i bond0 ip proto UDP -c 3 -n (注意这里要用大些的UDP)
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on bond0, link-type EN10MB (Ethernet), capture size 65535 bytes
15:44:07.161253 IP 1.81.5.162.8302 > 36.42.73.2.8302: UDP, length 519
15:44:07.331321 IP 139.215.138.150.8302 > 36.42.73.2.8302: UDP, length 137
15:44:07.493506 IP 36.42.73.2.8302 > 61.151.130.69.8302: UDP, length 586
3 packets captured
13 packets received by filter
0 packets dropped by kernel
说到底,上面的协议都包含在IP协议里面,详情参考如下IP协议列表:
十进制 十六进制 关键字 协议 引用
0 0x00 HOPOPT IPv6逐跳选项 RFC 2460
1 0x01 ICMP 互联网控制消息协议(ICMP) RFC 792
2 0x02 IGMP 因特网组管理协议(IGMP) RFC 1112
3 0x03 GGP 网关对网关协议 RFC 823
4 0x04 IPv4 IPv4 (封装) RFC 791
5 0x05 ST 因特网流协议 RFC 1190, RFC 1819
6 0x06 TCP 传输控制协议(TCP) RFC 793
7 0x07 CBT 有核树组播路由协议 RFC 2189
8 0x08 EGP 外部网关协议 RFC 888
9 0x09 IGP 内部网关协议(任意私有内部网关(用于思科的IGRP))
10 0x0A BBN-RCC-MON BBN RCC 监视
11 0x0B NVP-II 网络语音协议 RFC 741
12 0x0C PUP Xerox PUP
13 0x0D ARGUS ARGUS
14 0x0E EMCON EMCON
15 0x0F XNET Cross Net Debugger IEN 158
16 0x10 CHAOS Chaos
17 0x11 UDP 用户数据报协议(UDP) RFC 768
18 0x12 MUX 多路复用 IEN 90
19 0x13 DCN-MEAS DCN Measurement Subsystems
20 0x14 HMP Host Monitoring Protocol RFC 869
21 0x15 PRM Packet Radio Measurement
22 0x16 XNS-IDP XEROX NS IDP
23 0x17 TRUNK-1 Trunk-1
24 0x18 TRUNK-2 Trunk-2
25 0x19 LEAF-1 Leaf-1
26 0x1A LEAF-2 Leaf-2
27 0x1B RDP 可靠数据协议 RFC 908
28 0x1C IRTP Internet Reliable Transaction Protocol RFC 938
29 0x1D ISO-TP4 ISO Transport Protocol Class 4 RFC 905
30 0x1E NETBLT Bulk Data Transfer Protocol RFC 998
31 0x1F MFE-NSP MFE Network Services Protocol
32 0x20 MERIT-INP MERIT Internodal Protocol
33 0x21 DCCP Datagram Congestion Control Protocol RFC 4340
34 0x22 3PC Third Party Connect Protocol
35 0x23 IDPR Inter-Domain Policy Routing Protocol RFC 1479
36 0x24 XTP Xpress Transport Protocol
37 0x25 DDP Datagram Delivery Protocol
38 0x26 IDPR-CMTP IDPR Control Message Transport Protocol
39 0x27 TP++ TP++ Transport Protocol
40 0x28 IL IL Transport Protocol
41 0x29 IPv6 IPv6 封装 RFC 2473
42 0x2A SDRP Source Demand Routing Protocol RFC 1940
43 0x2B IPv6-Route IPv6路由拓展头 RFC 2460
44 0x2C IPv6-Frag IPv6分片扩展头 RFC 2460
45 0x2D IDRP Inter-Domain Routing Protocol
46 0x2E RSVP 资源预留协议 RFC 2205
47 0x2F GRE 通用路由封装(GRE) RFC 2784, RFC 2890
48 0x30 DSR 动态源路由
49 0x31 BNA BNA
50 0x32 ESP 封装安全协议(ESP) RFC 4303
51 0x33 AH 认证头协议(AH) RFC 4302
52 0x34 I-NLSP Integrated Net Layer Security Protocol TUBA
53 0x35 SWIPE SwIPe IP with Encryption
54 0x36 NARP NBMA Address Resolution Protocol RFC 1735
55 0x37 MOBILE IP Mobility (Min Encap) RFC 2004
56 0x38 TLSP 传输层安全性协议(使用Kryptonet密钥管理)
57 0x39 SKIP Simple Key-Management for Internet Protocol RFC 2356
58 0x3A IPv6-ICMP 互联网控制消息协议第六版(ICMPv6) RFC 4443, RFC 4884
59 0x3B IPv6-NoNxt IPv6无负载头 RFC 2460
60 0x3C IPv6-Opts IPv6目标选项扩展头 RFC 2460
61 0x3D 任意的主机内部协议
62 0x3E CFTP CFTP
63 0x3F 任意本地网络
64 0x40 SAT-EXPAK SATNET and Backroom EXPAK
65 0x41 KRYPTOLAN Kryptolan
66 0x42 RVD MIT远程虚拟磁盘协议
67 0x43 IPPC Internet Pluribus Packet Core
68 0x44 Any distributed file system
69 0x45 SAT-MON SATNET Monitoring
70 0x46 VISA VISA协议
71 0x47 IPCV Internet Packet Core Utility
72 0x48 CPNX Computer Protocol Network Executive
73 0x49 CPHB Computer Protocol Heart Beat
74 0x4A WSN Wang Span Network
75 0x4B PVP Packet Video Protocol
76 0x4C BR-SAT-MON Backroom SATNET Monitoring
77 0x4D SUN-ND SUN ND PROTOCOL-Temporary
78 0x4E WB-MON WIDEBAND Monitoring
79 0x4F WB-EXPAK WIDEBAND EXPAK
80 0x50 ISO-IP 国际标准化组织互联网协议
81 0x51 VMTP Versatile Message Transaction Protocol RFC 1045
82 0x52 SECURE-VMTP Secure Versatile Message Transaction Protocol RFC 1045
83 0x53 VINES VINES
84 0x54 TTP TTP
84 0x54 IPTM Internet Protocol Traffic Manager
85 0x55 NSFNET-IGP NSFNET-IGP
86 0x56 DGP Dissimilar Gateway Protocol
87 0x57 TCF TCF
88 0x58 EIGRP 增强型内部网关路由协议(EIGRP)
89 0x59 OSPF 开放式最短路径优先(OSPF) RFC 1583
90 0x5A Sprite-RPC Sprite RPC Protocol
91 0x5B LARP Locus Address Resolution Protocol
92 0x5C MTP Multicast Transport Protocol
93 0x5D AX.25 AX.25
94 0x5E IPIP IP-within-IP 封装协议 RFC 2003
95 0x5F MICP Mobile Internetworking Control Protocol
96 0x60 SCC-SP Semaphore Communications Sec. Pro
97 0x61 ETHERIP Ethernet-within-IP 封装协议 RFC 3378
98 0x62 ENCAP 封装头部 RFC 1241
99 0x63 任意的加密模式
100 0x64 GMTP GMTP
101 0x65 IFMP Ipsilon Flow Management Protocol
102 0x66 PNNI PNNI over IP
103 0x67 PIM Protocol Independent Multicast
104 0x68 ARIS IBM's ARIS (Aggregate Route IP Switching) Protocol
105 0x69 SCPS 空间通信协议规范 SCPS-TP[1]
106 0x6A QNX QNX
107 0x6B A/N Active Networks
108 0x6C IPComp IP负载压缩协议 RFC 3173
109 0x6D SNP Sitara Networks Protocol
110 0x6E Compaq-Peer Compaq Peer Protocol
111 0x6F IPX-in-IP 封装于IP的IPX
112 0x70 VRRP 虚拟路由器备援协议、共享地址冗余协议(没在IANA注册) VRRP:RFC 3768
113 0x71 PGM 实际通用多播 RFC 3208
114 0x72 Any 0-hop protocol
115 0x73 L2TP 第二层隧道协议第三版 RFC 3931
116 0x74 DDX D-II Data Exchange (DDX)
117 0x75 IATP Interactive Agent Transfer Protocol
118 0x76 STP Schedule Transfer Protocol
119 0x77 SRP SpectraLink Radio Protocol
120 0x78 UTI Universal Transport Interface Protocol
121 0x79 SMP Simple Message Protocol
122 0x7A SM Simple Multicast Protocol draft-perlman-simple-multicast-03
123 0x7B PTP Performance Transparency Protocol
124 0x7C IS-IS over IPv4 负载于IPv4的IS-IS RFC 1142 and RFC 1195
125 0x7D FIRE Flexible Intra-AS Routing Environment
126 0x7E CRTP Combat Radio Transport Protocol
127 0x7F CRUDP Combat Radio User Datagram
128 0x80 SSCOPMCE Service-Specific Connection-Oriented Protocol in a Multilink and Connectionless Environment ITU-T Q.2111 (1999)
129 0x81 IPLT
130 0x82 SPS Secure Packet Shield
131 0x83 PIPE Private IP Encapsulation within IP Expired I-D draft-petri-mobileip-pipe-00.txt
132 0x84 SCTP Stream Control Transmission Protocol
133 0x85 FC 光纤通道
134 0x86 RSVP-E2E-IGNORE Reservation Protocol (RSVP) End-to-End Ignore RFC 3175
135 0x87 Mobility Header IPv6移动IP扩展头 RFC 6275
136 0x88 UDPLite UDP-Lite RFC 3828
137 0x89 MPLS-in-IP 封装于IP协议的多协议标签交换 RFC 4023
138 0x8A manet MANET Protocols RFC 5498
139 0x8B HIP Host Identity Protocol RFC 5201
140 0x8C Shim6 Site Multihoming by IPv6 Intermediation RFC 5533
141 0x8D WESP 包装过的封装安全协议(ESP) RFC 5840
142 0x8E ROHC Robust Header Compression RFC 5856
143-252 0x8F-0xFC 未分配
253-254 0xFD-0xFE 用于实验和测试 RFC 3692
255 0xFF 保留
从bond0上面抓取3个ospf hello包(对照上表可知下面三条命令都可以):
tcpdump -i bond0 ip proto ospf -n -c 3
tcpdump -i bond0 ip proto 89 -n -c 3
tcpdump -i bond0 ip proto 0x59 -n -c 3
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on bond0, link-type EN10MB (Ethernet), capture size 65535 bytes
16:01:57.173839 IP 183.134.101.129 > 224.0.0.5: OSPFv2, Hello, length 84
16:01:57.406541 IP 183.134.101.178 > 224.0.0.5: OSPFv2, Hello, length 84
16:01:57.406554 IP 183.134.101.184 > 224.0.0.5: OSPFv2, Hello, length 84
3 packets captured
847 packets received by filter
759 packets dropped by kernel
1 packets dropped by interface
四. 对应用层进行抓包。应用层常用的协议:http,https,ftp,telnet,ssh,dns,snmp等。这里只详细实操下对http请求包的特征进行抓取,抓取之前最好了解下面的几张图表。 IP首部:
IP头部长度通常为20字节,有选项时更长,总共不超过60字节。
1、第一个4字节(也就是第一行):
(1)版本号(Version),4位;用于标识IP协议版本,IPv4是0100,IPv6是0110,也就是二进制的4和6。
(2)首部长度(Internet Header Length),4位;用于标识首部的长度,单位为4字节,所以首部长度最大值为:(2^4 – 1) * 4 = 60字节,但一般只推荐使用20字节的固定长度。
(3)服务类型(Type Of Service),8位;用于标识IP包的优先级,但现在并未使用。
(4)总长度(Total Length),16位;标识IP数据报的总长度,最大为:2^16 -1 = 65535字节。
2、第二个四字节:
(1)标识(Identification),16位;用于标识IP数据报,如果因为数据链路层帧数据段长度限制(也就是MTU,支持的最大传输单元),IP数据报需要进行分片发送,则每个分片的IP数据报标识都是一致的。
(2)标识(Flag),3位,但目前只有2位有意义;最低位为MF,MF=1代表后面还有分片的数据报,MF=0代表当前数据报已是最后的数据报。次低位为DF,DF=1代表不能分片,DF=0代表可以分片。
(3)片偏移(Fragment Offset),13位;代表某个分片在原始数据中的相对位置。
3、第三个四字节:
(1)生存时间(TTL),8位;以前代表IP数据报最大的生存时间,现在标识IP数据报可以经过的路由器数。
(2)协议(Protocol),8位;代表上层传输层协议的类型,1代表ICMP,2代表IGMP,6代表TCP,17代表UDP。
(3)校验和(Header Checksum),16位;用于验证数据完整性,计算方法为,首先将校验和位置零,然后将每16位二进制反码求和即为校验和,最后写入校验和位置。
4、第四个四字节:源IP地址
5、第五个四字节:目的IP地址TCP首部:
tcp报文由tcp header和tcp数据组成。
tcp header 的最大长度为60字节,而必须要有的固定长度也就是图一的前5层的20字节,每层占有32bit,也就是32/8=4字节,5层,5*4 = 20字节,那么第六层的可选项和填充也就是Tcp Options字段最大为60-20=40字节。填充是为了使TCP首部为4字节(32bit)的整数倍。
Source Port And Destination Port(源端口与目的端口):各占 2 个字节(也就是各占16位,这里也契合端口范围不大于65535),分别写入源端口号与目的端口号。
Sequence Number(序列号):占 4 个字节,范围是[0, 232 – 1],序号增加到 232 – 1 后,下一个序号就又回到 0。在 TCP 连接中传送的字节流中的每一个字节都要按顺序编号,起始序号在连接建立时就完成设置。因此序列号可以用来解决网络包乱序(reordering)问题。例如,一个报文段的序号是 301,而携带的数据共有 100 个字节。这就表明:本报文段的数据的第一个字节的序号是 301,最后一个字节的序号是 400。显然下一个报文段的数据序号要从 401 开始。
Acknowledgement Number(确认号):占 4 个字节,表示期望收到对方下一个报文段的第一个数据字节的序号。可以用来解决不丢包的问题。例如:B 收到了 A 发送过来的一个报文段,序号字段值为 501,而长度是 200 字节(序号 501 – 700),这表明 B 正确地收到了 A 发送的 200 个字节的数据。于是 B 在发送给 A 的确认报文段中把确认号设置为 701。若确认号等于 N,表明:到序号 N – 1 为止的所有数据都已经正确接收到。
Offset(数据偏移):占 4 位,指出 TCP 报文段的数据起始处距离 TCP 报文段的起始处有多远。这个字段实际上是指出 TCP 报文段的首部长度。Reserved(保留):保留为今后使用,目前应置为 0。
TCP Flags:数据包的属性,用于控制 TCP 的状态机。下面介绍其中的一些属性URG(紧急):当 URG=1 时,表明紧急指针字段有效,代表该报文段中有紧急数据,应尽快传送(相当于高优先级的数据)。于是发送方就把紧急数据插在本报文段数据的最前面,通常与 Urgent Pointer 一起配合使用。ACK(确认):只有当 ACK=1 时确认号字段才有效,代表这个封包为确认封包。当 ACK=0 时,确认号无效。TCP 规定,在连接建立后所有传送的报文段都必须把这个字段的值置为 1。PSH:这个标志位表示Push操作。所谓Push操作就是指在数据包到达接收端以后,立即传送给应用程序, 而不是在缓冲区中排队RST(复位):当RST=1时,表明TCP连接中出现严重差错(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立运输连接。SYN:表示同步序号,用来建立连接。SYN标志位和ACK标志位搭配使用,当连接请求的时候,SYN=1, ACK=0;连接被响应的时候,SYN=1,ACK=1;这个标志的数据包经常被用来进行端口扫描。扫描者发送 一个只有SYN的数据包,如果对方主机响应了一个数据包回来 ,就表明这台主机存在这个端口;但是由于这 种扫描方式只是进行TCP三次握手的第一次握手,因此这种扫描的成功表示被扫描的机器不很安全,一台安全 的主机将会强制要求一个连接严格的进行TCP的三次握手;FIN: 表示发送端已经达到数据末尾,也就是说双方的数据传送完成,没有数据可以传送了,发送FIN标志 位的TCP数据包后,连接将被断开。这个标志的数据包也经常被用于进行端口扫描。
Window(窗口):占 2 个字节,窗口值是一个 [0, 2^16 – 1] 之间的整数。窗口指的是发送本报文段的一方的接收窗口(而不是自己的发送窗口)。窗口值用于告诉对方:从本报文段首部中的确认号算起,接受方目前允许对方发送的数据量(以字节为单位)。之所以要有这个限制,是因为接受方的数据空间是有限的。例如:发送了一个报文段,其确认号是 701,窗口字段值为 1000。这就告诉对方:“从 701 序号开始算起,我(发送此报文段的一方)的接收缓存空间还可以接收 1000 个字节数据,字节序号是 701 – 1700,你在给我发送数据时,必须要考虑到这一点”。窗口字段值明确的指出了现在允许对方发送的数据量,窗口值通常是在不断的动态变化着。
Checksum(校验和):占 2 个字节,校验和字段检验的范围包括首部和数据两部分。
Urgent Pointer(紧急指针):占 2 个字节,紧急指针仅在 URG = 1时才有意义,它指出本报文段中的紧急数据的字节数。因此,紧急指针指出了紧急数据的末尾在报文段中的位置。
TCP Options(选项):长度可变,最长可达 40 字节。当没有使用“选项时”,TCP 的首部长度是 20 字节。这个选项的一些解析可以参考链接:https://blog.csdn.net/Hollake/article/details/89327474
分析过程中要用到ASCII对照表,如下:
二进制 八进制 十进制 十六进制 缩写/字符 解释
0000 0000 00 0 0x00 NUL(null) 空字符
0000 0001 01 1 0x01 SOH(start of headline) 标题开始
0000 0010 02 2 0x02 STX (start of text) 正文开始
0000 0011 03 3 0x03 ETX (end of text) 正文结束
0000 0100 04 4 0x04 EOT (end of transmission) 传输结束
0000 0101 05 5 0x05 ENQ (enquiry) 请求
0000 0110 06 6 0x06 ACK (acknowledge) 收到通知
0000 0111 07 7 0x07 BEL (bell) 响铃
0000 1000 010 8 0x08 BS (backspace) 退格
0000 1001 011 9 0x09 HT (horizontal tab) 水平制表符
0000 1010 012 10 0x0A LF (NL line feed, new line) 换行键
0000 1011 013 11 0x0B VT (vertical tab) 垂直制表符
0000 1100 014 12 0x0C FF (NP form feed, new page) 换页键
0000 1101 015 13 0x0D CR (carriage return) 回车键
0000 1110 016 14 0x0E SO (shift out) 不用切换
0000 1111 017 15 0x0F SI (shift in) 启用切换
0001 0000 020 16 0x10 DLE (data link escape) 数据链路转义
0001 0001 021 17 0x11 DC1 (device control 1) 设备控制1
0001 0010 022 18 0x12 DC2 (device control 2) 设备控制2
0001 0011 023 19 0x13 DC3 (device control 3) 设备控制3
0001 0100 024 20 0x14 DC4 (device control 4) 设备控制4
0001 0101 025 21 0x15 NAK (negative acknowledge) 拒绝接收
0001 0110 026 22 0x16 SYN (synchronous idle) 同步空闲
0001 0111 027 23 0x17 ETB (end of trans. block) 结束传输块
0001 1000 030 24 0x18 CAN (cancel) 取消
0001 1001 031 25 0x19 EM (end of medium) 媒介结束
0001 1010 032 26 0x1A SUB (substitute) 代替
0001 1011 033 27 0x1B ESC (escape) 换码(溢出)
0001 1100 034 28 0x1C FS (file separator) 文件分隔符
0001 1101 035 29 0x1D GS (group separator) 分组符
0001 1110 036 30 0x1E RS (record separator) 记录分隔符
0001 1111 037 31 0x1F US (unit separator) 单元分隔符
0010 0000 040 32 0x20 (space) 空格
0010 0001 041 33 0x21 ! 叹号
0010 0010 042 34 0x22 " 双引号
0010 0011 043 35 0x23 # 井号
0010 0100 044 36 0x24 $ 美元符
0010 0101 045 37 0x25 % 百分号
0010 0110 046 38 0x26 & 和号
0010 0111 047 39 0x27 ' 闭单引号
0010 1000 050 40 0x28 ( 开括号
0010 1001 051 41 0x29 ) 闭括号
0010 1010 052 42 0x2A * 星号
0010 1011 053 43 0x2B + 加号
0010 1100 054 44 0x2C , 逗号
0010 1101 055 45 0x2D - 减号/破折号
0010 1110 056 46 0x2E . 句号
0010 1111 057 47 0x2F / 斜杠
0011 0000 060 48 0x30 0 字符0
0011 0001 061 49 0x31 1 字符1
0011 0010 062 50 0x32 2 字符2
0011 0011 063 51 0x33 3 字符3
0011 0100 064 52 0x34 4 字符4
0011 0101 065 53 0x35 5 字符5
0011 0110 066 54 0x36 6 字符6
0011 0111 067 55 0x37 7 字符7
0011 1000 070 56 0x38 8 字符8
0011 1001 071 57 0x39 9 字符9
0011 1010 072 58 0x3A : 冒号
0011 1011 073 59 0x3B ; 分号
0011 1100 074 60 0x3C < 小于
0011 1101 075 61 0x3D = 等号
0011 1110 076 62 0x3E > 大于
0011 1111 077 63 0x3F ? 问号
0100 0000 0100 64 0x40 @ 电子邮件符号
0100 0001 0101 65 0x41 A 大写字母A
0100 0010 0102 66 0x42 B 大写字母B
0100 0011 0103 67 0x43 C 大写字母C
0100 0100 0104 68 0x44 D 大写字母D
0100 0101 0105 69 0x45 E 大写字母E
0100 0110 0106 70 0x46 F 大写字母F
0100 0111 0107 71 0x47 G 大写字母G
0100 1000 0110 72 0x48 H 大写字母H
0100 1001 0111 73 0x49 I 大写字母I
01001010 0112 74 0x4A J 大写字母J
0100 1011 0113 75 0x4B K 大写字母K
0100 1100 0114 76 0x4C L 大写字母L
0100 1101 0115 77 0x4D M 大写字母M
0100 1110 0116 78 0x4E N 大写字母N
0100 1111 0117 79 0x4F O 大写字母O
0101 0000 0120 80 0x50 P 大写字母P
0101 0001 0121 81 0x51 Q 大写字母Q
0101 0010 0122 82 0x52 R 大写字母R
0101 0011 0123 83 0x53 S 大写字母S
0101 0100 0124 84 0x54 T 大写字母T
0101 0101 0125 85 0x55 U 大写字母U
0101 0110 0126 86 0x56 V 大写字母V
0101 0111 0127 87 0x57 W 大写字母W
0101 1000 0130 88 0x58 X 大写字母X
0101 1001 0131 89 0x59 Y 大写字母Y
0101 1010 0132 90 0x5A Z 大写字母Z
0101 1011 0133 91 0x5B [ 开方括号
0101 1100 0134 92 0x5C \ 反斜杠
0101 1101 0135 93 0x5D ] 闭方括号
0101 1110 0136 94 0x5E ^ 脱字符
0101 1111 0137 95 0x5F _ 下划线
0110 0000 0140 96 0x60 ` 开单引号
0110 0001 0141 97 0x61 a 小写字母a
0110 0010 0142 98 0x62 b 小写字母b
0110 0011 0143 99 0x63 c 小写字母c
0110 0100 0144 100 0x64 d 小写字母d
0110 0101 0145 101 0x65 e 小写字母e
0110 0110 0146 102 0x66 f 小写字母f
0110 0111 0147 103 0x67 g 小写字母g
0110 1000 0150 104 0x68 h 小写字母h
0110 1001 0151 105 0x69 i 小写字母i
0110 1010 0152 106 0x6A j 小写字母j
0110 1011 0153 107 0x6B k 小写字母k
0110 1100 0154 108 0x6C l 小写字母l
0110 1101 0155 109 0x6D m 小写字母m
0110 1110 0156 110 0x6E n 小写字母n
0110 1111 0157 111 0x6F o 小写字母o
0111 0000 0160 112 0x70 p 小写字母p
0111 0001 0161 113 0x71 q 小写字母q
0111 0010 0162 114 0x72 r 小写字母r
0111 0011 0163 115 0x73 s 小写字母s
0111 0100 0164 116 0x74 t 小写字母t
0111 0101 0165 117 0x75 u 小写字母u
0111 0110 0166 118 0x76 v 小写字母v
0111 0111 0167 119 0x77 w 小写字母w
0111 1000 0170 120 0x78 x 小写字母x
0111 1001 0171 121 0x79 y 小写字母y
0111 1010 0172 122 0x7A z 小写字母z
0111 1011 0173 123 0x7B { 开花括号
0111 1100 0174 124 0x7C | 垂线
0111 1101 0175 125 0x7D } 闭花括号
0111 1110 0176 126 0x7E ~ 波浪号
0111 1111 0177 127 0x7F DEL (delete) 删除
112.10.66.250 是客户端IP,36.42.73.2 是服务端(web端)IP。
只抓取客户端的请求包:
tcpdump -i bond0 host 112.10.66.250 and dst port 80 -n
只抓取服务端的响应包:
tcpdump -i bond0 host 112.10.66.250 and src port 80 -n
同时抓取双方的交互包:
tcpdump -i bond0 host 112.10.66.250 and port 80 -n
实际上我们指定端口就可以解决大部分的抓包问题了,不过有时候需要对包进行更精细和准确的抓取,这个时候就要使用包过滤器来抓取。抓取http请求中的GET包常用的命令如下:
tcpdump -i bond0 host 112.10.66.250 and dst port 80 and 'tcp[(tcp[12]>>2):4] = 0x47455420' -AevvnnSs0
tcpdump: listening on bond0, link-type EN10MB (Ethernet), capture size 65535 bytes
10:55:13.512670 e8:68:19:64:37:01 > 54:a0:50:84:5e:d8, ethertype IPv4 (0x0800), length 183: (tos 0x4, ttl 46, id 41465, offset 0, flags [DF], proto TCP (6), length 169)
112.10.66.250.11737 > 36.42.73.2.80: Flags [P.], cksum 0x1087 (correct), seq 2517309358:2517309487, ack 420656012, win 517, length 129
E.....@....!p
B.$*I.-..P........P.......GET http://en.tingfun.net/ HTTP/1.1
Host: en.tingfun.net
User-Agent: curl/7.46.0
Accept: */*
Proxy-Connection: Keep-Alive
^C
1 packets captured
7 packets received by filter
0 packets dropped by kernel
用十六进制详细的看下:
tcpdump -i bond0 host 112.10.66.250 and dst port 80 and 'tcp[(tcp[12]>>2):4] = 0x47455420' -XevvnnSs0
tcpdump: listening on bond0, link-type EN10MB (Ethernet), capture size 65535 bytes
10:56:06.038276 e8:68:19:64:37:01 > 54:a0:50:84:5e:d8, ethertype IPv4 (0x0800), length 183: (tos 0x4, ttl 46, id 41472, offset 0, flags [DF], proto TCP (6), length 169)
112.10.66.250.11742 > 36.42.73.2.80: Flags [P.], cksum 0xc2bf (correct), seq 3609921535:3609921664, ack 3605926401, win 517, length 129
0x0000: 4504 00a9 a200 4000 2e06 8a1a 700a 42fa E.....@.....p.B.
0x0010: 242a 4902 2dde 0050 d72b 07ff d6ee 1201 $*I.-..P.+......
0x0020: 5018 0205 c2bf 0000 4745 5420 6874 7470 P.......GET.http
0x0030: 3a2f 2f65 6e2e 7469 6e67 6675 6e2e 6e65 ://en.tingfun.ne
0x0040: 742f 2048 5454 502f 312e 310d 0a48 6f73 t/.HTTP/1.1..Hos
0x0050: 743a 2065 6e2e 7469 6e67 6675 6e2e 6e65 t:.en.tingfun.ne
0x0060: 740d 0a55 7365 722d 4167 656e 743a 2063 t..User-Agent:.c
0x0070: 7572 6c2f 372e 3436 2e30 0d0a 4163 6365 url/7.46.0..Acce
0x0080: 7074 3a20 2a2f 2a0d 0a50 726f 7879 2d43 pt:.*\/*..Proxy-C
0x0090: 6f6e 6e65 6374 696f 6e3a 204b 6565 702d onnection:.Keep-
0x00a0: 416c 6976 650d 0a0d 0a Alive....
^C
1 packets captured
1 packets received by filter
0 packets dropped by kernel
下面这个过滤规则和上面基本可以达到相同的过滤效果,如下:
tcpdump -i bond0 host 112.10.66.250 and dst port 80 and 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420' -XevvnnSs0
tcpdump: listening on bond0, link-type EN10MB (Ethernet), capture size 65535 bytes
11:04:43.768761 e8:68:19:64:37:01 > 54:a0:50:84:5e:d8, ethertype IPv4 (0x0800), length 183: (tos 0x4, ttl 46, id 41478, offset 0, flags [DF], proto TCP (6), length 169)
112.10.66.250.11884 > 36.42.73.2.80: Flags [P.], cksum 0x05de (correct), seq 1971514973:1971515102, ack 1230559029, win 517, length 129
0x0000: 4504 00a9 a206 4000 2e06 8a14 700a 42fa E.....@.....p.B.
0x0010: 242a 4902 2e6c 0050 7582 ee5d 4958 d735 $*I..l.Pu..]IX.5
0x0020: 5018 0205 05de 0000 4745 5420 6874 7470 P.......GET.http
0x0030: 3a2f 2f65 6e2e 7469 6e67 6675 6e2e 6e65 ://en.tingfun.ne
0x0040: 742f 2048 5454 502f 312e 310d 0a48 6f73 t/.HTTP/1.1..Hos
0x0050: 743a 2065 6e2e 7469 6e67 6675 6e2e 6e65 t:.en.tingfun.ne
0x0060: 740d 0a55 7365 722d 4167 656e 743a 2063 t..User-Agent:.c
0x0070: 7572 6c2f 372e 3436 2e30 0d0a 4163 6365 url/7.46.0..Acce
0x0080: 7074 3a20 2a2f 2a0d 0a50 726f 7879 2d43 pt:.*\/*..Proxy-C
0x0090: 6f6e 6e65 6374 696f 6e3a 204b 6565 702d onnection:.Keep-
0x00a0: 416c 6976 650d 0a0d 0a Alive....
^C
1 packets captured
3 packets received by filter
0 packets dropped by kernel
上面的语法tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420解释如下:
1.从tcp首部的12字节开始向后取一个字节,即取到十六进制的 50
2.十六进制的50和十六进制的f0进行按位与运算,得到二进制的 1010000
3.二进制的1010000 逻辑右移2位,得到 10100,转换为10进制为 20
4.即从20字节向后取4字节,可以得到十六进制的 47455420 ,对照ASCII可解码为’GET ’(注意有个空格),这和过滤条件也是匹配的。
所以也可以简化为如下的表达语句:tcpdump -i bond0 host 112.10.66.250 and dst port 80 and tcp[20:4]=0x47455420 -XevvnnSs0但是这两种过滤方法在遇到TCP首部不是20的时候(即有可变长度和填充位的时候有些包抓不到),所以推荐如果用TCP过滤器来过滤的话就用第一种语法:tcpdump -i bond0 host 112.10.66.250 and dst port 80 and 'tcp[(tcp[12]>>2):4] = 0x47455420' -AevvnnSs0下面再示范下POST的请求,因为POST对应的ASCII是0x504f5354,所以如下:
tcpdump -i bond0 host 112.10.66.250 and dst port 80 and 'tcp[(tcp[12]>>2):4] = 0x504f5354' -XevvnnSs0
tcpdump: listening on bond0, link-type EN10MB (Ethernet), capture size 65535 bytes
11:40:31.698870 e8:68:19:64:37:01 > 54:a0:50:84:5e:d8, ethertype IPv4 (0x0800), length 261: (tos 0x4, ttl 46, id 41500, offset 0, flags [DF], proto TCP (6), length 247)
112.10.66.250.11994 > 36.42.73.2.80: Flags [P.], cksum 0xc226 (correct), seq 654825529:654825736, ack 4077610548, win 517, length 207
0x0000: 4504 00f7 a21c 4000 2e06 89b0 700a 42fa E.....@.....p.B.
0x0010: 242a 4902 2eda 0050 2707 d839 f30b 6634 $*I....P'..9..f4
0x0020: 5018 0205 c226 0000 504f 5354 2068 7474 P....&..POST.htt
0x0030: 703a 2f2f 656e 2e74 696e 6766 756e 2e6e p://en.tingfun.n
0x0040: 6574 2f20 4854 5450 2f31 2e31 0d0a 486f et/.HTTP/1.1..Ho
0x0050: 7374 3a20 656e 2e74 696e 6766 756e 2e6e st:.en.tingfun.n
0x0060: 6574 0d0a 5573 6572 2d41 6765 6e74 3a20 et..User-Agent:.
0x0070: 6375 726c 2f37 2e34 362e 300d 0a41 6363 curl/7.46.0..Acc
0x0080: 6570 743a 202a 2f2a 0d0a 5072 6f78 792d ept:.*\/*..Proxy-
0x0090: 436f 6e6e 6563 7469 6f6e 3a20 4b65 6570 Connection:.Keep
0x00a0: 2d41 6c69 7665 0d0a 436f 6e74 656e 742d -Alive..Content-
0x00b0: 4c65 6e67 7468 3a20 390d 0a43 6f6e 7465 Length:.9..Conte
0x00c0: 6e74 2d54 7970 653a 2061 7070 6c69 6361 nt-Type:.applica
0x00d0: 7469 6f6e 2f78 2d77 7777 2d66 6f72 6d2d tion/x-www-form-
0x00e0: 7572 6c65 6e63 6f64 6564 0d0a 0d0a 7465 urlencoded....te
0x00f0: 7374 2070 6f73 74 st.post
^C
1 packets captured
7 packets received by filter
0 packets dropped by kernel
至于其他的特征,比如握手和挥手的阶段,端口号,包长度,以及请求头里面的信息等等都可以通过tcp包过滤方法来实现,后面会具体举几个例子。
五. 抓TCP三次握手和四次挥手包。TCP的连接过程摘录了一篇文章。
TCP(Transmission Control Protocol 传输控制协议)是一种面向连接(连接导向)的、可靠的、 基于IP的传输层协议。TCP在IP报文的协议号是6。TCP是一个超级麻烦的协议,而它又是互联网的基础,也是每个程序员必备的基本功。首先来看看OSI的七层模型:
我们需要知道TCP工作在网络OSI的七层模型中的第四层——Transport层,IP在第三层——Network层,ARP 在第二层——Data Link层;在第二层上的数据,我们把它叫Frame,在第三层上的数据叫Packet,第四层的数 据叫Segment。 同时,我们需要简单的知道,数据从应用层发下来,会在每一层都会加上头部信息,进行 封装,然后再发送到数据接收端。这个基本的流程你需要知道,就是每个数据都会经过数据的封装和解封 装的过程。 在OSI七层模型中,每一层的作用和对应的协议如下:
三次握手又是什么?
TCP是面向连接的,无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。在TCP/IP协议中,TCP 协议提供可靠的连接服务,连接是通过三次握手进行初始化的。三次握手的目的是同步连接双方的序列号和确认号 并交换 TCP窗口大小信息。这就是面试中经常会被问到的TCP三次握手。只是了解TCP三次握手的 概念,对你获得一份工作是没有任何帮助的,你需要去了解TCP三次握手中的一些细节。先来看图说话:
多么清晰的一张图,当然了,也不是我画的,我也只是引用过来说明问题了。
1.第一次握手:建立连接。客户端发送连接请求报文段,将SYN位置为1,Sequence Number为x;然后,客户端进入SYN_SEND状态,等待服务器的确认;
2.第二次握手:服务器收到SYN报文段。服务器收到客户端的SYN报文段,需要对这个SYN报文段进行确认,设置Acknowledgment Number为x+1(Sequence Number+1);同时,自己自己还要发送SYN请求信息,将SYN位置为1,Sequence Number为y;服务器端将上述所有信息放到一个报文段(即SYN+ACK报文段)中,一并发送给客户端,此时服务器进入SYN_RECV状态;
3.第三次握手:客户端收到服务器的SYN+ACK报文段。然后将Acknowledgment Number设置为y+1,向服务器发送ACK报文段,这个报文段发送完毕以后,客户端和服务器端都进入ESTABLISHED状态,完成TCP三次握手。完成了三次握手,客户端和服务器端就可以开始传送数据。以上就是TCP三次握手的总体介绍。
那四次分手呢?
当客户端和服务器通过三次握手建立了TCP连接以后,当数据传送完毕,肯定是要断开TCP连接的啊。那对于TCP的断开连接,这里就有了神秘的“四次分手”。
1.第一次分手:主机1(可以使客户端,也可以是服务器端),设置Sequence Number和Acknowledgment Number,向主机2发送一个FIN报文段;此时,主机1进入FIN_WAIT_1状态;这表示主机1没有数据要发送给主机2了;
2.第二次分手:主机2收到了主机1发送的FIN报文段,向主机1回一个ACK报文段,Acknowledgment Number为Sequence Number加1;主机1进入FIN_WAIT_2状态;主机2告诉主机1,我也没有数据要发送了,可以进行关闭连接了;
3.第三次分手:主机2向主机1发送FIN报文段,请求关闭连接,同时主机2进入CLOSE_WAIT状态;
4.第四次分手:主机1收到主机2发送的FIN报文段,向主机2发送ACK报文段,然后主机1进入TIME_WAIT状态;主机2收到主机1的ACK报文段以后,就关闭连接;此时,主机1等待2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,主机1也可以关闭连接了。至此,TCP的四次分手就这么愉快的完成了。
当你看到这里,你的脑子里会有很多的疑问,很多的不懂,感觉很凌乱;没事,我们继续总结。为什么要三次握手?既然总结了TCP的三次握手,那为什么非要三次呢?怎么觉得两次就可以完成了。那TCP为什么非要进行三次连接呢?在谢希仁的《计算机网络》中是这样说的:为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。在书中同时举了一个例子,如下:"已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。" 这就很明白了,防止了服务器端的一直等待而浪费资源。为什么要四次分手?那四次分手又是为何呢?TCP协议是一种面向连接的、可靠的、基于字节流的运输层通信协议。TCP是全双工 模式,这就意味着,当主机1发出FIN报文段时,只是表示主机1已经没有数据要发送了,主机1告诉主机2, 它的数据已经全部发送完毕了;但是,这个时候主机1还是可以接受来自主机2的数据;当主机2返回ACK报文 段时,表示它已经知道主机1没有数据发送了,但是主机2还是可以发送数据到主机1的;当主机2也发送了FIN 报文段时,这个时候就表示主机2也没有数据要发送了,就会告诉主机1,我也没有数据要发送了,之后彼此 就会愉快的中断这次TCP连接。如果要正确的理解四次分手的原理,就需要了解四次分手过程中的状态变化。FIN_WAIT_1: 这个状态要好好解释一下,其实FIN_WAIT_1和FIN_WAIT_2状态的真正含义都是表示等 待对方的FIN报文。而这两种状态的区别是:FIN_WAIT_1状态实际上是当SOCKET在ESTABLISHED状态时, 它想主动关闭连接,向对方发送了FIN报文,此时该SOCKET即进入到FIN_WAIT_1状态。而当对方回应ACK报 文后,则进入到FIN_WAIT_2状态,当然在实际的正常情况下,无论对方何种情况下,都应该马上回应ACK 报文,所以FIN_WAIT_1状态一般是比较难见到的,而FIN_WAIT_2状态还有时常常可以用netstat看到。 (主动方)FIN_WAIT_2:上面已经详细解释了这种状态,实际上FIN_WAIT_2状态下的SOCKET,表示半连接,也即 有一方要求close连接,但另外还告诉对方,我暂时还有点数据需要传送给你(ACK信息),稍后再关闭连接。 (主动方)CLOSE_WAIT:这种状态的含义其实是表示在等待关闭。怎么理解呢?当对方close一个SOCKET后发送FIN 报文给自己,你系统毫无疑问地会回应一个ACK报文给对方,此时则进入到CLOSE_WAIT状态。接下来呢,实 际上你真正需要考虑的事情是察看你是否还有数据发送给对方,如果没有的话,那么你也就可以 close这个 SOCKET,发送FIN报文给对方,也即关闭连接。所以你在CLOSE_WAIT状态下,需要完成的事情是等待你去关 闭连接。(被动方)LAST_ACK: 这个状态还是比较容易好理解的,它是被动关闭一方在发送FIN报文后,最后等待对方的ACK报 文。当收到ACK报文后,也即可以进入到CLOSED可用状态了。(被动方)TIME_WAIT: 表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后即可回到CLOSED可用状态了。 如果FINWAIT1状态下,收到了对方同时带FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无 须经过FIN_WAIT_2状态。(主动方)CLOSED: 表示连接中断。
抓个包具体分析看下:
tcpdump -i bond0 host 112.10.66.250 and port 80 -Snn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on bond0, link-type EN10MB (Ethernet), capture size 65535 bytes
13:48:45.383276 IP 112.10.66.250.12038 > 36.42.73.2.80: Flags [S], seq 2746896287, win 64240, options [mss 1440,nop,wscale 8,nop,nop,sackOK], length 0
13:48:45.383315 IP 36.42.73.2.80 > 112.10.66.250.12038: Flags [S.], seq 3539405289, ack 2746896288, win 29200, options [mss 1460,nop,nop,sackOK,nop,wscale 10], length 0
13:48:45.438198 IP 112.10.66.250.12038 > 36.42.73.2.80: Flags [.], ack 3539405290, win 517, length 0
13:48:45.439301 IP 112.10.66.250.12038 > 36.42.73.2.80: Flags [P.], seq 2746896288:2746896417, ack 3539405290, win 517, length 129
13:48:45.439312 IP 36.42.73.2.80 > 112.10.66.250.12038: Flags [.], ack 2746896417, win 30, length 0
13:48:45.441060 IP 36.42.73.2.80 > 112.10.66.250.12038: Flags [P.], seq 3539405290:3539405877, ack 2746896417, win 30, length 587
13:48:45.441174 IP 36.42.73.2.80 > 112.10.66.250.12038: Flags [P.], seq 3539405877:3539405922, ack 2746896417, win 30, length 45
13:48:45.499405 IP 112.10.66.250.12038 > 36.42.73.2.80: Flags [.], ack 3539405922, win 515, length 0
13:48:45.500813 IP 112.10.66.250.12038 > 36.42.73.2.80: Flags [F.], seq 2746896417, ack 3539405922, win 515, length 0
13:48:45.500856 IP 36.42.73.2.80 > 112.10.66.250.12038: Flags [F.], seq 3539405922, ack 2746896418, win 30, length 0
13:48:45.554236 IP 112.10.66.250.12038 > 36.42.73.2.80: Flags [.], ack 3539405923, win 515, length 0
^C
11 packets captured
17 packets received by filter
0 packets dropped by kernel
对于flags标识解释如下:
S=SYN,发起连接标志。
P=PUSH,传送数据标志。
F=FIN,关闭连接标志。
.=ACK,表示确认包。
RST=RESET,异常关闭连接
客户端向服务端发起连接请求,syn 包的 seq 为 2746896287服务端响应客户端的syn请求并将其syn的seq加1,回复为 ack 2746896288;同时返回给客户端的还有自己的syn seq号3539405289客户端收到服务端的响应后把服务端的seq号加1,回复给服务端为 ack 3539405290到此,三次握手完成,开启push数据。上面的例子中客户端带着最后一次握手的ack 3539405290开始进行GET请求(包含请求body和请求头的内容)。服务端确认并回复客户端的最大请求序列号 ack 2746896417服务端开始发送数据给客户端,发送的同时告诉了客户端内容的序列号范围客户端接收完成后给服务端最后一次发送的序列号发送ack 包。
这里的关闭只用了三次挥手:客户端接收完成后发起关闭连接的fin ack 包 seq 2746896417, ack 3539405922服务端此时也发送完了数据,所以就直接也返回了 fin ack 包 seq 3539405922, ack 2746896418客户端接着就再次 ack 3539405923 结束对话。
六.列举一些常用逻辑及语句
抓取服务端和112.10.66.250的FTP双向通信包:
tcpdump -i bond0 host 112.10.66.250 and port 21 -nn
只抓取服务端发送给112.10.66.250的FTP通信包:
tcpdump -i bond0 dst 112.10.66.250 and port 21 -nn
只抓取112.10.66.250发送给服务端的FTP SYN通信包:
tcpdump -i bond0 'tcp[tcpflags]=tcp-syn' and src 112.10.66.250 and port 21 -nn
只抓取服务端发送给112.10.66.250的FTP ACK通信包:
tcpdump -i bond0 'tcp[tcpflags]=tcp-ack' and dst 112.10.66.250 and port 21 -nn
其中tcpflags等价于13,下面的几个TCP抓包也是比较精彩的:
只抓SYN包,第十四字节是二进制的00000010,也就是十进制的2
tcpdump -i eth1 'tcp[13] = 2'
抓SYN, ACK (00010010 or 18):
tcpdump -i eth1 'tcp[13] = 18'
抓SYN或者SYN-ACK:
tcpdump -i eth1 'tcp[13] & 2 = 2'
上面用到了位操作,就是不管ACK位是啥。
抓PSH-ACK:
tcpdump -i eth1 'tcp[13] = 24'
抓所有包含FIN标记的包(FIN通常和ACK一起):
tcpdump -i eth1 'tcp[13] & 1 = 1'
抓RST:
tcpdump -i eth1 'tcp[13] & 4 = 4'
网段过滤,比如抓取和112.10.66.0/24这个网段的通信:
tcpdump -i bond0 net 112.10.66 and port 80 -nn
抓取大于某个指定长度的包,比如抓取和112.10.66.250通信中大于800字节的包:
tcpdump -i bond0 'ip[2:2]>800' and host 112.10.66.250 -nn
抓取多个主机的tcp 80数据包:
tcpdump -i bond0 tcp and '(host 183.236.31.227 or host 112.10.66.250)' and port 80 -nn
抓取端口范围的数据包(抓取21-23端口的所有数据包):
tcpdump -i eth0 portrange 21-23
抓取以太网地址数据:
tcpdump ether host fa:26:3e:01:3c:40
抓取源ip是172.16.1.122且端口不是22的数据包:
tcpdump -v -i eth0 src host 172.16.1.122 and not port 22
抓取主机1.1.1.1和所有主机(除20.20.20.8)的通信数据包:
tcpdump host 1.1.1.1 and !20.20.20.8
抓取源ip是172.16.1.59且目的端口是22,或源ip是172.16.1.68且目的端口是80的数据包:
tcpdump -i eth0 -v 'src host 172.16.1.59 and dst port 22' or ' src host 172.16.1.68 and dst port 80 '
每隔60秒保存一次数据包文件,文件名是以年–月–日_时:分:秒.cap的形式进行命名的,一致持续抓包,持续保存数据包:
tcpdump -G 60 -s 0 -i eth0 -w ip_%Y-%m-%d_%H:%M:%S.cap
#-G 指定间隔60秒,与-w 文件名中的时间变量一同使用,就是隔60秒,保存一个文件
读取保存的数据包:
tcpdump -r xxx.cap
分析保存的数据包使用的参数和抓取时使用的参数是一致的,再结合linux文本编辑命令进行统计排序等操作。当然结合wireshark包分析软件来分析也是极好的….
相关链接: