0015. 编码差异:字符集为何重要【转载】

admin 2024年7月17日08:53:18评论30 views字数 4701阅读15分40秒阅读模式
本文章仅用网络安全研究学习,请勿使用相关技术进行违法犯罪活动。
声明:本文搬运自国外互联网,如你是原作者,请联系我们!
标签:XSS
您是否注意到以下 HTTP 响应中的某些内容?
HTTP/1.1 200 OKServer: Some ServerContent-Type: text/htmlContent-Length: 1337<!DOCTYPE html><html><head><title>Some Page</title></head><body>...
根据 HTTP 响应的这一小部分,您可以假设该 Web 应用程序可能容易受到 XSS 漏洞的影响
这怎么可能?你注意到什么了吗?
如果您对标头有疑问Content-Type,那么您是对的。这里只有一个小瑕疵:标头缺少一个属性。这听起来不是什么大问题,但是,这篇博文将解释攻击者如何利用这一点,通过有意识地更改浏览器假定的字符charset集将任意 JavaScript 代码注入网站。
这篇博文的内容也在TROOPERS24 会议上进行了展示。我们将在录音发布后立即添加链接,并在X/TwitterMastodon上通知您。

字符编码

HTTP 响应中的常见Content-Type标头如下所示:
HTTP/1.1 200 OKServer: Some ServerContent-Type: text/html;charset=utf-8...
charset属性告诉浏览器使用 UTF-8 编码 HTTP 响应主体。UTF-8 之类的字符编码定义了字符和字节之间的映射。当 Web 服务器提供 HTML 文档时,它会将文档的字符映射到相应的字节,并在 HTTP 响应主体中传输这些字节。此过程将字符转换为字节(编码):
0015. 编码差异:字符集为何重要【转载】
当浏览器在 HTTP 响应主体中收到这些字节时,它可以将它们转换回 HTML 文档的字符。此过程将字节转换为字符(解码):
0015. 编码差异:字符集为何重要【转载】

根据HTML 规范,UTF-8 只是现代浏览器必须支持的众多字符编码之一。还有很多其他编码,例如UTF-16、ISO-8859-xx、windows-125x、GBK、Big5等等浏览器必须知道服务器使用了哪种编码,否则它无法正确解码HTTP 响应主体中的字节。

charset但是如果标题中没有属性Content-Type或者属性无效怎么办?

<meta>在这种情况下,浏览器会在 HTML 文档本身中查找标签。此标签还可以具有charset指示字符编码的属性(例如<meta charset="UTF-8">)。对于浏览器来说,这已经是一种平衡行为:为了读取 HTML 文档,它需要解码 HTTP 响应主体。因此,它需要假设某种编码,解码 HTTP 主体,查找标签<meta>,并可能使用指示的字符编码重新解码主体。

另一种不太常用的表示字符编码的方法是字节顺序标记。这是一个特定的 Unicode 字符 ( U+FEFF),可以放在字符串前面以指示字节顺序和字符编码。它主要用于文件,但由于这些文件可能通过 Web 服务器提供,因此现代浏览器也支持它。HTML 文档开头的字节顺序标记甚至优先于Content-Type头和标签charset中的属性

综上所述,浏览器确定HTML 文档的字符编码的常用方法有三种,按优先级排序:

  1. HTML 文档开头的字节顺序标记

  2. Content-Type中的charset属性

  3. HTML 文档中的<meta>标签

缺少字符集信息

字节顺序标记通常很少见,并且该charset属性并不总是出现在Content-Type标头中,或者可能无效。此外,特别是对于部分 HTML 响应,通常没有<meta>指示字符编码的标记。在这些情况下,浏览器没有关于使用哪种字符集的任何信息:

0015. 编码差异:字符集为何重要【转载】

你见过这个错误信息吗?可能没有,因为它不存在

与错误的 HTML 语法类似,浏览器在解析 Web 服务器提供的内容时会尝试从缺失的字符集信息中恢复并充分利用它。这种不严格的行为有助于提供良好的用户体验,但也可能为mXSS漏洞利用技术打开方便之门

对于缺失的字符信息,浏览器会尝试根据内容做出有根据的猜测,这称为自动检测。这类似于MIME 类型嗅探,但在字符编码级别上运行。例如,Chromium 的渲染引擎 Blink 使用紧凑编码检测 (CED) 库来自动检测字符编码。从攻击者的角度来看,自动检测功能非常强大我们将会看到。

