Tcpdump&Wireshark 再学习与理解

常用参数:

-w 文件名,可以把报文保存到文件;

-c 数量,可以抓取固定数量的报文,这在流量较高时,可以避免一不小心抓取过多报文;

-s 长度,可以只抓取每个报文的一定长度,后面我会介绍相关的使用场景;

-n,不做地址转换(比如 IP 地址转换为主机名,port 80 转换为 http);

-v/-vv/-vvv,可以打印更加详细的报文信息;

-e,可以打印二层信息,特别是 MAC 地址;

-p,关闭混杂模式。所谓混杂模式,也就是嗅探(Sniffing),就是把目的地址不是本机地址的网络报文也抓取下;

-X,使用ASCII显示报文内容

 

通过tcptrace 工具(需要单独安装),读取报文:

通过RPMFIND寻找到YUM包

tcptrace -b test.pcap

 

 

用例记录:

# 使用偏移量的方法,抓取TLS 握手阶段的 Client Hello 报文

tcpdump -w file.pcap 'dst port 443 && tcp[20]==22 && tcp[25]==1'

:: 相关解释

dst port 443:这个最简单,就是抓取从客户端发过来的访问 HTTPS 的报文。

tcp[20]==22:这是提取了 TCP 的第 21 个字节(因为初始序号是从 0 开始的),由于 TCP 头部占 20 字节,TLS 又是 TCP 的载荷,那么 TLS 的第 1 个字节就是 TCP 的第 21 个字节,也就是 TCP[20],这个位置的值如果是 22(十进制),那么就表明这个是 TLS 握手报文。

tcp[25]==1:同理,这是 TCP 头部的第 26 个字节,如果它等于 1,那么就表明这个是 Client Hello 类型的 TLS 握手报文。

 

# 用偏移量方法,写一个 tcpdump 抓取 TCP SYN 包的过滤表达式

tcpdump 'tcp[13]&2 != 0'

 # 如果要指定只抓取 SYN 包而不抓取 SYN+ACK,可以用下面的表达式

tcpdump 'tcp[13]|2 = 2'

 

# 过滤出 TCP RST 报文(TCPDUMP 预定义)

tcpdump -w file.pcap 'tcp[tcpflags]&(tcp-rst) != 0'
# 偏移量的写法
tcpdump -w file.pcap 'tcp[13]&4 != 0'

 

# 查看端口80的数据包内容

tcpdump port 80 -X

 

# 读取报文内容示例

tcpdump -r file.pcap 'tcp[tcpflags] & (tcp-rst) != 0'

 

# 过滤报文并进行转存示例

tcpdump -r file.pcap 'tcp[tcpflags] & (tcp-rst) != 0' -w rst.pcap

 

# 抓包时间如何长一点  -s 参数 size

tcpdump -s 74 -w file.pcap

二层:帧头是 14 字节

三层:IP 头是 20 字节

四层:TCP 头是 20~40 字节

如果你明确地知道这次抓包的重点是传输层,那么理论上,对于每一个报文,你只要抓取到传输层头部即可,也就是前 14+20+40 字节(即前 74 字节)

# 如果确定问题是在 IP 层,tcpdump 命令如何写,可以做到既找到 IP 层的问题,又节约抓包文件大小呢?

tcpdump -s 36(计算字节为34+2[Linux cooked capture v1 占用2字节]) -w file.pcap

在 tcpdump 里,对于 any 这个接口,它在输出帧头的时候用了一种叫 Linux cooked capture v1 的格式,这个格式的长度是 16 个字节,而以太网帧是 14 字节。这就造成了 2 个字节的差异,也就是按原先的 34 字节去抓取就不够了,所以要扩大到 36 字节才可以抓到完整的 IP 头部。

 

# 指定抓包时间端,并且过滤重传包除开序列1的示例

frame.time >="Jan 08, 2024 08:30:00" and frame.time <="Jan 08, 2024 08:35:00" and ip.src_host == X.X.X.X and tcp.flags.reset eq 1 and !(tcp.seq_raw eq 1 and tcp.ack_raw eq 1)

  

# 寻找指定的TCP 裸序列号的报文

tcp.seq_raw eq 3322242815

 

 # 怎么知道抓包文件是在哪一端抓取的?

 要搞清楚这一点也很简单,我们可以利用 IP 的 TTL 属性。显然,无论是哪一端,它的报文在发出时,其 TTL 就是原始值,也就是 64、128、255 中的某一个。而对端报文的 TTL,因为会经过若干个网络跳数,所以一般都会比 64、128、255 这几个数值要小一些。

 

# 在 Linux 中,还有一个内核参数也是关于握手的,net.ipv4.tcp_synack_retries。你知道这个参数是用来做什么的吗?

man tcp
然后搜索 tcp_synack_retries 就可以了,也就是这个部分:
tcp_synack_retries (integer; default: 5; since Linux 2.2)The maximum number of times a SYN/ACK segment for a passive TCP connection will be retransmitted.  This number should not be higher than 255.

也就说,这是 TCP 回复 SYN+ACK 后等不到 ACK 时,需要重试的次数。

 

# 如果要在 Wireshark 中搜索到挥手阶段出现的 RST+ACK 报文,那么这个过滤器该如何写呢?

tcp.flags.ack eq 1 and tcp.flags.reset eq 1

# 利用 TCP 的载荷本身的特征去找到对应的报文 (其他类型的以此类推)

tcp contains "id=abcdafeafeagfeagfaraera1242dfea"
frame contains "id=abcdafeafeagfeagfaraera1242dfea"
ip contains "id=abcdafeafeagfeagfaraera1242dfea"
http contains "id=abcdafeafeagfeagfaraera1242dfea"

 

 

 

posted @ 2024-01-18 14:07  Cong0ks  阅读(69)  评论(0编辑  收藏  举报