|
前言 前面
《速通常见应用层协议:从流量视角打开HTTP(中)》
,我们在流量分析角度介绍了HTTP协议的概念、原理、发展历程、流量解码和简单的分析方法之后,又讲了两个重要的指标:请求方式和状态码。今天为大家带来短篇系列的第三篇文章,聊聊重要的HTTP首部字段,它们将对我们进行流量分析提供很大的帮助。HTTP首部内容,为客户端和服务器分别处理请求和响应提供所需要的信息,一般使用“key:value”的形式进行挪列(如host:colasoft.com.cn)。这里的每一种key,就是我们标题中提到的首部字段,value是字段的取值。
要做好HTTP流量分析,免不了要详细分析HTTP请求和HTTP响应的信息,而这些详细信息就保存在HTTP的首部中。HTTP首部位置如下图所示(HTTP数据包解码,我们在第一篇文章中已经讲过,这里不再赘述):
如图所示,首部字段根据实际用途分为了4种:
(1)通用首部字段(General Header Fields) 请求报文和响应报文都会使用的首部字段。
(2)请求首部报文(Request Headers Fields) 从客户端向服务端发送请求报文时使用的首部字段。补充了请求的附加内容、客户端信息、响应内容相关优先级等信息。
(3)响应首部字段(Response Header Fields) 从服务器端向客户端返回响应报文时使用的首部字段。补充了响应的附加内容、也会要求客户端附加额外的内容信息。
(4)实体首部字段(Entity Header Fields) 针对请求报文和响应报文的实体部分(上文中首部和报文主体部分)使用的首部字段。补充了资源内容更新时间等与实体相关的信息。
其中http/1.1规范定义了47种首部字段(后来又根据不同协议场景扩展了很多字段)。下面我们就对日常流量分析中常用到的字段作详细讲解。
请求首部字段 (1)host字段 在讲host字段前,先介绍一个重要概念——URL,看下图:
URI统一资源标志符,是一个用于标识某一互联网资源名称的字符串。它又包含了两个子集URL和URN。 - URL统一资源定位符:是URI的子集,是因特网上标准的资源的地址。
- URN统一资源名称:也是URI的子集,期望为资源提供持久的、位置无关的标识方式,并允许简单地将多个命名空间映射到单个URN命名空间。
URL和URN本来算孪生兄弟,后来URN基本被遗忘,只剩下URL。
因此要通过HTTP访问服务器上的资源,就必须提供具体的URL!URL的组成如下:
回到HTTP协议本身。HTTP请求中把URL分成了两部分,其中请求行中包括了URL中的协议类型和“资源路径”部分(见上图)。而服务器信息中的host部分,单独列为了一个首部字段(参见上图host位置)。
Host字段可以是主机名称(域名),也可以是IP+端口(为什么不直接列IP地址?因为一个服务器实际可以搭建很多个网站,而用host或不同端口来表示这些不同的网站)。
明确Host字段很重要,例如服务器被控,如果服务器上建有多个网站,找出哪个网站被攻击导致服务器失陷是前提条件,对后面的应急和漏洞修复很重要。
(2)User-Agent字段 代表客服端代理,其实就是客户端安装的浏览器。 流量分析中能够通过这个字段收集内网信息,User-Agent相当于是一种指纹,通过它可以知悉发出HTTP请求的浏览器信息,甚至系统信息,如:
在知晓了这些信息的前提下,就能够知道资产是否存在操作系统版本是否过低、浏览器版本过低的安全风险。
(3)Referer字段 HTTP请求中URI的原始获取方式,简单说就是当前网页是从什么网站跳转过来的。为我们掌握用户访问行为提供了非常大的帮助。
该字段在流量分析中,常用于分析溯源。
(4)Accept字段 指明用户代理(浏览器)可处理的媒体类型。后面的Value值为MIME(Multipurpose
Internet Mail Extensions)标准形式,MIME把数据分为了八大类,每个大类下面还有子类,格式为type/subtype。HTTP中常用的有text(文本)、image(图片)、audio/video(音视频)、application(应用)等,比如:application/json。
有时会看到“*”,它是通配符,代表任意类型;还会有一个权重值q,这是期望优先级,最大取值为1,数值越接近1代表期望值越高;
(5)Accept-Charset、Accept-Encoding、Accept-Language字段
Accept-Charset:告知用户代理支持的字符集和相对优先顺序。Accept-Encoding:告知服务器用户代理支持的内容编码及优先级顺序。Accept-Language:告知服务器用户代理自然语言集及优先级顺序。 以上字段都可以一次指定多种不同的类型,并用权重值q表示相对优先级。
(6)If-Match字段 这个字段稍微复杂一些,会去比较资源ETag的值(ETag也是一个首部字段)。仅当If-Match字段和ETag值一致时,才会执行请求,反之,会返回状态码412 Precondition
Failed(见上篇文章《HTTP请求方式和状态码》)。另外,可以使用“*”为If-Match字段的值,此时服务器会忽略ETag的值,只要资源存在就处理请求。
作流量分析时,这个字段对我们诊断HTTP业务故障会有一定帮助。
(7)其余首部字段 首部字段名 | 字段说明 | Authorization | Web认证信息 | Expect | 期待服务器的特定行为 | From | 用户的电子邮箱地址 | If-Modified-Since | 比较资源的更新时间 | If-None-Match | 比较实体标记(与 If-Match 相反) | If-Range | 资源未更新时发送实体 Byte 的范围请求 | If-Unmodified-Since | 比较资源的更新时间(与If-Modified-Since相反) | Max-Forwards | 最大传输逐跳数 | Proxy-Authorization | 代理服务器要求客户端的认证信息 | Range | 实体的字节范围请求 | TE | 传输编码的优先级 |
响应首部字段
(1)Age字段 这个字段是推算出的,具体算法可以参考RFC7234(RFC2616也有,但RFC7234的方法更科学)。可以简单认为是从资源创建(原始服务器创建资源,而不考虑中间代理服务器存储的时间)到接收到响应的时间。包括了中间网络传输的时间。
(2)ETag字段 ETag是Entity
Tag的缩写,是HTTP协议提供的缓存机制中的一种Web缓存验证机制,使缓存变得更加高效,能节省带宽。下面简单描述这种缓存机制:
(3)Location字段 首部字段Location可以将响应接收方,引导至某个与请求URI位置不同的资源上。该字段多会配合3xx:Redirection的响应,提供重定向的URI。几乎所有的浏览器在接收到包含首部字段Location的响应后,都会强制性地尝试对已提示的重定向资源的访问。
(4)Server字段 Server字段包含了HTTP服务器的安装信息。
从流量中可以被动收集对面服务器或主机的信息。
(5)其余响应字段 首部字段名 | 字段说明 | Accept-Ranges | 是否接受字节范围请求 | Proxy-Authenticate | 代理服务器对客户端的认证信息 | Retry-After | 对再次发起请求的时机要求 | Vary | 代理服务器缓存的管理信息 | WWW-Authenticate | 服务器对客户端的认证信息 |
通用首部字段
(1)Cache-Control字段 这是一个缓存控制字段,是前端开发中一个很重要的部分,在首部中显示为Cache-Control:XXXX。它的Value对应的取值很多。从流量分析视角,让大家能理解字段含义就行,不去作缓存的深入讲解,把指令通过表格的方式为大家做一个简单的挪列:
i.缓存请求指令: Cache-Control的值 | 说明 | no-cache | 强制向原服务器再次验证 | no-store | 不缓存请求或响应的任何内容 | max-age = [秒] | 响应的最大Age值 | max-stale( = [秒]) | 接收已过期的响应 | min-fresh = [秒] | 期望在指定的时间内的响应仍有效 | no-transform | 代理不可更改媒体类型 | only-if-cached | 代理不可更改媒体类型 | cache-extension | 新指令标记(token) |
ii.缓存响应指令: 指令 | 说明 | public | 可向任意方提供响应的缓存 | private | 仅向特定用户返回响应 | no-cache | 缓存前必需先确认其有效性 | no-store | 不缓存请求或响应的任何内容 | no-transform | 代理不可更改媒体类型 | must-revalidate | 可缓存但必须再向源服务器进行确认 | proxy-revalidate | 要求中间缓存服务器对缓存的响应有效性再进行确认 | max-age=[秒] | 响应的最大Age值 | s-maxage=[秒] | 公共缓存服务器响应的最大Age值 | cache-extension | 新指令标记(token) |
特别注意:no-cache并非代表不缓存,而是代表不缓存过期的资源。缓存会向源服务器进行有效期确认后处理资源。no-store才是真正地不进行缓存。
(2)Connection字段 Connection首部字段具备如下两个作用: 管理持久连接 HTTP/1.1版本的默认连接都是持久连接。因此,客户端会在持久连接上连续发送请求。当服务器端明确想断开连接时,则指定Connection首部字段的值为Close。
首部字段Date表明创建HTTP报文的日期和时间。
Pragma是HTTP/1.1之前版本的历史遗留字段,仅作为与HTTP/1.0的向后兼容而定义。规范定义的形式唯一:Pragma: no-cache。该首部字段属于通用首部字段,但只用在客户端发送的请求中。客户端会要求所有的中间服务器不返回缓存的资源。为什么不直接用上面讲过的Cache-Control: no-cache?主要是为了避免中间有服务器没有使用HTTP/1.1版本,因此常常在请求中会同时存在两个字段:Cache- Control: no-cache和Pragma: no-cache。首部字段Upgrade用于检测HTTP协议及其他协议是否可使用更高的版本进行通信,其参数值可以用来指定一个完全不同的通信协议。例如微信,抓到包是HTTP包,但指定了用它自己的加密应用层协议mmtls:使用首部字段Upgrade时,常常会额外指定Connection:Upgrade。前面请求、响应和通用首部字段都比较好理解,除此之外怎么还有个实体首部字段?大家想想上篇文章中讲解码时,请求有请求实体,响应也有相应的内容(响应实体)。因此,实体首部字段就是专门用来描述这些请求和响应主体部分内容(实体)的。Content-Encoding字段会告知客户端服务器对实体的主体部分选用的内容编码方式。内容编码是指在不丢失实体信息的前提下所进行的压缩方式。Content-Length字段表明了实体主体部分的大小(单位是字节)。对实体主体进行内容编码传输时,不能再使用Content-Length首部字段。Content-Type字段说明了实体主体内对象的媒体类型。和首部字段Accept一样,字段值用type/subtype形式赋值(见前文请求首部字段部分)。首部字段Last-Modified指明资源最终修改的时间。一般来说,这个值就是Request-URI指定资源被修改的时间。但类似使用CGI脚本进行动态数据处理时,该值有可能会变成数据最终修改时的时间。HTTP的首部字段类似上篇文章讲过的状态码,它是可扩展的。因此,我们在进行流量分析时,常常会见到很多前面没有讲过的首部字段。下面将一些分析中会遇到的扩展字段,做讲解:大家平时分析时,常常会看见一些用X开头的字段。这些字段要么是已经被弃用的字段,要么是某种设备添加的扩展字段。如下图:在RFC4229和RFC6648中提到,很多字段是“deprecated”,即过时了。但它们仍然会提供很多信息,RFC中也没有说带X的字段是禁用的,只是不推荐。有时这些带X的字段不仅不应该弃用,还会提供极大的便利。因此,要根据具体的场景来决定是否使用X开头的字段。我们也不用去强制记忆它们的功能(服务器和客户端能识别并交流不就行了?)。下面马上介绍用得最多的X开头的字段:X--Forwarded-For、X-Real-IP。(2) X-Forwarded-For、X-Real-IP、Remote-addr字段因此,我们在进行流量分析时(常常是溯源取证),可以按优先级X-Forwarded-For>X-Real-IP>Remote-addr来筛选信息。请求头由客户端发送给服务器,包含有关请求的详细信息,以下是一些关键的安全防护请求头字段:Referer:该字段指示了当前请求的来源页面(前文已经介绍,此处不再赘述)。 User-Agent:该字段标识了客户端的浏览器类型和版本(前文已经介绍,此处不再赘述)。 Origin:该字段用于跨域请求,指示了请求的源。通过验证Origin字段,服务器可以防止跨站请求伪造(CSRF)攻击。Content-Security-Policy (CSP):该字段定义了一组策略,限制了页面可以加载的资源类型和来源。通过配置CSP,可以有效防止XSS攻击和数据注入。Strict-Transport-Security (HSTS):该字段强制客户端在未来的请求中使用HTTPS,从而防止中间人攻击。启用HSTS后,即使用户尝试通过HTTP访问网站,浏览器也会自动重定向到HTTPS。X-Frame-Options:该字段控制了页面是否可以在iframe中显示。通过设置X-Frame-Options为DENY或SAMEORIGIN,可以防止点击劫持攻击。X-XSS-Protection:该字段启用了浏览器的XSS过滤器,可以帮助检测和阻止XSS攻击。虽然现代浏览器默认启用了这一功能,但显式设置该字段可以增加安全性。通过合理配置这些安全防护头字段,可以显著提高HTTP通信的安全性,保护用户数据免受攻击者的威胁。其余的一些安全相关的HTTP首部字段挪列如下: | | | | | | | Content-Security-Policy-Report-Only | | | no-referrer、no-referrer-when-downgrade、same-origin、strict-origin-when-cross-origin | | X-Permitted-Cross-Origin-Request-Headers | | | X-Content-Security-Policy | | | | | Certificate Transparency,简称CT。是一种确保SSL/TLS证书真实性的技术,通过将证书信息记录在公共日志中,使得任何人都可以验证证书的有效性。 | | 用于收集和报告安全事件。常于CSP及其他安全头部字段共同构建一个全面的安全报告机制。 | 注:在过滤字段时请注意,“Referer”字段是个错别字,单词中的r没有进行双写,却写进RFC成为了事实标准。但“Refferer-Policy”的其他Referer单词都修正了过来。因此,在查找字段(过滤)时,要注意拼写问题。Set-Cookie比较常见,因此单独把它列了出来,其实它也是一个HTTP安全首部字段。Set-Cookie是服务器设置客户端cookie信息,以便管理客户端状态。其中的HttpOnly属性是Cookie的扩展功能,它使JavaScript脚本无法获得 Cookie。其主要目的为防止XSS对Cookie的信息窃取。例1. 在研究WebShell冰蝎通信时,因为冰蝎使用了加密通信,通信内容无法知晓。而它在通信阶段无强特征进行识别,这时,我们可以通过冰蝎HTTP流量中,会包含的多个首部字段弱特征,进行组合,形成检测规则。当数据流中(传统安全设备只能进行单包检测)匹配中组合的规则,即能进行告警。(本例以冰蝎3举例,旨在提供一种流量检测思路)。分析:通过对冰蝎3WebShell管理工具的研究,和抓取的流量进行调研,发现HTTP有如下流量特征:(1)Content-Type:
application/octet-stream; (2)User-Agent,冰蝎3内置了15种,但都比较老旧,可以作弱特征进行判断; (3)Accept:
text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2; (4)Cache-Control:
no-cache; 当同时满足以上5个首部字段弱特征,并后续进行加密流量通信,则进行告警。(还可以添加更多流量特征,如上传动作,访问脚本文件等等,留给读者去发散)。例2. 某用户被浏览器升级钓鱼网站欺骗,被安装了木马,造成损失。如何确定:用户浏览器版本是否真的过低?它是怎么访问到钓鱼网站的?分析:(1)过滤出HTTP流量,可以通过User-Agent字段判断用户浏览器版本;可以看到确实是老旧浏览器,因此用户轻信了钓鱼网站让升级浏览器的话术。(2)可以通过查看Referer字段来判断用户是否从其他页面跳转到钓鱼页面;通过Referer字段,可以看到,用户是在浏览www.stmarybahrain.com/new/链接到钓鱼网页的。从流量角度学习HTTP协议这个短篇系列教程到此就完结了,希望大家通过阅读这三篇文章,对HTTP有了更深入的认识。后续我们为大家带来其它应用层协议的讲解,帮助大家提升流量分析技能!看了这篇文章,你有什么新的想法?欢迎在评论区留言和我们交流~
|