Web安全学院
Web安全学院
  • 首页
  • 译序
  • 学习路线
  • 前篇
    • Web应用程序安全测试
    • 动态应用程序安全测试(DAST)
    • 带外应用程序安全测试(OAST)
  • 服务器端主题
    • SQL注入
      • SQL注入
      • SQL注入UNION攻击
      • 在SQL注入攻击中检索数据库
      • SQL盲注
      • SQL注入速查表
    • 认证
      • 认证漏洞
      • 基于密码登录中的漏洞
      • 多因素认证中的漏洞
      • 其他认证机制中的漏洞
      • 如何保护你的认证机制
    • 目录遍历
      • 目录遍历
    • 命令注入
      • OS命令注入
    • 业务逻辑漏洞
      • 业务逻辑漏洞
      • 业务逻辑漏洞示例
    • 信息泄露
      • 信息泄露漏洞
      • 如何发现并利用信息泄露漏洞
    • 访问控制
      • 访问控制漏洞与权限提升
      • 不安全的直接对象引用(IDOR)
      • 访问控制安全模型
    • 文件上传漏洞
      • 文件上传漏洞
    • 条件竞争
      • 条件竞争
    • 服务器端请求伪造(SSRF)
      • 服务器端请求伪造(SSRF)
      • 盲SSRF漏洞
    • XXE注入
      • XML外部实体(XXE)注入
      • XML实体
      • 发现并利用盲XXE漏洞
  • 客户端主题
    • 跨站脚本(XSS)
      • 跨站脚本
      • 反射型XSS
      • 存储型XSS
      • 基于DOM的XSS
      • XSS上下文
        • 跨站脚本上下文
        • 客户端模版注入
      • 利用跨站脚本漏洞
      • 内容安全策略
      • 悬空标记注入
      • 如何防范XSS漏洞
      • 跨站脚本(XSS)速查表
    • 跨站请求伪造(CSRF)
      • 跨站请求伪造(CSRF)
      • XSS与CSRF
      • 绕过CSRF令牌验证
      • 绕过SameSite Cookie限制
      • 绕过基于Referer的CSRF防御
      • 如何防范CSRF漏洞
    • 跨域资源共享(CORS)
      • 跨域资源共享(CORS)
      • 同源策略(SOP)
      • CORS和Access-Control-Allow-Origin响应标头
    • 点击劫持
      • 点击劫持(UI伪装)
    • 基于DOM的漏洞
      • 基于DOM的漏洞
      • 控制Web消息源
      • 基于DOM的开放重定向
      • 基于DOM的Cookie操纵
      • 基于DOM的JavaScript注入
      • 基于DOM的document-domain操纵
      • 基于DOM的WebSocket URL投毒
      • 基于DOM的链接操纵
      • Web消息操纵
      • 基于DOM的Ajax请求标头操纵
      • 基于DOM的本地文件路径操纵
      • 基于DOM的客户端SQL注入
      • 基于DOM的HTML5 Storage操纵
      • 基于DOM的客户端XPath注入
      • 基于DOM的客户端JSON注入
      • DOM-data操纵
      • 基于DOM的拒绝服务
      • DOM破坏
    • WebSocket
      • 测试WebSocket安全漏洞
      • 什么是WebSocket?
      • 跨站WebSocket劫持
  • 进阶主题
    • 不安全的反序列化
      • 不安全的反序列化
      • 利用不安全的反序列化漏洞
    • 测试GraphQL API
      • 测试GraphQL API
      • 什么是GraphQL?
    • 服务器端模板注入
      • 服务器端模板注入
      • 利用服务器端模板注入漏洞
    • Web缓存投毒
      • Web缓存投毒
      • 缓存设计缺陷的利用
      • 缓存实现缺陷的利用
    • HTTP Host标头攻击
      • HTTP Host标头攻击
      • 如何识别和利用HTTP Host头的漏洞
      • 密码重置投毒
    • HTTP请求走私
      • HTTP请求走私
      • 查找HTTP请求走私漏洞
      • 利用HTTP请求走私漏洞
      • 高级请求走私
        • 高级请求走私
        • HTTP/2降级
        • 响应队列投毒
        • HTTP/2专属载体
        • HTTP请求隧道
      • 浏览器驱动的请求伪造
        • 浏览器驱动的请求伪造
        • CL.0请求走私
        • 客户端异步攻击
        • 基于暂停的异步攻击
    • OAuth认证
      • OAuth 2.0认证漏洞
      • OAuth授权类型
      • OpenID Connect
      • 如何防范OAuth认证漏洞
    • JWT攻击
      • JWT攻击
      • 在Burp Suite中使用JWT
      • 算法混淆攻击
    • 原型污染
      • 什么是原型污染?
      • JavaScript原型和继承
      • 客户端
        • 客户端原型污染漏洞
        • 通过浏览器API进行原型污染
      • 服务器端
        • 服务器端原型污染
      • 预防原型污染漏洞
    • 基本技能
      • 基本技能
      • 使用编码混淆攻击
      • 在手动测试中使用Burp Scanner
