我试图通过使用tcpdump来嗅探http标头。
此过滤器效果很好但我无法理解 -
(((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)
我用谷歌搜索了它,但我找不到任何有用的信息
这是整个tcpdump命令
sudo tcpdump -A 'dst [dest host] or src [src host] and tcp and
(((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)' -i eth0
答案 0 :(得分:16)
这不是BPF过滤器获取http标头,而是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'被删除。
ip[0]&0x0f
指的是IP头中字节0的后半部分(即第1个字节),它将为您提供32位字的IP头长度,因此,这通常会成倍增加这样的计算是4。
tcp[12]&0xf0)
指的是字节12的前半部分(即第11字节),它是数据偏移字段,它以32位字的形式指定TCP标头的大小,因此,对于这样的计算,这通常乘以4。
您需要将最后2个长度乘以4,因为它们是32位/ 4字节字,因此需要转换为总字节数才能使计算正确
您的过滤器应该计算:
并将该值视为零,即类似这样的
sudo tcpdump -A -nnpi eth0 '(ip[2:2] - ((ip[0]&0x0f)*4) - ((tcp[12]&0xf0)*4) != 0)'
当您执行减法时,您正在寻找非零总数。这个非零总数意味着第4层以上的数据,即tcp有效载荷中的数据,通常是应用流量。
假设大多数HTTP流量超过端口80,您可能还想添加port 80
。
这样的过滤器通常被安全人员用来检测SYN上的数据,这是不正常的,但根据RFC,它是允许的。所以整个事情看起来像 -
'tcp[13]=0x02 and (ip[2:2] - ((ip[0]&0x0f)*4) - ((tcp[12]&0xf0)*4) != 0)'
TCPIPGuide是一个非常好的,免费的TCP / IP btw在线指南。
更新:根据Guy Harris的更新修改位掩码上的“前导零”部分。