Tricks for Reliable Split-Second DNS Rebinding in Chrome and Safari

Tricks for Reliable Split-Second DNS Rebinding in Chrome and Safari

This is the second post in a two-part series on DNS rebinding. The first post covered a real-world exploit using DNS rebinding against our own product. In this post, I introduce new techniques for achieving reliable, split-second DNS rebinding in Chrome, Edge, and Safari when IPv6 is available, as well as a technique for bypassing the local network restrictions applied to the fetch API in Chromium-based browsers. This post assumes you have a basic understanding of DNS rebinding, as covered in the previous post.
这是关于 DNS 重新绑定的两部分系列文章中的第二篇。第一篇文章介绍了一个使用DNS重新绑定来攻击我们自己的产品的真实漏洞。在这篇文章中,我将介绍在 IPv6 可用时在 Chrome、Edge 和 Safari 中实现可靠的瞬间 DNS 重新绑定的新技术,以及一种绕过应用于基于 Chromium 的浏览器中获取 API 的本地网络限制的技术。这篇文章假设你对 DNS 重新绑定有基本的了解,如上一篇文章所述。

DNS rebinding in browsers has traditionally been seen as a way for attackers to access internal network services by tricking victims into loading a malicious website, but with many modern web applications now driving headless browsers for part of their functionality, it’s become a useful tool for attacking web applications. In the previous post, I covered an example of this using perhaps the simplest method for rebinding. In that scenario, I had the luxury of a long time for the exploit to run, but this is unlikely to be the case on many web applications, where faster techniques are necessary.
传统上,浏览器中的 DNS 重新绑定被视为攻击者通过诱骗受害者加载恶意网站来访问内部网络服务的一种方式,但随着许多现代 Web 应用程序现在驱动无头浏览器实现其部分功能,它已成为攻击 Web 应用程序的有用工具。在上一篇文章中,我介绍了一个示例,使用可能是最简单的重新绑定方法。在这种情况下,我有很长一段时间的时间来运行漏洞利用,但在许多需要更快技术的 Web 应用程序上,情况不太可能如此。

Slow Caches 慢速缓存

Simple DNS rebinding techniques rely on returning different DNS records for successive lookups of the same hostname. For these attacks, the minimum time taken is the time between two successive DNS lookups being performed by the browser. This can sometimes be sped up by flushing the browser cache – generating a large number of DNS lookups to fill up the available cache space, and causing older entries to be discarded before they’ve expired – to cause the browser to perform a second lookup of the same hostname sooner.
简单的 DNS 重新绑定技术依赖于返回不同的 DNS 记录来连续查找同一主机名。对于这些攻击,所花费的最短时间是浏览器执行两次连续 DNS 查找之间的时间。有时可以通过刷新浏览器缓存来加快速度 – 生成大量 DNS 查找以填满可用的缓存空间,并导致较旧的条目在过期之前被丢弃 – 使浏览器更快地执行同一主机名的第二次查找。

When this works, it will still take somewhere in the order of 10 seconds, and often this technique won’t work because of intermediate caches which can’t be cleared as easily as the browser’s cache. For example, during testing I found that on a freshly created Ubuntu EC2 instance I would only be able to get a different response for the same domain every 5 minutes due to the cache of systemd-resolve. On a VPN, I’ve seen DNS responses being cached for a minimum 30 minutes on the default resolver. It will often be a struggle to get users to keep a page open for this long to allow you to pull off a DNS rebinding exploit, let alone a headless browser being driven as part of a web application.
当这起作用时,它仍然需要大约 10 秒的时间,而且这种技术通常不起作用,因为中间缓存不能像浏览器的缓存那样容易清除。例如,在测试期间,我发现在新创建的 Ubuntu EC2 实例上,由于 systemd-resolve 的缓存,我每 5 分钟只能获得同一域的不同响应。在 VPN 上,我看到 DNS 响应在默认解析器上缓存了至少 30 分钟。要让用户保持页面打开这么长时间以允许您实施 DNS 重新绑定漏洞通常很困难,更不用说作为 Web 应用程序的一部分驱动的无头浏览器了。

To speed up exploits, in 2010 Craig Heffner presented the idea of performing DNS rebinding by replying with multiple A records for the same domain in the same response, a technique which was used by Gerald Doussot and Roger Meyer in singularity in 2019. The 2 records returned are the IP address of a public, attacker-controlled server and the (usually private) IP address of the target server.
为了加快漏洞利用速度,2010 年,Craig Heffner 提出了通过在同一响应中回复同一域的多个 A 记录来执行 DNS 重新绑定的想法,Gerald Doussot 和 Roger Meyer 在 2019 年的奇点中使用了这种技术。返回的 2 条记录是攻击者控制的公共服务器的 IP 地址和目标服务器的(通常是私有的)IP 地址。

