kin*_*smk 9 linux networking sniffing tcpdump packet-sniffers
我试图通过使用tcpdump来嗅探http标头.
这个过滤器运行良好,但我无法理解 -
(((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)
Run Code Online (Sandbox Code Playgroud)
我用谷歌搜索了它,但我找不到任何有用的信息
这是整个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
Run Code Online (Sandbox Code Playgroud)
Mar*_*ick 17
不是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的后半部分(即第一个字节),它将为您提供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有效载荷中的数据,通常是应用流量.
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 btw在线指南.
更新:根据Guy Harris的更新修改位掩码上的"前导零"部分.