vlambda博客
学习文章列表

tcpdump 实例-获取网络包的50种方法

TCPDUMP 毫无疑问是最重要的网络分析工具,因为它简单实用,而且功能强大。


这篇教程将会教你从 IP、端口、协议、应用层等多方面来获取通信数据包,确保你可以尽可能快的找到你想要的数据。


tcpdump 的安装很简单,在 ubuntu 上:

$ apt install tcpdump

在 Redhat/Centos 上:

$ yum install tcpdump


首先通过一个简单的命令来获取 HTPPS 的数据包:


$ tcpdump -nnSX port 443

17:59:25.938214 IP 138.68.249.192.443 > 10.236.216.235.65078: Flags [.], seq 3666844459:3666845907, ack 3574575735, win 248, options [nop,nop,TS val 2964126 ecr 782599132], length 1448
0x0000: 784f 43a0 abcd 200b c79d 065f 0800 4500 xOC........_..E.
0x0010: 05dc 2b11 4000 3006 b22e 8a44 f9c0 0aec [email protected]....
0x0020: d8eb 01bb fe36 da8f 9b2b d50f b277 8010 .....6...+...w..
0x0030: 00f8 d531 0000 0101 080a 002d 3a9e 2ea5 ...1.......-:...


上面展示了一些 HTTPS 通信的内容,通过十六进制的形式展现出来,并且还加密了。当你对网络有任何疑问时,就可以通过上面的命令去获取你关注端口的信息。下面来看一些更详细的例子。


基本用法

现在你可以获取一些基本的流量包,再来看看其他的用法,下面的这些例子在你从事网络、安全或者其他工作时都可以用到。


只需要一个接口

输入下面的命令,然后看看会出现什么:

$ tcpdump -i eth0

注:如果 eth0 网卡没有配置,那什么都不会出现 ,这个时候可以将 eth0 换成 any


通过 IP 获取流量

最常用的查询方法之一,通过 host 参数,获取从特定 IP 发出和收到的流量:

$ tcpdump host 1.1.1.1


通过源地址和目标地址来过滤

如果你只需要获取一个方向的流量,可以使用 srcdst 来限定方向:

$ tcpdump src 1.1.1.1
$ tcpdump dst 1.0.0.1


通过特定网络获取流量包

如果想从一个特定的网络或者子网获取流量,使用 net 参数:

$ tcpdump net 1.2.3.0/24


获取十六进制的数据包内容

十六进制输出在你想看数据内容的时候非常有用,特别是你想深入其中一部分内容的时候,这是最好的方法,只需要加上 -X 参数:

$ tcpdump -c 1 -X icmp
17:47:27.844781 IP 10.236.216.1 > sk-20200221gewc.mioffice.cn: ICMP 10.236.216.1 udp port nat-pmp unreachable, length 36
0x0000: 784f 43a0 abcd 200b c79d 065f 0800 45c0 xOC........_..E.
0x0010: 0038 2ef3 0000 ff01 c508 0aec d801 0aec .8..............
0x0020: d92f 0303 a6bf 0000 0000 4500 0058 a27e ./........E..X.~
0x0030: 0000 ff11 520d 0aec d92f 0aec d801 14e9 ....R..../......
0x0040: 14e7 0044 2c29 ...D,)


通过特定的端口获取流量包

你可以通过特定的端口来获取流量数据,只需要使用 port 参数,在参数后加上具体的端口:

$ tcpdump port 3389
$ tcpdump src port 1025


获取具体协议的流量包

如果你想获得特定类型的流量包,可以使用 tcpudpicmp 或者其他的协议:

$ tcpdump icmp


只获取 IPv6 的流量包

你也可以只获取 IPv6 的 流量包:

$ tcpdump ip6


通过端口范围来获取流量包

你也可以指定一个流量范围,然后只获取这个范围内的流量:

$ tcpdump portrange 21-23


通过流量包的大小来筛选

如果你想获得一个特定大小的包,你可以使用这个选项,你可以使用 less greate或者其他你可以在数学中能找到的符号:

$ tcpdump less 32
$ tcpdump greater 64
$ tcpdump <= 128


读写流量包(pcap)

还可以流量包存成一个文件,以便后续可以对这个流量包进行分析。这个文件的格式是 PCAP(PEE-cap),它可以被数百种的应用处理,包括网络分析,系统入侵检测,当然也可以被 tcpdump 本身所处理。只需要使用 -w 参数就可以把流量包存成文件:


$ tcpdump port 80 -w capture_file


也可以使用 -r 参数来读取 PCAP 文件。在读取这个文件的时候同时也可以使用其他的参数,唯一受限制的就是无法捕捉和处理文件中不存在的内容。


$ tcpdump -r capture_file


进阶用法


上面我们已经通过一些基本的例子展示 tcpdump 的能力,下来来看一下更进阶的内容。


其他参数

下面这些参数在你使用 tcpdump 的时候也可以使用:


  • -X : 通过 16 进制和 ASCII 码来展示数据包中的内容

  • -XX: 和 -X 类似,但会另外展示以太网头部

  • -D : 展示可用的借口列表

  • -l: 单行输出(以便在保存时查看或者发送到其他命令)

  • -q: 减少一些不必要的输出

  • -t: 输出可读的时间格式

  • -tttt: 提供最大程度的人类可读的时间戳输出

  • -i eth0: 监听 eth0 网口

  • -vv: 输出更详细的细节

  • c: 只获取一定的数量包,然后停止

  • -s: 获取以字节为单位固定大小的包,使用 -s0 可以获取到所有的内容

  • -S: 打印绝对序列号(注:TCP 的序列号)

  • -e: 同时获取以太网头部

  • -q: 减少协议信息的展示

  • -E: 通过提供加密密钥解密IPSEC通信