The attack will only work if the browser attempts to communicate with the public server first and loads the attacker’s malicious page. The attacker’s web server then starts blocking traffic from the victim’s browser, causing the browser to fall back to sending all future requests to the target server. In this case, JavaScript in the attacker’s page will be able to send requests to the target IP address under the same origin.
只有当浏览器首先尝试与公共服务器通信并加载攻击者的恶意页面时,攻击才会起作用。然后,攻击者的 Web 服务器开始阻止来自受害者浏览器的流量,导致浏览器回退到向目标服务器发送所有未来的请求。在这种情况下,攻击者页面中的 JavaScript 将能够向同一源下的目标 IP 地址发送请求。

Tricks for Reliable Split-Second DNS Rebinding in Chrome and Safari

This technique does bypass the caching problem as the browser only has to perform one DNS lookup, though during my testing all the major browsers would consistently attempt to communicate to private IP addresses before public ones, meaning these techniques didn’t work. While I don’t believe this behaviour is intended as a protection against DNS rebinding (I even got confirmation of this from one of the Chrome developers when informing them of my findings), it is effective at stopping this technique.
这种技术确实绕过了缓存问题,因为浏览器只需要执行一次DNS查找,尽管在我的测试中,所有主要浏览器都会在公共IP地址之前始终尝试与私有IP地址进行通信,这意味着这些技术不起作用。虽然我不认为这种行为是为了防止DNS重新绑定(我甚至在告知他们我的发现时得到了一位Chrome开发人员的确认),但它可以有效地阻止这种技术。

This new behaviour led me to research new techniques which can be used to achieve split-second DNS rebinding in Safari and Chromium-based browsers. The key to these techniques is finding new ways to make browsers initially use a public IP then switch to using a private IP when loading a website. Opening up Wireshark, I noticed that while loading websites in modern browsers, both an A and a AAAA query are sent. I started investigating whether this behaviour could be used to reliably perform DNS rebinding.
这种新行为促使我研究了新技术,这些新技术可用于在 Safari 和基于 Chromium 的浏览器中实现瞬间 DNS 重新绑定。这些技术的关键是找到新的方法,使浏览器最初使用公共IP,然后在加载网站时切换到使用私有IP。打开 Wireshark,我注意到在现代浏览器中加载网站时,会发送 A 和 AAAA 查询。我开始研究此行为是否可用于可靠地执行 DNS 重新绑定。

Attacking Safari: Delaying DNS Responses
攻击 Safari:延迟 DNS 响应

When you load a web page in Safari on a host with access to the internet over IPv6, A and AAAA DNS queries are sent for IPv4 and IPv6 addresses respectively. Safari will prioritise private IP addresses over public ones when multiple IP addresses are returned.
当您在通过 IPv6 访问互联网的主机上的 Safari 中加载网页时,将分别针对 IPv4 和 IPv6 地址发送 A 和 AAAA DNS 查询。当返回多个 IP 地址时,Safari 浏览器将优先使用私有 IP 地址而不是公共 IP 地址。

The interesting behaviour which allows for fast DNS rebinding in Safari occurs when either the A or AAAA response is delayed. In this case, Safari doesn’t wait for all DNS responses, but instead sends HTTP requests as soon as the first DNS response is received. When the delayed DNS response is received, the IP addresses in this response are added to the pool of IP addresses that Safari can use for future requests to the domain.
当 A 或 AAAA 响应延迟时,允许在 Safari 中快速重新绑定 DNS 的有趣行为就会发生。在这种情况下,Safari 浏览器不会等待所有 DNS 响应,而是在收到第一个 DNS 响应后立即发送 HTTP 请求。当收到延迟的 DNS 响应时,此响应中的 IP 地址将添加到 Safari 将来可以用于域请求的 IP 地址池中。

This means that if the first DNS response is for a public IP address, and the delayed DNS response is for a private IP address, Safari will send the first requests to the public IP address until the delayed DNS response is received, at which point it will start sending requests to the private IP address.
这意味着,如果第一个 DNS 响应是针对公共 IP 地址的,而延迟的 DNS 响应是针对专用 IP 地址的,则 Safari 将向公共 IP 地址发送第一个请求,直到收到延迟的 DNS 响应,此时它将开始向专用 IP 地址发送请求。

