抓包工具使用

背景介绍

对互联网服务而言, 网络问题是非常多的,而且很多问题的外在表现都是网络问题,这就需要我们从网络入手,分析清楚根本原因是什么。而要分析各种各样的网络问题,你必须掌握一些分析手段,这样在出现问题的时候,你就可以高效地找到原因。后文将会介绍工具tcpdump、wireshark等工具的使用。

tcpdump

概述

tcpdump就是一种免费的网络分析工具,尤其其提供了源代码,公开了接口,因此具备很强的可扩展性,对于网络维护和入侵者都是非常有用的工具。tcpdump可以将网络中传送的数据包的“头”完全截获下来提供分析。它支持针对网络层、协议、主机、网络或端口的过滤,并提供and、or、not等逻辑语句来帮助你去掉无用的信息。tcpdump存在于基本的FreeBSD系统中,由于它需要将网络界面设置为混杂模式,普通用户不能正常执行,但具备root权限的用户可以直接执行它来获取网络上的信息。因此系统中存在网络分析工具主要不是对本机安全的威胁,而是对网络上的其他计算机的安全存在威胁。

tcpdump 抓包使用的是 libpacp 这种机制。它的大致原理是:在收发包时,如果该包符合 tcpdump 设置的规则(BPF filter),那么该网络包就会被拷贝一份到 tcpdump 的内核缓冲区,然后以 PACKET_MMAP 的方式将这部分内存映射到 tcpdump 用户空间,解析后就会把这些内容给输出了。在收包的时候,如果网络包已经被网卡丢弃了,那么 tcpdump 是抓不到它的;在发包的时候,如果网络包在协议栈里被丢弃了,比如因为发送缓冲区满而被丢弃,tcpdump 同样抓不到它。我们可以将 tcpdump 的能力范围简单地总结为:网卡以内的问题可以交给 tcpdump 来处理;对于网卡以外(包括网卡上)的问题,tcpdump 可能就捉襟见肘了。这个时候,你需要在对端也使用 tcpdump 来抓包。简单的使用命令tcpdump会抓取能抓到的所有数据,数据量巨大,效率低下,会占用过多机器资源,所有必须进行一定的过滤。如果系统中存在非常多的 TCP 连接,那么这个过滤的过程是非常耗时的,所以在生产环境中要慎用。但是,在出现网络问题时,如果你真的没有什么排查思路,那就想办法使用 tcpdump 来抓一下包吧,也许它的输出会给你带来一些意外的惊喜。

选项

-A  以ASCII编码打印每个报文(不包括链路层的头),这对分析网页来说很方便
-c 数量。 收到count包后退出。
-C 在将原始数据包写入保存文件之前,请检查文件当前是否大于file_size,如果是,则关闭当前保存文件并打开一个新文件。第一个保存文件之后的保存文件将具有使用 -w 标志指定的名称,其后有一个数字,从 1 开始并继续向上。file_size的默认单位是百万字节。通过在值中添加 k/K、m/M 或 g/G 
后缀。
-D 打印系统上可用的网络接口列表以及 tcpdump 可以捕获数据包的网络接口列表。
-e 在每个转储行上打印链接级标题。例如,这可用于打印以太网和 IEEE 802.11 等协议的 MAC 层地址。
-i 监听指定网络接口的数据
-l 使标准输出行缓冲。
-U 使标准输出包缓冲。因此输出在每个包的末尾而不是每行的末尾被写入标准输出;
-n 不要将地址转换为名称。
-nn 不进行端口名称的转换。
-N 不要打印主机名的域名部分。
-r 文件名。 从文件中 读取数据包(使用 -w 选项或其他编写 pcap 或 pcapng 文件的工具创建)。如果文件是“-”, 则使用标准输入。
-s 长度,可以只抓取每个报文的一定长度。0表示包不截断,抓完整的数据包。默认的话 tcpdump 只显示部分数据包,默认68字节。
-t 不要在每个转储行上打印时间戳。
-tt 在每个转储行上打印时间戳,以自 1970 年 1 月 1 日 00:00:00 UTC 以来的秒数以及自该时间以来的几分之一秒。
-ttt 在每个转储行的当前行和上一行之间 打印一个增量(微秒或纳秒分辨率,具体取决于 --time-stamp-precision选项)。
-tttt 在每个转储行上打印时间戳,如小时、分钟、秒和自午夜以来的秒的小数部分,前面是日期。
-w文件 将原始数据包写入文件,而不是解析和打印出来。稍后可以使用 -r 选项打印它们。
-W文件计数 与 -C 选项一起使用,这会将创建的文件数限制为指定的数量,并从头开始覆盖文件,从而创建一个“循环”缓冲区。
-v 输出一个稍微详细的信息,例如在ip包中可以包括ttl和服务类型的信息。
-vv 输出详细的报文信息。
-p 关闭混杂模式。所谓混杂模式,也就是嗅探(Sniffering),就是接收所有经过对应网卡接口的数据包, 把目的地址不是本机地址的网络报文也抓取下来。
-X 以十六进制打印出数据报文内容

