2023-08-16 09:07:58 +00:00
# Shadow DOM
< details >
2024-01-01 19:59:31 +00:00
< summary > < strong > 从零到英雄学习AWS黑客技术, 通过< / strong > < a href = "https://training.hacktricks.xyz/courses/arte" > < strong > htARTE (HackTricks AWS Red Team Expert)< / strong > < / a > < strong > !< / strong > < / summary >
2023-08-16 09:07:58 +00:00
2024-01-01 19:59:31 +00:00
支持HackTricks的其他方式:
* 如果你想在 **HackTricks中看到你的公司广告** 或 **下载HackTricks的PDF** ,请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取 [**官方的PEASS & HackTricks商品** ](https://peass.creator-spring.com )
* 发现 [**PEASS家族** ](https://opensea.io/collection/the-peass-family ),我们独家的[**NFTs系列**](https://opensea.io/collection/the-peass-family)
* **加入** 💬 [**Discord群组** ](https://discord.gg/hRep4RUj7f ) 或 [**telegram群组** ](https://t.me/peass ) 或在 **Twitter** 🐦 上 **关注** 我 [**@carlospolopm** ](https://twitter.com/carlospolopm )**.**
* **通过向** [**HackTricks** ](https://github.com/carlospolop/hacktricks ) 和 [**HackTricks Cloud** ](https://github.com/carlospolop/hacktricks-cloud ) github仓库提交PR来分享你的黑客技巧。
2023-08-16 09:07:58 +00:00
< / details >
## 基本信息
2024-01-01 19:59:31 +00:00
Shadow DOM是[Web组件](https://developer.mozilla.org/en-US/docs/Web/Web\_Components)功能套件的一部分, 旨在允许JS开发者创建具有封装功能的可复用自定义元素, 与网站代码的其余部分隔离。
2023-08-16 09:07:58 +00:00
2024-01-01 19:59:31 +00:00
本质上, 你可以使用Shadow DOM来**隔离你的组件的HTML和CSS, 使其与网页的其余部分隔离**。例如, 如果你在shadow DOM中创建元素ID, 它们**不会与父DOM中的元素ID冲突**。你在shadow DOM中使用的任何CSS选择器只会应用于shadow DOM内部, 而不会影响到父DOM, 你在父DOM中使用的任何选择器也不会渗透到shadow DOM内部。
2023-08-16 09:07:58 +00:00
```js
// creating a shadow DOM
let $element = document.createElement("div");
$shadowDomRef = $element.attachShadow({ mode: "open" }); // open or closed
```
2024-01-01 19:59:31 +00:00
通常,当你将一个**"open" 影子 DOM 附加到一个元素上**时,你可以通过 ** `$element.shadowRoot` ** 获取到影子 DOM 的引用。然而,如果影子 DOM 是以**"closed"** 模式附加的,你**无法**通过这种方式获得它的引用。即使我阅读了我能找到的所有开发者文档,我对 closed 模式的目的仍然有些不清楚。[根据 Google 的说法](https://developers.google.com/web/fundamentals/web-components/shadowdom):
2023-08-16 09:07:58 +00:00
2024-01-01 19:59:31 +00:00
> 影子 DOM 还有另一种叫做 "closed" 模式的形式。当你创建一个**closed** 影子树时,**外部的 JavaScript 将无法访问你组件的内部 DOM**。这和像 `<video>` 这样的原生元素的工作方式类似。JavaScript 无法访问 `<video>` 的影子 DOM, 因为浏览器是用 closed-mode 影子根来实现的。
2023-08-16 09:07:58 +00:00
然而,他们也指出:
2024-01-01 19:59:31 +00:00
> Closed 影子根并不是很有用。一些开发者会将 closed 模式视为一个**人为的安全特性**。但让我们明确一点,它**不是**一个安全特性。
2023-08-16 09:07:58 +00:00
2024-01-01 19:59:31 +00:00
## 访问影子 DOM
2023-08-16 09:07:58 +00:00
2024-01-01 19:59:31 +00:00
### window.find() 和文本选择 <a href="#introducing-windowfind-and-text-selections" id="introducing-windowfind-and-text-selections"></a>
2023-08-16 09:07:58 +00:00
2024-01-01 19:59:31 +00:00
函数 ** `window.find("search_text")` 能够穿透影子 DOM**。这个函数实际上具有与网页上的 ctrl-F 相同的功能。
2023-08-16 09:07:58 +00:00
2024-01-01 19:59:31 +00:00
可以调用 ** `document.execCommand("SelectAll")` ** 尽可能地扩大选择范围,然后调用 ** `window.getSelection()` ** 来**返回**影子 DOM 内所选文本的**内容**。
2023-08-16 09:07:58 +00:00
2024-01-01 19:59:31 +00:00
在 **firefox** 中,你可以使用 `getSelection()` ,它返回一个 [Selection ](https://developer.mozilla.org/en-US/docs/Web/API/Selection ) 对象,其中 `anchorElement` 是**影子 DOM 中元素的引用**。因此,我们可以按如下方式泄露影子 DOM 的内容:
2023-08-16 09:07:58 +00:00
```js
getSelection().anchorNode.parentNode.parentNode.parentNode.innerHTML
```
2024-01-01 19:59:31 +00:00
但这在Chromium中不起作用。
2023-08-16 09:07:58 +00:00
2024-01-01 19:59:31 +00:00
### 可编辑内容或CSS注入 <a href="#contenteditable-or-css-injection" id="contenteditable-or-css-injection"></a>
2023-08-16 09:07:58 +00:00
2024-01-01 19:59:31 +00:00
我们可能与shadow DOM交互的一种方式是, 如果我们在其中有**HTML或JS注入**。在某些有趣的情况下, 你可以在shadow DOM中获得注入, 而在普通的crossorigin页面上则无法做到。
2023-08-16 09:07:58 +00:00
2024-01-01 19:59:31 +00:00
一个例子是,如果你有任何带有`contenteditable`属性的**元素**。这是一个已弃用且很少使用的HTML属性, 它声明了**该元素的内容可由用户编辑**。我们可以使用选择与**`document.execCommand`** API来与可编辑内容的元素交互并获得HTML注入!
2023-08-16 09:07:58 +00:00
```js
find('selection within contenteditable');
document.execCommand('insertHTML',false,'< svg / onload = console.log(this.parentElement.outerHTML) > ')
```
2024-01-01 19:59:31 +00:00
或许更有趣的是,**`contenteditable`** 可以通过应用一个已弃用的 **CSS 属性:`-webkit-user-modify:read-write`** 在 chromium 中的任何元素上声明。
2023-08-16 09:07:58 +00:00
2024-01-01 19:59:31 +00:00
这使我们能够通过向元素添加 CSS 属性,然后使用 `insertHTML` 命令,将 **CSS/样式注入提升为 HTML 注入** 。
2023-08-16 09:07:58 +00:00
## CTF
2024-01-01 19:59:31 +00:00
查看这篇 writeup, 其中使用了这项技术作为 CTF 挑战:[https://github.com/Super-Guesser/ctf/blob/master/2022/dicectf/shadow.md](https://github.com/Super-Guesser/ctf/blob/master/2022/dicectf/shadow.md)
2023-08-16 09:07:58 +00:00
## 参考资料
* [https://blog.ankursundara.com/shadow-dom/ ](https://blog.ankursundara.com/shadow-dom/ )
< details >
2024-01-01 19:59:31 +00:00
< summary > < strong > 从零开始学习 AWS 黑客攻击直到成为专家,通过< / strong > < a href = "https://training.hacktricks.xyz/courses/arte" > < strong > htARTE (HackTricks AWS 红队专家)< / strong > < / a > < strong > ! < / strong > < / summary >
支持 HackTricks 的其他方式:
2023-08-16 09:07:58 +00:00
2024-01-01 19:59:31 +00:00
* 如果你想在 **HackTricks 中看到你的公司广告** 或 **下载 HackTricks 的 PDF** ,请查看 [**订阅计划** ](https://github.com/sponsors/carlospolop )!
* 获取 [**官方 PEASS & HackTricks 商品** ](https://peass.creator-spring.com )
* 发现 [**PEASS 家族** ](https://opensea.io/collection/the-peass-family ),我们独家的 [**NFT 集合** ](https://opensea.io/collection/the-peass-family )
* **加入** 💬 [**Discord 群组** ](https://discord.gg/hRep4RUj7f ) 或 [**telegram 群组** ](https://t.me/peass ) 或在 **Twitter** 🐦 上 **关注** 我 [**@carlospolopm** ](https://twitter.com/carlospolopm )**。**
* **通过向 [**HackTricks** ](https://github.com/carlospolop/hacktricks ) 和 [**HackTricks Cloud** ](https://github.com/carlospolop/hacktricks-cloud ) github 仓库提交 PR 来分享你的黑客技巧。**
2023-08-16 09:07:58 +00:00
< / details >