Tricks for Reliable Split-Second DNS Rebinding in Chrome and Safari

This provides a simple method for achieving DNS rebinding in Safari using a custom DNS server which handles queries for *.r.intrud.es:
这提供了一种简单的方法,用于在 Safari 中使用自定义 DNS 服务器实现 DNS 重新绑定,该服务器处理对 *.r.intrud.es 的查询:

  1. Make the target browser load http://safari.r.intrud.es, triggering A and AAAA lookups for safari.r.intrud.es.
    使目标浏览器加载 http://safari.r.intrud.es,触发 A 和 AAAA 查找 safari.r.intrud.es。
  2. Have the DNS server return a AAAA record instantly, containing the IPv6 address of an attacker-controlled web server on the internet. Do not return the A response yet.
    让 DNS 服务器立即返回 AAAA 记录,其中包含 Internet 上攻击者控制的 Web 服务器的 IPv6 地址。暂时不要返回 A 响应。
  3. Safari will make the first request to the attacker’s web server once it has received the AAAA response. From the attacker’s web server, return a page with JavaScript to repeatedly request http://safari.r.intrud.es/secret.txt.
    Safari 在收到 AAAA 响应后,将向攻击者的 Web 服务器发出第一个请求。从攻击者的 Web 服务器返回一个带有 JavaScript 的页面,以重复请求 http://safari.r.intrud.es/secret.txt。
  4. Send the A response from the DNS server containing the IP address of the target server on the local network.
    从 DNS 服务器发送 A 响应,其中包含本地网络上目标服务器的 IP 地址。
  5. Safari will now send the requests for http://safari.r.intrud.es/secret.txt to the target server on the local network. The responses of these requests can be read by the page loaded from the attacker’s server without violating the same-origin policy.
    Safari 现在会将 http://safari.r.intrud.es/secret.txt 请求发送到本地网络上的目标服务器。这些请求的响应可以由从攻击者服务器加载的页面读取,而不会违反同源策略。

To achieve this, I’ve written a small DNS server which can be used to delay DNS responses with command-line arguments. In practice, I found that delaying the A response by 100ms was almost always enough, though a delay of 200ms or more can be used to make the technique even more reliable. This server, as well as instructions for setting it up, can be found here.
为了实现这一点,我编写了一个小型DNS服务器,可用于通过命令行参数延迟DNS响应。在实践中,我发现将 A 响应延迟 100 毫秒几乎总是足够的,尽管 200 毫秒或更长时间的延迟可用于使该技术更加可靠。可以在此处找到此服务器以及设置说明。

The PHP script I’ve used to exploit this will redirect the user to a random subdomain of r.intrud.es to avoid intermediate caches interfering with the exploit. It also includes the JavaScript directly in the page to avoid another resource load. You can find the code used here.
我用来利用这一点的 PHP 脚本会将用户重定向到 r.intrud.es 的随机子域,以避免中间缓存干扰该漏洞利用。它还直接在页面中包含 JavaScript,以避免其他资源负载。您可以在此处找到使用的代码。

Here’s a video of this script in action, retrieving the contents of a file from a local web server:
下面是此脚本的运行视频,该脚本从本地 Web 服务器检索文件的内容:

I’ve tested in Safari and Brave on iOS, and found that this same technique will work to access services on the internal network.
我在 iOS 上的 Safari 和 Brave 中进行了测试,发现同样的技术也适用于访问内部网络上的服务。

Attacking Chrome: Using AAAA Prioritisation
攻击 Chrome:使用 AAAA 优先级

Chrome will prioritise loading pages on the local network over pages on the internet, but it gives more priority to loading pages over IPv6 instead of IPv4 when available. So the priority is:
Chrome 会优先在本地网络上加载网页,而不是在互联网上加载网页,但它会更优先地通过 IPv6 而不是 IPv4(如果可用)加载网页。所以优先级是:

  1. Local IPv6 (Highest Priority)
    本地 IPv6(最高优先级)
  2. Public IPv6 公共 IPv6
  3. Local IPv4 本地 IPv4
  4. Public IPv4 (Lowest Priority)
    公共 IPv4(最低优先级)

The key part here is that Chrome will prioritise a public IPv6 address over a private IPv4 address. Further, when Chrome knows multiple IP addresses for a domain, it will try a different IP address as soon as the server at one resets the connection.
这里的关键部分是 Chrome 将优先考虑公共 IPv6 地址而不是私有 IPv4 地址。此外,当 Chrome 知道一个域的多个 IP 地址时,一旦服务器重置连接,它就会尝试使用不同的 IP 地址。

