车海快讯

超详细的网络抓包神器 tcpdump 使用指南

admin 157

tcpdump是一款强大的网络抓包工具,它使用libpcap库来抓取网络数据包,这个库在几乎在所有的Linux/Unix中都有。熟悉tcpdump的使用能够帮助你分析调试网络数据,本文将通过一个个具体的示例来介绍它在不同场景下的使用方法。不管你是系统管理员,程序员,云原生工程师还是yaml工程师,掌握tcpdump的使用都能让你如虎添翼,升职加薪。

1.基本语法和使用方法

tcpdump的常用参数如下:

$tcpdump-ieth0-nn-s0-vport80复制代码

-i:选择要捕获的接口,通常是以太网卡或无线网卡,也可以是vlan或其他特殊接口。如果该系统上只有一个网络接口,则无需指定。

-nn:单个n表示不解析域名,直接显示IP;两个n表示不解析域名和端口。这样不仅方便查看IP和端口号,而且在抓取大量数据时非常高效,因为域名解析会降低抓取速度。

-s0:tcpdump默认只会截取前96字节的内容,要想截取所有的报文内容,可以使用-snumber,number就是你要截取的报文字节数,如果是0的话,表示截取报文全部内容。

-v:使用-v,-vv和-vvv来显示更多的详细信息,通常会显示更多与特定协议相关的信息。

port80:这是一个常见的端口过滤器,表示仅抓取80端口上的流量,通常是HTTP。

额外再介绍几个常用参数:

-p:不让网络接口进入混杂模式。默认情况下使用tcpdump抓包时,会让网络接口进入混杂模式。一般计算机网卡都工作在非混杂模式下,此时网卡只接受来自网络端口的目的地址指向自己的数据。当网卡工作在混杂模式下时,网卡将来自接口的所有数据都捕获并交给相应的驱动程序。如果设备接入的交换机开启了混杂模式,使用-p选项可以有效地过滤噪声。

-e:显示数据链路层信息。默认情况下tcpdump不会显示数据链路层信息,使用-e选项可以显示源和目的MAC地址,以及VLANtag信息。例如:

$tcpdump-n-e-c5notip6tcpdump:verboseoutputsuppressed,use-vor-vvforfullprotocoldecodelisteningonbr-lan,link-typeEN10MB(Ethernet),capturesize262144bytes18:27:53.61986524:5e:be:0c:17:af00:e2:69:23:d3:3b,ethertypeIPv4(0x0800),length1162:192.168.100.20.51410180.176.26.193.58695:Flags[.],seq2045333376:2045334484,ack3398690514,win751,length110818:27:53.62649000:e2:69:23:d3:3b24:5e:be:0c:17:af,ethertypeIPv4(0x0800),length68:220.173.179.66.36017192.168.100.20.51410:UDP,length2618:27:53.62689324:5e:be:0c:17:af00:e2:69:23:d3:3b,ethertypeIPv4(0x0800),length1444:192.168.100.20.51410220.173.179.66.36017:UDP,length140218:27:53.62883700:e2:69:23:d3:3b24:5e:be:0c:17:af,ethertypeIPv4(0x0800),length1324:46.97.169.182.6881192.168.100.20.59145:Flags[P.],seq3058450381:3058451651,ack14349180,win502,length127018:27:53.62909624:5e:be:0c:17:af00:e2:69:23:d3:3b,ethertypeIPv4(0x0800),length54:192.168.100.20.59145192.168.100.1.12345:Flags[.],ack3058451651,win6350,length05packetscaptured复制代码
显示ASCII字符串

-A表示使用ASCII字符串打印报文的全部数据,这样可以使读取更加简单,方便使用grep等工具解析输出内容。-X表示同时使用十六进制和ASCII字符串打印报文的全部数据。这两个参数不能一起使用。例如:

$tcpdump-A-s0port80复制代码
抓取特定协议的数据

后面可以跟上协议名称来过滤特定协议的流量,以UDP为例,可以加上参数udp或protocol17,这两个命令意思相同。

$tcpdump-ieth0udp$tcpdump-ieth0proto17复制代码

同理,tcp与protocol6意思相同。

抓取特定主机的数据

使用过滤器host可以抓取特定目的地和源IP地址的流量。

$复制代码

也可以使用src或dst只抓取源或目的地:

$复制代码
将抓取的数据写入文件

