概述
用简单的话来定义 tcpdump,就是:dump the traffic on a network,根据使用者的定义对网络上的数据包进行截获的包分析工具。
tcpdump 可以将网络中传送的数据包的“头”完全截获下来提供分析。它支持针对网络层、协议、主机、网络或端口的过滤,并提供 and、or、not 等逻辑语句来帮助你去掉无用的信息。
tcpdump 基于底层 libpcap 库开发,运行需要 root 权限。
一、tcpdump 安装
环境 虚拟机:vmware 15.5.2 os: ubuntu 12.04
安装 tcpdump
sudo apt-get install tcpdump
3. 版本查看
tcpdump --h
tcpdump version 4.0。
libpcap version 1.1.1 表示 libpcap 的版本。
二、tcpdump 参数
常用参数选项说明:
参数 | 含义 |
---|---|
-a | 将网络地址和广播地址转变成名字 |
-c | 在收到指定的包的数目后,tcpdump 就会停止; |
-d | 将匹配信息包的代码以人们能够理解的汇编格式给出;以可阅读的格式输出。 |
-dd | 将匹配信息包的代码以 c 语言程序段的格式给出; |
-ddd | 将匹配信息包的代码以十进制的形式给出; |
-e | 在输出行打印出数据链路层的头部信息; |
-f | 将外部的 Internet 地址以数字的形式打印出来; |
-l | 使标准输出变为缓冲行形式; |
-n | 直接显示 IP 地址,不显示名称; |
-nn | 端口名称显示为数字形式,不显示名称; |
-t | 在输出的每一行不打印时间戳; |
-v | 输出一个稍微详细的信息,例如在 ip 包中可以包括 ttl 和服务类型的信息; |
-vv | 输出详细的报文信息; |
-F | 从指定的文件中读取表达式,忽略其它的表达式; |
-i | 指定监听的网络接口; |
-r | 从指定的文件中读取包(这些包一般通过 -w 选项产生); |
-w | 直接将包写入文件中,并不分析和打印出来; |
-T | 将监听到的包直接解释为指定的类型的报文,常见的类型有 rpc (远程过程调用)和 snmp(简单 网络管理协议;) |
三、命令选项使用举例
1. 截获主机收到和发出的所有数据包。
命令:
tcpdump
说明:
tcpdump 截取包默认显示数据包的头部。
普通情况下,直接启动 tcpdump 将监视第一个网络接口上所有流过的数据包。
基础格式:时间 数据包类型 源 IP 端口 / 协议 > 目标 IP 端口 / 协议 协议详细信息
按下 Ctrl+C 会终止 tcpdump 命令。且会在结尾处生成统计信息。
终止 tcpdump
2. 指定抓包数量 -c
指定抓取 2 个数据包。
命令:
tcpdump -c 2
说明:
最后会自动生成统计信息。
【注意,已经切换到管理员了,虚拟机中要产生数据包,可以另外开一个窗口 ping baidu.com 后面不再提示】
ping baidu.com
3. 将抓包信息写入文件 -w
使用 -w 选项指定记录文件。
命令:
tcpdump -c 10 -w tcpdump_test.log
说明:
保存的文件不是文本格式,不能直接查看。tcpdump 保存的文件的格式是几乎所有主流的抓包工具软件都可以读取。所以可以使用更易读的图形界面工具来查看记录文件。
4. 读取记录文件 -r
使用 -r 选项读取文件。
命令:
tcpdump -r tcpdump_test.log
![读取记录文件
5. 打印出所有可工作的接口 -D
命令:
tcpdump -D
其中网卡为 eth0。
6. 指定监控的网卡 -i
命令:
tcpdump -i eth0
如果不指定网卡,默认 tcpdump 只会监视第一个网络接口,一般是 eth0。
7. 显示更详细的数据包信息 -v -vv
选项 -v,-vv 可以显示更详细的抓包信息。
tcpdump -v
tcpdump -vv
8. 不使用域名反解 -n
使用 -n 后,tcpdump 会直接显示 IP 地址,不会显示域名(与 netstat 命令相似)。
9. 增加抓包时间戳 -tttt 选项
tcpdump 的所有输出打印行中都会默认包含时间戳信息;时间戳信息的显示格式如下
hh:mm:ss.frac (nt: 小时:分钟:秒 .)
此时间戳的精度与内核时间精度一致, 反映的是内核第一次看到对应数据包的时间;
而数据包从物理线路传递到内核的时间, 以及内核花费在此包上的中断处理时间都没有算进来;
使用 -tttt 选项,抓包结果中将包含抓包日期:
命令:
tcpdump -tttt
增加抓包时间戳
四、条件过滤
1. 过滤:指定需要抓取的协议
tcpdump 可以只抓某种协议的包,支持指定以下协议:「ip,ip6,arp,tcp,udp,wlan」等。
命令:
tcpdump udp
tcpdump icmp
tcpdump tcp
tcpdump arp
2. 过滤:指定协议的端口号
使用 port 参数,用于指定端口号。
命令:tcpdump tcp port 80
使用 portrange 参数,用于指定端口范围。
命令:tcpdump tcp portrange 1-1024
3. 过滤:指定源与目标
src 表示源。
dst 表示目标。
命令:
tcpdump src port 8080
tcpdump dst port 80
4. 过滤:指定特定主机的消息包
使用 host 指定需要监听的主机。
命令:
tcpdump host 192.168.1.113
注意:若使用了 host 参数使用了计算机名或域名。例 tcpdump host shi-pc ,则无法再使用 -n 选项。
5. 过滤:指定数据包大小
使用 greater(大于)与 less(小于)可以指定数据包大小的范围。
「例:只抓取大于 1000 字节的数据包。」
命令:
tcpdump greater 1000
「例:只抓取小于 10 字节的数据包。」
命令:
tcpdump less 10
五、 逻辑表达式
使用基本逻辑组合拼装出更精细的过滤条件。
1. 逻辑与
逻辑与关系,使用 and。
命令:
tcpdump tcp and host 192.168.1.112
tcpdump tcp and src 192.168.1.112 and port 8080
2. 逻辑或
逻辑或关系,使用 or。
命令:
tcpdump host 192.168.1.112 or 192.168.1.113
3. 逻辑非
逻辑非关系,使用 not,也可以使用 ! 。
若使用 ! 必须与其后面的字符隔开一个空格。
例:当通过 ssh 协议远程使用 tcpdump 时,为了避免 ssh 的数据包的输出,所以一般需要禁止 ssh 数据包的输出。
命令:
tcpdump not tcp port 22
tcpdump ! tcp port 22
4. 括号
括号需要使用在引号内,或转意使用。否则会报错。
例:抓取非 22 端口,且主机为 192.168.1.112 和 192.168.1.113 的 TCP 数据包。
命令:
tcpdump not tcp port 22 and host 192.168.1.112or192.168.1.113
tcpdump "not tcp port 22 and host (192.168.1.112 or 192.168.1.113)"
tcpdump not tcp port 22 and host "(192.168.1.112 or 192.168.1.113)"
六、其他实例
1. 打印所有进入或离开 sundown 的数据包 .
tcpdump host sundown
2. 截获主机 210.27.48.1 和主机 210.27.48.2 或 210.27.48.3 的通信
tcpdump host 210.27.48.1 and (210.27.48.2 or 210.27.48.3 )
3. 如果想要获取主机 210.27.48.1 除了和主机 210.27.48.2 之外所有主机通信的 ip 包,使用命令:
tcpdump ip host 210.27.48.1 and ! 210.27.48.2
4. 监视所有送到主机 hostname 的数据包
tcpdump -i eth0 dst host hostname
5. 获取主机 210.27.48.1 接收或发出的 telnet 包
23 为 telnet 的端口
tcpdump tcp port 23 and host 210.27.48.1
6. 监视本机的 udp 123 端口
123 为 ntp 的服务端口
tcpdump udp port 123
7. 使用 tcpdump 抓取 HTTP 包
tcpdump -XvvennSs 0 -i eth0 tcp[20:2]=0x4745 or tcp[20:2]=0x4854
- 0x4745 为"GET"前两个字母"GE",0x4854 为"HTTP"前两个字母"HT"。
tcpdump 对截获的数据并没有进行彻底解码,数据包内的大部分内容是使用十六进制的形式直接打印输出的。
显然这不利于分析网络故障,通常的解决办法是先使用带**-w 参数的 tcpdump 截获数据并保存到文件中**,然后再使用其他程序(如 Wireshark)进行解码分析。当然也应该定义过滤规则,以避免捕获的数据包填满整个硬盘。
六、查看数据包完整内容
tcpdump 默认不显示数据包的详细内容。
方法一:
使用 -A 参数能以 ASCII 码显示数据包。
例:只抓取 1 个数据包,并显示其内容。
命令:
tcpdump -c 1 -A
方法二:
使用 -X 参数能 16 进制数与 ASCII 码共同显示数据包。
例:只抓取 1 个数据包,并显示其内容。
命令:
tcpdump -c 1 -X
七、tcpdump 与 wireshark
Wireshark(以前是 ethereal)是 Windows 下非常简单易用的抓包工具,现在也有 Linux 版本。
通过 Tcpdump 抓取的数据包分析比较麻烦,要想很方便的分析数据包, 我们可以用 Tcpdump + Wireshark 的完美组合实现:在 Linux 里抓包,然后在 Windows 里分析包。
保存数据包为 wireshark 能识别的文件:
tcpdump tcp -i eth1 -t -s 0 -c 100 and dst port ! 22 and src net 192.168.1.0/24 -w ./target.cap
参数 | 含义 |
---|---|
tcp | ip icmp arp rarp 和 tcp、udp、icmp 这些选项等都要放到第一个参数的位置,用来过滤数据报的类型 |
-i eth1 | 只抓经过接口 eth1 的包 |
-t | 不显示时间戳 |
-s 0 | 抓取数据包时默认抓取长度为 68 字节。加上 -S 0 后可以抓到完整的数据包 |
-c 100 | 只抓取 100 个数据包 |
dst port ! 22 | 不抓取目标端口是 22 的数据包 |
src net 192.168.1.0/24 | 数据包的源网络地址为 192.168.1.0/24 |
-w ./target.cap | 保存成 cap 文件,方便用 ethereal(即 wireshark)分析 |