查看: 957|回复: 0

速通常见应用层协议:从流量视角打开HTTP(下)

[复制链接]
发表于 2025-3-13 17:30:00 | 显示全部楼层 |阅读模式

  前言  

前面 《速通常见应用层协议:从流量视角打开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缓存验证机制,使缓存变得更加高效,能节省带宽。下面简单描述这种缓存机制:


  • 在大多数场景下,当一个URL被请求,Web服务器会返回资源和其相应的ETag值,它会被放置在HTTP响应头的ETag字段中;

  • 客户端可以决定是否缓存这个资源和它的ETag;

  • 以后,如果客户端想再次请求相同的URL,将会发送一个包含已保存的ETag和If-None-Match字段的请求;

  • 客户端请求之后,服务器可能会比较客户端的ETag和当前版本资源的ETag。如果ETag值匹配,这就意味着资源没有改变,服务器便会发送回一个极短的响应,包含HTTP “304 未修改”的状态。304状态码告诉客户端,它的缓存版本是最新的,可以直接使用它。



(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首部字段具备如下两个作用:

  1. 控制不再转发给代理的首部字段
  2. 管理持久连接

HTTP/1.1版本的默认连接都是持久连接。因此,客户端会在持久连接上连续发送请求。当服务器端明确想断开连接时,则指定Connection首部字段的值为Close。



(3)Date字段
首部字段Date表明创建HTTP报文的日期和时间。



(4)Pragma字段
Pragma是HTTP/1.1之前版本的历史遗留字段,仅作为与HTTP/1.0的向后兼容而定义。规范定义的形式唯一:Pragma: no-cache。该首部字段属于通用首部字段,但只用在客户端发送的请求中。客户端会要求所有的中间服务器不返回缓存的资源。

为什么不直接用上面讲过的Cache-Control: no-cache?主要是为了避免中间有服务器没有使用HTTP/1.1版本,因此常常在请求中会同时存在两个字段:Cache- Control: no-cache和Pragma: no-cache。


(5)Upgrade字段
首部字段Upgrade用于检测HTTP协议及其他协议是否可使用更高的版本进行通信,其参数值可以用来指定一个完全不同的通信协议。例如微信,抓到包是HTTP包,但指定了用它自己的加密应用层协议mmtls:


使用首部字段Upgrade时,常常会额外指定Connection:Upgrade。

(6)其余通用首部字段
首部字段名
说明
Trailer
报文末端的首部一览
Transfer-Encoding
指定报文主体的传输编码方式
Via
代理服务器的相关信息
Warning
错误通知

前面请求、响应和通用首部字段都比较好理解,除此之外怎么还有个实体首部字段?大家想想上篇文章中讲解码时,请求有请求实体,响应也有相应的内容(响应实体)。因此,实体首部字段就是专门用来描述这些请求和响应主体部分内容(实体)的。

  实体首部字段  
(1)Content-Encoding字段
Content-Encoding字段会告知客户端服务器对实体的主体部分选用的内容编码方式。内容编码是指在不丢失实体信息的前提下所进行的压缩方式。


(2)Content-Length字段
Content-Length字段表明了实体主体部分的大小(单位是字节)。对实体主体进行内容编码传输时,不能再使用Content-Length首部字段。


(3)Content-Type字段
Content-Type字段说明了实体主体内对象的媒体类型。和首部字段Accept一样,字段值用type/subtype形式赋值(见前文请求首部字段部分)。


(4)Last-Modified字段
首部字段Last-Modified指明资源最终修改的时间。一般来说,这个值就是Request-URI指定资源被修改的时间。但类似使用CGI脚本进行动态数据处理时,该值有可能会变成数据最终修改时的时间。


(5)其它实体首部字段
首部字段名
说明
Allow
资源可支持的HTTP方法
Content-Language
实体主体的自然语言
Content-Location
替代对应资源的URI
Content-MD5
实体主体的报文摘要
Content-Range
实体主体的位置范围
Expires
实体主体过期的日期时间

  扩展首部字段  

HTTP的首部字段类似上篇文章讲过的状态码,它是可扩展的。因此,我们在进行流量分析时,常常会见到很多前面没有讲过的首部字段。下面将一些分析中会遇到的扩展字段,做讲解:

(1) 带X的首部字段
大家平时分析时,常常会看见一些用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:简称XFF头,它代表客户端,也就是HTTP的请求端真实的IP。只有在通过HTTP代理或者负载均衡服务器时才会添加该字段(一般需要人为进行配置,设备默认不会自动添加)。这在追踪溯源时由为重要,如果没有该字段,你看到的安全设备告警可能会是:内网服务器一直被负载设备攻击!一般做了SNAT(源地址转换)的设备,将转换前的真实IP写在XFF字段中,让服务器知晓真实的访问IP。



  • X-Real-IP:一般是nginx作反向代理时,使用$remote_addr变量获得用户的真实ip。但X-Real-IP有个问题,就是如果通过cdn访问过来的,那么后面web服务器获取到的是cdn的ip而非真实用户ip。因此,当分析溯源时,XFF比X-Real-IP更优先、更可靠。



  • Remote-addr:类似X-Real-IP,不同的是X-Real-IP可以记录每一跳代理的IP,而Remote-addr记录的是最远端客户的IP。



因此,我们在进行流量分析时(常常是溯源取证),可以按优先级X-Forwarded-For>X-Real-IP>Remote-addr来筛选信息。

(3) HTTP安全字段
  • 请求头的安全字段

请求头由客户端发送给服务器,包含有关请求的详细信息,以下是一些关键的安全防护请求头字段:

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首部字段挪列如下:

首部字段名
说明
X-Content-Type-Options
用于防止MIME类型嗅探攻击
X-Forwarded-Proto
确认原始请求的协议类型
Content-Security-Policy-Report-Only
用于测试和调试CSP策略
Referrer-Policy
控制Referer字段的值,包括有:
no-referrer、no-referrer-when-downgrade、same-origin、strict-origin-when-cross-origin
X-Permitted-Cross-Origin-Request-Headers
用于控制跨域请求中允许的自定义头字段。
X-Content-Security-Policy
是CSP的一个变体,主要用于兼容旧版浏览器。
Feature-Policy
用于控制浏览器中的各种功能和API。
Expect-CT
Certificate Transparency,简称CT。是一种确保SSL/TLS证书真实性的技术,通过将证书信息记录在公共日志中,使得任何人都可以验证证书的有效性。
Report-To
用于收集和报告安全事件。常于CSP及其他安全头部字段共同构建一个全面的安全报告机制。
注:在过滤字段时请注意,“Referer”字段是个错别字,单词中的r没有进行双写,却写进RFC成为了事实标准。但“Refferer-Policy”的其他Referer单词都修正了过来。因此,在查找字段(过滤)时,要注意拼写问题。

(4) Set-Cookie字段
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)Pragma: no-cache

