利用DNS重绑定在Chrome、Edge和Safari中实现瞬间DNS重绑定的攻击技术
2023-12-22 11:45:0 Author: www.4hou.com(查看原文) 阅读量:12 收藏

本文介绍了在Chrome、Edge和Safari中实现可靠的DNS重绑定的新技术,并讨论了绕过本地网络限制的技术。通过分析慢缓存的根本原因,提出了新的解决技术。本文研究了利用DNS重绑定在Chrome、Edge和Safari中实现瞬间DNS重绑定的攻击技术。

本文是关于DNS重新绑定系列文章中的第二篇。第一篇文章介绍了一个使用DNS重新绑定后攻击的案例。在这篇文章中,我介绍了在IPv6可用时在Chrome, Edge和Safari中实现可靠的,瞬间DNS重新绑定的新技术,以及一种绕过本地网络限制的技术,该技术适用于基于Chrome的浏览器的获取API。

浏览器中的DNS重绑定传统上被视为攻击者通过诱骗受害者加载恶意网站来访问内部网络服务的一种方式,但随着许多现代web应用程序现在在其部分功能上驱动无头浏览器,它已成为攻击web应用程序的有用工具。无头浏览器,即 Headless Browser,是一种没有界面的浏览器。它拥有完整的浏览器内核,包括 JavaScript 解析引擎、渲染引擎等。与普通浏览器最大的不同是,无头浏览器执行过程中看不到运行的界面,但是我们依然可以用 GUI 测试框架的截图功能截取它执行中的页面。在上一篇文章中,我介绍了一个使用可能是最简单的重新绑定方法的例子。在这种情况下,我有很长的时间让漏洞运行,但这在许多web应用程序中不太可能,需要更快的技术。

缓慢的缓存

简单的DNS重绑定技术依赖于对相同主机名的连续查找返回不同的DNS记录。对于这些攻击,所花费的最小时间是浏览器执行两次连续DNS查找之间的时间。这有时可以通过刷新浏览器缓存来加快速度,生成大量DNS查找以填充可用的缓存空间,并导致旧条目在过期之前被清除,从而使浏览器更快地对相同的主机名执行第二次查找。

当它工作时,它仍然需要大约10秒的时间,而且通常这种技术不会起作用,因为中间缓存不能像浏览器的缓存那样容易地被清除。例如,在测试期间,我发现在一个新创建的Ubuntu EC2实例上,由于系统解析的缓存,我只能每5分钟为同一域获得不同的响应。在VPN上,我看到DNS响应在默认解析器上至少缓存30分钟。让用户将页面打开这么长时间以允许攻击者实现DNS重新绑定漏洞,通常是一件很困难的事情,更不用说将无头浏览器作为web应用程序的一部分驱动了。

为了加速漏洞利用,2010年Craig Heffner提出了通过在相同响应中回复同一域的多个A记录来执行DNS重新绑定的想法,Gerald Doussot和Roger Meyer在2019年的singularity 中使用了这种技术。Singularity 是一个开放源码容器平台,旨在简化、快速和安全。Singularity 是针对 EPC 和 HPC 工作负载进行优化的,允许不受信任的用户以可信的方式运行不受信任的容器。

返回的两条记录是攻击者控制的公共服务器的IP地址和目标服务器的(通常是私有的)IP地址。

只有当浏览器试图首先与公共服务器通信并加载攻击者的恶意页面时,攻击才会起作用。然后,攻击者的web服务器开始阻止来自受害者浏览器的流量,导致浏览器退回到将所有请求发送到目标服务器。在这种情况下,攻击者页面中的JavaScript将能够向同一来源下的目标IP地址发送请求。‍

1.png

这种技术确实绕过了缓存问题,因为浏览器只需要执行一次DNS查找,尽管在我的测试期间,所有主要浏览器都会始终尝试在公共IP地址之前与私有IP地址通信,这意味着这些技术不起作用。虽然我不相信这种行为是为了防止DNS重新绑定,但它可以有效的阻止这种技术。

这种新行为促使我研究新的技术,可以用来在Safari和基于chrome的浏览器中实现瞬间DNS重新绑定。这些技术的关键是找到新的方法,使浏览器最初使用公共IP,然后在加载网站时切换到使用私有IP。打开Wireshark,我注意到在现代浏览器中加载网站时,会同时发送A和AAAA查询。我开始调查这种行为是否可以用来可靠地执行DNS重新绑定。

