tcpdump

tcpdump man

tcpdump 须在管理员权限下运行。

#tcpdump
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
  • 输出结果表明 tcpdump 的监听网卡为 ens33
  • 默认截断大小为 262144 字节(随版本而改变),超过该数字报文会被截断。

使用 ifconfig 查看其他网卡:

#ifconfig
ens33     Link encap:Ethernet  HWaddr 00:0c:29:48:09:a9  
          inet addr:192.168.248.128  Bcast:192.168.248.255  Mask:255.255.255.0
          inet6 addr: fe80::555a:9e00:3f14:e7f/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:12058 errors:0 dropped:0 overruns:0 frame:0
          TX packets:4911 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:9115911 (9.1 MB)  TX bytes:577567 (577.5 KB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:1110 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1110 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:1022006 (1.0 MB)  TX bytes:1022006 (1.0 MB)

-i 指定网卡

上面默认监听网卡是 ens33 ,我们也可以指定为 lo

 tcpdump -i lo
listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes

-i any 可以监听所有网卡。


-nn 直接显示IP和端口号

#tcpdump -i lo
listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
01:12:54.640796 IP localhost.44438 > localhost.12345: Flags [S], seq 1028792545, win 65495, options [mss 65495,sackOK,TS val 1381449987 ecr 0,nop,wscale 7], length 0
01:12:54.640834 IP localhost.12345 > localhost.44438: Flags [S.], seq 3925511357, ack 1028792546, win 65483, options [mss 65495,sackOK,TS val 1381449987 ecr 1381449987,nop,wscale 7], length 0
01:12:54.640870 IP localhost.44438 > localhost.12345: Flags [.], ack 1, win 512, options [nop,nop,TS val 1381449987 ecr 1381449987], length 0

监听环回网卡时,我们运行自己编写的简易 TCP 服务器端和客户端的回射程序,结果输出以上三次握手内容。其中主机地址为 localhost ,由于 server 和 client 都在一台主机,所以都为 localhost 。如果服务器的端口为著名端口(如 ssh 为 22 号端口),那么 22 也会显示为 ssh。若想直接显示 IP 和端口号,则使用 -nn 命令:

#tcpdump -i lo -nn
01:14:54.615811 IP 127.0.0.1.44438 > 127.0.0.1.12345: Flags [P.], seq 1028792546:1028792548, ack 3925511358, win 512, options [nop,nop,TS val 1381569983 ecr 1381449987], length 2

-n 不将IP转换为域名

不讲 IP 转为域名,则可以省去 DNS 查询,输出速度会快很多。


过滤主机

  • 抓取所有经过 eth1,目的或源地址是 192.168.1.1 的网络数据
#tcpdump -i eth1 host 192.168.1.1
  • 指定源地址
#tcpdump -i eth1 src host 192.168.1.1
  • 指定目的地址
#tcpdump -i eth1 dst host 192.168.1.1
  • 也可直接指定域名:
#tcpdump -i eth1 dest host "baidu.com"

过滤端口

  • 抓取所有经过 eth1,目的或源端口是 25 的网络数据
#tcpdump -i eth1 port 25
  • 指定源端口
#tcpdump -i eth1 src port 25
  • 指定目的端口
#tcpdump -i eth1 dst port 25
  • 指定端口范围:portrange

    # tcpdump -i lo portrange 10000-20000
    
  • 对于著名端口,可直接用应用层协议替代,相当于宏:

    # tcpdump port http 
    

网段过滤

#tcpdump -i eth1 net 192.168
#tcpdump -i eth1 src net 192.168
#tcpdump -i eth1 dst net 192.168.0.0/16  

协议过滤

#tcpdump arp  
#tcpdump ip   
#tcpdump tcp  

不能直接过滤协议,如下

#tcpdump http  

而应该

#tcpdump port http

常用表达式

非 : ! 或 not 
且 : && 或 and  
或 : || 或 or
#tcpdump -i lo -nn tcp && dst port 12345 && src host 127.0.0.1
#tcpdump -i lo -nn tcp and dst port 12345 and src host 127.0.0.1

有时条件比较复杂的需要用括号:

#tcpdump -i eth1 '((tcp) and (! port 80) and ((dst host 192.168.1.254) or (dst host 192.168.1.200)))'
抓取所有经过eth1,目的地址是192.168.1.254或192.168.1.200,并且端口不是80的TCP数据

如果使用括号,则整个表达式需要用 ''"" 包住。


包头过滤

proto[x:y]          : 过滤从x字节开始的y字节数。比如ip[2:2]过滤出3、4字节(从第0字节开始)
proto[x:y] & z = 0  : proto[x:y]和z的与操作为0
proto[x:y] & z !=0  : proto[x:y]和z的与操作不为0

IP报头格式:

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1   \bit
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
0   |Version|  IHL  |Type of Service|          Total Length         |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4   |         Identification        |Flags|      Fragment Offset    |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
12  |  Time to Live |    Protocol   |         Header Checksum       |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16  |                       Source Address                          |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
20  |                    Destination Address                        |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24  |                    Options                    |    Padding    | <-- optional
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
28  |                            DATA ...                           |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
\byte

TCP报头格式:

   0                   1                   2                   3
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1  \bit
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
0  |          Source Port          |       Destination Port        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4  |                        Sequence Number                        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
8  |                    Acknowledgment Number                      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |  Data |       |C|E|U|A|P|R|S|F|                               |
12 | Offset|  Res. |W|C|R|C|S|S|Y|I|            Window             |
   |       |       |R|E|G|K|H|T|N|N|                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16 |           Checksum            |         Urgent Pointer        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
20 |                    Options                    |    Padding    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24 |                             data                              |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
\byte
# tcpdump -i lo "tcp[2:2]=12345"
只显示目的端口号为12345的报文

TCP标记定义在TCP头的第 13 个字节:

# tcpdump -i lo "src port 12345 && tcp[13]&1 = 1"
只显示目的端口号为12345的FIN报文

TCP标记宏可以替代数值:

tcpflags , tcp-fin , tcp-syn , tcp-rst , tcp-push , tcp-push , tcp-ack , tcp-urg

# tcpdump -i lo "dst port 12345 && tcp[tcpflags]&tcp-fin=tcp-fin"

-w 输出到文件、-r 读取文件

# tcpdump tcp -w test.cap

把信息输出到 test.cap 文件。将文件保存为 cappcap 类型就能方便地使用 wireshark 打开并分析:

# tcpdump tcp -r test.cap

读取 test.cap 文件并打印在终端,同时也可以使用过滤规则:

# tcpdump tcp -r test.cap port 12345

输出时间

  • -t:在每行的输出中不输出时间
  • -tt:在每行的输出中会输出时间戳
  • -ttt:输出每两行打印的时间间隔(以毫秒为单位)
  • -tttt:在每行打印的时间戳之前添加日期的打印
# tcpdump -t dst  "baidu.com"
IP 192.168.248.128 > 39.156.66.10: ICMP echo request, id 11930, seq 1650, length 64

# tcpdump -tt dst  "baidu.com"
1680352032.093467 IP 192.168.248.128 > 39.156.66.10: ICMP echo request, id 11930, seq 1662, length 64

# tcpdump -ttt dst  "baidu.com"
 00:00:00.000000 IP 192.168.248.128 > 39.156.66.10: ICMP echo request, id 11930, seq 1672, length 64
 00:00:01.002438 IP 192.168.248.128 > 39.156.66.10: ICMP echo request, id 11930, seq 1673, length 64

# tcpdump -tttt dst  "baidu.com"
2023-04-01 05:27:30.131073 IP 192.168.248.128 > 39.156.66.10: ICMP echo request, id 11930, seq 1680, length 64

-v 展示详细信息

-v:产生详细的输出。比如包的TTL,id标识,数据包长度,以及IP包的一些选项:

root@ubuntu:/home/butcher/Documents# tcpdump -v dst  "baidu.com"
tcpdump: listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
05:36:46.543701 IP (tos 0x0, ttl 64, id 44013, offset 0, flags [DF], proto ICMP (1), length 84)
    192.168.248.128 > 39.156.66.10: ICMP echo request, id 12115, seq 7, length 64

-c 指定接收报文个数

# tcpdump -v -c 3 
05:46:32.275269 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 192.168.248.2 tell 192.168.248.1, length 46
05:46:32.276545 IP (tos 0x0, ttl 64, id 50690, offset 0, flags [DF], proto UDP (17), length 72)
    192.168.248.128.34566 > 192.168.248.2.domain: 39118+ PTR? 2.248.168.192.in-addr.arpa. (44)
05:46:32.280758 IP (tos 0x0, ttl 128, id 35219, offset 0, flags [none], proto UDP (17), length 127)
    192.168.248.2.domain > 192.168.248.128.34566: 39118 NXDomain 0/1/0 (99)
3 packets captured

抓满指定数量的报文后自动停止。

-C -W 分文件写入

#tcpdump -C 1 -W 4 -w test

-C 和 -w 配套使用,后者将抓包情况写入文件,前者指定每个文件的最大大小,单位为 1MB(小文件利于分析)。

  • -C 1 :指定单个文件最大为 1MB
  • -W :指定最多写 4 个文件
  • -w :写入文件

每个文件会依次添加后缀:test1、test2、test3、test4 。注意,如果写满这 4 个文件后,数据还在持续,那么会重新覆盖这 4 个文件并继续写入,而不会新建文件。


-Q 指定方向

  • -Q in :只显示收到的数据
  • -Q out :只显示发出的数据
# tcpdump -Q in
06:04:34.157713 IP 192.168.248.1.50277  > 239.255.255.250.1900: UDP, length 175
06:04:34.163603 IP 192.168.248.2.domain > 192.168.248.128.34566: 27092 NXDomain 0/1/0 (103)
06:04:35.003369 IP 180.101.49.186.https > 192.168.248.128.33644: Flags [.], ack 769671203, win 64240, length 0

-s 指定截取大小

-s 指定每个包捕获的长度、单位是 byte,而不是默认的 262144 字节;如果超过了设定的大小限制,包就会被截断,并在打印行出现[|proto]这种标识,这个proto就是被截断的报文的协议名字。但是抓取越长,包的处理时间越长,并且会减少 tcpdump 可缓存的数据包的数量,从而会导致数据包的丢失,所以在能抓取我们想要的包的前提下,抓取长度越小越好,一般只抓报头 ,抓 80 个字节一般就能包含 TCP 层、IP 层、链路层。

-s 0 使用默认长度 262144。

-e 显示链路层信息

# tcpdump  -e 
06:49:36.315000 00:0c:29:48:09:a9 (oui Unknown) > 00:50:56:fb:6d:e0 (oui Unknown), ethertype IPv4 (0x0800), length 54: 192.168.248.128.33644 > 180.101.49.186.https: Flags [.], ack 565954419, win 65535, length 0

-F 指定过滤过滤表达式文件

有些过滤表达式经常用,但又很冗长,每次输入都很麻烦。所以可以保存为文件,每次 tcpdump 时指定该文件为过滤规则:

#tcpdump -F filter_file

该命令行中的其他命令会被忽略。


less,greater 指定大小

#tcpdump less 100

-X 打印数据内容
-X 除了打印每个数据包的头之外,还可以用十六进制和ASCII打印每个数据包的数据(不包括链路级头,-XX 可包含):

文章作者: 极简
本文链接:
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 后端技术分享
工具
喜欢就支持一下吧