获取 http 标头的不是 BPF 过滤器,而是 tcpdump 命令上的“-A”开关。
您的 tcpdump 命令在 eth0 上查找到某个目的地或某个源的 tcp 流量,其中最终 BPF 过滤器涉及的计算结果为非零总数。使用“-A”选项,它以 ASCII 格式打印每个数据包减去其链接级别的标头。
我已经解释了下面的计算,但我相信实际过滤器中存在一些问题,可能是通过复制和粘贴。当您在 tcpdump 中使用这些过滤器时,您使用的是 tcp 位掩码,通常在检查不落在字节边界上的字段时使用
ip[2:2]
指 IP 标头中的两个字节(即第 3 和第 4 字节),从字节 2 开始(记住它从偏移量 0 开始)。这个总数表示 IP 数据包的总长度,最大可以是 65535 字节。
对于这里的位掩码,为清楚起见,我预先添加了一个“0”,因此掩码0xf
变为0x0f
. 根据下面 GuyHarris 的评论,面具上的前导“0”被删除。
您需要将最后 2 个长度乘以 4,因为它们是 32 位/4 字节字,因此需要转换为以字节为单位的总数,以便计算正确
您的过滤器应该计算:
- IP 数据包长度(以字节为单位) - IP 标头长度 - TCP 标头长度
并寻找该值为零,即像这样
sudo tcpdump -A -nnpi eth0 '(ip[2:2] - ((ip[0]&0x0f)*4) - ((tcp[12]&0xf0)*4) != 0)'
当您执行减法时,您正在寻找一个非零的总数。这个非零总数意味着在第 4 层之上有数据,即 tcp 有效负载中的数据,通常是应用程序流量。
port 80
假设大多数 http 流量通过端口 80,您可能还需要添加。
安全人员通常使用这样的过滤器来检测 SYN 上的数据,这是不正常的,但根据 RFC,这是允许的。所以整个事情看起来像 -
'tcp[13]=0x02 and (ip[2:2] - ((ip[0]&0x0f)*4) - ((tcp[12]&0xf0)*4) != 0)'
TCPIPGuide是一个非常好的免费在线 TCP/IP 指南。
更新:根据 Guy Harris 的更新修改位掩码上的“前导零”部分。