更多详见帮助文档

例子

  1. tcpdump -D
    命令列出可以抓包的网络接口:
$ tcpdump -D
1.eth0 [Up, Running]
2.lo [Up, Running, Loopback]
3.any (Pseudo-device that captures on all interfaces) [Up, Running]
4.bluetooth-monitor (Bluetooth Linux Monitor) [none]
5.nflog (Linux netfilter log (NFLOG) interface) [none]
6.nfqueue (Linux netfilter queue (NFQUEUE) interface) [none]
7.usbmon0 (All USB buses) [none]
8.usbmon1 (USB bus number 1)

如上,可以看到我的机器中所有可以抓包的各种接口。其中特殊接口 any 可用于抓取所有活动的网络接口的数据包。

  1. tcpdump -i eth0 -nn -tttt -c5 -l
    命令使用行缓存显示经过eth0接口的5个包,显示时不将ip地址和端口转换为名字,并且打印时间戳
$ tcpdump -i eth0 -nn -tttt -c5 -l
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
2022-02-15 17:37:40.201273 IP 172.19.16.77.22 > 58.34.80.234.2059: Flags [P.], seq 2859535474:2859535686, ack 3774262381, win 251, length 212
2022-02-15 17:37:40.201590 IP 172.19.16.77.22 > 58.34.80.234.2059: Flags [P.], seq 212:408, ack 1, win 251, length 196
2022-02-15 17:37:40.201626 IP 172.19.16.77.22 > 58.34.80.234.2059: Flags [P.], seq 408:588, ack 1, win 251, length 180
2022-02-15 17:37:40.201655 IP 172.19.16.77.22 > 58.34.80.234.2059: Flags [P.], seq 588:768, ack 1, win 251, length 180
2022-02-15 17:37:40.201683 IP 172.19.16.77.22 > 58.34.80.234.2059: Flags [P.], seq 768:948, ack 1, win 251, length 180
5 packets captured
8 packets received by filter
0 packets dropped by kernel
  1. tcpdump -i eth0 -w tmp.pcap -C 10M -W 10
    命令将从eth0接口抓取的包,保存到tmp.pcap,文件大于10M时,保存到下一个文件,文件名后缀加1,保存文件达到10个时,下一个文件将从最开始的文件开始覆盖文件。
  2. tcpdump -i eth0 -nn -tttt -c5 -r tmp.pcap
    以3例的方式从tmp.pcap文件中读取并显示数据。

报文格式

以tcp为例,格式如下
时间戳 src > dst Flags:[tcpflags], seq data-seqno, ack ackno, win window, urg urgent, options [opts], length len