Tricks for Reliable Split-Second DNS Rebinding in Chrome and Safari

This gives a plan for fast DNS rebinding against Chrome:
这给出了针对 Chrome 的快速 DNS 重新绑定计划:

  1. Load http://chrome.r.intrud.es which will trigger A and AAAA lookups for chrome.r.intrud.es.
    加载 http://chrome.r.intrud.es,这将触发 A 和 AAAA 查找 chrome.r.intrud.es。
  2. Have the DNS server return an A record pointing to the target web server on the local network, and a AAAA record pointing to an attacker-controlled web server on the public internet.
    让 DNS 服务器返回指向本地网络上目标 Web 服务器的 A 记录,以及指向公共 Internet 上攻击者控制的 Web 服务器的 AAAA 记录。
  3. Chrome will prioritise the IPv6 address, and make the first request to load the page from the attacker controlled web-server, which returns JavaScript to repeatedly make requests to http://chrome.r.intrud.es/secret.txt.
    Chrome 将优先处理 IPv6 地址,并发出第一个请求,从攻击者控制的网络服务器加载页面,该服务器返回 JavaScript 以重复向 http://chrome.r.intrud.es/secret.txt 发出请求。
  4. Shut down the attacker-controlled server so that all connections are reset. Chrome will now make all requests to the target server on the local network.
    关闭攻击者控制的服务器,以便重置所有连接。Chrome 现在将向本地网络上的目标服务器发出所有请求。
  5. Have the loaded page make requests to http://chrome.r.intrud.es/secret.txt. The responses to these requests can be read without violating the same-origin policy.
    让加载的页面向 http://chrome.r.intrud.es/secret.txt 发出请求。可以在不违反同源策略的情况下读取对这些请求的响应。

