发送端发送一个SYN=1,ACK=0标志的数据包给接收端,请求进行连接,这是第一次握手;接收端收到请求并且允许连接的话,就会发送一个SYN=1,ACK=1标志的数据包给发送端,告诉它,可以通讯了,并且让发送端发送一个确认数据包,这是第二次握手;最后,发送端发送一个SYN=0,ACK=1的数据包给接收端,告诉它连接已被确认,这就是第三次握手。之后,一个TCP连接建立,开始通讯。
SYN:同步标志。同步序列编号(Synchronize Sequence Numbers)栏有效。该标志仅在三次握手建立TCP连接时有效。它提示TCP连接的服务端检查序列编号,该序列编号为TCP连接初始端(一般是客户端)的初始序列编号。在这里,可以把 TCP序列编号看作是一个范围从0到4,294,967,295的32位计数器。通过TCP连接交换的数据中每一个字节都经过序列编号。在TCP报头中的序列编号栏包括了TCP分段中第一个字节的序列编号。
ACK:确认标志。确认编号(Acknowledgement Number)栏有效。大多数情况下该标志位是置位的。TCP报头内的确认编号栏内包含的确认编号(w+1,Figure-1)为下一个预期的序列编号,同时提示远端系统已经成功接收所有数据。
RST:复位标志。复位标志有效。用于复位相应的TCP连接。
URG:紧急标志。紧急(The urgent pointer) 标志有效。紧急标志置位,
PSH:推标志。该标志置位时,接收端不将该数据进行队列处理,而是尽可能快将数据转由应用处理。在处理 telnet 或 rlogin 等交互模式的连接时,该标志总是置位的。
FIN:结束标志。带有该标志置位的数据包用来结束一个TCP回话,但对应端口仍处于开放状态,准备接收后续数据。
.TCP的几个状态对于我们分析所起的作用。在TCP层,有个FLAGS字段,这个字段有以下几个标识:SYN, FIN, ACK, PSH, RST, URG.其中,对于我们日常的分析有用的就是前面的五个字段。它们的含义是:
其中,ACK是可能与SYN,FIN等同时使用的,比如SYN和ACK可能同时为1,它表示的就是建立连接之后的响应,如果只是单个的一个SYN,它表示的只是建立连接。TCP的几次握手就是通过这样的ACK表现出来的。但SYN与FIN是不会同时为1的,因为前者表示的是建立连接,而后者表示的是断开连接。RST一般是在FIN之后才会出现为1的情况,表示的是连接重置。一般地,当出现FIN包或RST包时,我们便认为客户端与服务器端断开了连接;而当出现SYN和SYN+ACK包时,我们认为客户端与服务器建立了一个连接。PSH为1的情况,一般只出现在 DATA内容不为0的包中,也就是说PSH为1表示的是有真正的TCP数据包内容被传递。TCP的连接建立和连接关闭,都是通过请求-响应的模式完成的。
在linux下tcpdump是一个很强大的tcp抓包工具,但是由于linux分析不方便,因此可以将抓包数据保存到.cap文件中,然后在windos下使用wireshark进行分析,非常方便。
tcpdump tcp -i eth2 -s 0 and port 20058 -w /home/pjroot/attence.cap
tcpdump tcp -i eth2 -t -s 0 -c 100 and port 20058 -w /home/pjroot/attence.cap
tcpdump tcp -i eth2 -s 0 and port 20058 and host 125.77.252.211 -w ./attence.cap
-i eth2 指定数据包经过的网卡
-s 0 抓取数据包时默认抓取长度为68字节。加上-S 0 后可以抓到完整的数据包
port 指定端口 可以加上src 和dst表示现在为源端口还是目的端口
host 指定主机可以加上src和dst表示源地址还是目的地址
-w 表示要写入到文件中
-t 表示不显示时间戳
-c 100 表示只抓取初始的100个数据包
打印所有进入或离开sundown的数据包.
tcpdump host sundown
也可以指定ip,例如截获所有210.27.48.1 的主机收到的和发出的所有的数据包
tcpdump host 210.27.48.1
打印helios 与 hot 或者与 ace 之间通信的数据包
tcpdump host helios and \( hot or ace \)
截获主机210.27.48.1 和主机210.27.48.2 或210.27.48.3的通信
tcpdump host 210.27.48.1 and \ (210.27.48.2 or 210.27.48.3 \)
打印ace与任何其他主机之间通信的IP 数据包, 但不包括与helios之间的数据包.
tcpdump ip host ace and not helios
如果想要获取主机210.27.48.1除了和主机210.27.48.2之外所有主机通信的ip包,使用命令:
tcpdump ip host 210.27.48.1 and ! 210.27.48.2
截获主机hostname发送的所有数据
tcpdump -i eth0 src host hostname
监视所有送到主机hostname的数据包
tcpdump -i eth0 dst host hostname
如果想要获取主机210.27.48.1接收或发出的telnet包,使用如下命令
tcpdump tcp port 23 and host 210.27.48.1
tcpdump -XvvennSs 0 -i eth0 tcp[20:2]=0x4745 or tcp[20:2]=0x4854
0x4745 为"GET"前两个字母"GE",0x4854 为"HTTP"前两个字母"HT"。
-i any : 监听所有接口
-n : 不解析主机名
-nn : 不解析主机名和端口名
-X : 以16进制和ascii格式显示包
-XX : 和-X一样,但会显示以太网头
-v, -vv, -vvv : 获取包含信息量更多的包
-c : 获取指定数量的包,达到该数量后tcpdump停止
-S : 显示绝对序列号
-e : 获取以太网头
-q : 显示少量的协议信息
-E : 通过密钥来解密IPSEC交互
-s : 设置snaplength(snaplength是抓取的字节数)
- host // 根据ip地址查询交互(不用"-n"也能根据主机名查询交互)
# tcpdump host 1.2.3.4
- src,dst // 找出指定源地址或目的地址的交互
# tcpdump src 2.3.4.5
# tcpdump dst 3.4.5.6
- net // 根据网络号抓取整个网络
# tcpdump net 1.2.3.0/24
- proto // 工作在tcp,udp,和icmp。注意你不用必须输入proto。
# tcpdump icmp
- port // 查看经过指定端口的交互
# tcpdump port 3389
- src,dst port // 找出指定源端口或目的端口的交互
# tcpdump src port 1025
# tcpdump dst port 389
- src/dst, port, protocol // 将三个联合在一起
# tcpdump src port 1025 and tcp
# tcpdump udp and src port 53
你也可以用选项来找出多个端口而不用一一指定,也可以仅查看大于或小于某一字节大小的包。
- Port Ranges // 查看经过范围内端口的交互
tcpdump portrange 21-23
- Packet Size Filter // 查看大于或小于某一字节大小的包
tcpdump less 32
tcpdump greater 128
也可以用符号来代替
tcpdump > 32
tcpdump <= 128
写到一个文件
tcpdump用"-w"选项可以将抓到的内容存入文件,再用"-r"选项读回来,这个功能非常好,可以抓取原始交互之后再用其他工具运行它。
以这种方式抓取到的交互会存成tcpdump格式的文件,现在网络分析圈内基本都用这种格式,因此文件可以被所有工具读取,包括Wireshark, Snort等。
- 抓取所有经过端口80的交互存入一个文件
# tcpdump -s 1514 port 80 -w capture_file
- 以后可以再读回来
# tcpdump -r capture_file
更多的例子
# 从10.5.2.3到端口3389的tcp交互
tcpdump -nnvvS and src 10.5.2.3 and dst port 3389
# 从网络192.168到网络10或172.16的交互
tcpdump -nvX src net 192.168.0.0/16 and dst net 10.0.0.0/8 or 172.16.0.0/16
# 从192.168.0.2到网络172.16的非icmp交互
tcpdump -nvvXSs 1514 dst 192.168.0.2 and src net and not icmp
# 从Mars或Pluto到非SSH端口的交互
tcpdump -vv src Mars or Pluto and not dst port 22
分组
如果你试图运行这个本来非常有用的命令,因为括号的原因会报错,可以对括号进行转义(前面加"/")或者将整个命令放在单引号中:
# 从10.0.2.4到端口3389或22的交互(正确的表达)
tcpdump 'src 10.0.2.4 and (dst port 3389 or 22)'