到目前为止,我们已经熟悉了浏览器可能使用的不同机制来确定 HTML 文档的字符编码。但攻击者如何利用这一点呢?

编码差异

字符编码的目的是将字符转换为计算机可处理的字节序列。这些字节可以通过网络传输,并由接收方解码回字符。这样,就可以恢复发送方想要传输的完全相同的字符

0015. 编码差异:字符集为何重要【转载】
只有当发送方和接收方就所使用的字符编码达成一致时,这种方法才有效。如果用于编码和解码的字符编码不匹配,接收方可能会看到不同的字符:
0015. 编码差异:字符集为何重要【转载】

这种用于编码和解码的字符编码之间的不匹配就是我们在这里所说的编码差异

对于 Web 应用程序,当用户控制的数据需要清理以防止跨站点脚本 (XSS) 漏洞时,这一点至关重要。如果浏览器采用的字符编码与 Web 服务器预期的字符编码不同,理论上这可能会破坏清理并导致 XSS 漏洞。

这本身不是什么大新闻,甚至谷歌在 2005 年也容易遇到类似的问题。谷歌的 404 页面没有提供字符集信息,可以通过插入UTF-7 XSS 负载来利用这一点。在 UTF-7 中,HTML 特殊字符(如尖括号)的编码与 ASCII 不同,可以利用它们来绕过清理:

+ADw-script+AD4-alert(1)+ADw-+AC8-script+AD4-

这极大地证明了这种编码的危险性,为了防止此类安全问题,这种编码在接下来的几年里被弃用。如今,HTML 规范甚至明确禁止使用 UTF-7以防止 XSS 漏洞。

虽然还有很多其他受支持的字符编码,但从攻击者的角度来看,其中大多数都没有什么用处。所有HTML 特殊字符(如尖括号和引号)支持 ASCII,而且由于大多数字符编码都兼容 ASCII,因此这些字符没有区别。即使对于 UTF-16(由于每个字符固定为两个字节,因此不兼容 ASCII),通常也不可能偷运 ASCII 字符,因为它们对应的字节表示是相同的,只是带有尾随(小端)或前导(大端)零字节。

然而,有一个特别有趣的编码:ISO-2022-JP

ISO-2022-JP

ISO-2022-JP 是RFC 1468中定义的日语字符编码。它是HTML 标准中定义的用户代理必须支持的官方字符编码之一。这种编码特别有趣的是,它支持某些转义序列在不同的字符集之间切换

例如,如果字节序列包含字节0x1b0x28、0x42。这些字节不会解码为字符,而是指示所有后续字节都应使用 ASCII 解码。总共有四种不同的转义序列可用于在字符集 ASCII、JIS X 0201 1976、JIS X 0208 1978 和 JIS X 0208 1983 之间切换:

0015. 编码差异:字符集为何重要【转载】

ISO-2022-JP 的这一特性不仅提供了极大的灵活性,而且还打破了基本假设。此外,还有一个问题:在撰写本文时,Chrome(Blink)Firefox(Gecko)会自动检测此编码。这些转义序列之一的一次出现通常足以使自动检测算法相信 HTTP 响应主体是用 ISO-2022-JP 编码的。

以下部分介绍了攻击者在使浏览器假定使用 ISO-2022-JP 字符集时可能使用的两种不同的利用技术。根据攻击者的能力,例如,可以通过直接控制标头charset中的属性Content-Type<meta>通过 HTML 注入漏洞插入标签来实现。如果 Web 服务器提供了无效charset属性或根本没有提供属性,通常没有其他先决条件,因为攻击者可以通过自动检测轻松将字符集切换为 ISO-2022-JP。

技术 1:否定反斜杠转义

此技术的场景是将用户控制的数据放置 JavaScript 字符串中

