一、IP/TCP包头图参考!
二、实例抓包分析(IP/TCP包头)
#tcpdump 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'
作用:打印所有源或目的端口是80, 网络层协议为IPv4, 并且含有数据,而不是SYN,FIN以及ACK-only等不含数据的数据包
解释:
tcp port 80 不在赘述。
1、ip[2:2] ip数据包总长度
如下图所示,红框标记的二进制00000000 00101000换算成10进制正好40.
2、(ip[0]&0xf)
ip包头长度。
ip[0]:表示IP包头从第一个字节。
0xf:16进制f,二进制即1111;
ip[0]&0xf:ip包头第一个字节和16进制f做“与”计算。
即01000101 & 00001111 => 00000101
目的:通过与计算ip包头第一个字节高位4位清零,只剩包头长度字节位。
最终目的是为了计算ip包头长度
3、((ip[0]&0xf)<<2))
:表示包头二进制左移两位,为什么要左移2位,原因如下
此域的单位为32bit, 要换算成字节(8bit)数需要乘以4, 即二进制左移2(<<2)。
如下图所示:
length 为20,bytes(5)。5二进制为00000101 左移两位变为00010100 转换为10进制就是20
4、(tcp[12]&0xf0)>>2)
这个其实应写为:(((tcp[12]&0xf0) >> 4)<<2):意思是计算tcp包头长度
1)tcp[12]&0xf0
tcp第12个字节和16进制的f0进行“与”操作。第12字节低四位清零,高四位不变。
2)(tcp[12]&0xf0) >> 4
(tcp[12]&0xf0)右移四位后变为00000101,可计算出tcp包头数值
3)((tcp[12]&0xf0) >> 4)<<2
(tcp[12]&0xf0) >> 4,此域的单位为32bit, 要换算成字节(8bit)数需要乘以4, 即二进制左移2即:((tcp[12]&0xf0) >> 4)<<2可转化为((tcp[12]&0xf0)>>2))
三、实例分析(http get post)
抓取http get
#tcpdump -s 0 -A 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420'
#tcpdump -s 0 -A 'tcp[((tcp[12] & 0xf0) >> 2):4] = 0x47455420'
tcp[12:1]和tcp[12]意思应该相同
1)((tcp[12] & 0xf0) >> 2)
tcp头部总长度,
2)tcp[((tcp[12] & 0xf0) >> 2):4]
TCP头部长度位置向后取4字节,即http开始前4个字节。
即:tcp上层是http,http get 占http header前4个字节。
3)0x47455420
http get十六进制的数值
如下图所示红框所示:
http get 二进制01000111 01000101 01010100 00100000 转换为16进制就是47455420
2)抓取http post
tcpdump
-s 0 -A
'tcp dst port 80 and (tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x504f5354)'
不做分析。