使用tcpdump截取数据报文的时候,默认会打印到屏幕的默认输出,你会看到按照顺序和格式,很多的数据一行行快速闪过,根本来不及看清楚所有的内容。不过,tcpdump提供了把截取的数据保存到文件的功能,以便后面使用其他图形工具(比如wireshark,Snort)来分析。

-w选项用来把数据报文输出到文件:

$复制代码
行缓冲模式

如果想实时将抓取到的数据通过管道传递给其他工具来处理,需要使用-l选项来开启行缓冲模式(或使用-c选项来开启数据包缓冲模式)。使用-l选项可以将输出通过立即发送给其他命令,其他命令会立即响应。

$tcpdump-ieth0-s0-lport80|grep'Server:'复制代码
组合过滤器

过滤的真正强大之处在于你可以随意组合它们,而连接它们的逻辑就是常用的与/AND/、或/OR/||和非/not/!。

andororor||notor!复制代码
2.过滤器

关于tcpdump的过滤器,这里有必要单独介绍一下。

机器上的网络报文数量异常的多,很多时候我们只关系和具体问题有关的数据报(比如访问某个网站的数据,或者icmp超时的报文等等),而这些数据只占到很小的一部分。把所有的数据截取下来,从里面找到想要的信息无疑是一件很费时费力的工作。而tcpdump提供了灵活的语法可以精确地截取关心的数据报,简化分析的工作量。这些选择数据包的语句就是过滤器(filter)!

Host过滤器

Host过滤器用来过滤某个主机的数据报文。例如:

$复制代码

该命令会抓取所有发往主机1.2.3.4或者从主机1.2.3.4发出的流量。如果想只抓取从该主机发出的流量,可以使用下面的命令:

$复制代码
Network过滤器

Network过滤器用来过滤某个网段的数据,使用的是CIDR模式。可以使用四元组()、三元组()、二元组()和一元组(x)。四元组就是指定某个主机,三元组表示子网掩码为255.255.255.0,二元组表示子网掩码为255.255.0.0,一元组表示子网掩码为255.0.0.0。例如,

抓取所有发往网段192.168.1.x或从网段192.168.1.x发出的流量:

$复制代码

抓取所有发往网段10.或从网段10.发出的流量:

$tcpdumpnet10复制代码

和Host过滤器一样,这里也可以指定源和目的:

$tcpdumpsrcnet10复制代码

也可以使用CIDR格式:

$/12复制代码
Proto过滤器

Proto过滤器用来过滤某个协议的数据,关键字为proto,可省略。proto后面可以跟上协议号或协议名称,支持icmp,igmp,igrp,pim,ah,esp,carp,vrrp,udp和tcp。因为通常的协议名称是保留字段,所以在于proto指令一起使用时,必须根据shell类型使用一个或两个反斜杠(/)来转义。Linux中的shell需要使用两个反斜杠来转义,MacOS只需要一个。

例如,抓取icmp协议的报文:

$tcpdump-nproto\\icmp21-UbuntuSMPTueApr2406:16:15UTC2018x86_64复制代码

可以通过tcpdump抓取GetRequest和GetResponse:

$tcpdump-n-s0port161andudptcpdump:verboseoutputsuppressed,use-vor-vvforfullprotocoldecodelisteningonwlp58s0,link-typeEN10MB(Ethernet),capturesize262144bytes23:39:13.725522:GetRequest(28).1.3.6.1.2.1.1.1.023:39:13.728789:GetResponse(109).1.3.6.1.2.1.1.1.0="#21-UbuntuSMPTueApr2406:16:15UTC2018x86_64"复制代码
切割pcap文件

当抓取大量数据并写入文件时,可以自动切割为多个大小相同的文件。例如,下面的命令表示每3600秒创建一个新文件capture-(hour).pcap,每个文件大小不超过200*1000000字节:

$tcpdump-w/tmp/capture-%复制代码

这些文件的命名为capture-{1-24}.pcap,24小时之后,之前的文件就会被覆盖。

抓取IPv6流量

可以通过过滤器ip6来抓取IPv6流量,同时可以指定协议如TCP:

$tcpdump-nnip6proto6复制代码

从之前保存的文件中读取IPv6UDP数据报文:

$复制代码
检测端口扫描

在下面的例子中,你会发现抓取到的报文的源和目的一直不变,且带有标志位[S]和[R],它们与一系列看似随机的目标端口进行匹配。当发送SYN之后,如果目标主机的端口没有打开,就会返回一个RESET。这是Nmap等端口扫描工具的标准做法。