攻击Safari:延迟DNS响应

当你在通过IPv6访问互联网的主机上加载Safari网页时,分别为IPv4和IPv6地址发送A和AAAA DNS查询。当返回多个IP地址时,Safari将优先考虑私有IP地址而不是公共IP地址。

当A或AAAA响应延迟时,Safari中允许快速DNS重新绑定的有趣行为会发生。在这种情况下,Safari不会等待所有DNS响应,而是在接收到第一个DNS响应后立即发送HTTP请求。当收到延迟的DNS响应时,此响应中的IP地址将被添加到IP地址池中,Safari可以在将来请求该域时使用该IP地址池。

这意味着,如果第一个DNS响应是针对公共IP地址的,而延迟的DNS响应是针对私有IP地址的,Safari将向公共IP地址发送第一个请求,直到接收到延迟的DNS响应,此时它将开始向私有IP地址发送请求。

2.png

这提供了一种在Safari中使用自定义DNS服务器实现DNS重新绑定的简单方法,该服务器可处理*.r.inded.es的查询:

1.加载目标浏览器http://safari.r.intrud.es,触发safari.r.intrud.es的A和AAAA查找。

2.让DNS服务器立即返回AAAA记录,其中包含互联网上攻击者控制的web服务器的IPv6地址。暂时不要返回A响应。

3.一旦收到AAAA响应,Safari将向攻击者的web服务器发出第一个请求。从攻击者的web服务器返回一个带有JavaScript的页面来重复请求http://safari.r.intrud.es/secret.txt。

4.从DNS服务器发送包含本地网络上目标服务器的IP地址的A响应。

5.Safari现在将对http://safari.r.intrud.es/secret.txt的请求发送到本地网络上的目标服务器。从攻击者的服务器加载的页面可以读取这些请求的响应,而不会违反同源策略。

为了实现这一点,我编写了一个小型DNS服务器,可以使用命令行参数延迟DNS响应。在实践中,我发现将A响应延迟100毫秒几乎总是足够的,尽管可以使用200毫秒或更长时间的延迟来使该技术更加可靠。可以在这里https://github.com/intruder-io/dns-delay-server找到这个服务器以及设置它的说明。

我用来利用它的PHP脚本会将用户重定向到r.introd.es的随机子域,以避免中间缓存干扰利用。它还将JavaScript直接包含在页面中,以避免另一个资源负载。你可以在这里找到使用的代码。

该脚本在操作中的视频请点此,从本地web服务器检索文件的内容:

3.jpg

我在iOS上的Safari和Brave上进行了测试,发现同样的技术也可以用于访问内部网络上的服务。

攻击Chrome:使用AAAA优先级

Chrome将优先加载本地网络上的页面,而不是互联网上的页面,但在可用的情况下,它会优先加载IPv6而不是IPv4上的页面。所以首要任务是:

1.本地IPv6(最高优先级);

2.公共IPv6;

3.当地IPv4;

4.公共IPv4(最低优先级);

这里的关键部分是Chrome会优先考虑公共IPv6地址而不是私有IPv4地址。此外,当Chrome知道一个域的多个IP地址时,一旦服务器重置连接,它就会尝试不同的IP地址。

4.png

这给出了一个针对Chrome的快速DNS重绑定计划:

1.加载http://chrome.r.intrud.es,这将触发A和AAAA查找chrome.r.intrud.es。

2.让DNS服务器返回指向本地网络上目标web服务器的A记录和指向公共互联网上攻击者控制的web服务器的AAAA记录。

3.Chrome将优先考虑IPv6地址,并从攻击者控制的web服务器发出第一个加载页面的请求,该服务器返回JavaScript以重复向http://chrome.r.intrud.es/secret.txt发出请求。

4.关闭攻击者控制的服务器,以便重置所有连接。Chrome现在将把所有请求发送到本地网络上的目标服务器。

5.让加载的页面向http://chrome.r.intrud.es/secret.txt发出请求。可以在不违反同源策略的情况下读取对这些请求的响应。

这个计划几乎成功了。从互联网加载的页面上的JavaScript试图向本地网络上的目标发出请求,但这些请求被阻止,并在控制台中显示以下错误:

