关于HTTP头域User-Agent二三事

  本文主要思考了HTTP协议中User-Agent相关的内容。

  strings命令用来提取pcap文件中的UA,host等头域字段,大致的形式是strings-d *.pcap | grep -ioP "User-Agent:.*" | sort | uniq –c,意思是统计该目录下面的所有pcap文件中的UA字段,并统计该UA出现的次数。我试了一下,却发现如下图所示的情况

关于HTTP头域User-Agent二三事_第1张图片

  黑线标识的那一行出现了KHTf这个东西,我们知道KHTML是浏览器的渲染引擎,但是并没有听说过KHTf这种东西,查看报文后得知造成这种现象的原因是由于HTTP上层传来的报文过大,大于了以太网的数据上限1500,因此要分包传输。也就是说UA部分分成了两个包进行传输。而我们的strings命令仅仅只能够提取含有UA报文中的那个部分。剩下的部分为什么不能够提取呢,原因要从pcap文件格式说起。

  pcap的格式是:文件头(指的是整个pcap文件的头)24字节+数据包头(每一个报文的头)16字节+数据包内容。因此将pcap以文本的形式打开的时候会发现两个报文之间会有16个字节的数据,就是pcap格式中下一个报文的数据包头。Strings本质的功能是将pcap按照文本方式进行搜索,因此在数据进行分段的时候,会造成本是同一个UA,但是分段之后,筛选出来的只前半部分,甚至如果数据包头之中有可显示自字符,会产生不同的UA,即上图所示的内容。但是这个命令额外带来的好处就是能够提示我们报文发生了分段。

  有没有提取UA的方法能够规避上述的情况的,毕竟我们如果要进行UA的统计,上述的情况会造成很大的误差。既然文本的方式不可行,那么我们就按照pcap的格式进行处理。tshark命令可以方便的做到这一点,类似的形式如:

tshark -r PCONLINE_Android5.0.2_GALAXYTABS_v4.5.1_zixun_201600525.pcap -T fields -e http.user_agent -E header=y -E separator=/t | sort | uniq –c

可以通过-h查询其具体用法。但是tshark的缺点在于不能够向strings那样.*直接遍历本目录下面所有的文件,于是写了一个shell脚本如下:

find -name '*.pcap' > pcapfilename.txt
while read LINE
do
 echo $LINE
 tshark -r $LINE -T fields -e http.user_agent -E header=y -E separator=, | sort | uniq -c >> UA.txt
 print $LINE
 done < pcapfilename.txt
 cat UA.txt | sort -k 2,30 -d| awk '{$1=""}{print $0}' | uniq -c | awk '{$1=""}{print $0}' | grep -v "^$" >UASORT.txt

  find命令遍历本目录,循环使用tshark命令提取UA,sort排序命令,uniq删除重复行,>>追加到尾部,由于awk输出指定列,grep删除空格。最后我统计了不重复的UA有8187个,去重之前UA个数为127935次。看了一些这些UA,发现写的非常的“有意思”。如下图所示

关于HTTP头域User-Agent二三事_第2张图片

  Youtube 的UA还是比较规范的,但是很多的UA并不是这个样子,继续看:

关于HTTP头域User-Agent二三事_第3张图片

  难道6577行代表的是Linux注释吗,6573行又是什么鬼,如果想伪装,那怎么也得伪装的像一点吧

关于HTTP头域User-Agent二三事_第4张图片

  好吧,纪念一下曾经的视频领域王者,快播,默哀三分钟

关于HTTP头域User-Agent二三事_第5张图片

  在notepad里面以UTF-8格式显示,居然出现了带上标的UA,这个什么鬼

关于HTTP头域User-Agent二三事_第6张图片

  难道写程序的哥们认为UA是可以任意嵌套的吗

关于HTTP头域User-Agent二三事_第7张图片

  这一串数字让UA这个字段只能够被写程序的那个人懂得

关于HTTP头域User-Agent二三事_第8张图片

关于HTTP头域User-Agent二三事_第9张图片

  好吧,反正HTTP  law在UA中并没有强制规定什么,难道你们就如此的钻法律的漏洞。。。。。。

  我以前理解HTTP是一个松散的协议是从HTTP头部可以很容易的扩展来理解的,比如最近经常发现APP这种私有的头域,还有就是腾讯的一些服务里面有较多的自定义的头域,以及以X开头的非标准头域等。提一句就是RFC2616已经被废弃了,最新的文档变成了RFC7230,RFC7231,RFC7232 ,RFC7233,RFC7234,RFC7235具体参考http://www.infoq.com/cn/news/2014/06/http-11-updated/

  看了一下RFC7231中关于UA的定义发现有这样一句asender MUST NOT generate advertising or other nonessential information withinthe product identifier。但是实际上关于UA头域的值,RFC7231里面很多的是should或者建议这么写,这与前面那一句本身就是一种矛盾,从这个方面看HTTP是不是也是松散的呢?从另一个方面来讲,UA甚至其他的头域很多的是should或者建议这么写,但是实际的开发者并没有这么做,这本身也是松散的。

  分析完事之后,难道UA头域的乱象应该归咎于HTTPlaw的制定者,我的天。。。。

  看完了上面千奇百怪的UA,我们看一下比较规范的UA是什么样子的http://www.73207.com/useragent/pages/useragentstring.php.htm,这个页面展示了互联网上一些比较出名爬虫,浏览器,离线浏览器等应用的UA。例如百度,有道,搜狗的爬虫等。浏览器的诸如Chrome和Firefox等。可以看到浏览器的书写的都是很规范的,每一个字段的含义可以参考http://www.cnblogs.com/langtianya/p/4378801.html。从浏览器的标识字段依稀可以看到网景公司作为浏览器的先行者所做的贡献。浏览器的默认的是浏览器标识+操作系统标识+加密等级标识+浏览器语言+渲染引擎标识+各自浏览器信息,RFC说了一般约定这部分会按照重要性进行降序,但是我反而觉得各自的浏览器信息更重要呢?这个默认标准应该是最初浏览器的厂商没约定标准,因为HTTP协议本身并没有做相关的规定,大多数的浏览器还是基本遵循了这样一个标准,但是诸如UC等并没有这样做。后来移动APP的普及,很多就是直接写上了APP的名字,省去了其他的信息,个人觉得反而更加接近RFC7231中的建议。

  以上就是在提取UA过程中一些思考,如有不准确的地方,多多指教。


你可能感兴趣的:(协议分析,认识计算机网络)