条件组合

上面提到的这些命令就已经很强大了,但 tcpdump 的真正黑魔法是你可以随意的组合这些参数,来达到找特定内容的目的。


有三种组合方式,如果你会一点编程的话,这些对你来说应该很熟悉:

  • 与:  and&&

  • 或:  or||

  • 非:  not!


原始输出视图

使用此组合可以查看详细的输出,不包含主机名或端口号的解析,使用绝对序列号,并显示人类可读的时间戳。

$ tcpdump -ttnnvvS


下面是一些使用组合命令的例子。


获取特定 IP 和特定端口号的数据包


比如获取所有从 10.5.2.3 发出去,并且目标端口号是 3389 的数据包:

$ tcpdump -nnvvS src 10.5.2.3 and dst port 3389


从一个网络到另一挂网络的包


比如获取从 192.168.x.x 网络发到 10.x 或者 172.16.x.x 网络的包,并且会通过16进制的形式展现出来。

$ tcpdump -nvX src net 192.168.0.0/16 and dst net 10.0.0.0/8 or 172.16.0.0/16


到特定 IP 且不包含 ICMP 的包


比如获取目标 IP 是192.168.0.2 且不包含 ICMP 的包:

$ tcpdump dst 192.168.0.2 and src net and not icmp


获取从特定 IP 发出但不包含特定端口的包


比如获取一个从特定 IP 出发,但不包括 SSH 的包(假设使用的是默认端口):

$ tcpdump -vv src mars and not dst port 22


如你所见,你可以构建查询来查找所需的任何内容。关键是首先精确地找出要查找的内容,然后构建语法来隔离特定类型的流量。


要注意的是,在构建复杂查询时,可能必须使用单引号对选项进行分组。使用单引号是为了告诉tcpdump忽略括号下面的某些特殊字符。同样的方式也可以用于使用其他表达式分组,如主机、端口、网络等。

$ tcpdump 'src 10.0.2.4 and (dst port 3389 or 22)'


隔离 TCP 标志

你还可以使用过滤器来隔离设置了特定TCP标志的数据包。


隔离 TCP RST 标志

$ tcpdump 'tcp[13] & 4!=0'
$ tcpdump 'tcp[tcpflags] == tcp-rst'


隔离 TCP SYN 标志

$ tcpdump 'tcp[13] & 2!=0'
$ tcpdump 'tcp[tcpflags] == tcp-syn'


隔离设置了 SYN 和 ACK 标志的包

$ tcpdump 'tcp[13]=18'


隔离TCP URG 标志

$ tcpdump 'tcp[13] & 32!=0'
$ tcpdump 'tcp[tcpflags] == tcp-urg'


隔离 TCP ACK 标志

$ tcpdump 'tcp[13] & 16!=0'
$ tcpdump 'tcp[tcpflags] == tcp-ack'


隔离 TCP PSH 标志

$ tcpdump 'tcp[13] & 8!=0'
$ tcpdump 'tcp[tcpflags] == tcp-psh'


隔离 TCP FIN 标志

$ tcpdump 'tcp[13] & 1!=0'
$ tcpdump 'tcp[tcpflags] == tcp-fin'


日常例子

最后,我们已经看完了基本理论,下面的这些例子可以用于日常快速获取某种类型的数据包。


同时设置 SYN 和 RST 标志

$ tcpdump 'tcp[13] = 6'


查找 HTTP 使用的 Agent

$ tcpdump -vvAls0 | grep 'User-Agent:'


获取明文的 Get 请求

$ tcpdump -vvAls0 | grep 'GET'


获取 HTTP 的 host 头部

$ tcpdump -vvAls0 | grep 'Host:'


获取 HTTP 的 cookies

$ tcpdump -vvAls0 | grep 'Set-Cookie|Host:|Cookie:'


获取 SSH 连接

无论连接来自哪个端口,这个都可以工作。

$ tcpdump 'tcp[(tcp[12]>>2):4] = 0x5353482D'


获取 DNS 的包

$ tcpdump -vvAs0 port 53


获取 FTP 的包

$ tcpdump -vvAs0 port ftp or ftp-data


获取 NTP 的包

$ tcpdump -vvAs0 port 123


获取明文的密码

$ tcpdump port http or port ftp or port smtp or port imap or port pop3 or port telnet -lA | egrep -i -B5 'pass=|pwd=|log=|login=|user=|username=|pw=|passw=|passwd= |password=|pass:|user:|username:|password:|login:|pass |user '


发现包中不正常的数据

在IP报头中,有一点合法的应用程序永远不会设置,如果设置了就不正常。这里有一个有趣的过滤器,可以找到它被设置的包。

$ tcpdump 'ip[6] & 128 != 0'


总结


下面是一些思考:

  1. tcpdump 对于任何希望进入网络或信息安全领域的人来说都是一个有价值的工具

  1. 它有可以与流量交互的直接接口,加上它在检查数据包方面提供的精确性,它可能是学习TCP/IP最好的工具

  1. 像 Wireshark 这样的工具虽然也很棒,但是如果你想真正掌握数据包的结构,你必须先学会 tcpdump


这篇初级教程应该能让你能开始使用 tcpdump,但是对于其他更多的使用场景,还是要查阅手册。我希望这对你有用,如果你有任何问题,请随时联系我。



译 / Rayjun