当同时满足以上5个首部字段弱特征,并后续进行加密流量通信,则进行告警。(还可以添加更多流量特征,如上传动作,访问脚本文件等等,留给读者去发散)。


例2. 某用户被浏览器升级钓鱼网站欺骗,被安装了木马,造成损失。如何确定:用户浏览器版本是否真的过低?它是怎么访问到钓鱼网站的?

分析:(1)过滤出HTTP流量,可以通过User-Agent字段判断用户浏览器版本;



可以看到确实是老旧浏览器,因此用户轻信了钓鱼网站让升级浏览器的话术。

(2)可以通过查看Referer字段来判断用户是否从其他页面跳转到钓鱼页面;

通过Referer字段,可以看到,用户是在浏览www.stmarybahrain.com/new/链接到钓鱼网页的。

  结语  
从流量角度学习HTTP协议这个短篇系列教程到此就完结了,希望大家通过阅读这三篇文章,对HTTP有了更深入的认识。后续我们为大家带来其它应用层协议的讲解,帮助大家提升流量分析技能!

看了这篇文章,你有什么新的想法?欢迎在评论区留言和我们交流~
应用负载均衡场景中,要关注哪些首部字段?

免费易用的流量分析工具下载
扫码关注公众号
更多网络分析技术、技巧、干货分享


- End -

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?CSNA会员注册

×
回复

使用道具 举报

您需要登录后才可以回帖 登录 | CSNA会员注册

本版积分规则

快速回复 返回顶部 返回列表