0015. 编码差异:字符集为何重要【转载】
假设有一个网站接受两个查询参数,分别称为searchlang。第一个参数反映在纯文本上下文中,第二个参数lang) 插入到 JavaScript 字符串中:
0015. 编码差异:字符集为何重要【转载】
参数中的 HTML 特殊字符search经过 HTML 编码,并且lang参数已通过转义双引号(")和反斜杠()进行了正确清理。因此,无法突破字符串上下文并注入 JavaScript 代码:
0015. 编码差异:字符集为何重要【转载】
ISO-2022-JP 的默认模式是 ASCII。这意味着收到的 HTTP 响应主体的所有字节都用 ASCII 解码,生成的 HTML 文档看起来就像我们期望的那样:
0015. 编码差异:字符集为何重要【转载】
现在,假设攻击者在参数search中插入转义序列0x1b,0x28,0x4a)以切换到 JIS X 0201 1976 字符集
0015. 编码差异:字符集为何重要【转载】
浏览器现在使用 JIS X 0201 1976 解码遵循此转义序列的所有字节:
0015. 编码差异:字符集为何重要【转载】
我们可以看到,这仍然会产生与以前相同的字符,因为 JIS X 0201 1976主要与ASCII 兼容。但是,如果我们仔细检查其代码表,我们会注意到有两个例外(以黄色突出显示):
0015. 编码差异:字符集为何重要【转载】
字节0x5c被映射到日元字符(¥),而字节被映射0x7e到上划线字符 ()。这与 ASCII 不同,在 ASCII 中,0x5c被映射到反斜杠字符 ()0x7e波浪符号字符 (~)
这意味着当 Web 服务器尝试使用lang反斜杠转义参数中的双引号时,浏览器不再看到反斜杠,而是看到日元符号:
0015. 编码差异:字符集为何重要【转载】
因此,插入的双引号实际上指定了字符串的结尾,并允许攻击者注入任意 JavaScript 代码:
0015. 编码差异:字符集为何重要【转载】
虽然这种技术非常强大,但它仅限于在 JavaScript 上下文中绕过清理,因为反斜杠字符在 HTML 中没有特殊含义。下一节将介绍一种可以在纯 HTML 上下文中应用的更高级的技术。

技术 2:破坏 HTML 上下文
第二种技术的应用场景是攻击者可以控制两个不同 HTML 上下文中的值。一个常见的用例是支持 markdown 的网站。例如,让我们考虑以下 markdown 文本:

0015. 编码差异:字符集为何重要【转载】
生成的 HTML 代码如下所示:
0015. 编码差异:字符集为何重要【转载】
这种技术的关键在于攻击者可以控制两个不同 HTML 上下文中的值。在本例中,它们是:
  • 属性上下文(图像描述/来源)
  • 纯文本上下文(图像周围的文本)
默认情况下,ISO-2022-JP处于ASCII模式,浏览器将按预期看到HTML文档:
0015. 编码差异:字符集为何重要【转载】
现在,假设攻击者在第一个图像描述中插入转义序列以将字符集切换为 JIS X 0208 1978:
0015. 编码差异:字符集为何重要【转载】
这会使浏览器解码所有遵循 JIS X 0208 1978 的字节。此字符集每个字符使用固定数量的 2 个字节,并且不兼容 ASCII。这实际上破坏了 HTML 文档:
0015. 编码差异:字符集为何重要【转载】
但是,可以在两个图像之间的纯文本上下文中插入第二个转义序列,以将字符集切换回 ASCII:
0015. 编码差异:字符集为何重要【转载】
这样,所有以下字节将再次使用 ASCII 解码:
0015. 编码差异:字符集为何重要【转载】
然而,检查 HTML 语法时,我们可以注意到有些东西发生了变化。第二个标签的开头现在是属性值img的一部分:alt
0015. 编码差异:字符集为何重要【转载】
原因是两个转义序列之间的 4 个字节是使用 JIS X 0208 1978 解码的。这还消耗了属性值的结束双引号
0015. 编码差异:字符集为何重要【转载】
此时,src第二张图片的属性值不再是属性值。因此,攻击者可以用 JavaScript 错误处理程序替换该值:
0015. 编码差异:字符集为何重要【转载】

这再次允许攻击者注入任意 JavaScript 代码。

概括

在这篇博文中,我们强调了在提供 HTML 文档时提供字符集信息的重要性。如果攻击者能够更改浏览器假定的字符集,则缺少字符集信息可能会导致严重的 XSS 漏洞。

我们详细介绍了浏览器如何确定用于解码 HTTP 响应主体的字符集,并解释了攻击者可能使用的利用 ISO-2022-JP 字符编码向网站注入任意 JavaScript 代码的两种不同技术。

虽然我们认为缺失的字符集才是真正的漏洞,但浏览器的自动检测功能会大大增加其影响。因此,我们希望浏览器能够根据我们的建议禁用自动检测机制 - 至少针对 ISO-2022-JP 字符编码。

原文始发于微信公众号(Rsec):0015. 编码差异:字符集为何重要【转载】

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年7月17日08:53:18
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   0015. 编码差异:字符集为何重要【转载】https://cn-sec.com/archives/2963356.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息