Access to fetch at 'http://chrome.r.intrud.es/secret.txt' from origin 'http://chrome.r.intrud.es' has been blocked by CORS policy: The request client is not a secure context and the resource is in more-private address space `local`.

出现此错误是因为Chrome部分实现了私有网络访问(PNA)https://wicg.github.io/private-network-access/规范中描述的保护。

绕过PNA

Private Network Access(以前称为 CORS-RFC1918 )限制了网站向私有网络上的服务器发送请求的能力。根据规范,此类请求只允许来自安全上下文。另外,该规范扩展了跨域资源共享(CORS)协议,因此网站现在必须在允许发送任意请求之前,必须显式请求私有网络上服务器的许可。

私有网络是指目标服务器的IP地址比从其获取请求服务器的IP地址更私有的请求。例如,从公共网站(https://example.com)向私有网站(http://router.local)的请求,或从私有网站向 localhost 的请求。

PNA保护阻止通过普通HTTP从公共互联网加载的页面向私有网络发出请求。在Chrome中,这些保护是为fetch请求实现的,但还没有为iframe实现。不完整的实现以及DNS重新绑定允许绕过对获取请求的PNA限制。

我们可以重复利用到上面的步骤4,其中公共web服务器已经关闭,所有对http://chrome.r.intrud.es的请求现在都被定向到本地网络上的目标服务器。加载的首页不能向本地网络发出请求,因为它是通过HTTP从公共互联网加载的,但是我们可以在iFrame中加载http://chrome.r.intrud.es。这个iFrame中的页面将从目标web服务器加载。由于此服务器位于本地网络上,因此允许在iFrame中加载的页面向本地网络发出请求。

iFrame中的页面也与顶部页面处于相同的起源,这使得顶部页面可以完全控制框架页面的DOM。这包括注入脚本,使获取请求进入框架页面。这些脚本可以用来访问目标web服务器并泄露数据,就像如果PNA根本没有实现的话,它们可以从首页获取数据一样。

6.png

所以,把这些放在一起,我们最终得到了一个完整的步骤:

1.加载http://chrome.r.intrud.es,这将触发A和AAAA查找chrome.r. imports .es。

2.让DNS服务器返回一条A记录,指向本地网络中的目标web服务器,并返回一条AAAA记录,指向公网上攻击者控制的web服务器。

3.Chrome将首先请求从攻击者的web服务器加载顶部页面,该服务器返回一个页面以执行以下步骤。

4.关闭攻击者控制的服务器,以便重置所有连接尝试。5.Chrome现在将把所有请求发送到本地网络上的目标服务器。

6.从首页,将一个脚本注入框架页面以请求http://chrome.r.intrud.es/secret.txt并将响应发送到攻击者的web服务器。

这可以在Chrome中实现瞬间DNS重新绑定。

7.jpg

为了帮助实现这个漏洞,我编写了一个小型web服务器,当它接收到/block请求时将停止。你可以在这里找到运行它的源代码和说明。

当攻击自动浏览器时,你通常想要在页面中包含一个iFrame,这需要一些时间来加载。这将阻止浏览器认为页面已完全加载,直到iFrame已加载,并确保漏洞利用脚本有足够的时间运行。下面的演示显示,当gowitness被用来从启用了IPv6的EC2上截取恶意网站的截图时,这个漏洞被用来从AWS元数据服务中提取凭证:

8.jpg

或者对于更可能在web应用程序中发现的场景,使用无头Chromium将网页转换为PDF:

9.jpg

这种绕过Chrome的PNA限制的行为通过他们的问题跟踪器报告给了Chrome团队。他们确定这不是安全问题,因为PNA的限制仍在实施过程中。

总结

DNS重新绑定是攻击web应用程序的一个武器。在本系列的第一篇文章中,我试图展示如何在不太复杂的情况下实现针对web应用程序的重新绑定漏洞。在这篇文章中,我提供了一些工具和技术来构建可靠的漏洞攻击驱动自动浏览器的web应用程序,即使它们只加载页面很短的时间。

本文翻译自:https://www.intruder.io/research/split-second-dns-rebinding-in-chrome-and-safari如若转载,请注明原文地址


文章来源: https://www.4hou.com/posts/z4O5
如有侵权请联系:admin#unsafe.sh