tcpdump实例
实用的tcpdump实例可以解决你的网络故障和安全问题。 命令和示例并不仅仅是使用tcpdump
,而且还是掌了解你的网络的方法。
了解tcpdump
是一项必不可少的技能,可以为系统管理员,网络工程师或者专业的安全人员派上用场。
基础
分解Tcpdump命令
以下命令是使用tcpdump
时经常能看到的参数。
:~$ sudo tcpdump -i eth0 -nn -s0 -v port 80
-i: 选择在哪个端口上进行捕捉,这通常是一个网卡或者无线适配器,但也可以是一个vlan
或某些更不常用的设备。 如果只有一个网络适配器的话,就不需要这参数了。
-nn: 单独一个(n)不会解析主机名(直接显示IP)。 两个(n)将不会解析主机名或端口(直接显示IP或端口号)。 这个不仅更方便于查看IP/端口,还可以捕获大量的数据,并且可以大大提高捕获速度,因为名称解析会降低捕获速度。
-s0: 捕获数据的长度,捕获数据包的大小。-s0
将大小设置为无限制,如果要捕获所有流量,请使用此选项。 另外,如果你想从网络流量中获取二进制文件或文件,需要使用这个选项。
-v: 详细信息,使用(-v)或者(-vv)增加输出的详细信息的信息量,经常是显示更多的协议的特定信息。
port 80: 这通常是一个端口过滤器,只捕获80端口上的流量,这个端口当然通常是HTTP。
显示ASCII字符的文本
在命令中加入-A
参数,会从捕获的输会包含ascii
字符。 这样可以很容易的读取并使用grep
或其他命令来解析输出。 另外还有个选项-X
也可以显示ASCII,并且可以显示十六进制输出。
:~$ sudo tcpdump -A -s0 port 80
捕获指定协议
过滤UDP的流量。 另一种方法是指定协议号protocol 17,这就是udp
。 以下这两个命令的结果是相同的。 与tcp
过滤器相同的是protocol 6。
:~$ sudo tcpdump -i eth0 udp
:~$ sudo tcpdump -i eth0 proto 17
基于IP地址来捕获指定的主机
使用host
过滤器可以捕获到达(目的地)和来自(源)这个IP的流量。
:~$ sudo tcpdump -i eth0 host 10.10.1.1
或者,使用src
或dst
来捕获一个方向的包。
:~$ sudo tcpdump -i eth0 dst 10.10.1.20
写入一个捕获文件
通过一个普通的命令选项就可以写一个标准的pcap
文件。 写入的捕获文件可以在Wireshark或者其它的包分析工具中打开。
:~$ sudo tcpdump -i eth0 -s0 -w test.pcap
行缓冲模式
如果没有强制使用行缓冲模式(-l)或者数据包缓冲模式(-C)选项,在tcpdump
输出时,通过管道传递给另一个命令(如grep)时,你不过实时获得预期的响应。 通过使用此选项,输出会立即通过管道发送给另一个命令,在排除故障时会立即响应。
:~$ sudo tcpdump -i eth0 -s0 -l port 80 | grep 'Server:'
组合过滤器
在上面这些示例中,你可以使用以下的标准逻辑来组合不同的过滤器。
and or &&
or or ||
not or !
实例
在下面的例子中,很多都是可以用多种方法来实现相同的结果。 如在一些示例中所见,可以直接捕获包中的各个位。
你使用什么方法将取决于你想要的什么样的输出及在线路上的流量。 如在一个流量频繁的千兆链接上,可能会强制你使用特定的低级别的数据包过滤器。
当在排障时,你经常是想直接得到结果,这时需要在端口上进行过滤,并且选择ascii输出来结合grep
, cut
或者awk
来获得最后结果。如果需要,你可以随时深入挖掘数据包。
例如,当捕获HTTP请求和返回时,你可以通过移除SYN/ACK/FIN来过滤所有的除了数据之外的数据包,但无论怎样你如果使用grep
都可以过滤掉噪音。(Keep it simple.)
可以在下面的例子中看到,其目的也是以最简单(也是最快)的方式来获得结果。
1. 提取HTTP的User-Agent
从HTTP请求头中提取User-Agent。
:~$ sudo tcpdump -nn -A -s1500 -l | grep "User-Agent:"
通过使用egrep
和多匹配项,我们可以获取User-Agent和Host(或者其它的字段)从请求中。
:~$ sudo tcpdump -nn -A -s1500 -l | egrep -i 'User-Agent:|Host:'
2. 只捕获HTTP的GET和POST包
深入的了解了过滤器后,发现我们只能指定匹配GET请求。
:~$ sudo tcpdump -s 0 -A -vv 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420'
或者我们只能选择匹配POST请求。 注意,这里可能POST的数据没有包含在这个过滤器捕获的数据包中,POST请求可能会被拆分跨多个TCP数据包。
:~$ sudo tcpdump -s 0 -A -vv 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x504f5354'
上面表达式的中16进制匹配的是GET和POST的ascii码。
tcp[((tcp[12:1] & 0xf0) >> 2):4]中首先我们先确定我们需要的字节位置(在TCP标头之后的), 然后选择我们希望匹配的4个字节。
3. 提取HTTP请求中的URL
从流量中简单的分析Host和HTTP请求的位置(URL)。 这里不指定80端口,我们可能在任何端口找到HTTP的请求,例如运行在高端口的HTTP服务。
:~$ sudo tcpdump -s 0 -v -n -l | egrep -i "POST /|GET /|Host:"
tcpdump: listening on enp7s0, link-type EN10MB (Ethernet), capture size 262144 bytes
POST /wp-login.php HTTP/1.1
Host: dev.example.com
GET /wp-login.php HTTP/1.1
Host: dev.example.com
GET /favicon.ico HTTP/1.1
Host: dev.example.com
GET / HTTP/1.1
Host: dev.example.com
4. 提取POST请求中的HTTP密码
从POST数据中获取密码。 这里提取信息包括”Host:”和请求的位置,以便知道密码的用途。
:~$ sudo tcpdump -s 0 -A -n -l | egrep -i "POST /|pwd=|passwd=|password=|Host:"
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp7s0, link-type EN10MB (Ethernet), capture size 262144 bytes
11:25:54.799014 IP 10.10.1.30.39224 > 10.10.1.125.80: Flags [P.], seq 1458768667:1458770008, ack 2440130792, win 704, options [nop,nop,TS val 461552632 ecr 208900561], length 1341: HTTP: POST /wp-login.php HTTP/1.1
.....s..POST /wp-login.php HTTP/1.1
Host: dev.example.com
.....s..log=admin&pwd=notmypassword&wp-submit=Log+In&redirect_to=http%3A%2F%2Fdev.example.com%2Fwp-admin%2F&testcookie=1
5. 从服务器端和客户端捕获Cookies
在服务器上通过检索”Set-Cookie:”(服务器端)和”Cookie:”(客户端)来捕获cookies。
:~$ sudo tcpdump -nn -A -s0 -l | egrep -i 'Set-Cookie|Host:|Cookie:'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on wlp58s0, link-type EN10MB (Ethernet), capture size 262144 bytes
Host: dev.example.com
Cookie: wordpress_86be02xxxxxxxxxxxxxxxxxxxc43=admin%7C152xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxfb3e15c744fdd6; _ga=GA1.2.21343434343421934; _gid=GA1.2.927343434349426; wordpress_test_cookie=WP+Cookie+check; wordpress_logged_in_86be654654645645645654645653fc43=admin%7C15275102testtesttesttestab7a61e; wp-settings-time-1=1527337439
6. 捕获所有ICMP数据包
查看线路上所有的ICMP
数据包。
:~$ sudo tcpdump -n icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp7s0, link-type EN10MB (Ethernet), capture size 262144 bytes
11:34:21.590380 IP 10.10.1.217 > 10.10.1.30: ICMP echo request, id 27948, seq 1, length 64
11:34:21.590434 IP 10.10.1.30 > 10.10.1.217: ICMP echo reply, id 27948, seq 1, length 64
11:34:27.680307 IP 10.10.1.159 > 10.10.1.1: ICMP 10.10.1.189 udp port 59619 unreachable, length 115
7. 显示没有应答/返回的ICMP数据包(标准ping)
通过过滤icmp
类型来选择出非标准的ping
数据包的icmp
数据包。
:~$ sudo tcpdump 'icmp[icmptype] != icmp-echo and icmp[icmptype] != icmp-echoreply'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp7s0, link-type EN10MB (Ethernet), capture size 262144 bytes
11:37:04.041037 IP 10.10.1.189 > 10.10.1.20: ICMP 10.10.1.189 udp port 36078 unreachable, length 156
8. 捕获SMTP/POP3 Email
这样能提取出email邮件体和其他的数据, 在这个例子中我们仅解析出邮件的收件人。
:~$ sudo tcpdump -nn -l port 25 | grep -i 'MAIL FROM\|RCPT TO'
9. 诊断NTP的查询和响应
在这个例子中可以看到NTP的查询和响应。
:~$ sudo tcpdump dst port 123
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
21:02:19.112502 IP test33.ntp > 199.30.140.74.ntp: NTPv4, Client, length 48
21:02:19.113888 IP 216.239.35.0.ntp > test33.ntp: NTPv4, Server, length 48
21:02:20.150347 IP test33.ntp > 216.239.35.0.ntp: NTPv4, Client, length 48
21:02:20.150991 IP 216.239.35.0.ntp > test33.ntp: NTPv4, Server, length 48
10. 捕获SNMP查询和响应
用onsixtyone
快速SNMP协议扫描器来测试一个本地网络的SNMP服务,并且捕获GetRequest
和GetResponse
。 对于那些有过诊断SNMP故障愉快或不愉快经历的人,这都是一个很好的方法去查看线路上到底发生了什么状况。
:~$ onesixtyone 10.10.1.10 public
Scanning 1 hosts, 1 communities
10.10.1.10 [public] Linux test33 4.15.0-20-generic #21-Ubuntu SMP Tue Apr 24 06:16:15 UTC 2018 x86_64
:~$ sudo tcpdump -n -s0 port 161 and udp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on wlp58s0, link-type EN10MB (Ethernet), capture size 262144 bytes
23:39:13.725522 IP 10.10.1.159.36826 > 10.10.1.20.161: GetRequest(28) .1.3.6.1.2.1.1.1.0
23:39:13.728789 IP 10.10.1.20.161 > 10.10.1.159.36826: GetResponse(109) .1.3.6.1.2.1.1.1.0="Linux testmachine 4.15.0-20-generic #21-Ubuntu SMP Tue Apr 24 06:16:15 UTC 2018 x86_64"
11. 捕获FTP凭据和命令
可以直接捕获FTP命令和登录细节。 身份验证之后,FTP的会话可能是主动(active)或被动(passive)模式,使用的模式将确定会话的数据部分是通过TCP 20端口还是另一个随机端口传输的。 使用以下命令你可以捕获输出中的USER和PASS(可以输出给grep),以及LIST, CWD和PASSIVE等FTP命令。
:~$ sudo tcpdump -nn -v port ftp or ftp-data
12. 轮转捕获文件
当捕获大量的流量或者长时间的进行捕获时,采用自动轮转会很有帮助,它会按照固定大小来创建新文件。 使用参数-W
, -G
和-C
来完成自动轮转。
在下面这个命令中,会每(-G)3600秒(1小时)创建文件capture-(hour).pcap。 在第二天这些文件将会被重写,最终这个文件应该是capture-{1-24}.pcap, 如15点,那么新文件就是/tmp/capture-15.pcap__。
:~$ tcpdump -w /tmp/capture-%H.pcap -G 3600 -C 200
13. 捕获IPv6的流量
使用ip6
过滤器可以捕获IPv6的流量。 在下面的例子中我们使用proto 6
和proto 17
指定了TCP和UDP协议。
tcpdump -nn ip6 proto 6
可以从之前保存的捕获文件中读取IPv6的UDP协议。
tcpdump -nr ipv6-test.pcap ip6 proto 17
14. 在网络流量中探测端口扫描
下面这个例子中可以看到这些流量来自一个源到一个目的的。 可以看到标志[S]和[R]与看似随机的一系列目标端口进行匹配。 当SYN在目标系统上发现一个关闭的端口,这些端口会在RESET上被看到。 这是一个典型的被像Nmap样的工具进行扫面的行为。
这里有另一个Nmap的教程, 详细介绍了Wireshark中捕获的端口扫面(open/close/filtered)。
:~$ tcpdump -nn
21:46:19.693601 IP 10.10.1.10.60460 > 10.10.1.199.5432: Flags [S], seq 116466344, win 29200, options [mss 1460,sackOK,TS val 3547090332 ecr 0,nop,wscale 7], length 0
21:46:19.693626 IP 10.10.1.10.35470 > 10.10.1.199.513: Flags [S], seq 3400074709, win 29200, options [mss 1460,sackOK,TS val 3547090332 ecr 0,nop,wscale 7], length 0
21:46:19.693762 IP 10.10.1.10.44244 > 10.10.1.199.389: Flags [S], seq 2214070267, win 29200, options [mss 1460,sackOK,TS val 3547090333 ecr 0,nop,wscale 7], length 0
21:46:19.693772 IP 10.10.1.199.389 > 10.10.1.10.44244: Flags [R.], seq 0, ack 2214070268, win 0, length 0
21:46:19.693783 IP 10.10.1.10.35172 > 10.10.1.199.1433: Flags [S], seq 2358257571, win 29200, options [mss 1460,sackOK,TS val 3547090333 ecr 0,nop,wscale 7], length 0
21:46:19.693826 IP 10.10.1.10.33022 > 10.10.1.199.49153: Flags [S], seq 2406028551, win 29200, options [mss 1460,sackOK,TS val 3547090333 ecr 0,nop,wscale 7], length 0
21:46:19.695567 IP 10.10.1.10.55130 > 10.10.1.199.49154: Flags [S], seq 3230403372, win 29200, options [mss 1460,sackOK,TS val 3547090334 ecr 0,nop,wscale 7], length 0
21:46:19.695590 IP 10.10.1.199.49154 > 10.10.1.10.55130: Flags [R.], seq 0, ack 3230403373, win 0, length 0
21:46:19.695608 IP 10.10.1.10.33460 > 10.10.1.199.49152: Flags [S], seq 3289070068, win 29200, options [mss 1460,sackOK,TS val 3547090335 ecr 0,nop,wscale 7], length 0
21:46:19.695622 IP 10.10.1.199.49152 > 10.10.1.10.33460: Flags [R.], seq 0, ack 3289070069, win 0, length 0
21:46:19.695637 IP 10.10.1.10.34940 > 10.10.1.199.1029: Flags [S], seq 140319147, win 29200, options [mss 1460,sackOK,TS val 3547090335 ecr 0,nop,wscale 7], length 0
21:46:19.695650 IP 10.10.1.199.1029 > 10.10.1.10.34940: Flags [R.], seq 0, ack 140319148, win 0, length 0
21:46:19.695664 IP 10.10.1.10.45648 > 10.10.1.199.5060: Flags [S], seq 2203629201, win 29200, options [mss 1460,sackOK,TS val 3547090335 ecr 0,nop,wscale 7], length 0
21:46:19.695775 IP 10.10.1.10.49028 > 10.10.1.199.2000: Flags [S], seq 635990431, win 29200, options [mss 1460,sackOK,TS val 3547090335 ecr 0,nop,wscale 7], length 0
21:46:19.695790 IP 10.10.1.199.2000 > 10.10.1.10.49028: Flags [R.], seq 0, ack 635990432, win 0, length 0
15. 展示Nmap NSE脚本测试的实例
在这个示例中,展示了Nmap NSE脚本http-enum.nse
针对访问HTTP服务有效的URL的测试。
在Nmap的服务器上:
:~$ nmap -p 80 --script=http-enum.nse targetip
在目标服务器上:
:~$ tcpdump -nn port 80 | grep "GET /"
GET /w3perl/ HTTP/1.1
GET /w-agora/ HTTP/1.1
GET /way-board/ HTTP/1.1
GET /web800fo/ HTTP/1.1
GET /webaccess/ HTTP/1.1
GET /webadmin/ HTTP/1.1
GET /webAdmin/ HTTP/1.1
16. 捕获每个非本地主机的开始和结尾的数据包
这个例子是出自tcpdump
的man page。 通过筛选tcp-syn
和tcp-fin
数据包,可以显示每个已经连接的TCP会话,其中包含时间戳,但没有数据。 与许多过滤器一样,这样可以减少噪音,从而更专注于你关心的信息。
:~$ tcpdump 'tcp[tcpflags] & (tcp-syn|tcp-fin) != 0 and not src and dst net localnet'
17. 捕获DNS请求与响应
在这个捕获中可以看到对外访问Google公共DNS的请求和A记录(ip地址)的响应。
:~$ sudo tcpdump -i wlp58s0 -s0 port 53
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on wlp58s0, link-type EN10MB (Ethernet), capture size 262144 bytes
14:19:06.879799 IP test.53852 > google-public-dns-a.google.com.domain: 26977+ [1au] A? play.google.com. (44)
14:19:07.022618 IP google-public-dns-a.google.com.domain > test.53852: 26977 1/0/1 A 216.58.203.110 (60)
18. 捕获HTTP数据包
在80端口仅捕获HTTP的数据包。 避免捕获TCP的连接(SYN/FIN/ACK)。
tcpdump 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'
19. 使用tcpdump进行捕获并在Wireshark中查看
使用Wireshark(或tshark)解析与分析完整的应用程序流(如HTTP)比用tcpdump
更容易。 通常更实用的事使用tcpdump
捕获结果写入文件的选项来捕获远程系统上的流量。 然后拷贝这个pcap
文件到本地的工作机,使用Wireshark来分析。
除了手动将文件从远程系统移动到本地工作机之外,还可以通过SSH来实时捕获远程系统的流量信息提供给Wireshark。 别忘了使用not port 22
来过滤掉SSH的流量。
:~$ ssh root@remotesystem 'tcpdump -s0 -c 1000 -nn -w - not port 22' | wireshark -k -i -
另一个提示,在远程使用tcpdump
时使用计数选项-c
来允许捕获完成,否则当ctrl-c
时不仅会kiil掉tcpdump
,还会kill掉Wireshark和正在进行捕获。
20. 根据数据包量的主机排名
列出在一段时间根据数据包量来排名连接的主机。 使用简单的命令行通过字段提取来获取IP地址,对事件进行排序和计数。 别忘记限制捕获数量的选项-c
。
sudo tcpdump -nnn -t -c 200 | cut -f 1,2,3,4 -d '.' | sort | uniq -c | sort -nr | head -n 20
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp7s0, link-type EN10MB (Ethernet), capture size 262144 bytes
200 packets captured
261 packets received by filter
0 packets dropped by kernel
108 IP 10.10.211.181
91 IP 10.10.1.30
1 IP 10.10.1.50
21. 捕获所有明文密码
在这个命令中,我们专注于纯文本的协议,并使用grep
来找出和用户或密码相关的信息。 通过grep
的-B5
选项来获得前5行输出,这些行是提供了捕获的密码(主机名, IP地址, 系统)的上下文。
:~$ sudo tcpdump port http or port ftp or port smtp or port imap or port pop3 or port telnet -l -A | egrep -i -B5 'pass=|pwd=|log=|login=|user=|username=|pw=|passw=|passwd=|password=|pass:|user:|username:|password:|login:|pass |user '
22. DHCP的例子
最后一个tcpdump
的例子是监控DHCP请求和应答的。 DHCP请求是在端口67上,应答是在端口68上。 使用-v
选项可以看到协议的选项和其它的细节。
:~$ sudo tcpdump -v -n port 67 or 68
tcpdump: listening on enp7s0, link-type EN10MB (Ethernet), capture size 262144 bytes
14:37:50.059662 IP (tos 0x10, ttl 128, id 0, offset 0, flags [none], proto UDP (17), length 328)
0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from 00:0c:xx:xx:xx:d5, length 300, xid 0xc9779c2a, Flags [none]
Client-Ethernet-Address 00:0c:xx:xx:xx:d5
Vendor-rfc1048 Extensions
Magic Cookie 0x63825363
DHCP-Message Option 53, length 1: Request
Requested-IP Option 50, length 4: 10.10.1.163
Hostname Option 12, length 14: "test-ubuntu"
Parameter-Request Option 55, length 16:
Subnet-Mask, BR, Time-Zone, Default-Gateway
Domain-Name, Domain-Name-Server, Option 119, Hostname
Netbios-Name-Server, Netbios-Scope, MTU, Classless-Static-Route
NTP, Classless-Static-Route-Microsoft, Static-Route, Option 252
14:37:50.059667 IP (tos 0x10, ttl 128, id 0, offset 0, flags [none], proto UDP (17), length 328)
0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from 00:0c:xx:xx:xx:d5, length 300, xid 0xc9779c2a, Flags [none]
Client-Ethernet-Address 00:0c:xx:xx:xx:d5
Vendor-rfc1048 Extensions
Magic Cookie 0x63825363
DHCP-Message Option 53, length 1: Request
Requested-IP Option 50, length 4: 10.10.1.163
Hostname Option 12, length 14: "test-ubuntu"
Parameter-Request Option 55, length 16:
Subnet-Mask, BR, Time-Zone, Default-Gateway
Domain-Name, Domain-Name-Server, Option 119, Hostname
Netbios-Name-Server, Netbios-Scope, MTU, Classless-Static-Route
NTP, Classless-Static-Route-Microsoft, Static-Route, Option 252
14:37:50.060780 IP (tos 0x0, ttl 64, id 53564, offset 0, flags [none], proto UDP (17), length 339)
10.10.1.1.67 > 10.10.1.163.68: BOOTP/DHCP, Reply, length 311, xid 0xc9779c2a, Flags [none]
Your-IP 10.10.1.163
Server-IP 10.10.1.1
Client-Ethernet-Address 00:0c:xx:xx:xx:d5
Vendor-rfc1048 Extensions
Magic Cookie 0x63825363
DHCP-Message Option 53, length 1: ACK
Server-ID Option 54, length 4: 10.10.1.1
Lease-Time Option 51, length 4: 86400
RN Option 58, length 4: 43200
RB Option 59, length 4: 75600
Subnet-Mask Option 1, length 4: 255.255.255.0
BR Option 28, length 4: 10.10.1.255
Domain-Name-Server Option 6, length 4: 10.10.1.1
Hostname Option 12, length 14: "test-ubuntu"
T252 Option 252, length 1: 10
Default-Gateway Option 3, length 4: 10.10.1.1
总结
这些tcpdump
的例子,提示和命令是让你对tcpdump
可以有的用途做个基本了解。 根据你要实现的目标,有许多更深入的方法或组合不同的捕获过滤器来满足你的实际需求。
将tcpdump
和Wireshark结合使用会得到很强的功能,特别是你希望深入了解完整的应用层会话时,因为解释器可以组合完整的流。