tcpdump

TL;DR

# List available network interfaces:
$ tcpdump -D

# Capture the traffic of a specific interface:
$ tcpdump -i eth0

# Capture all TCP traffic showing contents (ASCII) in console:
$ tcpdump -A tcp

# Capture the traffic from or to a host:
$ tcpdump host www.example.com

# Capture the traffic from a specific interface, source, destination and destination port:
$ tcpdump -i eth0 src 192.168.1.1 and dst 192.168.1.2 and dst port 80

# Capture the traffic of a network:
$ tcpdump net 192.168.1.0/24

# Capture all traffic except traffic over port 22 and save to a dump file:
$ tcpdump -w dumpfile.pcap port not 22

# Read from a given dump file:
$ tcpdump -r dumpfile.pcap

$ sudo tcpdump -i any -n -p tcp port 22
$ sudo tcpdump -i vmbr0 port 22

Usage

更多详细例子

# 抓取 DNS 包
$ tcpdump -i en0 udp dst port 53

# 抓取 TCP 并且是 80 端口,目标 IP 是 192.168.1.254 或者 192.168.1.200
$ tcpdump -i en0 '((tcp) and (port 80)and ((dst host 192.168.1.254) or (dst host 192.168.1.200)))'

# 抓取 ICMP 包并且目标 MAC 地址是 00:01:02:03:04:05
$ tcpdump -i en0 '((icmp) and ((ether dst host00:01:02:03:04:05)))'

# 抓取 TCP 包并且网络段是 192.168 的,目标 IP 不是 192.168.1.200
$ tcpdump -i en0 '((tcp) and ((dst net192.168) and (not dst host 192.168.1.200)))'

# 只抓取 SYN 包
$ tcpdump -i en0 'tcp[tcpflags] = tcp-syn'

# 抓取 SYN 不等于 0 且 ACK 不等于 0 的包
$ tcpdump -i en0 'tcp[tcpflags] & tcp-syn != 0 andtcp[tcpflags] & tcp-ack != 0'

# 抓取 SMTP 包
$ tcpdump -i en0 '((port 25) and (tcp[(tcp[12]>>2):4] = 0x4d41494c))'

# 抓取 HTTP GET 包,GET 的十六进制是 47455420
$ tcpdump -i en0 'tcp[(tcp[12]>>2):4] = 0x47455420'

# 抓取 SSH 返回包,SSH-的十六进制是 0x5353482D
$ tcpdump -i en0 'tcp[(tcp[12]>>2):4] = 0x5353482D'

# 抓取旧版本的 SSH 返回包,SSH-1.99
$ tcpdump -i en0 '(tcp[(tcp[12]>>2):4] = 0x5353482D) and(tcp[((tcp[12]>>2)+4):2]= 0x312E)'

# 抓取 8000 端口的 GET 包,保存文件
$ tcpdump -i en0 '((port 8000) and (tcp[(tcp[12]>>2):4]=0x47455420))' -nnAl -w /tmp/GET.log

# 监听UDP上所有的DNS网络流量
$ tcpdump -i any -n -p udp port 53
# 取得关于一个IP地址的所有访问量
$ tcpdump host 8.8.8.8
# 把所有网络访问写入PCAP文件
$ tcpdump -i any -w output.txt
# 从PCAP文件读取所有网络访问
$ tcpdump -r  output.txt

# 监控80端口的数据包
$ tcpdump tcp port 80 -s 0 -w http.pcap

$ tcpdump -i ens33 -nn ip host 172.16.0.66 and host 172.16.0.67

$ tcpdump -i eth0 -s 1000 -w /tmp/tcpdump.cap

$ tcpdump -s 1024 -l -A port 8140 -i eth0 -vvvv

# 服务器抓包
$ tcpdump -Xnlp port 22

# net.ipv6.conf.wlp3s0.disable_ipv6 = 1
$ tcpdump -i wlp3s0 -Xnlp port 22

# 抓取HTTPS流量
$ tcpdump -s 0 -i eth0 port 443 and host 10.235.173.30 -w https.pcap

# 抓取mysql流量
$ tcpdump -s 65535 -x -nn -q -tttt -i any -c 1024 port 3306 > mysql-tcp.lo

# 监听vmbr0接口的ARP协议通信
$ sudo tcpdump -i vmbr0 arp

# 监听en0接口的所有通信。
$ sudo tcpdump -i enO

# 用ASCII显示en0接口的通信内容。
$ sudo tcpdump -A -i enO

# 显示enp2s0f0接口的22端口的通信。
$ sudo tcpdump -i enp2s0f0 'port 22'

# 显示eth1接口来自192.168.1.200的通信。
$ sudo tcpdump -i ethl src 192.168.1.200

# 显示eth1接口80端口、目的地为192.168.1.101的通信。
$ sudo tcpdump -i ethl dst 192.168.1.101 and port 80

# 将lo0接口的通信存入文件record.pcap
$ sudo tcpdump -w record.pcap -i lo0

# IP过滤
$ tcpdump -i en0 host 192.168.1.1
$ tcpdump -i en0 src host 192.168.1.1
$ tcpdump -i en0 dst host 192.168.1.1

# 端口过滤
$ tcpdump -i en0 port 25
$ tcpdump -i en0 src port 25
$ tcpdump -i en0 dst port 25

# 网络过滤
$ tcpdump -i en0 net 192.168
$ tcpdump -i en0 src net 192.168
$ tcpdump -i en0 dst net 192.168

# 协议过滤
$ tcpdump -i en0 arp
$ tcpdump -i en0 iptcpdump -i en0 tcp
$ tcpdump -i en0 udp
$ tcpdump -i en0 icmp