$tcpdump-nn21:46:19.693601:Flags[S],seq116466344,win29200,options[mss1460,sackOK,TSval3547090332ecr0,nop,wscale7],length021:46:19.693626:Flags[S],seq3400074709,win29200,options[mss1460,sackOK,TSval3547090332ecr0,nop,wscale7],length021:46:19.693762:Flags[S],seq2214070267,win29200,options[mss1460,sackOK,TSval3547090333ecr0,nop,wscale7],length021:46:19.693772:Flags[R.],seq0,ack2214070268,win0,length021:46:19.693783:Flags[S],seq2358257571,win29200,options[mss1460,sackOK,TSval3547090333ecr0,nop,wscale7],length021:46:19.693826:Flags[S],seq2406028551,win29200,options[mss1460,sackOK,TSval3547090333ecr0,nop,wscale7],length021:46:19.695567:Flags[S],seq3230403372,win29200,options[mss1460,sackOK,TSval3547090334ecr0,nop,wscale7],length021:46:19.695590:Flags[R.],seq0,ack3230403373,win0,length021:46:19.695608:Flags[S],seq3289070068,win29200,options[mss1460,sackOK,TSval3547090335ecr0,nop,wscale7],length021:46:19.695622:Flags[R.],seq0,ack3289070069,win0,length021:46:19.695637:Flags[S],seq140319147,win29200,options[mss1460,sackOK,TSval3547090335ecr0,nop,wscale7],length021:46:19.695650:Flags[R.],seq0,ack140319148,win0,length021:46:19.695664:Flags[S],seq2203629201,win29200,options[mss1460,sackOK,TSval3547090335ecr0,nop,wscale7],length021:46:19.695775:Flags[S],seq635990431,win29200,options[mss1460,sackOK,TSval3547090335ecr0,nop,wscale7],length021:46:19.695790:Flags[R.],seq0,ack635990432,win0,length0复制代码
过滤NmapNSE脚本测试结果

本例中NmapNSE测试脚本用来检测HTTP服务的合法URL。

在执行脚本测试的主机上:

$nmap-p80--script=复制代码

在目标主机上:

$tcpdump-nnport80|grep"GET/"GET/w3perl/HTTP/1.1GET/w-agora/HTTP/1.1GET/way-board/HTTP/1.1GET/web800fo/HTTP/1.1GET/webaccess/HTTP/1.1GET/webadmin/HTTP/1.1GET/webAdmin/HTTP/1.1复制代码
抓取DNS请求和响应

向Google公共DNS发起的出站DNS请求和A记录响应可以通过tcpdump抓取到:

$tcpdump-iwlp58s0-s0port53tcpdump:verboseoutputsuppressed,use-vor-vvforfullprotocoldecodelisteningonwlp58s0,link-typeEN10MB(Ethernet),capturesize262144bytes14:19:06.879799:26977+[1au]A?(44)14:19:07.022618:269771/0/1(60)复制代码
抓取HTTP有效数据包

抓取80端口的HTTP有效数据包,排除TCP连接建立过程的数据包(SYN/FIN/ACK):

$tcpdump'tcpport80and(((ip[2:2]-((ip[0]0xf)2))-((tcp[12]0xf0)2))!=0)'复制代码
将输出内容重定向到Wireshark

通常Wireshark(或tshark)比tcpdump更容易分析应用层协议。一般的做法是在远程服务器上先使用tcpdump抓取数据并写入文件,然后再将文件拷贝到本地工作站上用Wireshark分析。

还有一种更高效的方法,可以通过ssh连接将抓取到的数据实时发送给Wireshark进行分析。以MacOS系统为例,可以通过brewcaskinstallwireshark来安装,然后通过下面的命令来分析:

$sshroot@remotesystem'tcpdump-s0-c1000-nn-w-notport22'|/Applications//Contents/MacOS/Wireshark-k-i-复制代码

例如,如果想分析DNS协议,可以使用下面的命令:

$sshroot@remotesystem'tcpdump-s0-c1000-nn-w-port53'|/Applications//Contents/MacOS/Wireshark-k-i-复制代码

抓取到的数据:

-c选项用来限制抓取数据的大小。如果不限制大小,就只能通过ctrl-c来停止抓取,这样一来不仅关闭了tcpdump,也关闭了wireshark。