Powered by GitBook
On this page
  • 什么是HTTP请求走私?
  • HTTP请求走私攻击中发生了什么?
  • HTTP请求走私漏洞是如何产生的?
  • 如何进行HTTP请求走私攻击
  • CL.TE漏洞
  • TE.CL漏洞
  • TE.TE行为:混淆TE头
  • 如何识别HTTP请求走私漏洞
  • 如何利用HTTP请求走私漏洞
  • 高级HTTP请求走私
  • 浏览器驱动的请求走私
  • 如何防止HTTP请求走私漏洞
  1. 进阶主题
  2. HTTP请求走私

HTTP请求走私

PreviousHTTP请求走私Next查找HTTP请求走私漏洞

Last updated 1 year ago

在本节中,我们将讲解HTTP请求走私攻击,并描述常见的请求走私漏洞是如何产生的。

Labs

如果你已经熟悉HTTP请求走私,只想在一系列故意易受攻击的网站上进行练习,请点击下面的链接查看本专题中所有实验的概述。

什么是HTTP请求走私?

HTTP请求走私是一种干扰网站处理一个或多个用户发送的HTTP请 求序列的技术。请求走私漏洞在本质上通常是严重的,它允许攻击者绕过安全控制,未经授权访问敏感数据,并直接危及其他应用程序用户。

注意

HTTP请求走私攻击中发生了什么?

今天的Web应用程序经常在用户和最终应用程序逻辑之间使用HTTP服务器链。用户向前端服务器(有时称为负载均衡或反向代理)发送请求,此服务器将请求转发给一个或多个后端服务器。这种类型的架构在现代基于云的应用程序中越来越普遍,而且在某些情况下是不可避免的。

当前端服务器将HTTP请求转发到后端服务器时,它通常会在同一后端网络连接上发送多个请求,因为这样做更有效率且性能更高。协议非常简单:一个接一个地发送HTTP请求,接收服务器解析HTTP请求标头以确定一个请求的结束和下一个请求的开始:

在这种情况下,前端和后端系统对请求之间的界限达成一致是非常关键的。否则,攻击者可能会发送一个模糊的请求,该请求会被前端和后端系统作出不同的解释:

在这里,攻击者使得其前端请求的一部分被后端服务器解释为下一个请求的开始。它实际上被附加到下一个请求的开头,因此可以干扰应用程序处理该请求的方式。这就是请求走私攻击,它可能会产生毁灭性的结果。

HTTP请求走私漏洞是如何产生的?

大多数HTTP请求走私漏洞产生的原因是,HTTP规范提供了两种不同的方法来指定请求结束的位置:Content-Length标头和Transfer-Encoding标头。

Content-Length标头很简单:它指定消息正文的长度(以字节为单位)。例如:

POST /search HTTP/1.1
Host: normal-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 11

q=smuggling

Transfer-Encoding标头可用于指定消息正文使用分块编码。这意味着消息正文包含一个或多个数据块。每个分块由以字节为单位的分块大小(用十六进制表示)组成,然后是分块内容。消息以一个大小为零的块结束。例如:

POST /search HTTP/1.1
Host: normal-website.com
Content-Type: application/x-www-form-urlencoded
Transfer-Encoding: chunked

b
q=smuggling
0

注意