相关概念

参数解释

tcpdump [-AdDefLnNOpqRStuUvxX] [-c count] [-C fle_size] [-F fle] [-i interface] 
  [-m module][-M secret] [-r fle] [-s snaplen] [-T type] [-w fle] [-W flecount] 
  [-E spi@ipaddr algo:secret,...] [-y datalinktype] [-Z user] [expression]

tcpdump [-adeflnNOpqStvx] [-c 数量] [-F 文件名] [-i 网络接口] [-r 文件名] [-s snaplen] [-T 类型] [-w 文件名] [表达式]
TIMESTAMP SRC_IP:PORT> DEST_IP:PORT: NAME1 VALUE1, NAME2 VALUE2,...

Flags: 分组所具有的标志如下 - S代表SYN(发起连接) - F代表FIN(终止连接) - P代表PUSH(推送数据) - R代表RST(重置连接) - 点号.表示没有对应的标志

  • seq: 指的是分组的序列号。这个序列号会回显(echoed)在ACK中来确认接收到的分组。
  • ack: 作用是确认已接收到某个分组。这个值是上一个分组的序列号。
  • win: 指明了目的端的缓冲区大小。
  • options: 指明了分组中定义的TCP选项

常用参数如下:

  • -c: 指定包个数。
  • -n: IP地址,端口用数字方式显示。
  • port: 指定端口
  • -i: 指定需要抓包的网卡。
  • -nnn: 不要将ip、port转化为对应的服务名称。
  • -s: 指定抓包大小;0表示不限制大小,以防止比较大的数据包被截断。
  • -c: 指定抓包的个数。
  • -w: 保存抓包内容到指定文件
  • -i: 指定网络接口,如eth0、lo等(使用ifconfig或tcpdump-D查看网络接口)。
  • -c: 抓取指定数量的包后停止,如关注TCP的建链过程。
  • -C file_size: 将数据包写入到文件中,一旦文件大小超过file_size(单位兆字节,即1000000 bytes)则新建文件。
  • -F file: 以file中的内容作为过滤表达式。
  • -X: 十六进制显示包内容。
  • -l: 输出行缓冲(主要控制输出的格式化——遇到换行即输出,便于查看)。
  • -n: 数字形式显示网络地址,避免DNS查询。
  • -s snaplen: 截断指定的长度显示。
  • -t: 不在每一行打印时间戳。
  • -t: 在每一行中输出至1970年的秒数(-ttt: 年月日,时分秒)。
  • -X: 以十六进制和ASCII码形式显示每个报文(去掉链路层报头,-XX则包含链路层报文头)。
  • -w file: 以原始网络包写入文件而不是打印出来。该文件可以使用wireshark来分析或使用-r读取。
  • -s 0:抓取全部数据包,抓取数据包时默认抓取长度为68字节。加上-S 0后可以抓到完整的数据包。
  • -w t1.pcap:表示将抓到的内容存入t1.pcap这个文件中。
  • -v:表示在命令执行过程中显示当前抓到的包的数量。

过滤器

类型关键字: host、port、net。

  • tcpdump host sundown: 截获来自和发往主机sundown的网络包,可直接写ip地址。
  • tcpdump host helios and \(hot or ace\):截获主机helios和主机hot或ace间的网络包(注意使用转义符或使用引号)。
  • tcpdump ip host ace and not helios: 截获除helios外,所有与主机ace通信的IP网络包。
  • tcpdump net 192.168.1.0/24: 截获来自和发往192.168.1.0/24的所有主机的网络包。
  • 指定端口(数字端口或知名端口):
    • tcpdump port 80
    • tcpdump port not ssh
    • tcpdump port snmp
  • 指定网络: tcpdump net ucb-ether,表示打印本机与Berkeley网络主机的网络包。
  • 指定接口: tcpdump-i eth0

传输方向的关键字: src、dst。

源地址和目的地址,即来自和发往两个方向。由逻辑表达式还可构成dst or src、dst and src。

  • tcpdump src host sundown: 截获来自主机sundown的网络包。
  • tcpdump dst host sundown: 截获发往主机sundown的网络包。
  • tcpdump-i ppp0 dst net 192.168.43.132: 跟踪网卡接口ppp0,目标主机192.168.43.132。

协议的关键字: ip、arp、rarp、tcp、udp、ppp等类型。

  • tcpdump 'tcp port 80 and (((ip[2:2]-((ip[0]&0xf)<<2))-((tcp[12]&0xf0)>>2))!=0)':打印端口80所有IPv4 HTTP的网络包。
  • tcpdump 'gateway snup and ip[2:2]>576': 打印由网关snup发送的,大于576字节的网络包。
  • tcpdump 'icmp[icmptype]!=icmp-echo and icmp[icmptype]!=icmp-echoreply': 打印所有非ping的ICMP包。
  • tcpdump -i lo udp: 跟踪本机回环接口udp。
  • tcpdump dst net 192.168.43.132 and port 162 and not src 192.168.43.145 and not src 192.168.43.146: 跟踪目的主机为192.168.43.132,端口号为162和1234。
  • tcpdump udp and port 161: 跟踪udp和端口161。

逻辑运算关键字。

  • 与: and、&&。
  • 或: or、||。
  • 非: not、!。

  • tcpdump dst host 192.168.43.132 and (port 162 or port 161): 截获发往主机192.168.43.132的161或162端口的网络包。

其他重要的关键字:portrange、gateway、broadcast、less、greater等。

  • tcpdump -n dst portrange 161-1611: 截获目标端口在161和1611之间的所有报文。
  • tcpdump greater 20: 截获所有报文长度大于20的报文。