——注意:以下所有的选项都是跟在 tcpdump 之后,例如:tcpdump -i any -i any:监听所有的网卡是否有流量 -i eth0:监听 eth0 接口 -D:显示可用的接口列表 -n:不解析主机名 -nn:不解析主机名或者端口名 -q:简略的输出(更安静) -X:将数据包的内容同时以十六进制和 ASCII 的格式显示 -XX:和 -X 一样,但多显示以太网报头 -v,-vv,-vvv:不断增加你所获取的数据包的信息 -c:只捕获特定数量的数据包,然后停止 icmp:只捕获 ICMP 数据包 -s:定义每个数据包要截取的字节数。使用 -s0 来截取所有数据,除非你故意捕获很少的数据 -S:打印绝对序列号 -e:同时捕获以太网报头 -E:通过提供一个加密密钥来解密 IPSEC 流量 基本用法 所以,根据我所要寻找的流量类型,我使用不同的 tcpdump 选项组合,正如下面的一样: 基本通信 //查看基本信息,不需要其它选项 # tcpdump -nS 基本通信(很详细) //查看流量的详细信息,不解析主机名和端口名 # tcpdump -nnvvS 更深入地查看流量 //增加 -X 选项,但没有抓取数据包更多的数据 # tcpdump -nnvvXS 非常深入的查看数据包 //最后的“s”增加了捕获数据包的数据量,抓取整个数据包的数据 # tcpdump -nnvvXSs 1514 例子 表达式允许你选出各种各样的流量类型,精准地找到你想要的数据。掌握并且创造性地将表达式结合在一起是 tcpdump 真正强大的地方。一共有三类主要的表达式:类型、方向和协议。 类型选项有主机、网络和端口。方向由关键字 dir 表示,可以有以下表达式,src,dst,src or dst和src and dst。这里有一些你应该比较熟悉的: host //根据 IP 地址查询流量(如果你没有使用-n 的话,用域名也可以) # tcpdump host 1.2.3.4 src,dst //查找从源或者目标发出的流量(忽略会话的另一方) # tcpdump src 2.3.4.5 # tcpdump dst 3.4.5.6 net //使用 CIDR 符号来捕获整个网络的流量 # 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 除了单独定义单个的端口来过滤信息,你也可以定义一个范围的端口,大于或者小于某一字节数的数据包。 端口范围 //查找任意范围的端口 # tcpdump portrange 21-23 数据包大小过滤 //只查找大于或小于某一字节数的数据包(单位是字节) # tcpdump less 32 # tcpdump greater 128 你也可以使用以下比较符号,>,<,<=,>= # tcpdump > 32 # tcpdump <= 128 写到文件 使用选项 -w,tcpdump 允许你将捕获的数据保存到文件也便以后分析,然后使用选项 -r 将保存的数据进行分析。这是一个很好的捕获原始数据的方法,然后将数据使用其它工具分析。 以这种方式捕获的数据被保存为 tcpdump 的格式,这在网络分析领域是非常普遍的。这意味着它可以被各种各样的工具读取,包括 Wireshark,Snort 等等。 捕获所有的 80 端口的流量到文件 # tcpdump -s 1514 port 80 -w capture_file 然后在将来的某个时候,你可以将捕获的数据按一下方式读取: 将捕获的数据读回 tcpdump # tcpdump -r capture_file 创意 表达式很好,但 tcpdump 真正神奇的地方是,它可以将这些表达式创造性的结合到一起,以便可以精确地找到你想要的。共有三种方式进行结合,如果你有学过计算机,你对这会非常熟悉: AND and 或者 && OR or 或者 || EXCEPT not 或者 ! 更多例子 # 源 IP 为 10.5.2.3 目标端口为 3389 的 TCP 流量 # tcpdump -nnvvS 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 # 没有 ICMP 流量,目标主机是 192.168.0.2 并且源网络是 172.16 # tcpdump -nvvXSs 1514 dst 192.168.0.2 and src net and not icmp # 从 mars 或者 pluto 发出的并且目标端口不是 SSH 的流量 # tcpdump -vv src mars and not dst port 22 正如你所看到的那样,你可以建立查询来找到任意你想要的流量。关键是,首先你需要精确地知道你想要查找什么,然后建立查询来查找你想要的具体流量。 分组 同样需要记住的是,当你建立一个复杂的查询时,你可能需要使用括号将你的选项括起来。括号可以告诉 tcpdump 忽略其它特殊字符——这里是“()”。这项技术可以使用于组合其它表达式,例如 host,port,net 等等。请看下面的命令行: # 来自主机 10.0.2.4 目标端口是 3389 或 22(不正确的例子) # tcpdump src 10.0.2.4 and (dst port 3389 or 22) 如果你尝试运行这条非常有用的命令,你会得到一个关于括号的错误。有两个方法来更正这个错误,一个是将括号进行转义(在每个括号之前加一个转义符 \ ),另一个是将整个表达式放到单引号里面: # 来自主机 10.0.2.4 目标端口是 3389 或 22(正确的例子) # tcpdump src 10.0.2.4 and \(dst port 3389 or 22\) # tcpdump 'src 10.0.2.4 and (dst port 3389 or 22)' 高级 你也可以根据数据包的某一部分进行过滤,也可以将多个条件组合起来。前者对 SYN 或者 RST 之类的有用,后者则是更高级的网络数据隔离。 ——提示: TCP 标志的构成 # 显示所有的 URGENT(URG)数据包... # tcpdump ‘tcp[13] & 32!=0‘ # 显示所有的 ACKNOWLEDGE(ACK)数据包... # tcpdump ‘tcp[13] & 16!=0‘ # 显示所有的 PUSH(PSH)数据包... # tcpdump ‘tcp[13] & 8!=0‘ # 显示所有的 RESET(RST)数据包... # tcpdump ‘tcp[13] & 4!=0‘ # 显示所有的 SYNCHRONIZE(SYN)数据包... # tcpdump ‘tcp[13] & 2!=0‘ # 显示所有的 FINISH(FIN)数据包... # tcpdump ‘tcp[13] & 1!=0‘ # 显示所有的 SYNCHRONIZE/ACKNOWLEDGE(SYN/ACK)数据包... # tcpdump ‘tcp[13]=18‘ ——注意:只有 PSH,RST,SYN 和 FIN 标志会显示在 tcpdump 的标志段那里。URG 和 ACK 也会被显示,但他们会显示在输出的其它地方,而不是标志段 请记住这些过滤的工作原理。上面的过滤器能够找到各式各样的数据包是因为 tcp[13] 是 TCP 头部的 13 个位移,那个数字代表的是位位置,!=0 意味着那个标志为 1,也就是说打开。 和其它强大的工具一样,它有很多种方式来工作的。下面的例子展示了另一种捕获特定 TCP 标志位的数据包的方法。 # 使用 tcpflags 选项来捕获 TCP 标志... # tcpdump ‘tcp[tcpflags] && tcp-syn != 0‘ 特定的流量 最后,当捕获特定和专门的流量时,例如 IPv6 和 畸形/恶意的数据包,这里有一些快速方法需要记住的。 # IPv6 流量 # tcpdump ip6 # 同时设置 RST 和 SYN 标志位的数据包 # tcpdump ‘tcp[13] = 6’ 原文地址 https://danielmiessler.com/study/tcpdump/