原文:https://labs.detectify.com/2018/09/04/xss-using-quirky-implementations-of-acme-http-01/
摘要
对于有些托管服务提供商来说,他们实现的http-01验证方法会将部分challenge密钥放到响应中去,从而导致大量实现了http-01 ACME-challenge的网站很容易受到XSS的攻击。
半年以前,Frans对不同的Let's Encrypt验证方法进行了研究,并将结果放到了一篇关于如何利用TLS SNI为共享主机上的其他域颁发证书的文章中。
在这篇报告,还考察了其他验证方法,例如http-01。该验证方法的工作原理是,让Let’s Encrypt 的请求位于/.well-known/acme-challenge/KEY1中的文件,并期望获得具有KEY1.KEY2的格式的响应。
由于KEY1同时出现在响应和请求中,所以,一些托管服务提供商使用支持ACME的证书颁发者(Let's Encrypt只是其中之一)创建了一种解决方案,其中第一个密钥KEY1将从URL中取得,然后,使其与响应中使用的固定的KEY2相结合。
发送请求:
/.well-known/acme-challenge/ABC123
响应如下所示:
ABC123.XYZ567
很明显,这里很容易受到XSS攻击,不过,还需要考虑是否采用了相应的缓解措施:
实际上,这三种缓解措施都有相应的绕过方法,于是,我们向两家主要的网络托管公司报告了这些问题,因为这使得他们的所有客户都容易受到攻击。其中,一家是大型国际服务提供商,另一家是瑞典最大的托管服务提供商之一。但是,自从将其应用到Detectify监控中后,我们仍然会在客户的网站上发现这个问题,这表明,还有很多服务提供商也容易受到该漏洞的影响。
下面,我们深入介绍如何绕过上述缓解措施。
内容类型非HTML
对于国际托管服务提供商来说,由于内容默认为text/plain,因此,只能将响应呈现为纯文本。但是,Apache有一个名为Magic MIME的旧模式,它将根据响应的第一个字节来确定内容类型。如果启用了该模式,则可以根据响应包含的字符类型来控制内容类型。例如,<b>
会导致内容类型为text/html,<?xml
会导致内容类型为text/xml。在进行测试时,对于请求/.well-known/acme-challenge/<b>
,响应实际上以text/html的形式返回的。
虽然我们的报告中也提到了Magic MIME,然而,相关托管服务提供商婉转表示,他们并没有使用Apache,而是通过某种形式的中间件来完成内容类型的嗅探工作。
当然,我们无法修改Swedish主机提供商的内容类型。然而,正如Jan Kopecky在去年四月发表的文章所展示的那样,我们可以设法让Internet Explorer将纯文本作为HTML执行,到目前为止,这一技巧仍适用于Windows 8.1,不过在Windows 10平台上面已经失效了。
实际上,这种方法是通过创建.eml文件,并将content-type设置为message/rfc822来完成的。它代表Microsoft Outlook Express邮件,用于将电子邮件内容保存到文件中。当加载这类文件时,Internet Explorer会对其余内容执行mime-sniffing(猜测其内容类型)。因此,我们只要将iFrame放到易受攻击的端点中,其内容就会被视为HTML。
对请求内容进行URL编码
当向Swedish托管服务提供商发送请求时,响应中的KEY1的内容总是会进行URL编码。
我们可以再次使用Internet Explorer来解决此问题。关于Internet Explorer的一个不太为人所知的事情是,实际上搜索部分(在URL中的?之后的部分)默认情况下是不进行URL编码。在这种情况下,/.well-known/acme-challenge/
之后的所有内容都直接写入页面,这意味着/.well-known/acme-challenge/?<h1>hi
将生成一个具有正常HTML标签的响应。
值得一提的是,即使只有路径名会被写入页面的话,也可以这样做。如果它确实会重定向,则Internet Explorer也会将该部分以非URL编码的形式保留下来,这意味着PoC会非常简单:
<?php
header(“Location: https://vulnerable/.well-known/acme-challenge/<h1>test”);
?>
XSS auditor
在我们忙活半天之后,在发送漏洞报告之前,最后一件事是确保JavaScript确实在Web浏览器中执行。虽然Firefox缺乏XSS-auditor,但随着Chrome的广泛使用,最好让它实现一个XSS-auditor,因为这样可以发挥出最大的效力。
请记住,我们可以控制内容类型。虽然Chrome XSS-auditor不会触发XML,但是,可以提供一个XHTML命名空间,将XML作为HTML来进行安全评估。
POC
针对该国际提供商的完整PoC如下所示:
/.well-known/acme-challenge/%3C%3fxml%20version=%221.0%22%3f%3E%3Cx:script%20xmlns:x=%22http://www.w3.org/1999/xhtml%22%3Ealert%28document.domain%26%23x29%3B%3C/x:script%3E
对于Swedish供应商来说,对应的PoC则是这样的:
TESTEML
Content-Type: text/html
Content-Transfer-Encoding: quoted-printable
<iframe src=3D"http://[redacted]/.well-known/acme-challenge/?<HTML><h1>meh</h1>"></iframe>
缓解措施
这里的关键在于,反模式有时会导致意想不到的副作用,我们的建议是根本不要让acme-challenge请求中的内容泄露出来。相反,如果KEY1恰好需要用于challenge中的话,则使用建议的方法,并仅提供KEY1.KEY2的响应。