许多安全测试人员并不知道分块编码可以用于HTTP请求,原因有两个:

  • Burp Suite会自动解包分块编码,使消息更容易查看和编辑。

  • 浏览器通常不会在请求中使用分块编码,分块编码通常只在服务器响应中出现。

由于HTTP规范提供了两种不同的方法来指定HTTP消息的长度,因此一个消息可以同时使用这两种方法,从而使它们相互冲突。HTTP规范试图通过声明,如果Content-Length和Transfer-Encoding标头同时存在,则应忽略Content-Length标头来解决这个问题。当只有一个服务器时,这可能足以避免歧义,但在涉及两个或更多服务器时可能就不行了。在这种情况下,问题可能出现的原因有两个:

  • 有些服务器不支持请求中的Transfer-Encoding标头。

  • 如果标头以某种方式被混淆,有些支持Transfer-Encoding标头的服务器就会被诱使而不处理它。

如果前端和后端服务器对(可能混淆的)Transfer-Encoding标头的处理方式不同,那么它们可能对连续请求之间的界限产生分歧,从而导致请求走私漏洞。

如何进行HTTP请求走私攻击

请求走私攻击涉及将Content-Length标头和Transfer-Encoding标头放入单个HTTP请求中,并对其进行操作,使前端和后端服务器对请求进行不同的处理。具体操作方式取决于这两个服务器的行为:

  • CL.TE:前端服务器使用Content-Length标头,后端服务器使用Transfer-Encoding标头。

  • TE.CL:前端服务器使用Transfer-Encoding标头,后端服务器使用Content-Length标头。

  • TE.TE:前端和后端服务器都支持Transfer-Encoding标头,但可以通过某种方式混淆头部来诱导其中一个服务器不处理它。

注意

这些技巧仅适用于HTTP/1请求。浏览器和其他客户端(包括Burp)默认使用HTTP/2与服务器进行通信,这些服务器通过ALPN作为TLS握手的一部分明确地宣告支持HTTP/2。因此,在测试支持HTTP/2的站点时,你需要在Burp Repeater中手动切换协议。你可以在Inspector面板的Request attributes部分执行此操作。

CL.TE漏洞

在这里,前端服务器使用Content-Length标头,后端服务器使用Transfer-Encoding标头。我们可以执行一个简单的HTTP请求走私攻击,如下所示:

POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 13
Transfer-Encoding: chunked

0

SMUGGLED

前端服务器处理Content-Length标头,并确定请求体的长度为13字节,直到SMUGGLED的结尾。此请求将转发给后端服务器。

后端服务器处理Transfer-Encoding标头,将消息正文视为使用分块编码。它处理第一个分块,该分块的长度声明为零,因此被视为终止请求。随后的SMUGGLED字节未被处理,后端服务器将把这些字节视为序列中下一个请求的开始。

LAB

TE.CL漏洞

在这里,前端服务器使用Transfer-Encoding标头,后端服务器使用Content-Length标头。我们可以执行一个简单的HTTP请求走私攻击,如下所示:

POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 3
Transfer-Encoding: chunked

8
SMUGGLED
0

注意

要使用Burp Repeater发送此请求,你首先需要转到Repeater菜单并确保“Update Content-Length”选项未选中。

在最后的0之后,需要包含尾随序列\r\n\r。

前端服务器处理Transfer-Encoding标头,将消息正文视为使用分块编码。它处理第一个分块,声明长度为8个字节,直到SMUGGLED之后的行的开头。它处理第二个分块,该分块的长度为零,因此被视为终止请求。此请求将转发给后端服务器。

后端服务器处理Content-Length标头,并确定请求体长度为3个字节,直到8之后的行的开头。随后的字节,以SMUGGLED开头,未被处理,后端服务器将把这些字节视为序列中下一个请求的开始。

LAB

TE.TE行为:混淆TE头

在这里,前端和后端服务器都支持Transfer-Encoding标头,但可以通过某种方式混淆头部来诱导其中一个服务器不处理它。

要混淆Transfer-Encoding标头的方法有很多。例如:

Transfer-Encoding: xchunked

Transfer-Encoding : chunked

Transfer-Encoding: chunked
Transfer-Encoding: x