This plan almost worked. The JavaScript on the page loaded from the internet attempted to make requests to the target on the local network, but these requests were blocked with the following error in the console:
这个计划几乎奏效了。从 Internet 加载的页面上的 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`.

This error occurs because Chrome partially implements the protections outlined in the Private Network Access (PNA) specification.
出现此错误的原因是 Chrome 部分实施了专用网络访问 (PNA) 规范中概述的保护措施。

Bypassing Private Network Access
绕过专用网络访问

The PNA protections block pages loaded over plain HTTP from the public internet from making requests to the private networks. In Chrome, these protections are implemented for fetch requests, but aren’t yet implemented for iFrames. The incomplete implementation, along with DNS rebinding, allows the PNA restrictions on fetch requests to be bypassed.
PNA 保护阻止通过纯 HTTP 从公共 Internet 加载的页面向专用网络发出请求。在 Chrome 中,这些保护措施是针对提取请求实施的,但尚未针对 iFrame 实施。不完整的实现以及 DNS 重新绑定允许绕过 PNA 对提取请求的限制。

We can repeat the exploit through to step 4 above, where the public web server has been shut off and all requests to http://chrome.r.intrud.es are now directed to the target server on the local network. The loaded top page can’t make requests to the local network as it was loaded over HTTP from the public internet, but we can load http://chrome.r.intrud.es in an iFrame. The page in this iFrame will be loaded from the target web server. As this server is on the local network, the page loaded in the iFrame is allowed to make requests to the local network.
我们可以在上面的第 4 步中重复该漏洞利用,其中公共 Web 服务器已被关闭,所有对 http://chrome.r.intrud.es 的请求现在都定向到本地网络上的目标服务器。加载的首页无法向本地网络发出请求,因为它是通过 HTTP 从公共 Internet 加载的,但我们可以在 iFrame 中加载 http://chrome.r.intrud.es。此 iFrame 中的页面将从目标 Web 服务器加载。由于此服务器位于本地网络上,因此允许 iFrame 中加载的页面向本地网络发出请求。

The page in the iFrame is also under the same origin as the top page, which allows the top page to fully control the DOM of the framed page. This includes injecting scripts which make fetch requests into the framed page. These scripts can be used to access the target web server and exfiltrate data just as they would be able to from the top page if PNA wasn’t implemented at all.
iFrame 中的页面也与首页处于同一源位置,这使得首页可以完全控制被框页面的 DOM。这包括将脚本注入到框架页面中,这些脚本会发出提取请求。这些脚本可用于访问目标 Web 服务器并泄露数据,就像在根本没有实现 PNA 的情况下从首页泄露数据一样。

Tricks for Reliable Split-Second DNS Rebinding in Chrome and Safari

So, putting this all together we end up with a complete plan:
因此,将所有这些放在一起,我们最终会得到一个完整的计划:

  1. Load http://chrome.r.intrud.es which will trigger A and AAAA lookups for chrome.r.intrud.es.
    加载 http://chrome.r.intrud.es,这将触发 A 和 AAAA 查找 chrome.r.intrud.es。
  2. Have the DNS server return an A record pointing to the target web server on the local network, and a AAAA record pointing to an attacker-controlled web server on the public internet.
    让 DNS 服务器返回指向本地网络上目标 Web 服务器的 A 记录,以及指向公共 Internet 上攻击者控制的 Web 服务器的 AAAA 记录。
  3. Chrome will make the first request to load the top page from the attacker’s web-server, which returns a page to execute the following steps.
    Chrome 将发出第一个请求,从攻击者的网络服务器加载首页,该请求将返回一个页面以执行以下步骤。
  4. Shut down the attacker-controlled server so that all connection attempts are reset. Chrome will now make all requests to the target server on the local network.
    关闭攻击者控制的服务器,以便重置所有连接尝试。Chrome 现在将向本地网络上的目标服务器发出所有请求。
  5. Load http://chrome.r.intrud.es in an iFrame.
    在 iFrame 中加载 http://chrome.r.intrud.es。
  6. From the top page, inject a script into the framed page to request http://chrome.r.intrud.es/secret.txt and send the response to the attacker’s web server.
    在首页,将脚本注入框架页面以请求 http://chrome.r.intrud.es/secret.txt 并将响应发送到攻击者的 Web 服务器。

This works to achieve split-second DNS rebinding in Chrome:
这适用于在 Chrome 中实现瞬间 DNS 重新绑定:

To help achieve this exploit, I wrote a small web server which will stop when it receives a request to /block. You can find the source code and instructions for running it here.
为了帮助实现这个漏洞,我编写了一个小型 Web 服务器,当它收到对 /block 的请求时,它将停止。您可以在此处找到源代码和运行说明。

When attacking automated browsers, you’ll often want to include an iFrame in the page which takes some time to load. This stops the browser considering the page fully loaded until that iFrame has loaded, and ensures that the exploit script has enough time to run. The following demo shows this exploit being used to extract credentials from the AWS metadata service when gowitness is used to take a screenshot of a malicious website from an EC2 with IPv6 enabled:
在攻击自动浏览器时,您通常希望在页面中包含一个 iFrame,这需要一些时间才能加载。这将停止浏览器认为页面已完全加载,直到该 iFrame 加载完毕,并确保漏洞利用脚本有足够的时间运行。以下演示显示了当 gowitness 用于从启用了 IPv6 的 EC2 截取恶意网站的屏幕截图时,此漏洞用于从 AWS 元数据服务中提取凭证:

Or, for a scenario more likely to be found in a web application, headless Chromium being used to convert a web page to a PDF:
或者,对于更有可能在 Web 应用程序中找到的方案,使用无头 Chromium 将网页转换为 PDF:

This bypass of Chrome’s PNA restrictions was reported to the Chrome team through their issue tracker. They determined that it wasn’t a security issue since the PNA restrictions are still in the process of being implemented.
Chrome 团队通过其问题跟踪器向 Chrome 团队报告了这种绕过 Chrome 的 PNA 限制的行为。他们确定这不是安全问题,因为PNA限制仍在实施过程中。

Summary 总结

DNS rebinding can be a useful weapon in your arsenal for attacking web applications. In the first post in this series, I tried to show how rebinding exploits against web applications can be achievable without much complexity. In this post, I’ve provided tools and techniques to build reliable exploits against web applications driving automated browsers, even if they only load pages for a short time. I hope you now feel well-equipped to start using DNS rebinding in exploits against the applications you test.
DNS 重新绑定可以成为攻击 Web 应用程序的有用武器。在本系列的第一篇文章中,我试图展示如何实现针对 Web 应用程序的重新绑定漏洞,而不会有太多的复杂性。在这篇文章中,我提供了一些工具和技术来构建针对驱动自动浏览器的 Web 应用程序的可靠漏洞利用,即使它们只加载了很短的时间页面。我希望您现在觉得自己已经准备好开始使用 DNS 重新绑定来攻击您测试的应用程序。

原文始发于Daniel Thatcher:Tricks for Reliable Split-Second DNS Rebinding in Chrome and Safari

版权声明:admin 发表于 2023年12月12日 下午8:40。
转载请注明:Tricks for Reliable Split-Second DNS Rebinding in Chrome and Safari | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...