【Network】tcpdump 抓包

Posted by 西维蜀黍 on 2020-06-20, Last Modified on 2023-11-26

OpenWrt安装

$ opkg update && opkg install tcpdump

Usage

默认启动

$ tcpdump

普通情况下,直接启动tcpdump将监视第一个网络接口上所有流过的数据包。

# get list of interfaces
$ ifconfig

# do tcpdump on lan interface 'br-lan'
$ tcpdump -i br-lan -n

# dump for http traffic
$ tcpdump -i br-lan port 80

# dump for ssh traffic on wan, but do not show self
$ tcpdump -i eth0 port 22 and not host 192.168.1.7

tcpdump -D - List available network interfaces

$ tcpdump -D
1.br-lan [Up, Running]
2.eth0 [Up, Running]
3.eth1 [Up, Running]
4.lo [Up, Running, Loopback]
5.any (Pseudo-device that captures on all interfaces) [Up, Running]
6.wlan0 [none]

# Or
$ tcpdump --list-interfaces

-i [interface] - 监视指定网络接口的数据包

$ tcpdump -i eth1

如果不指定网卡,默认tcpdump只会监视第一个网络接口,一般是eth0,下面的例子都没有指定网络接口。 

-i any 是监听所有接口。

监视指定主机的数据包

打印所有进入或离开sundown的数据包

$ tcpdump host [sundown]

也可以指定ip,例如截获所有210.27.48.1 的主机收到的和发出的所有的数据包

$ tcpdump host 210.27.48.1 

截获主机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 \) 

如果想要获取主机210.27.48.1除了和主机210.27.48.2之外所有主机通信的ip包,使用命令:

$ tcpdump ip host 210.27.48.1 and ! 210.27.48.2

Capture the traffic from a specific interface, source, destination and destination port:

 tcpdump -i eth0 src 192.168.1.1 and dst 192.168.1.2 and dst port 80

监视除以外端口的数据包

$ tcpdump  port ! 2423 and port ! 12984 and port ! 2538

监视指定主机和端口的数据包

如果想要获取主机210.27.48.1接收或发出的telnet包,使用如下命令

$ tcpdump tcp port 23 and host 210.27.48.1

对本机的udp 123 端口进行监视 123 为ntp的服务端口

$ tcpdump udp port 123 

Capture by a network

Capture the traffic of a network:

$ tcpdump net 192.168.1.0/24

-w [file] - 写入到文件

$ tcpdump -w all.cap

Usage By Package Types

Capture TCP/UDP

Capture all TCP traffic showing contents (ASCII) in console:

$ tcpdump -A tcp

DHCP

$ tcpdump -i any udp and port 67 and port 68

HTTP

# To monitor HTTP traffic including request and response headers and message body:
$ tcpdump -vv -A -s 0 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
14:43:47.219633 IP 192.168.18.68.57481 > ce827a05db87.3000: Flags [P.], seq 3103190490:3103191420, ack 2573239252, win 2048, options [nop,nop,TS val 566888354 ecr 4013071655], length 930
E.....@.?..!...D.............`......r......
!....2.'PUT /api/datasources/1 HTTP/1.1
Host: 192.168.18.129:3000
Connection: keep-alive
Content-Length: 369
accept: application/json, text/plain, */*
x-grafana-org-id: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36
content-type: application/json
Origin: http://192.168.18.129:3000
Referer: http://192.168.18.129:3000/datasources/edit/AYdIJLm7z
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: grafana_session=05c5e5d081c4f0505ad9a9d6da497a5d

{"id":1,"uid":"AYdIJLm7z","orgId":1,"name":"Prometheus","type":"prometheus","typeLogoUrl":"","access":"proxy","url":"http://192.168.18.129:9090/","password":"","user":"","database":"","basicAuth":false,"basicAuthUser":"","basicAuthPassword":"","withCredentials":false,"isDefault":true,"jsonData":{"httpMethod":"POST"},"secureJsonFields":{},"version":7,"readOnly":false}
14:43:47.227354 IP ce827a05db87.3000 > 192.168.18.68.57481: Flags [P.], seq 1:697, ack 930, win 501, options [nop,nop,TS val 4013275727 ecr 566888354], length 696
E...g.@.@.QM.......D.....`.....|...........
.5.O!...HTTP/1.1 200 OK
Cache-Control: no-cache
Content-Type: application/json
Expires: -1
Pragma: no-cache
X-Content-Type-Options: nosniff
X-Frame-Options: deny
X-Xss-Protection: 1; mode=block
Date: Thu, 15 Jul 2021 14:43:47 GMT
Content-Length: 442

{"datasource":{"id":1,"uid":"AYdIJLm7z","orgId":1,"name":"Prometheus","type":"prometheus","typeLogoUrl":"","access":"proxy","url":"http://192.168.18.129:9090/","password":"","user":"","database":"","basicAuth":false,"basicAuthUser":"","basicAuthPassword":"","withCredentials":false,"isDefault":true,"jsonData":{"httpMethod":"POST"},"secureJsonFields":{},"version":8,"readOnly":false},"id":1,"message":"Datasource updated","name":"Prometheus"}
# monitor prometheus agent's curl (modify the port accordingly)
$ tcpdump -vv -A -s 0 'tcp port 50881 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'

# To monitor HTTP traffic including request and response headers and message body from a particular source:
$ tcpdump -vv -A -s 0 'src example.com and tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'

# To monitor HTTP traffic including request and response headers and message body from localhost to localhost:
$ tcpdump -vv -A -s 0 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)' -i lo

# for HTTP GET
$ tcpdump -vv -s 0 -A 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420'

# for HTTP POST 
$ tcpdump -vv -s 0 -A 'tcp dst port 80 and (tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x504f5354)'

ICMP

$ tcpdump icmp

DNS

$ tcpdump -i any port 53 -vv

-v/-vv - Verbose

tcpdump 与Wireshark

Wireshark是一个非常简单易用的抓包工具。但在Linux下很难找到一个好用的图形化抓包工具。

还好有tcpdump。我们可以用Tcpdump + Wireshark 的完美组合实现:在 Linux 里抓包,然后在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文件,方便用 Wireshark 分析

Reference