tcpdump - dump traffic on a network
tcpdump是一个用于截取网络分组,并输出分组内容的工具。凭借强大的功能和灵活的截取策略,使其成为类UNIX系统下用于网络分析和问题排查的首选工具
tcpdump 支持针对网络层、协议、主机、网络或端口的过滤,并提供and、or、not等逻辑语句来帮助你去掉无用的信息
-c:指定要抓取的包数量。
-i interface:指定tcpdump需要监听的接口。默认会抓取第一个网络接口
-n:对地址以数字方式显式,否则显式为主机名,也就是说-n选项不做主机名解析。
-nn:除了-n的作用外,还把端口显示为数值,否则显示端口服务名。
-P:指定要抓取的包是流入还是流出的包。可以给定的值为"in"、"out"和"inout",默认为昌尘"inout"。
-s len:设置tcpdump的数据包抓取长度为渗宏len,如果不设置默认将会是65535字节。对于要抓取的数据包较大时,长度设置不够可能会产生包截断,若出现包截断,
:输出行中会出现"[|proto]"的标志(proto实际会显示为协议名)。但是抓取len越长,包的处理时间越长,并且会减少tcpdump可缓存的数据包的数量,
:从而会导致数据包的丢失,所以在能抓取我们想要的包的前提下,抓取长度越小越好。
-e:输出的每行中都将包括数据链路层头部信息,例如源MAC和目标MAC。
-q:快速打印输出。即打印很少的协议丛迅册相关信息,从而输出行都比较简短。
-X:输出包的头部数据,会以16进制和ASCII两种方式同时输出。
-XX:输出包的头部数据,会以16进制和ASCII两种方式同时输出,更详细。
-v:当分析和打印的时候,产生详细的输出。
-vv:产生比-v更详细的输出。
-vvv:产生比-vv更详细的输出。
-D:列出可用于抓包的接口。将会列出接口的数值编号和接口名,它们都可以用于"-i"后。
-F:从文件中读取抓包的表达式。若使用该选项,则命令行中给定的其他表达式都将失效。
-w:将抓包数据输出到文件中而不是标准输出。可以同时配合"-G
time"选项使得输出文件每time秒就自动切换到另一个文件。可通过"-r"选项载入这些文件以进行分析和打印。
-r:从给定的数据包文件中读取数据。使用"-"表示从标准输入中读取。
== 一个基本的表达式单元格式为"proto dir type ID" ==
对于表达式语法,参考 pcap-filter 【pcap-filter - packet filter syntax】
host, net, port, portrange
例如:host 192.168.201.128 , net 128.3, port 20, portrange 6000-6008'
src, dst, src or dst, src and dst
tcp, udp , icmp,若未给定协议类型,则匹配所有可能的类型
==表达式单元之间可以使用 *** 作符" and / &&/ or / || / not / ! "进行连接,从而组成复杂的条件表达式==。如"host foo and not port ftp and not port ftp-data",这表示筛选的数据包要满足"主机为foo且端口不是ftp(端口21)和ftp-data(端口20)的包",常用端口和名字的对应关系可在linux系统中的/etc/service文件中找到。
另外,同样的修饰符可省略,如"tcp dst port ftp or ftp-data or domain"与"tcp dst port ftp or tcp dst port ftp-data or tcp dst port domain"意义相同,都表示包的协议为tcp且目的端口为ftp或ftp-data或domain(端口53)。
使用括号"()"可以改变表达式的优先级,但需要注意的是括号会被shell解释,所以应该使用反斜线""转义为"()",在需要的时候,还需要包围在引号中。
==**tcpdump只能抓取流经本机的数据包 **==
默认情况下,直接启动tcpdump将监视第一个网络接口(非lo口)上所有流通的数据包。这样抓取的结果会非常多,滚动非常快。
注意,表达式被单引号括起来了,这可以防止shell对其中的括号进行错误解析
tcpdump 是一款强大的网络抓包工具,它使用 libpcap 库来抓取网络数据包,这个库在几乎在所有的 Linux/Unix 中都有。熟悉 tcpdump 的使用能够帮助你分析调试网络数据,本文将通过一个个具体的示例来介绍它在不同场景下的使用方法。不管你是系统管理员,程序员,云原生工程师还是 yaml 工程师,掌握 tcpdump 的使用都能让你如虎添翼,升职加薪。
tcpdump 的常用参数如下:
额外再介绍几个常用参数:
-A 表示使用 ASCII 字符串打印报文的全部数据,这样可以使读取更加简单,方便使用 grep 等工具解析输出内容。 -X 表示同时使用十六进制和 ASCII 字符串打印报文的全部数据。这两个参数不能一起使用。例如:
后面可以跟上协议名称来过滤特定协议的流量,以 UDP 为例,可以加上参数 udp 或 protocol 17 ,这两个命令意思相同。
同理, tcp 与 protocol 6 意思相同。
使用过滤器 host 可以抓取特定目的地和源 IP 地址的流量。
也可以使用 src 或 dst 只抓取源或目的地:
使用 tcpdump 截取数据报文的时候,默认会打印到屏幕的默认输出,你会看到按照顺序和格式,很多的数据一行行快速闪过,根本来不及仿棚册看清楚所有的内容。不过,tcpdump 提供了把截取的数据保存到文件的功能,以便后面使用其他图形工具(比如 wireshark,Snort)来分析。
-w 选项用来把数据报文输出到文件:
如果想实时将抓取到的数据通过管道传递备宏给其他工具来处理,需要使用 -l 选项来开启行缓冲模式(或使用 -c 选项来开启数据包缓冲模式)。使用 -l 选项可以将输出通过立即发送给其他命令,其他命令会立即响应。
过滤的真正强大之处在于你可以随意组合它们,而连接它们的逻辑就是常用的 与/AND/&&、 或/OR/|| 和 非/not/!。
关于 tcpdump 的过滤器,这里有必要单独介绍和中一下。
机器上的网络报文数量异常的多,很多时候我们只关系和具体问题有关的数据报(比如访问某个网站的数据,或者 icmp 超时的报文等等),而这些数据只占到很小的一部分。把所有的数据截取下来,从里面找到想要的信息无疑是一件很费时费力的工作。而 tcpdump 提供了灵活的语法可以精确地截取关心的数据报,简化分析的工作量。这些选择数据包的语句就是过滤器(filter)!
Host 过滤器用来过滤某个主机的数据报文。例如:
该命令会抓取所有发往主机 1.2.3.4 或者从主机 1.2.3.4 发出的流量。如果想只抓取从该主机发出的流量,可以使用下面的命令:
Network 过滤器用来过滤某个网段的数据,使用的是 CIDR[2] 模式。可以使用四元组(x.x.x.x)、三元组(x.x.x)、二元组(x.x)和一元组(x)。四元组就是指定某个主机,三元组表示子网掩码为 255.255.255.0,二元组表示子网掩码为 255.255.0.0,一元组表示子网掩码为 255.0.0.0。例如,
抓取所有发往网段 192.168.1.x 或从网段 192.168.1.x 发出的流量:
抓取所有发往网段 10.x.x.x 或从网段 10.x.x.x 发出的流量:
和 Host 过滤器一样,这里也可以指定源和目的:
也可以使用 CIDR 格式:
Proto 过滤器用来过滤某个协议的数据,关键字为 proto,可省略。proto 后面可以跟上协议号或协议名称,支持 icmp, igmp, igrp, pim, ah, esp, carp, vrrp, udp和 tcp。因为通常的协议名称是保留字段,所以在与 proto 指令一起使用时,必须根据 shell 类型使用一个或两个反斜杠(/)来转义。Linux 中的 shell 需要使用两个反斜杠来转义,MacOS 只需要一个。
例如,抓取 icmp 协议的报文:
Port 过滤器用来过滤通过某个端口的数据报文,关键字为 port。例如:
截取数据只是第一步,第二步就是理解这些数据,下面就解释一下 tcpdump 命令输出各部分的意义。
最基本也是最重要的信息就是数据报的源地址/端口和目的地址/端口,上面的例子第一条数据报中,源地址 ip 是 192.168.1.106,源端口是 56166,目的地址是 124.192.132.54,目的端口是 80。>符号代表数据的方向。
此外,上面的三条数据还是 tcp 协议的三次握手过程,第一条就是 SYN 报文,这个可以通过 Flags [S] 看出。下面是常见的 TCP 报文的 Flags:
下面给出一些具体的例子,每个例子都可以使用多种方法来获得相同的输出,你使用的方法取决于所需的输出和网络上的流量。我们在排障时,通常只想获取自己想要的内容,可以通过过滤器和 ASCII 输出并结合管道与 grep、cut、awk 等工具来实现此目的。
例如,在抓取 HTTP 请求和响应数据包时,可以通过删除标志 SYN/ACK/FIN 来过滤噪声,但还有更简单的方法,那就是通过管道传递给 grep。在达到目的的同时,我们要选择最简单最高效的方法。下面来看例子。
从 HTTP 请求头中提取 HTTP 用户代理:
通过 egrep 可以同时提取用户代理和主机名(或其他头文件):
抓取 HTTP GET 流量:
也可以抓取 HTTP POST 请求流量:
注意:该方法不能保证抓取到 HTTP POST 有效数据流量,因为一个 POST 请求会被分割为多个 TCP 数据包。
上述两个表达式中的十六进制将会与 GET 和 POST 请求的 ASCII 字符串匹配。例如,tcp[((tcp[12:1] &0xf0) >>2):4] 首先会确定我们感兴趣的字节的位置[3](在 TCP header 之后),然后选择我们希望匹配的 4 个字节。
提取 HTTP 请求的主机名和路径:
从 HTTP POST 请求中提取密码和主机名:
提取 Set-Cookie(服务端的 Cookie)和 Cookie(客户端的 Cookie):
查看网络上的所有 ICMP 数据包:
通过排除 echo 和 reply 类型的数据包使抓取到的数据包不包括标准的 ping 包:
可以提取电子邮件的正文和其他数据。例如,只提取电子邮件的收件人:
抓取 NTP 服务的查询和响应
通过 SNMP 服务,渗透测试人员可以获取大量的设备和系统信息。在这些信息中,系统信息最为关键,如 *** 作系统版本、内核版本等。使用 SNMP 协议快速扫描程序 onesixtyone,可以看到目标系统的信息:
当抓取大量数据并写入文件时,可以自动切割为多个大小相同的文件。例如,下面的命令表示每 3600 秒创建一个新文件 capture-(hour).pcap,每个文件大小不超过 200*1000000 字节:
这些文件的命名为 capture-{1-24}.pcap,24 小时之后,之前的文件就会被覆盖。
可以通过过滤器 ip6 来抓取 IPv6 流量,同时可以指定协议如 TCP:
从之前保存的文件中读取 IPv6 UDP 数据报文:
在下面的例子中,你会发现抓取到的报文的源和目的一直不变,且带有标志位 [S] 和 [R],它们与一系列看似随机的目标端口进行匹配。当发送 SYN 之后,如果目标主机的端口没有打开,就会返回一个 RESET。这是 Nmap 等端口扫描工具的标准做法。
本例中 Nmap NSE 测试脚本 http-enum.nse 用来检测 HTTP 服务的合法 URL。
在执行脚本测试的主机上:
在目标主机上:
向 Google 公共 DNS 发起的出站 DNS 请求和 A 记录响应可以通过 tcpdump 抓取到:
抓取 80 端口的 HTTP 有效数据包,排除 TCP 连接建立过程的数据包(SYN / FIN / ACK):
通常 Wireshark(或 tshark)比 tcpdump 更容易分析应用层协议。一般的做法是在远程服务器上先使用 tcpdump 抓取数据并写入文件,然后再将文件拷贝到本地工作站上用 Wireshark 分析。
还有一种更高效的方法,可以通过 ssh 连接将抓取到的数据实时发送给 Wireshark 进行分析。以 MacOS 系统为例,可以通过 brew cask install wireshark 来安装,然后通过下面的命令来分析:
例如,如果想分析 DNS 协议,可以使用下面的命令:
抓取到的数据:
找出一段时间内发包最多的 IP,或者从一堆报文中找出发包最多的 IP,可以使用下面的命令:
cut -f 1,2,3,4 -d '.' : 以 . 为分隔符,打印出每行的前四列。即 IP 地址。
sort | uniq -c : 排序并计数
sort -nr : 按照数值大小逆向排序
本例将重点放在标准纯文本协议上,过滤出于用户名和密码相关的报文:
最后一个例子,抓取 DHCP 服务的请求和响应报文,67 为 DHCP 端口,68 为客户机端口。
本文主要介绍了 tcpdump 的基本语法和使用方法,并通过一些示例来展示它强大的过滤功能。将 tcpdump 与 wireshark 进行组合可以发挥更强大的功效,本文也展示了如何优雅顺滑地结合 tcpdump 和 wireshark。如果你想了解更多的细节,可以查看 tcpdump 的 man 手册。
大部分 Linux 发行版都内置了 Tcpdump 工具。如果没有,也可以直接使用对应的包管理器进行安装(如: $ sudo apt-get install tcpdump 和 $ sudo yum install tcpdump )
通过表达式可以对各种不同类型的网络流量进行过滤,以获取到需要的信息。这也是 tcpdump 强大功能的一个体现。
主要有 3 种类型的表达式:
指定网络接口 :
# tcpdump -i <dev>
原始信息输出模式 :
# tcpdump -ttttnnvvS
更详细的输出,不解析主机名和端口名,使毁空用绝对序列号,方便阅读的时间戳
通过IP地址过滤 :
# tcpdump host 10.2.64.1
HEX 输出
# tcpdump -nnvXSs 0 -c1 icmp
通过源地址和目标地址进行过滤
# tcpdump src 10.2.67.203
# tcpdump dst 10.2.67.203
通过子网进行过滤
# tcpdump net 10.2.64.0/24
监听指定端口号
# tcpdump port 515
指定协议
# tcpdmp icmp
端口范围
# tcpdump portrange 21-23
通过睁余基包大小过滤
# tcpdump less 32
# tcpdump greater 64
# tcpdump <= 128
写入 PCAP 文件
# tcpdump port 80 -w capture_file
读取 PCAP 文件
# tcpdump -r capture_file
可以通过命令选项的不同组合(使用 逻辑运算符 )完成更复杂的任务。运算符包括以下3种:
# tcpdump src 10.2.64.29 and dst port 80
即捕捉从指定主机(10.2.64.92)发出,且目标端口为悉谨 80 的所有网络数据
# tcpdump src net 192.168.0.0/16 and dst net 10.0.0.0/8 or 172.16.0.0/16
即捕捉从指定子网(192.168.0.0/16)发送到目标子网(10.0.0.0/8 和 172.16.0.0/16)的所有网络数据
# tcpdump src 192.168.56.1 and not dst port 22
即捕捉从指定主机(192.168.56.1)发出,且目标端口不为 22 的所有网络数据
# tcpdump 'tcp[13] &32!=0' 所有 URGENT ( URG ) 包
# tcpdump 'tcp[13] &16!=0' 所有 ACKNOWLEDGE ( ACK ) 包
# tcpdump 'tcp[13] &8!=0' 所有 PUSH ( PSH ) 包
# tcpdump 'tcp[13] &4!=0' 所有 RESET ( RST ) 包
# tcpdump 'tcp[13] &2!=0' 所有 SYNCHRONIZE ( SYN ) 包
# tcpdump 'tcp[13] &1!=0' 所有 FINISH ( FIN ) 包
# tcpdump 'tcp[13]=18' 所有 SYNCHRONIZE/ACKNOWLEDGE ( SYNACK ) 包
其他指定标志位的方式如:
# tcpdump 'tcp[tcpflags] == tcp-syn'
# tcpdump 'tcp[tcpflags] == tcp-fin'
一些特殊的用法
# tcpdump 'tcp[13] = 6' RST 和 SYN 同时启用的数据包(不正常)
# tcpdump 'tcp[32:4] = 0x47455420' 获取 http GET 请求的文本
# tcpdump 'tcp[(tcp[12]>>2):4] = 0x5353482D' 获取任何端口的 ssh 连接(通过 banner 信息)
# tcpdump 'ip[8] <10' ttl 小于 10 的数据包(出现问题或 traceroute 命令)
# tcpdump 'ip[6] &128 != 0' 非常有可能是黑客入侵的情况
A tcpdump Tutorial and Primer with Examples
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)