Transfer-Encoding:[tab]chunked

[space]Transfer-Encoding: chunked

X: X[\n]Transfer-Encoding: chunked

Transfer-Encoding
: chunked

这些技巧中的每一种都涉及到对HTTP规范的微妙偏离。实现协议规范的实际代码很少完全精确地遵循它,而且不同实现对规范的不同变体的容忍度也有所不同。为了发现TE.TE漏洞,需要找到Transfer-Encoding标头的某种变体,使得前端或后端服务器中只有一个处理它,而另一个服务器忽略它。

取决于是前端还是后端服务器可以被诱导不处理混淆的Transfer-Encoding标头,攻击的其余部分,将采取与已经描述的CL.TE或TE.CL漏洞相同的形式。

LAB

如何识别HTTP请求走私漏洞

查看以下部分,了解如何自行识别HTTP请求走私漏洞的一些建议。我们还提供了一些交互式实验,以便你了解实际操作中的情况。

阅读更多

如何利用HTTP请求走私漏洞

现在你已经熟悉了基本概念,让我们看看如何利用HTTP请求走私来实施一些高危攻击。与往常一样,我们提供了很多完全交互式的实验,让你尝试攻击现实目标。

阅读更多

高级HTTP请求走私

如果已经完成了我们的其他请求走私实验,那么你可以学习一些更高级的技巧了。我们根据PortSwigger研究人员发现的真实世界的漏洞,创建了一些交互式的实验。你甚至有机会尝试使用Burp的独特功能进行基于HTTP/2的测试。

阅读更多

浏览器驱动的请求走私

迄今为止,你所学到的请求走私技术依赖于使用专用的黑客工具(如Burp Repeater)发送有意畸形的请求。事实上,你可以使用完全兼容浏览器的请求来执行相同的攻击,使用完全正常的Content-Length标头来使两个服务器不同步。

这甚至使你能够发起这些攻击的客户端变种,诱使受害者的浏览器毒化自己与易受攻击网站的连接。这不仅使单服务器站点受到请求走私风格的攻击,甚至使你能够攻击那些无法直接访问的站点。请查看学习材料和实验,了解如何操作。

阅读更多

如何防止HTTP请求走私漏洞

HTTP请求走私漏洞出现在,前端服务器和后端服务器使用不同机制确定请求之间的边界的情况下。这可能是由于HTTP/1服务器是使用Content-Length标头还是分块传输编码来确定每个请求的结束位置之间存在差异。在 HTTP/2 环境中,为后端降级HTTP/2请求的常见做法也充满了问题,导致或简化了许多额外的攻击。

为了防止HTTP请求走私漏洞,我们建议采取以下高级措施:

  • 尽可能端到端使用HTTP/2,并禁用HTTP降级。HTTP/2使用一种健壮的机制来确定请求的长度,端到端使用时,本身具有防止请求走私的能力。如果无法避免HTTP降级,请确保根据HTTP/1.1规范验证重写的请求。例如,拒绝那些在标头中含有换行符、在标头名称中含有冒号、在请求方法中含有空格的请求。

  • 使前端服务器将模糊的请求规范化,并使后端服务器拒绝任何仍然模糊的请求,在此处理过程中关闭TCP连接。

  • 永远不要假设请求不会有正文。这是CL.0和客户端解异步漏洞的根本原因。

  • 如果在处理请求时触发了服务器级异常,那么默认丢弃连接。

  • 如果你通过转发代理路由流量,如果可能的话,请确保启用上游的HTTP/2。

正如我们在学习材料中所展示的,禁用后端连接重用将有助于缓解某些类型的攻击,但这仍无法保护你免受请求隧道攻击的侵害。

阅读更多

HTTP请求走私首次在2005年被记录,最近因而重新流行。

PortSwigger的研究
HTTP请求走私,基础的CL.TE漏洞
HTTP请求走私,基础的TE.CL漏洞
HTTP请求走私,混淆TE头
查找HTTP请求走私漏洞
利用HTTP请求走私漏洞
高级HTTP请求走私漏洞
浏览器驱动的请求走私
使用Burp Suite的Web漏洞扫描器发现HTTP请求走私漏洞
查看所有HTTP请求走私实验