2022-02-15 19:16:36.160191 IP 127.0.0.1.56050 > 127.0.0.1.40000: Flags [S], seq 225110315, win 43690, options [mss 65495,sackOK,TS val 3737754299 ecr 0,nop,wscale 7], length 0
2022-02-15 19:16:36.160201 IP 127.0.0.1.40000 > 127.0.0.1.56050: Flags [S.], seq 1065875303, ack 225110316, win 43690, options [mss 65495,sackOK,TS val 3737754299 ecr 3737754299,nop,wscale 7], length 0
2022-02-15 19:16:36.160210 IP 127.0.0.1.56050 > 127.0.0.1.40000: Flags [.], ack 1, win 342, options [nop,nop,TS val 3737754299 ecr 3737754299], length 0
2022-02-15 19:17:26.994224 IP 127.0.0.1.56050 > 127.0.0.1.40000: Flags [F.], seq 1, ack 1, win 342, options [nop,nop,TS val 3737805132 ecr 3737754299], length 0
2022-02-15 19:17:26.994337 IP 127.0.0.1.40000 > 127.0.0.1.56050: Flags [F.], seq 1, ack 2, win 342, options [nop,nop,TS val 3737805132 ecr 3737805132], length 0
2022-02-15 19:17:26.994349 IP 127.0.0.1.56050 > 127.0.0.1.40000: Flags [.], ack 2, win 342, options [nop,nop,TS val 3737805132 ecr 3737805132], length 0

  • src和dst:分别时源和目标的 ip地址和端口
  • Tcpflags:是 E (ECN-Echo)、U (URG)、.(ACK)、P (PUSH)、R (RST)、S(SYN)、F (FIN) 的某种组合。,如果没有设置标志,则为“无”。
  • Data-seqno:描述了这个数据包中的数据所覆盖的序列空间部分。
  • Ackno:是此连接上另一个方向预期的下一个数据的序列号。
  • Window:是此连接上另一个方向可用的接收缓冲区空间的字节数。
  • Urg:表示数据包中有“紧急”数据。
  • mss:通信双方协调最大报文段长度,一般为(MTU-40)字节,从而避免发生IP分片。
  • sackOK:选择性确认,使tcp模块只重新发送丢失的tcp报文段,不用发送所有未被确认的报文段
  • wscale:窗口扩大因子,为了解决接收窗口太小问题。
  • length:数据包有效载荷字节长度
    更多详见帮助文档

过滤表达式

类型

主要包括host,net,port。如果没有指定类型,缺省的类型是host.

  • 过滤主机 210.27.48.2
tcpdump host 210.27.48.2
  • 过滤 202.0.0.0/24 网段,
tcpdump net 202.0.0.0/24
  • 过滤通过端口23的报文。
tcpdump port 23

方向

主要包括src(来源) , dst(目的),dst or src, dst and src,这些关键字指明了传输的方向。如果没有指明方向关键字,则缺省是src or dst关键字。

  • 过滤ip包中源地址是 210.27.48.2 的报文
tcpdump src 210.27.48.2
  • 过滤目的网段是202.1.2.0/24的报文
tcpdump dst net 202.1.2.0/24

协议

主要包括ip,ip6,arp,rarp,icmp,tcp,udp等。如果没有指定任何协议,则tcpdump将会监听所有协议的信息包。

  • 过滤icmp相关报文
tcpdump icmp

逻辑运算

取非运算是 'not ' '! ',与运算是'and','&&';或运算 是'or','││';

  • 过滤eth0接口的来自ip包含127.0.0.1 且非1.2.3.4 tcp端口包含4000或2000的报文,
tcpdump -i eth0 'tcp and src 127.0.0.1 and (port 4000 || port 2000) and not 1.2.3.4'

proto [ expr : size] 语法

  • Proto 即protocol的缩写,它表示这里要指定的是某种协议名称,如 ether,fddi,tr,wlan,ppp,slip,link,ip,ip6,arp,rarp,icmp,tcp,udp等。
  • expr 用来指定数据报字节单位的偏移量,该偏移量相对于指定的协议层,默认的起始位置是0;
  • size 表示从偏移量的位置开始提取多少个字节,可以设置为1、2、4,默认为1字节。

如果只设置了expr,而没有设置size,则默认提取1个字节。比如ip[2:2],就表示提取出第3、4个字节;而ip[0]则表示提取ip协议头的第一个字节。在我们提取了特定内容之后,我们就需要设置我们的过滤条件了,我们可用的“比较操作符”包括:>,<,>=,<=,=,!=,总共有6个。而对于TCP协议的标志字段域,则可以细分为tcp-fin, tcp-syn, tcp-rst, tcp-push, tcp-ack, tcp-urg。

 0                            15                              31
 -----------------------------------------------------------------
 |          source port          |       destination port        |
 -----------------------------------------------------------------
 |                        sequence number                        |
 -----------------------------------------------------------------
 |                     acknowledgment number                     |
 -----------------------------------------------------------------
 |  HL   | rsvd  |C|E|U|A|P|R|S|F|        window size            |
 -----------------------------------------------------------------
 |         TCP checksum          |       urgent pointer          |
 -----------------------------------------------------------------