找出发包最多的IP

找出一段时间内发包最多的IP,或者从一堆报文中找出发包最多的IP,可以使用下面的命令:

$tcpdump-nnn-t-c200|cut-f1,2,3,4-d'.'|sort|uniq-c|sort-nr|head-n20tcpdump:verboseoutputsuppressed,use-vor-vvforfullprotocoldecodelisteningonenp7s0,link-typeEN10MB(Ethernet),capturesize262144bytes200packetsc复制代码

cut-f1,2,3,4-d'.':以.为分隔符,打印出每行的前四列。即IP地址。

sort|uniq-c:排序并计数

sort-nr:按照数值大小逆向排序

抓取用户名和密码

本例将重点放在标准纯文本协议上,过滤出于用户名和密码相关的报文:

$tcpdumpporthttporportftporportsmtporportimaporportpop3orporttelnet-l-A|egrep-i-B5'pass=|pwd=|log=|login=|user=|username=|pw=|passw=|passwd=|password=|pass:|user:|username:|password:|login:|pass|user'复制代码
抓取DHCP报文

最后一个例子,抓取DHCP服务的请求和响应报文,67为DHCP端口,68为客户机端口。

$tcpdump-v-nport67or68tcpdump:listeningonenp7s0,link-typeEN10MB(Ethernet),capturesize262144bytes14:37:50.059662IP(tos0x10,ttl128,id0,offset0,flags[none],protoUDP(17),length328)0.0.0.0.68255.255.255.255.67:BOOTP/DHCP,Requestfrom00:0c:xx:xx:xx:d5,length300,xid0xc9779c2a,Flags[none]Client-Ethernet-Address00:0c:xx:xx:xx:d5Vor-rfc1048ExtensionsMagicCookie0x63825363DHCP-MessageOption53,length1:RequestRequested-IPOption50,length4:10.10.1.163HostnameOption12,length14:"test-ubuntu"Parameter-RequestOption55,length16:Subnet-Mask,BR,Time-Zone,Default-GatewayDomain-Name,Domain-Name-Server,Option119,HostnameNetbios-Name-Server,Netbios-Scope,MTU,Classless-Static-RouteNTP,Classless-Static-Route-Microsoft,Static-Route,Option25214:37:50.059667IP(tos0x10,ttl128,id0,offset0,flags[none],protoUDP(17),length328)0.0.0.0.68255.255.255.255.67:BOOTP/DHCP,Requestfrom00:0c:xx:xx:xx:d5,length300,xid0xc9779c2a,Flags[none]Client-Ethernet-Address00:0c:xx:xx:xx:d5Vor-rfc1048ExtensionsMagicCookie0x63825363DHCP-MessageOption53,length1:RequestRequested-IPOption50,length4:10.10.1.163HostnameOption12,length14:"test-ubuntu"Parameter-RequestOption55,length16:Subnet-Mask,BR,Time-Zone,Default-GatewayDomain-Name,Domain-Name-Server,Option119,HostnameNetbios-Name-Server,Netbios-Scope,MTU,Classless-Static-RouteNTP,Classless-Static-Route-Microsoft,Static-Route,Option25214:37:50.060780IP(tos0x0,ttl64,id53564,offset0,flags[none],protoUDP(17),length339)10.10.1.1.6710.10.1.163.68:BOOTP/DHCP,Reply,length311,xid0xc9779c2a,Flags[none]:0c:xx:xx:xx:d5Vor-rfc1048ExtensionsMagicCookie0x63825363DHCP-MessageOption53,length1:ACKServer-IDOption54,length4:10.10.1.1Lease-TimeOption51,length4:86400RNOption58,length4:43200RBOption59,length4:75600Subnet-MaskOption1,length4:255.255.255.0BROption28,length4:10.10.1.255Domain-Name-ServerOption6,length4:10.10.1.1HostnameOption12,length14:"test-ubuntu"T252Option252,length1:10Default-GatewayOption3,length4:10.10.1.1复制代码
5.总结

本文主要介绍了tcpdump的基本语法和使用方法,并通过一些示例来展示它强大的过滤功能。将tcpdump与wireshark进行组合可以发挥更强大的功效,本文也展示了如何优雅顺滑地结合tcpdump和wireshark。如果你想了解更多的细节,可以查看tcpdump的man手册。


作者:米开朗基杨
链接:

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。