想截取每个TCP会话的起始和结束报文(SYN 和 FIN 报文)
tcpdump -nn -tttt 'tcp[13] & 3 != 0'
tcpdump -nn -tttt 'tcp[tcpflags] & 3 != 0'
tcpdump -nn -tttt 'tcp[tcpflags]&tcp-syn!=0 or tcp[tcpflags]&tcp-fin!=0'

2022-02-15 19:16:36.160191 IP 127.0.0.1.56050 > 127.0.0.1.40000: Flags [S], seq 225110315, win 43690, options [mss 65495,sackOK,TS val 3737754299 ecr 0,nop,wscale 7], length 0
2022-02-15 19:16:36.160201 IP 127.0.0.1.40000 > 127.0.0.1.56050: Flags [S.], seq 1065875303, ack 225110316, win 43690, options [mss 65495,sackOK,TS val 3737754299 ecr 3737754299,nop,wscale 7], length 0
2022-02-15 19:17:26.994224 IP 127.0.0.1.56050 > 127.0.0.1.40000: Flags [F.], seq 1, ack 1, win 342, options [nop,nop,TS val 3737805132 ecr 3737754299], length 0
2022-02-15 19:17:26.994337 IP 127.0.0.1.40000 > 127.0.0.1.56050: Flags [F.], seq 1, ack 2, win 342, options [nop,nop,TS val 3737805132 ecr 3737805132], length 0

其他

其他重要的关键字如下:gateway, broadcast, less, greater, portrang

过滤端口范围21-40
tcpdump portrang 21-40
通过报文大小过滤报文,单位是字节
tcpdump less 40
tcpdump < 40
tcpdump greater 40
tcpdump >=  40

这些关键字可以组合起来构成强大的组合条件来满足人们的需要,你也可以使用括号来创建更为复杂的过滤规则,但在 shell 中请用引号包含你的过滤规则以防止被识别为 shell 表达式。
更多详细语法

wireshark

wireshark是一个网络封包分析软件,功能比tcpdump丰富点,自带图形界面。它可以自己抓取网络封包,也可以使用其他工具抓取保存的封包文件,进行分析和统计,并尽可能的显示出最为详细网络封包资料。wireshark使用winpcap作为接口,直接与网卡进行数据报文交换

下载

官网下载一个安装包,安装需要管理员权限。

界面详情

wireshark界面
  1. 菜单栏: 更多高级的界面设置、显示设置、协议设置、抓包设置
  2. 显示过滤器: 用于捕获数据包后,从捕获的数据包列表中隐藏一些数据包。
  3. 封包文件历史记录
  4. 捕获过滤器: 用于抓包前的设置,用于减少原始数据包捕获的大小,并且在捕获期间无法修改。
  5. 网络接口列表(同tcpdump -D),捕获过滤器后面带有接口筛选器
  6. 用户指南、wiki地址、使用中的问题和答案等网站快捷链接

捕获过滤器表达式

同tcpdump过滤表达式,详见上面 1.2 tcpdump过滤表达式 部分
更多详细语法

显示过滤器表达式

协议

主要包括ip,ip6,arp,rarp,icmp,tcp,udp, http等。

  • 过滤ip包中源地址是 210.27.48.2 的报文
ip.addr == 10.6.1.50
  • 过滤某个网段
ip.addr == 129.111.0.0/16
  • 过滤通过端口23的报文
tcp.port eq 23
  • 过滤某个时间段的报文
frame.time < "2022-01-01"
  • 过滤tcp syn数据包
tcp.flags & 0x02
tcp.flags.syn == 1

更多详细语法

运算符

  • 逻辑运算: 取非运算是 'not ' '! ',与运算是'and','&&';或运算 是'or','││';

  • 关系运算:等于是 'eq' '==',不等是 'ne' '!=',大于是 'gt' '>',大于等于是 'ge' '>=',小于是 'lt' '<',小于等于是 'le' '<='。

  • 其他:'contains' 协议、字段或切片包含一个值;'matches'协议或文本字段匹配perl兼容的正则表达式;in 某个字段或值处于在某个集合中;string(将某个值转换成字符串)、lower(转换成小写)、upper(转换成大写)

  • 过滤包含地址10.6.1.50和端口80或443或8080的数据包

ip.addr == 10.6.1.50 and tcp.port in {80, 443, 8080}
  • 过滤包含地址端口或443或 4430-4434之间的数据包
tcp.port == 443 || (tcp.port >= 4430 && tcp.port <= 4434)
  • 目的地址符合正则表达式
string(ip.dst) matches r"^172\.(1[6-9]|2[0-9]|3[0-1])\.[0-9]{1,3}\.255"
  • http 来自apache
lower(http.server) contains "apache"

保存捕获的数据

可以使用File → Save或File → Save As...菜单项来保存捕获的数据包。您可以选择要保存的数据包以及要使用的文件格式。

常见协议分析

ARP协议

如何产生一个arp协议
nmap -sn 192.168.1.1

arp协议教程

ICMP协议

如何产生一个ICMP协议
ping -c1 192.168.1.1

ICMP协议教程

TCP协议

如何产生一个简单完整的tcp协议

一个终端执行 nc -l 192.168.1.1 40000
一个终端执行 nc 192.168.1.1 40000
通信完都直接关闭就行

TCP协议教程

HTTP协议

如何产生一个简单完整的tcp协议
curl -I www.baidu.com

HTTP协议教程

简单案例分析

简单案例教程

远程抓包

对于没有GUI界面或者没有安装wireshark、tcpdump的远程主机,wireshark为我们提供了远程抓包的功能。远程主机只需要编译运行rpcapd就行。

远程linux主机安装rpcapd及启动

  • 源码安装rpcapd
yum install gcc flex byacc -y
git clone https://github.com/frgtn/rpcapd-linux.git rpcapd
cd rpcapd/libpcap
./configure && make -j4
cd ../ && make -j4
如果提示:
/usr/bin/ld: cannot find -lcrypt
/usr/bin/ld: cannot find -lpthread
/usr/bin/ld: cannot find –lc

解决方法: vi Makefile
CFLAGS  = -pthread -D_DEBUG -g -Wall -DHAVE_REMOTE -DHAVE_SNPRINTF –static
修改为:(去掉–static)
CFLAGS  = -pthread -D_DEBUG -g -Wall -DHAVE_REMOTE -DHAVE_SNPRINTF
  • 启动rpcapd
./rpcapd -h
USAGE:
 rpcapd [-b <address>] [-p <port>] [-6] [-l <host_list>] [-a <host,port>]
        [-n] [-v] [-d] [-s <file>] [-f <file>]
  -b <address>: the address to bind to (either numeric or literal).
      Default: it binds to all local IPv4 addresses
  -p <port>: the port to bind to. Default: it binds to port 2002
  -t <data port>: the port to transfer data.
  -4: use only IPv4 (default both IPv4 and IPv6 waiting sockets are used)
  -l <host_list>: a file that keeps the list of the hosts which are allowed
      to connect to this server (if more than one, list them one per line).
      We suggest to use literal names (instead of numeric ones) in order to
      avoid problems with different address families
  -n: permit NULL authentication (usually used with '-l')
  -a <host,port>: run in active mode when connecting to 'host' on port 'port'
      In case 'port' is omitted, the default port (2003) is used
  -v: run in active mode only (default: if '-a' is specified, it accepts
      passive connections as well
  -d: run in daemon mode (UNIX only) or as a service (Win32 only)
      Warning (Win32): this switch is provided automatically when the service
      is started from the control panel
  -s <file>: save the current configuration to file
  -f <file>: load the current configuration from file; all the switches
      specified from the command line are ignored
  -h: print this help screen

启动
./rpcapd -n

wireshark增加远程接口

  • 方法一:本地dos运行命令
wireshark -k -i rpcapd://<capture_box_ip>:<rpcapd_port>/<interface_to_capture>
  • 方法二:点击'Capture' → 点击'Manage Interfaces' → 选择'远程接口' → 点击'添加' → 填入远程host和端口(默认2002) → 点击'ok' → 接口中会出现远程接口进行抓包,如下图:


    添加远程接口

参考资料

tcpdump网站
tcpdump帮助文档
wireshark wiki
wireshark user's guide
学神网络安全教学视频

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,734评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,931评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,133评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,532评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,585评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,462评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,262评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,153评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,587评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,792评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,919评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,635评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,237评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,855评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,983评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,048评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,864评论 2 354

推荐阅读更多精彩内容